#include "TEveParamList.h"
#include "TGLabel.h"
#include "TGButton.h"
#include "TGNumberEntry.h"
#include "TGColorSelect.h"
#include "TGDoubleSlider.h"
#include "TEveGValuators.h"
#include "TGNumberEntry.h"
#include "TGedEditor.h"
ClassImp(TEveParamList);
TEveParamList::TEveParamList(const char* n, const char* t, Bool_t doColor) :
   TNamed(n, t),
   fColor(0)
{
   
   if (doColor) SetMainColorPtr(&fColor);
}
TEveParamList::FloatConfig_t TEveParamList::GetFloatParameter(const TString& name)
{
   
   static const TEveException eh("TEveParamList::GetFloatParameter ");
   for (FloatConfigVec_ci itr = fFloatParameters.begin(); itr != fFloatParameters.end(); ++itr)
      if (itr->fName.CompareTo(name)==0 ) return *itr;
   Error(eh, "parameter not found.");
   return FloatConfig_t();
}
TEveParamList::IntConfig_t TEveParamList::GetIntParameter(const TString& name)
{
   
   static const TEveException eh("TEveParamList::GetIntParameter ");
   for (IntConfigVec_ci itr = fIntParameters.begin(); itr != fIntParameters.end(); ++itr)
      if (itr->fName.CompareTo(name) == 0) return *itr;
   Error(eh, "parameter not found.");
   return IntConfig_t();
}
Bool_t TEveParamList::GetBoolParameter(const TString& name)
{
   
   static const TEveException eh("TEveParamList::GetBoolParameter ");
   for (BoolConfigVec_ci itr = fBoolParameters.begin(); itr != fBoolParameters.end(); ++itr)
      if ( itr->fName.CompareTo(name)==0 ) return itr->fValue;
   Error(eh, "parameter not found.");
   return kFALSE;
}
void TEveParamList::ParamChanged(const char* name)
{
   
   Emit("ParamChanged(char*)", name);
}
ClassImp(TEveParamListEditor);
TEveParamListEditor::TEveParamListEditor(const TGWindow *p, Int_t width, Int_t height,
                                         UInt_t options, Pixel_t back) :
   TGedFrame(p, width, height, options | kVerticalFrame, back),
   fM          (0),
   fParamFrame (0)
{
   
   MakeTitle("TEveParamList");
}
void TEveParamListEditor::InitModel(TObject* obj)
{
   
   fM = dynamic_cast<TEveParamList*>(obj);
   if (fParamFrame) {
      fParamFrame->UnmapWindow();
      RemoveFrame(fParamFrame);
      fParamFrame->DestroyWindow();
      delete fParamFrame;
   }
   fParamFrame = new TGVerticalFrame(this);
   AddFrame(fParamFrame);
   
   fIntParameters.clear();
   for (UInt_t i = 0; i < fM->fIntParameters.size(); ++i)
   {
      TGCompositeFrame* frame = new TGHorizontalFrame(fParamFrame);
      
      TGNumberEntry* widget = new TGNumberEntry
         (frame, fM->fIntParameters[i].fValue,
          5,                                 
          i,                                 
          TGNumberFormat::kNESInteger,       
          TGNumberFormat::kNEAAnyNumber,     
          TGNumberFormat::kNELLimitMinMax,   
          fM->fIntParameters[i].fMin,        
          fM->fIntParameters[i].fMax);       
      frame->AddFrame(widget, new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2,8,2,2));
      widget->Connect("ValueSet(Long_t)", "TEveParamListEditor", this, "DoIntUpdate()");
      fIntParameters.push_back(widget);
      
      frame->AddFrame(new TGLabel(frame,fM->fIntParameters[i].fName.Data()),
                      new TGLayoutHints(kLHintsLeft|kLHintsCenterY));
      fParamFrame->AddFrame(frame, new TGLayoutHints(kLHintsTop));
   }
   
   fFloatParameters.clear();
   for (UInt_t i = 0; i < fM->fFloatParameters.size(); ++i)
   {
      TGCompositeFrame* frame = new TGHorizontalFrame(fParamFrame);
      
      TGNumberEntry* widget = new TGNumberEntry
         (frame, fM->fFloatParameters[i].fValue,
          5,                                
          i,                                
          TGNumberFormat::kNESReal,         
          TGNumberFormat::kNEAAnyNumber,    
          TGNumberFormat::kNELLimitMinMax,  
          fM->fFloatParameters[i].fMin,     
          fM->fFloatParameters[i].fMax);    
      frame->AddFrame(widget, new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2,8,2,2));
      widget->Connect("ValueSet(Long_t)", "TEveParamListEditor", this, "DoFloatUpdate()");
      fFloatParameters.push_back( widget );
      
      frame->AddFrame(new TGLabel(frame,fM->fFloatParameters[i].fName.Data()),
                      new TGLayoutHints(kLHintsLeft|kLHintsCenterY) );
      fParamFrame->AddFrame(frame, new TGLayoutHints(kLHintsTop));
   }
   
   fBoolParameters.clear();
   for (UInt_t i = 0; i < fM->fBoolParameters.size(); ++i)
   {
      TGCheckButton* widget = new TGCheckButton(fParamFrame,
                                                fM->fBoolParameters[i].fName.Data(),
                                                i);
      widget->Connect("Clicked()", "TEveParamListEditor", this, "DoBoolUpdate()");
      fBoolParameters.push_back(widget);
      fParamFrame->AddFrame(widget, new TGLayoutHints(kLHintsTop,2,0,1,1));
   }
   MapSubwindows();
}
void TEveParamListEditor::SetModel(TObject* obj)
{
   
   InitModel(obj);
   for (UInt_t i = 0; i < fIntParameters.size(); ++i)
      fIntParameters[i]->GetNumberEntry()->SetIntNumber(fM->fIntParameters[i].fValue);
   for (UInt_t i = 0; i < fFloatParameters.size(); ++i)
      fFloatParameters[i]->GetNumberEntry()->SetNumber(fM->fFloatParameters[i].fValue);
   for (UInt_t i = 0; i < fBoolParameters.size(); ++i)
      fBoolParameters[i]->SetState( fM->fBoolParameters[i].fValue ? kButtonDown : kButtonUp);
}
void TEveParamListEditor::DoIntUpdate()
{
   
   TGNumberEntry *widget = (TGNumberEntry*) gTQSender;
   Int_t id = widget->WidgetId();
   if (id < 0 || id >= (int) fM->fIntParameters.size()) return;
   fM->fIntParameters[id].fValue = widget->GetNumberEntry()->GetIntNumber();
   fM->ParamChanged(fM->fIntParameters[id].fName);
   gTQSender = (void*) widget;
}
void TEveParamListEditor::DoFloatUpdate()
{
   
   TGNumberEntry *widget = (TGNumberEntry*) gTQSender;
   Int_t id = widget->WidgetId();
   if (id < 0 || id >= (int) fM->fFloatParameters.size()) return;
   fM->fFloatParameters[id].fValue = widget->GetNumberEntry()->GetNumber();
   fM->ParamChanged(fM->fFloatParameters[id].fName);
   gTQSender = (void*) widget;
}
void TEveParamListEditor::DoBoolUpdate()
{
   
   TGCheckButton *widget = (TGCheckButton*) gTQSender;
   Int_t id = widget->WidgetId();
   if (id < 0 || id >= (int) fM->fBoolParameters.size()) return;
   fM->fBoolParameters[id].fValue = widget->IsOn();
   fM->ParamChanged(fM->fBoolParameters[id].fName);
   gTQSender = (void*) widget;
}