// Generated by gtkmmproc -- DO NOT MODIFY!


#include <gdkmm/color.h>
#include <gdkmm/private/color_p.h>

// -*- c++ -*-
/* $Id: color.ccg,v 1.3 2004/01/05 17:32:12 murrayc Exp $ */

/*
 *
 * Copyright 2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gdkmm/colormap.h>
#include <gdk/gdkcolor.h>
#include <gdk/gdkrgb.h>

namespace Gdk
{

Color::Color()
{
  GdkColor tmp = { 0, 0, 0, 0, };
  gobject_ = gdk_color_copy(&tmp);
}

Color::Color(const Glib::ustring& value)
{
  GdkColor tmp = { 0, 0, 0, 0, };
  gobject_ = gdk_color_copy(&tmp);

  set(value);
}

void Color::set_grey(gushort value)
{
  gobject_->red = gobject_->green = gobject_->blue = value;
}

void Color::set_grey_p(double g)
{
 gobject_->red = gobject_->green = gobject_->blue = (gushort)(g * 65535.0);
}

void Color::set_rgb(gushort red_, gushort green_, gushort blue_)
{
  gobject_->red = red_;
  gobject_->green = green_;
  gobject_->blue = blue_;
}

void Color::set_rgb_p(double red_, double green_, double blue_)
{
  gobject_->red = (gushort)(red_ * 65535.0);
  gobject_->green = (gushort)(green_ * 65535.0);
  gobject_->blue = (gushort)(blue_ * 65535.0);
}

void Color::set_hsv(double h, double s, double v)
{
  //TODO: Comments/Documentation. I have no idea what this code does. murrayc.
  
  h /= 60.0;
  int i = (int)h;
  double p = v * (1 - s);
  double q = v * (1 - s * (h - i));
  double t = v * (1 - s * (1 - h + i));

  switch(i)
  {
    case 0:
      set_rgb_p(v, t, p);
      break;
    case 1:
      set_rgb_p(q, v, p);
      break;
    case 2:
      set_rgb_p(p, v, t);
      break;
    case 3:
      set_rgb_p(p, q, v);
      break;
    case 4:
      set_rgb_p(t, p, v);
      break;
    default:
      set_rgb_p(v, p, q);
  }
}

void Color::set_hsl(double h, double s, double l)
{
  //TODO: Comments/Documentation. I have no idea what this code does. murrayc.

  if(s == 0.0)
    set_grey_p(l);
  else
  {
    double t2 = (l < 0.5) ? l * (1.0 + s) : l + s - l * s;
    double t1 = 2*l-t2;
    h /= 360.0;

    double tr = h + 1.0/3.0;
    double tg = h;
    double tb = h - 1.0/3.0;
    if (tb < 0) tb += 1.0;

    double r = 0.0, g = 0.0, b = 0.0;

    if (tr < 1.0/6.0)
      r = t1 +(t2-t1) * 6 * tr;
    else if (tr < 1.0/2.0)
      r = t2;
    else if (tr < 2.0/3.0)
      r = t1+(t2-t1)*(2.0/3.0 - tr) * 6.0;

    if (tg < 1.0/6.0)
      g = t1 + (t2 - t1) * 6 * tg;
    else if (tg < 1.0/2.0)
      g = t2;
    else if (tg < 2.0/3.0)
      g = t1+(t2-t1)*(2.0/3.0 - tg) * 6.0;

    if (tb < 1.0/6.0)
      b = t1 +(t2-t1) * 6 * tb;
    else if (tb < 1.0/2.0)
      b = t2;
    else if (tb < 2.0/3.0)
      b = t1+(t2-t1)*(2.0/3.0 - tb) * 6.0;

    set_rgb_p(r, g, b);
  }
}

bool Color::set(const Glib::ustring& value)
{
  return gdk_color_parse(value.c_str(), gobj());
}

bool Color::parse(const Glib::ustring& spec)
{
  return set(spec);
}

gushort Color::get_red() const
{
  return gobject_->red;
}

gushort Color::get_green() const
{
  return gobject_->green;

}
gushort Color::get_blue() const
{
 return gobject_->blue;
}

void Color::set_red(gushort value)
{
  gobject_->red = value;
}

void Color::set_green(gushort value)
{
  gobject_->green = value;
}

void Color::set_blue(gushort value)
{
  gobject_->blue = value;
}

void Color::rgb_find_color(const Glib::RefPtr<Gdk::Colormap>& map)
{
  gdk_rgb_find_color(map->gobj(), gobj());
}

guint Color::get_pixel() const
{
  return gobject_->pixel;
}

double Color::get_red_p() const
{
  return gobject_->red / 65535.0;
}

double Color::get_green_p() const
{
  return gobject_->green / 65535.0;
}

double Color::get_blue_p() const
{
  return gobject_->blue / 65535.0;
}


} //namespace Gdk


namespace
{
} // anonymous namespace


namespace Glib
{

Gdk::Color wrap(GdkColor* object, bool take_copy)
{
  return Gdk::Color(object, take_copy);
}

} // namespace Glib


namespace Gdk
{


// static
GType Color::get_type()
{
  return gdk_color_get_type();
}


Color::Color(const Color& other)
:
  gobject_ ((other.gobject_) ? gdk_color_copy(other.gobject_) : 0)
{}

Color::Color(GdkColor* gobject, bool make_a_copy)
:
  // For BoxedType wrappers, make_a_copy is true by default.  The static
  // BoxedType wrappers must always take a copy, thus make_a_copy = true
  // ensures identical behaviour if the default argument is used.
  gobject_ ((make_a_copy && gobject) ? gdk_color_copy(gobject) : gobject)
{}

Color& Color::operator=(const Color& other)
{
  Color temp (other);
  swap(temp);
  return *this;
}

Color::~Color()
{
  if(gobject_)
    gdk_color_free(gobject_);
}

void Color::swap(Color& other)
{
  GdkColor *const temp = gobject_;
  gobject_ = other.gobject_;
  other.gobject_ = temp;
}

GdkColor* Color::gobj_copy() const
{
  return gdk_color_copy(gobject_);
}


bool operator==(const Color& lhs, const Color& rhs)
{
  return (gdk_color_equal(lhs.gobj(), rhs.gobj()) != 0);
}

bool operator!=(const Color& lhs, const Color& rhs)
{
  return (gdk_color_equal(lhs.gobj(), rhs.gobj()) == 0);
}


} // namespace Gdk


