/////////////////////////////////////////////////////////////////////////////
// Name:        slider.h
// Purpose:
// Author:      Cesar Mauri Loba
// Modified by:
// Created:     13/04/2011 18:37:56
// RCS-ID:
// Copyright:   (C) 2011 Cesar Mauri Loba - CREA Software Systems
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
/////////////////////////////////////////////////////////////////////////////

#ifndef _SLIDER_H_
#define _SLIDER_H_


/*!
 * Includes
 */

////@begin includes
////@end includes
#include "base_widget.h"

#include "linear2exp.h"

#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/slider.h>
#include <wx/textctrl.h>

/*!
 * Forward declarations
 */

////@begin forward declarations
////@end forward declarations

/*!
 * Control identifiers
 */

////@begin control identifiers
#define ID_SLIDER 10000
#define wxID_STATIC_LABEL 10003
#define ID_SLIDER_CONTROL 10001
#define ID_TEXTCTRL 10002
#define SYMBOL_SLIDERPANEL_STYLE wxTAB_TRAVERSAL
#define SYMBOL_SLIDERPANEL_TITLE _("Slider")
#define SYMBOL_SLIDERPANEL_IDNAME ID_SLIDER
#define SYMBOL_SLIDERPANEL_SIZE wxDefaultSize
#define SYMBOL_SLIDERPANEL_POSITION wxDefaultPosition
////@end control identifiers

using namespace spcore;

namespace mod_widgets {

class SliderComponent;

/*!
 * SliderPanel class declaration
 */

class SliderPanel: public wxPanel, public BaseWidgetPanel<SliderComponent>
{
    DECLARE_DYNAMIC_CLASS( SliderPanel )
    DECLARE_EVENT_TABLE()

public:
    /// Constructors
    SliderPanel();
    SliderPanel( wxWindow* parent, wxWindowID id = SYMBOL_SLIDERPANEL_IDNAME, const wxPoint& pos = SYMBOL_SLIDERPANEL_POSITION, const wxSize& size = SYMBOL_SLIDERPANEL_SIZE, long style = SYMBOL_SLIDERPANEL_STYLE, const wxString& name = SYMBOL_SLIDERPANEL_TITLE );

    /// Creation
    bool Create( wxWindow* parent, wxWindowID id = SYMBOL_SLIDERPANEL_IDNAME, const wxPoint& pos = SYMBOL_SLIDERPANEL_POSITION, const wxSize& size = SYMBOL_SLIDERPANEL_SIZE, long style = SYMBOL_SLIDERPANEL_STYLE, const wxString& name = SYMBOL_SLIDERPANEL_TITLE );

    /// Destructor
    ~SliderPanel();

	// Notify value change
	void ValueChanged();

private:
    /// Initialises member variables
    void Init();

    /// Creates the controls and sizers
    void CreateControls();

////@begin SliderPanel event handler declarations

    /// wxEVT_COMMAND_SLIDER_UPDATED event handler for ID_SLIDER_CONTROL
    void OnSliderControlUpdated( wxCommandEvent& event );

////@end SliderPanel event handler declarations

	// Value change event
	void OnValueChanged( wxCommandEvent& );


////@begin SliderPanel member function declarations

    /// Retrieves bitmap resources
    wxBitmap GetBitmapResource( const wxString& name );

    /// Retrieves icon resources
    wxIcon GetIconResource( const wxString& name );
////@end SliderPanel member function declarations

    /// Should we show tooltips?
    static bool ShowToolTips();

////@begin SliderPanel member variables
    wxStaticText* m_staLabel;
    wxSlider* m_sldSlider;
    wxTextCtrl* m_txtNumber;
////@end SliderPanel member variables
};

/**
	widget_slider component

	Slider component widget

	Input pins:
		value (CTypeFloat or CTypeInt)

		Sets the value of the widget. 
		The type of the pin depends on the construction parameters

	Output pins:
		value (CTypeFloat or CTypeInt)

		Sends the value when the slider is manipulated

	Command line:
		[-e [0|1|false|true]]	Enabled. Control will be initially enabled (def. 1)
		[-l <label> ]	Label. If empty, no label is shown.
		[-i ]			Integer slider (default float).
		[-v <val> ]		Value (default min).
		[--min <val>]	(= 0) Minimum range value.
		[--max <val>]	(= 1) Maximum range value.
		[--log [<val>]] 
			Use logarithmic scale. "val" set how fast the logarithmic curve
			grows (default 0)
*/
class SliderComponent : public BaseWidgetComponent<SliderPanel,SliderComponent> {
public:
	static const char* getTypeName() { return "widget_slider"; };
	virtual const char* GetTypeName() const { return SliderComponent::getTypeName(); };

	//
	// Component methods
	//
	SliderComponent(const char * name, int argc, const char * argv[]);
	
	virtual int DoInitialize();

	// 
	// Called from GUI
	//	
	int GetSliderMin() const { return m_sliderMin; }
	int GetSliderMax() const { return m_sliderMax; }

	void SetSliderValue (int v);
	int GetSliderValue() const;

	std::string GetTextboxValue() const;

private:
	enum ESliderType { SLD_FLOAT= 0, SLD_INT, SLD_LOG };

	//
	// Data members
	//
	ESliderType m_sldType;
	Linear2ExpMapping m_linear2exp;
	int m_sliderMin, m_sliderMax;
	float m_fmin, m_fmax;
	SmartPtr<IInputPin> m_iPin;
	SmartPtr<IOutputPin> m_oPin;
	SmartPtr<CTypeFloat> m_valueFloat;
	SmartPtr<CTypeInt> m_valueInt;

	//
	// Private methods
	//	
	void OnPinValueFloat (const CTypeFloat & msg);
	void OnPinValueInt (const CTypeInt & msg);

	//
	// Input pin classes
	//
	class InputPinFloat : public spcore::CInputPinWriteOnly<CTypeFloat, SliderComponent> {
	public:
		InputPinFloat (SliderComponent & component)
		: CInputPinWriteOnly<CTypeFloat, SliderComponent>("value", component) { }

		virtual int DoSend(const CTypeFloat & msg) {
			m_component->OnPinValueFloat(msg);
			return 0;
		}
	};

	class InputPinInt : public spcore::CInputPinWriteOnly<CTypeInt, SliderComponent> {
	public:
		InputPinInt (SliderComponent & component)
		: CInputPinWriteOnly<CTypeInt, SliderComponent>("value", component) { }

		virtual int DoSend(const CTypeInt & msg) {
			m_component->OnPinValueInt(msg);
			return 0;
		}
	};
};

typedef ComponentFactory<SliderComponent> SliderComponentFactory;

};

#endif
    // _SLIDER_H_
