///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//         This example code is from the book:
//
//           Object-Oriented Programming with C++ and OSF/Motif, 2nd Edition
//         by
//           Douglas Young
//           Prentice Hall, 1995
//           ISBN 0-13-20925507
//
//         Copyright 1995 by Prentice Hall
//         All Rights Reserved
//
//  Permission to use, copy, modify, and distribute this software for 
//  any purpose except publication and without fee is hereby granted, provided 
//  that the above copyright notice appear in all copies of the software.
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////
// ColorChooser.C:
///////////////////////////////////////////////////
#include "ColorModel.h"
#include "HSVView.h"
#include "SwatchView.h"
#include "RGBController.h"
#include "RGBView.h"
#include "ColorChooser.h"
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/BulletinB.h>
#include <Xm/Separator.h>
#include <Xm/PushB.h>

// Default resources needed by the ColorChooser component

static String colorChooserResources[] = {
    "*rgbView.x:                        150",
    "*rgbView.y:                         20",
    "*rgbView*label1*labelString:       Red:",
    "*rgbView*label2*labelString:       Green:",
    "*rgbView*label3*labelString:       Blue:",
    "*hsvView.x:                        300",
    "*hsvView.y:                         20",
    "*hsvView*label1*labelString:       Hue:",
    "*hsvView*label2*labelString:       Saturation:",
    "*hsvView*label3*labelString:       Value:",
    "*rgbController.x:                   50",
    "*rgbController.y:                  150",
    "*rgbController*scaleWidth:         375",
    "*rgbController*scaleHeight:         22",
    "*colorView.x:                       20",
    "*colorView.y:                       20",
    "*swatch.width:                     100",
    "*swatch.height:                    100",
    "*colorView.shadowType:             shadow_in",
    "*ok.x:                              20",
    "*ok.y:                             240",
    "*ok*labelString:                   OK",
    "*cancel.x:                         400",
    "*cancel.y:                         240",
    "*cancel*labelString:               Cancel",
    //  Debatable use of color
    "*rgbController*red*troughColor:    red",
    "*rgbController*green*troughColor:  green",
    "*rgbController*blue*troughColor:   blue",
    NULL,
};
ColorChooser::ColorChooser ( const char *name, Widget parent ) : 
UIComponent ( name )
{
    _clientData = NULL;
    
    // Load ColorChooser componentŐs resources into the esource database
    
    setDefaultResources ( parent , colorChooserResources );
    
    // The ColorChooser is a dialog, but no existing Motif dialog
    // supports the required layout, so use a BulletinBoard
    
    _w = XmCreateBulletinBoardDialog ( parent, _name, NULL, 0 );
    
    _okButton     = XtCreateManagedWidget ( "ok", 
					    xmPushButtonWidgetClass,
					    _w, NULL, 0 );
    
    _cancelButton = XtCreateManagedWidget ( "cancel",
					    xmPushButtonWidgetClass,
					    _w, NULL, 0 );
    
    // Set up the Ok and Cancel buttons, so the BulletinBoard
    // widget can handle them automatically. Assign all callbacks.
    
    XtVaSetValues ( _w, 
		    XmNdefaultButton, _okButton,
		    XmNcancelButton,  _cancelButton, 
		    NULL );
    XtAddCallback ( _okButton, 
		    XmNactivateCallback, 
		    &ColorChooser::okCallback,
		    (XtPointer) this );
    XtAddCallback ( _cancelButton, 
		    XmNactivateCallback, 
		    &ColorChooser::cancelCallback,
		    (XtPointer) this );
    
    // Create a ColorModel object, and instantiate one of each 
    // available ColorView class
    
    _model      = new ColorModel();
    _rgbSliders = new RGBController ( "rgbController", _w, _model );
    _swatch     = new SwatchView ( "colorView", _w );
    _rgbView    = new RGBView ( "rgbView", _w );
    _hsvView    = new HSVView ( "hsvView", _w );
    
    // Attach each ColorView to the ColorModel object
    
    _model->attachView ( _swatch );
    _model->attachView ( _rgbView );
    _model->attachView ( _hsvView );
    _model->attachView ( _rgbSliders );
    
    // Manage each of the views
    
    _rgbSliders->manage();
    _swatch->manage();
    _rgbView->manage();
    _hsvView->manage();
}
ColorChooser::~ColorChooser()
{
    delete _model;
    delete _rgbSliders;
    delete _swatch;
    delete _rgbView;
    delete _hsvView;
}
void ColorChooser::pickColor ( ColorSelectedCallback okCB,
			       CancelCallback        cancelCB,
			       void                 *clientData )
{
    _clientOkCallback     = okCB;
    _clientCancelCallback = cancelCB;
    _clientData           = clientData;
    
    manage();
}
void ColorChooser::okCallback ( Widget, 
				XtPointer clientData, 
				XtPointer )
{
    ColorChooser *obj = ( ColorChooser * ) clientData;
    obj->ok();
}
void ColorChooser::ok()
{
    if ( _clientOkCallback )
	( *_clientOkCallback )( _model->red(),  
				_model->green(), 
				_model->blue(), 
				_clientData );
}
void ColorChooser::cancelCallback ( Widget, 
				    XtPointer clientData, 
				    XtPointer )
{
    ColorChooser *obj = ( ColorChooser * ) clientData;
    obj->cancel();
}
void ColorChooser::cancel()
{
    if ( _clientCancelCallback )
	( *_clientCancelCallback )( _clientData );
}


















