/******************************************************************************
 JXChooseColorDialog.cc

	BASE CLASS = JXDialogDirector

	Copyright © 1998 by John Lindal. All rights reserved.

 ******************************************************************************/

#include <JXChooseColorDialog.h>
#include <JXWindow.h>
#include <JXTextButton.h>
#include <JXSlider.h>
#include <JXIntegerInput.h>
#include <JXFlatRect.h>
#include <JXStaticText.h>
#include <JXColormap.h>
#include <jMath.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

 ******************************************************************************/

JXChooseColorDialog::JXChooseColorDialog
	(
	JXWindowDirector*	supervisor,
	const JColorIndex	colorIndex
	)
	:
	JXDialogDirector(supervisor, kTrue)
{
	BuildWindow(colorIndex);

	JXColormap* colormap = GetColormap();
	colormap->PrepareForMassColorAllocation();
	colormap->UsingColor(colorIndex);
}

/******************************************************************************
 Destructor

 ******************************************************************************/

JXChooseColorDialog::~JXChooseColorDialog()
{
	JXColormap* colormap = GetColormap();
	colormap->MassColorAllocationFinished();
	colormap->DeallocateColor(GetColor());
}

/******************************************************************************
 BuildWindow (protected)

 ******************************************************************************/

void
JXChooseColorDialog::BuildWindow
	(
	const JColorIndex colorIndex
	)
{
// begin JXLayout

    JXWindow* window = new JXWindow(this, 240,250, "");
    assert( window != NULL );
    SetWindow(window);

    JXTextButton* okButton =
        new JXTextButton("OK", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 139,219, 62,22);
    assert( okButton != NULL );
    okButton->SetShortcuts("^M");

    JXTextButton* cancelButton =
        new JXTextButton("Cancel", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 40,220, 60,20);
    assert( cancelButton != NULL );

    JXStaticText* obj1 =
        new JXStaticText("Sample:", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,25, 50,20);
    assert( obj1 != NULL );

    JXStaticText* obj2 =
        new JXStaticText("Hue:", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 20,70, 50,20);
    assert( obj2 != NULL );

    JXStaticText* obj3 =
        new JXStaticText("Sat:", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 20,90, 50,20);
    assert( obj3 != NULL );

    JXStaticText* obj4 =
        new JXStaticText("Value:", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 20,110, 50,20);
    assert( obj4 != NULL );

    itsHSlider =
        new JXSlider(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,70, 150,20);
    assert( itsHSlider != NULL );

    itsSSlider =
        new JXSlider(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,90, 150,20);
    assert( itsSSlider != NULL );

    itsVSlider =
        new JXSlider(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,110, 150,20);
    assert( itsVSlider != NULL );

    itsColorSample =
        new JXFlatRect(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 130,20, 30,30);
    assert( itsColorSample != NULL );

    JXStaticText* obj5 =
        new JXStaticText("Red", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 20,140, 50,20);
    assert( obj5 != NULL );

    JXStaticText* obj6 =
        new JXStaticText("Green", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 20,160, 50,20);
    assert( obj6 != NULL );

    JXStaticText* obj7 =
        new JXStaticText("Blue", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 20,180, 50,20);
    assert( obj7 != NULL );

    itsRInput =
        new JXIntegerInput(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 150,140, 70,20);
    assert( itsRInput != NULL );

    itsGInput =
        new JXIntegerInput(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 150,160, 70,20);
    assert( itsGInput != NULL );

    itsBInput =
        new JXIntegerInput(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 150,180, 70,20);
    assert( itsBInput != NULL );

    JXStaticText* obj8 =
        new JXStaticText("(0-65535):", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,140, 80,20);
    assert( obj8 != NULL );

    JXStaticText* obj9 =
        new JXStaticText("(0-65535):", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,160, 80,20);
    assert( obj9 != NULL );

    JXStaticText* obj10 =
        new JXStaticText("(0-65535):", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,180, 80,20);
    assert( obj10 != NULL );

// end JXLayout

	window->SetTitle("Choose color");
	SetButtons(okButton, cancelButton);

	const JRGB rgb = (GetColormap())->JColormap::GetRGB(colorIndex);
	const JHSV hsv(rgb);

	itsHSlider->SetRange(0.0, kJMaxHSVValueF);
	itsHSlider->SetValue(hsv.hue);
	ListenTo(itsHSlider);

	itsSSlider->SetRange(0.0, kJMaxHSVValueF);
	itsSSlider->SetValue(hsv.saturation);
	ListenTo(itsSSlider);

	itsVSlider->SetRange(0.0, kJMaxHSVValueF);
	itsVSlider->SetValue(hsv.value);
	ListenTo(itsVSlider);

	itsRInput->SetIsRequired();
	itsRInput->SetLimits(0, kJMaxRGBValue);
	itsRInput->SetValue(rgb.red);
	ListenTo(itsRInput);

	itsGInput->SetIsRequired();
	itsGInput->SetLimits(0, kJMaxRGBValue);
	itsGInput->SetValue(rgb.green);
	ListenTo(itsGInput);

	itsBInput->SetIsRequired();
	itsBInput->SetLimits(0, kJMaxRGBValue);
	itsBInput->SetValue(rgb.blue);
	ListenTo(itsBInput);

	itsColorSample->SetBackColor(colorIndex);
}

/******************************************************************************
 GetColor

 ******************************************************************************/

JColorIndex
JXChooseColorDialog::GetColor()
	const
{
	return itsColorSample->GetBackColor();
}

/******************************************************************************
 Receive (virtual protected)

 ******************************************************************************/

void
JXChooseColorDialog::Receive
	(
	JBroadcaster*	sender,
	const Message&	message
	)
{
	if (message.Is(JSliderBase::kMoved))
		{
		UpdateColor(kTrue);
		}
	else if (message.Is(JXWidget::kLostFocus))
		{
		UpdateColor(kFalse);
		}

	else
		{
		JXDialogDirector::Receive(sender, message);
		}
}

/******************************************************************************
 UpdateColor (private)

 ******************************************************************************/

void
JXChooseColorDialog::UpdateColor
	(
	const JBoolean sliderChanged
	)
{
	JXColormap* colormap             = GetColormap();
	const JColorIndex origColorIndex = GetColor();
	const JRGB origColor             = colormap->JColormap::GetRGB(origColorIndex);

	JRGB newColor;
	if (sliderChanged)
		{
		newColor = JHSV(JRound(itsHSlider->GetValue()),
						JRound(itsSSlider->GetValue()),
						JRound(itsVSlider->GetValue()));
		itsRInput->SetValue(newColor.red);
		itsGInput->SetValue(newColor.green);
		itsBInput->SetValue(newColor.blue);
		}
	else
		{
		JInteger r,g,b;
		JBoolean ok = itsRInput->GetValue(&r);
		assert( ok );
		ok = itsGInput->GetValue(&g);
		assert( ok );
		ok = itsBInput->GetValue(&b);
		assert( ok );
		newColor.Set(r,g,b);

		StopListening(itsHSlider);
		StopListening(itsSSlider);
		StopListening(itsVSlider);
		JHSV hsv(newColor);
		itsHSlider->SetValue(hsv.hue);
		itsSSlider->SetValue(hsv.saturation);
		itsVSlider->SetValue(hsv.value);
		ListenTo(itsHSlider);
		ListenTo(itsSSlider);
		ListenTo(itsVSlider);
		}

	JColorIndex newColorIndex;
	colormap->DeallocateColor(origColorIndex);
	if (colormap->JColormap::AllocateStaticColor(newColor, &newColorIndex) ||
		colormap->JColormap::AllocateStaticColor(origColor, &newColorIndex))
		{
		itsColorSample->SetBackColor(newColorIndex);
		}
	else
		{
		itsColorSample->SetBackColor(colormap->GetDefaultBackColor());
		}
}

/******************************************************************************
 OKToDeactivate (virtual protected)

	Update the color based on the latest input field values.

 ******************************************************************************/

JBoolean
JXChooseColorDialog::OKToDeactivate()
{
	UpdateColor(kFalse);
	return JXDialogDirector::OKToDeactivate();
}
