
// SDPGTK Library
// Copyright (c) 1995-2004, Timothy M. Shead
//
// Contact: tshead@k-3d.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include <k3dsdk/color.h>
#include <k3dsdk/vectors.h>

#include "sdpgtkcolorselection.h"

////////////////////////////////////////////////////////////////////////////////////////
// sdpGtkColorSelection

sdpGtkColorSelection::sdpGtkColorSelection() : sdpGtkVBox()
{
}

sdpGtkColorSelection::sdpGtkColorSelection(GtkColorSelection* ColorSelection) : sdpGtkVBox(GTK_VBOX(ColorSelection))
{
}

bool sdpGtkColorSelection::Create()
{
	m_Object = GTK_OBJECT(gtk_color_selection_new());
	return Attached();
}

bool sdpGtkColorSelection::Create(sdpGtkIObjectContainer* const ObjectContainer, sdpxml::Document& Document, sdpxml::Element& Element)
{
	// Sanity checks ...
	g_assert(ObjectContainer);

	return Create();
}

void sdpGtkColorSelection::SetUpdatePolicy(GtkUpdateType Policy)
{
	// Sanity checks ...
	g_return_if_fail(Attached());

	gtk_color_selection_set_update_policy(*this, Policy);
}

void sdpGtkColorSelection::SetColor(const double Red, const double Green, const double Blue)
{
	// Sanity checks ...
	g_return_if_fail(Attached());

	double color[4];
	color[0] = Red;
	color[1] = Green;
	color[2] = Blue;
	color[3] = 0.0;
	gtk_color_selection_set_color(*this, color);
}

void sdpGtkColorSelection::GetColor(double& Red, double& Green, double& Blue)
{
	g_return_if_fail(Attached());

	double color[4];
	gtk_color_selection_get_color(*this, color);

	Red = color[0];
	Green = color[1];
	Blue = color[2];
}

template<class Type> Type radians(const Type& degrees)
{ return degrees * 0.01745329252; }

void sdpGtkColorSelection::InteractiveSetColor(const double Red, const double Green, const double Blue, const gdouble Speed, const bool Pause)
{
	// Sanity checks ...
	g_return_if_fail(Attached());

	// Convert the current and new colors to HSV ...
	double red, green, blue;
	GetColor(red, green, blue);
	const k3d::basic_hsv current_hsv = k3d::color(red, green, blue);
	const k3d::basic_hsv new_hsv = k3d::color(Red, Green, Blue);

	if(current_hsv == new_hsv)
		return;

	// Make ourselves visible ...
	InteractiveShow(Speed, Pause);

	GtkColorSelection* colorselection = GTK_COLOR_SELECTION(m_Object);

	// If hue or saturation have changed, update the color wheel ...
	if(current_hsv.hue != new_hsv.hue || current_hsv.saturation != new_hsv.saturation)
		{
			const k3d::basic_hsv temp_hsv(new_hsv.hue, new_hsv.saturation, current_hsv.value);

			const double theta = radians(temp_hsv.hue);
			k3d::vector2 offset(-sin(theta) * temp_hsv.saturation, -cos(theta) * temp_hsv.saturation);
			offset *= 0.5;
			offset += 0.5;

#ifndef K3D_HAVE_GTK2
			sdpGtkWidget wheelarea(colorselection->wheel_area);
			wheelarea.InteractiveWarpPointer(offset[0], offset[1], Speed, Pause, false);
#endif
			const k3d::color temp_rgb(temp_hsv);
			SetColor(temp_rgb.red, temp_rgb.green, temp_rgb.blue);
		}

	// If value has changed, update the value area ...
	if(current_hsv.value != new_hsv.value)
		{
#ifndef K3D_HAVE_GTK2
			sdpGtkWidget valuearea(colorselection->value_area);
			valuearea.InteractiveWarpPointer(0.5, 1.0 - new_hsv.value, Speed, Pause, false);
#endif
			const k3d::color temp_rgb(new_hsv);
			SetColor(temp_rgb.red, temp_rgb.green, temp_rgb.blue);
		}
}


