text: #include "GwenParameterInterface.h"
  #include "gwenInternalData.h"
  
  struct MyButtonEventHandler : public Gwen::Event::Handler
  {
  	ButtonParamChangedCallback m_callback;
  	void* m_userPointer;
  	int m_buttonId;
  
  	MyButtonEventHandler(ButtonParamChangedCallback callback, int buttonId, void* userPointer)
  		:m_callback(callback),
  		m_userPointer(userPointer),
  		m_buttonId(buttonId)
  	{
  	}
  
  	void onButtonPress( Gwen::Controls::Base* pControl )
  	{
  		if (m_callback)
  		{
  			(*m_callback)(m_buttonId, true, m_userPointer);
  		}
  	}
  };
  
  
  template<typename T>
  struct MySliderEventHandler : public Gwen::Event::Handler
  {
  	SliderParamChangedCallback m_callback;
  	void* m_userPointer;
  	Gwen::Controls::TextBox* m_label;
  	Gwen::Controls::Slider* m_pSlider;
  	char m_variableName[1024];
  	T* m_targetValue;
      bool m_showValue;
  
  	MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider,T* target, SliderParamChangedCallback callback, void* userPtr)
  	:	m_callback(callback),
  		m_userPointer(userPtr),
  		m_label(label),
  		m_pSlider(pSlider),
  	m_targetValue(target),
  	m_showValue(true)
  
  	{
  		memcpy(m_variableName,varName,strlen(varName)+1);
  	}
  
  
  	void SliderMoved( Gwen::Controls::Base* pControl )
  	{
  		Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
  		//printf("value = %f\n", pSlider->GetValue());//UnitPrint( Utility::Format( L"Slider Value: %.2f", pSlider->GetValue() ) );
  		float bla = pSlider->GetValue();
  		T v = T(bla);
  		SetValue(v);
  
  		if (m_callback)
  		{
  			(*m_callback)(v, m_userPointer);
  		}
  
  	}
  
  	void	SetValue(T v)
  	{
  		if (v < m_pSlider->GetRangeMin())
  		{
  			printf("?\n");
  		}
  
  		if (v > m_pSlider->GetRangeMax())
  		{
  						printf("?\n");
  
  		}
  		m_pSlider->SetValue(v,true);
  		(*m_targetValue) = v;
  		float val = float(v);//todo: specialize on template type
          if (m_showValue)
          {
              char txt[1024];
              sprintf(txt,"%s : %.3f", m_variableName,val);
              m_label->SetText(txt);
          }
  
  	}
  };
  
  
  struct  GwenParameters
  {
  	b3AlignedObjectArray<MySliderEventHandler<btScalar>*> m_sliderEventHandlers;
  	b3AlignedObjectArray<Gwen::Controls::HorizontalSlider*> m_sliders;
  	b3AlignedObjectArray<Gwen::Controls::ComboBox*> m_comboBoxes;
  	b3AlignedObjectArray<Gwen::Controls::Button*> m_buttons;
  	b3AlignedObjectArray<MyButtonEventHandler*> m_buttonEventHandlers;
  	b3AlignedObjectArray<Gwen::Controls::TextBox*> m_textLabels;
  	int m_savedYposition;
  };
  
  GwenParameterInterface::GwenParameterInterface(GwenInternalData* gwenInternalData)
  :m_gwenInternalData(gwenInternalData)
  {
  	m_paramInternalData = new GwenParameters;
  	m_paramInternalData->m_savedYposition = m_gwenInternalData->m_curYposition;
  
  }
  
  GwenParameterInterface::~GwenParameterInterface()
  {
  
  	removeAllParameters();
  	delete m_paramInternalData;
  }
  
  
  void GwenParameterInterface::setSliderValue(int sliderIndex, double sliderValue)
  {
      int sliderCapped = sliderValue+4;
      sliderCapped /= 8;
      sliderCapped *= 8;
      
      if (sliderIndex>=0 && sliderIndex<m_paramInternalData->m_sliders.size())
      {
          m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin();
          
          m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax();
          float mappedValue =m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()+
          (m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax()-
           m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin())*sliderCapped/128.f;
          printf("mappedValue = %f\n",mappedValue);
          m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue);
      }
  }
  
  #include <stdio.h>
  
  void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
  {
  	
  	Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
  	MyButtonEventHandler* handler = new MyButtonEventHandler(params.m_callback,params.m_buttonId,params.m_userPointer);
  	button->SetText(params.m_name);
  	button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
      button->SetIsToggle(params.m_isTrigger);
      
  	m_paramInternalData->m_buttons.push_back(button);
  	m_paramInternalData->m_buttonEventHandlers.push_back(handler);
  
  	button->SetPos( 5, m_gwenInternalData->m_curYposition );
  	button->SetWidth(220);
  	
  	m_gwenInternalData->m_curYposition+=22;
  
  }
  
  struct MyComboBoxHander2   :public Gwen::Event::Handler
  {
  	GwenInternalData*	m_data;
  	int					m_buttonId;
  	ComboBoxCallback	m_callback;
  	void*				m_userPointer;
  
  	MyComboBoxHander2  (GwenInternalData* data, int buttonId,ComboBoxCallback callback, void* userPointer)
  		:m_data(data),
  		m_buttonId(buttonId),
  		m_callback(callback),
  		m_userPointer(userPointer)
  	{
  	}
  
  	void onSelect( Gwen::Controls::Base* pControl )
  	{
  		Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
  
  		Gwen::String str = Gwen::Utility::UnicodeToString(	but->GetSelectedItem()->GetText());
  
  		if (m_callback)
  			(*m_callback)(m_buttonId,str.c_str(),m_userPointer);
  	}
  
  };
  
  
  void GwenParameterInterface::registerComboBox(ComboBoxParams& params)
  {
  	Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_gwenInternalData->m_demoPage->GetPage());
  	m_paramInternalData->m_comboBoxes.push_back(combobox);
  	MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId,params.m_callback, params.m_userPointer);
  	m_gwenInternalData->m_handlers.push_back(handler);
  
  	combobox->onSelection.Add(handler,&MyComboBoxHander2::onSelect);
  	int ypos = m_gwenInternalData->m_curYposition;
  	m_gwenInternalData->m_curYposition+=22;
  	combobox->SetPos(5, ypos );
  	combobox->SetWidth( 220 );
  	//box->SetPos(120,130);
  	for (int i=0;i<params.m_numItems;i++)
  	{
  		Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(params.m_items[i]));
  		if (i==params.m_startItem)
  			combobox->OnItemSelected(item);
  	}
  
      
  	
  
  }
  
  void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params)
  {
  	Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(m_gwenInternalData->m_demoPage->GetPage());
  	m_paramInternalData->m_textLabels.push_back(label);
  	//m_data->m_myControls.push_back(label);
  	label->SetText( params.m_name);
  	label->SetPos( 10, 10 + 25 );
  	label->SetWidth(210);
  	label->SetPos(10,m_gwenInternalData->m_curYposition);
  	m_gwenInternalData->m_curYposition+=22;
  
  	Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( m_gwenInternalData->m_demoPage->GetPage());
  	m_paramInternalData->m_sliders.push_back(pSlider);
  	//m_data->m_myControls.push_back(pSlider);
  	pSlider->SetPos( 10, m_gwenInternalData->m_curYposition );
  	pSlider->SetSize( 200, 20 );
  	pSlider->SetRange( params.m_minVal, params.m_maxVal);
      if (params.m_clampToIntegers)
      {
          pSlider->SetNotchCount( int( params.m_maxVal - params.m_minVal ) );
          pSlider->SetClampToNotches( params.m_clampToNotches );
      }
      else
      {
          pSlider->SetNotchCount( 16 );//float(params.m_maxVal-params.m_minVal)/100.f);
          pSlider->SetClampToNotches( params.m_clampToNotches );
      }
  	pSlider->SetValue( *params.m_paramValuePointer);//dimensions[i] );
  	char labelName[1024];
  	sprintf(labelName,"%s",params.m_name);//axisNames[0]);
  	MySliderEventHandler<btScalar>* handler = new MySliderEventHandler<btScalar>(labelName,label,pSlider,params.m_paramValuePointer,params.m_callback, params.m_userPointer);
      handler->m_showValue = params.m_showValues;
  	m_paramInternalData->m_sliderEventHandlers.push_back(handler);
  
  	pSlider->onValueChanged.Add( handler, &MySliderEventHandler<btScalar>::SliderMoved );
  	handler->SliderMoved(pSlider);
  //	float v = pSlider->GetValue();
  	m_gwenInternalData->m_curYposition+=22;
  }
  
  void GwenParameterInterface::syncParameters()
  {
  	for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
  	{
  		MySliderEventHandler<btScalar>* handler = m_paramInternalData->m_sliderEventHandlers[i];
  		handler->m_pSlider->SetValue(*handler->m_targetValue,true);
  	}
  }
  
  void GwenParameterInterface::removeAllParameters()
  {
  
  	for (int i=0;i<m_paramInternalData->m_buttons.size();i++)
  	{
  		delete m_paramInternalData->m_buttons[i];
  	}
  	m_paramInternalData->m_buttons.clear();
  	
  	for (int i=0;i<m_paramInternalData->m_buttonEventHandlers.size();i++)
  	{
  		delete m_paramInternalData->m_buttonEventHandlers[i];
  	}
  	m_paramInternalData->m_buttonEventHandlers.clear();
  	
  	
  	m_gwenInternalData->m_curYposition+=22;
  
  	
  	for (int i=0;i<m_paramInternalData->m_sliders.size();i++)
  	{
  		delete m_paramInternalData->m_sliders[i];
  	}
  	m_paramInternalData->m_sliders.clear();
  
  	for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
  	{
  		delete m_paramInternalData->m_sliderEventHandlers[i];
  	}
  	m_paramInternalData->m_sliderEventHandlers.clear();
  	
  	for (int i=0;i<m_paramInternalData->m_textLabels.size();i++)
  	{
  		delete m_paramInternalData->m_textLabels[i];
  	}
  	m_paramInternalData->m_textLabels.clear();
  	
  	for (int i=0;i<m_paramInternalData->m_comboBoxes.size();i++)
  	{
  		delete m_paramInternalData->m_comboBoxes[i];
  	}
  	m_paramInternalData->m_comboBoxes.clear();
  
  	m_gwenInternalData->m_curYposition = this->m_paramInternalData->m_savedYposition;
  	for (int i=0;i<m_gwenInternalData->m_handlers.size();i++)
  	{
  		delete m_gwenInternalData->m_handlers[i];
  	}
  	m_gwenInternalData->m_handlers.clear();
  
  	
  }
  