//------------------------------------------------------------------------------
// gui numeric control class																	--
// (C) Piero Giubilato 2008-2010, Berkeley Lab										   --
//------------------------------------------------------------------------------

//______________________________________________________________________________
// {Trace}
// [File name] "gui_Numeric.cpp"
// [Author] "Piero Giubilato"
// [Version] "1.0"
// [Modified by] "Piero Giubilato"
// [Last revision] "02 Apr 2009"
// [Language] "C++"
// [Compiler] "Visual C++ 8.x 9.x"
// [Member of] "Cool SEAL"
// [Project] "SEAL"
// [Description] "Source for the gui_Numeric class"
// [Key documentation]
// "Visual C++ Reference Help"
// "Root reference guide"
// {Trace}
//______________________________________________________________________________

// Standard component

// Root Component
#include <TSystem.h>

// Application component
#include "global.h"
#include "gui_Numeric.h"


// CINT Preprocessor class import definition
ClassImp(gui_Numeric)

//______________________________________________________________________________
gui_Numeric::gui_Numeric(Double_t value, UInt_t left, UInt_t top, UInt_t width, UInt_t height)
{
   // Default constructor. gui_Numeric provides an interface layer that
   // integrates a root TGNumberEntry plus all the code necessary to implement
   // events management.
	//
	// 'label' is the text appearing into the button
	// 'left', 'top', 'width', 'height' set the position and size of the button
	// 'evn_Hnd' is a function pointer pointing to the callback function
	// provided to handle the event (must be a void f(void)).
	
	// Debug
   dbg_Print("gui_Numeric::gui_Numeric: default constructor", DBG_LVL_ZERO);

   // Sets up the button
   Init(value, left, top, width, height);
}

//______________________________________________________________________________
gui_Numeric::gui_Numeric(Double_t value, UInt_t left, UInt_t top, UInt_t width, UInt_t height,
							  Double_t min, Double_t max)
{
   // Default constructor that allows to set limits. 
	// 'label' is the text appearing into the button
	// 'left', 'top', 'width', 'height' set the position and size of the button
	// 'min' and 'max' are the minimum and maximum values allowed
	// 'evn_Hnd' is a function pointer pointing to the callback function
	// provided to handle the event (must be a void f(void)).
	
	// Debug
   dbg_Print("gui_Numeric::gui_Numeric: default constructor", DBG_LVL_ZERO);

   // Sets up the button
   Init(value, left, top, width, height, min, max);
}

//______________________________________________________________________________
gui_Numeric::~gui_Numeric()
{
   // Default destructor.
   dbg_Print("gui_Numeric::gui_Numeric: default destructor", DBG_LVL_ZERO);

   // Removes the root object from the root graphical server
	Container()->RemoveFrame(numeric);
	numeric->DestroyWindow();
	
	// Deletes the root object
   delete numeric;
}

//______________________________________________________________________________
void gui_Numeric::Init(Double_t value, UInt_t left, UInt_t top, UInt_t width, UInt_t height)
{
   // Creates a layer over a root number control
   dbg_Print("gui_Numeric::num_Place:(default)", DBG_LVL_MAKE);
	
   // Initializes the root button
   numeric = new TGNumberEntry(Container(), value);

	// Connects it to the button handler function
   numeric->Connect(numeric, "ValueSet(Long_t)", "gui_Numeric", this, "num_Do(Long_t)");
	
	// By default hex_Mode is off
	hex_Mode = false;

   // Renders the button into the frame and adds it to the window 
   Container()->AddFrame(numeric, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
   MoveResize(left, top, width, height); // Updates the container also
}

//______________________________________________________________________________
void gui_Numeric::Init(Double_t value, UInt_t left, UInt_t top, UInt_t width, UInt_t height,
									Double_t min, Double_t max)
{
   // Creates a layer over a root number control
   dbg_Print("gui_Numeric::num_Place:(range)", DBG_LVL_MAKE);
	
   // Initializes the root button
   numeric = new TGNumberEntry(Container(), value);

	// Connects it to the button handler function
   numeric->Connect(numeric, "ValueSet(Long_t)", "gui_Numeric", this, "num_Do(Long_t)");

	// Sets min and max values
	num_Min(min);
	num_Max(max);
	num_Limits(true);
	
   // Renders the button into the frame and adds it to the window 
   Container()->AddFrame(numeric, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
   MoveResize(left, top, width, height); // Updates the container also
}

//______________________________________________________________________________
void gui_Numeric::num_Do(Long_t val)
{
   // This function is called whenever the numeric is changed
	dbg_Print("gui_Numeric::num_Do:(Long)", DBG_LVL_FLOW)
	   
   // Calls the associated handler, if anyone, passing the ID as argument
	gui_Object::task_Call(gui_Object::obj_Id());
}

//______________________________________________________________________________
const TGNumberEntry* gui_Numeric::Root() const
{
	// Returns the pointer to the embedded root object
   return numeric;
}

//______________________________________________________________________________
void gui_Numeric::MoveResize(UInt_t left, UInt_t top, UInt_t width, UInt_t height)
{
   // Moves and resizes the button
   numeric->MoveResize(left, top, width, height);
	
   // Stores the new datas
   obj_Left = left;
   obj_Top = top;
   obj_Width = width;
   obj_Height = height;
	
   // Paint
	Update();
}

//______________________________________________________________________________
void gui_Numeric::color_Set(UInt_t foreColor, UInt_t backColor)
{
   // Moves and resizes the button
   numeric->SetForegroundColor(foreColor);
   numeric->SetBackgroundColor(backColor);

   // Stores the new datas
   obj_foreColor = foreColor;
   obj_backColor = backColor;
   
   // Refresh the graphical container
   Update();
}

//______________________________________________________________________________
void gui_Numeric::Text(const char* text)
{
   // Sets the button caption
   // At the monent, no text displayed into numeric
	//button->SetText(text); 

   // Stores the new data
   obj_Text.Form(text);
}

//______________________________________________________________________________
const TString gui_Numeric::Text() const
{
   // Returns the button text
   return obj_Text;
}

//______________________________________________________________________________
void gui_Numeric::fontBold(bool bold)
{
   // Sets the boldness of the text (true = bold)
	
	// Retrieves the font structure
	TGFontPool* pool = gClient->GetFontPool();
	Int_t kFontWeight = (bold == true) ? kFontWeightBold : kFontWeightNormal;
	TGFont* font = pool->GetFont("helvetica", -12, kFontWeight, kFontSlantRoman);
	FontStruct_t ft = font->GetFontStruct();
	
	// No font bold at the moment for numeric
	// Sets the font into the button
	//button->SetFont(ft, false); 
   
   // Stores the new data
   obj_fontBold = bold;

	// Refresh the graphical container
   Update();
}

//______________________________________________________________________________
bool gui_Numeric::fontBold() const
{
   // Returns the boldness of the button text
   return obj_fontBold;
}


//______________________________________________________________________________
Double_t gui_Numeric::num_Val() const
{
   // Returns the current value of the numeric
	Double_t value;
	(!hex_Mode) ? value = numeric->GetNumber() : value = numeric->GetHexNumber(); 

	// Return
	return value;
}


//______________________________________________________________________________
Double_t gui_Numeric::num_Val(Double_t val)
{
   // Sets the current value of the numeric
   (!hex_Mode) ? numeric->SetNumber(val) : numeric->SetHexNumber((ULong_t)val); 
	return num_Val();	
}

//______________________________________________________________________________
Double_t gui_Numeric::num_Min() const
{
   // Returns the current min limit of the numeric
   return numeric->GetNumMin(); 
}


//______________________________________________________________________________
Double_t gui_Numeric::num_Min(Double_t val)
{
   // Sets the current value of the numeric
   numeric->SetLimitValues(val, numeric->GetNumMax());
	return num_Min();
}

//______________________________________________________________________________
Double_t gui_Numeric::num_Max() const
{
   // Returns the current max limit of the numeric
   return numeric->GetNumMax(); 
}


//______________________________________________________________________________
Double_t gui_Numeric::num_Max(Double_t val)
{
   // Sets the current max limit of the numeric
	numeric->SetLimitValues(numeric->GetNumMin(), val);
	return num_Max();
}

//______________________________________________________________________________
bool gui_Numeric::num_Hex() const
{
   // Returns the current max limit of the numeric
   return hex_Mode;
}


//______________________________________________________________________________
void gui_Numeric::num_Hex(bool state)
{
   // Sets the current max limit of the numeric
	(state) ? numeric->SetNumStyle(TGNumberFormat::kNESHex) : numeric->SetNumStyle(TGNumberFormat::kNESReal);
	hex_Mode = state;
}

//______________________________________________________________________________
bool gui_Numeric::num_Limits() const
{
   // Returns the current state of range limits
	if (numeric->GetNumLimits() == TGNumberFormat::kNELNoLimits) {
		return false;
	} else {
		return true;
	}
}

//______________________________________________________________________________
bool gui_Numeric::num_Limits(bool state)
{
   // Sets if the number range limits are enabled
	if (state) {
		numeric->SetLimits(TGNumberFormat::kNELLimitMinMax, 
								 numeric->GetNumMin(), numeric->GetNumMax());
	} else {
		numeric->SetLimits(TGNumberFormat::kNELNoLimits,
								 numeric->GetNumMin(), numeric->GetNumMax());
	}

	// returns current setting
	return num_Limits();
}