#ifndef _TK_SPINBOX_H_
#define _TK_SPINBOX_H_

#include "tk_base.h"

/**
 * \brief Represent "TkSpinBox" Tk widget
 * \date 01-12-2006
 *
 * \author Ondrej Svejdar
 *
 * \todo 
 *
 * \bug 
 *
 */
class TkSpinBox:public TkBase,public IStateable,public ITextable,public IInnerVariable
{
	TclStringVar defaultVar;
protected:
	void doSerialize(TiXmlElement& element) const;
	void doDeserialize(const TiXmlElement& element);
public:
	static TXmlObject* newObject()
	{
		return new TkSpinBox(TclInterp::defaultInterp);
	}

	const static Ptr<TkOptionDef> OPT_ACTIVEBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_BACKGROUND ;
	const static Ptr<TkOptionDef> OPT_BORDERWIDTH ;
	const static Ptr<TkOptionDef> OPT_BUTTONDOWNRELIEF ;
	const static Ptr<TkOptionDef> OPT_BUTTONUPRELIEF ;
	const static Ptr<TkOptionDef> OPT_COMMAND ;
	const static Ptr<TkOptionDef> OPT_CURSOR ;
	const static Ptr<TkOptionDef> OPT_DISABLEDBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_FONT ;
	const static Ptr<TkOptionDef> OPT_FOREGROUND ;
	const static Ptr<TkOptionDef> OPT_FORMAT ;
	const static Ptr<TkOptionDef> OPT_FROM ;
	const static Ptr<TkOptionDef> OPT_HIGHLIGHTBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_HIGHLIGHTCOLOR ;
	const static Ptr<TkOptionDef> OPT_HIGHLIGHTTHICKNESS ;
	const static Ptr<TkOptionDef> OPT_INCREMENT ;
	const static Ptr<TkOptionDef> OPT_INSERTBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_INSERTOFFTIME ;
	const static Ptr<TkOptionDef> OPT_INSERTONTIME ;
	const static Ptr<TkOptionDef> OPT_INSERTWIDTH ;
	const static Ptr<TkOptionDef> OPT_INVALIDCOMMAND ;
	const static Ptr<TkOptionDef> OPT_JUSTIFY ;
	const static Ptr<TkOptionDef> OPT_RELIEF ;
	const static Ptr<TkOptionDef> OPT_READONLYBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_REPEATDELAY ;
	const static Ptr<TkOptionDef> OPT_SELECTBACKGROUND ;
	const static Ptr<TkOptionDef> OPT_SELECTBORDERWIDTH ;
	const static Ptr<TkOptionDef> OPT_SELECTFOREGROUND ;
	const static Ptr<TkOptionDef> OPT_STATE ;
	const static Ptr<TkOptionDef> OPT_TAKEFOCUS ;
	const static Ptr<TkOptionDef> OPT_TEXTVARIABLE ;
	const static Ptr<TkOptionDef> OPT_TO ;
	const static Ptr<TkOptionDef> OPT_VALIDATE ;
	const static Ptr<TkOptionDef> OPT_VALIDATECOMMAND ;
	const static Ptr<TkOptionDef> OPT_VALUES ;
	const static Ptr<TkOptionDef> OPT_WRAP ;
	const static Ptr<TkOptionDef> OPT_XSCROLLCOMMAND ;

	const static Ptr<TkOptionDef> optAll[];
	const static char* type;
	const static char* tkClass;

	const Ptr<TkOptionDef>* getOptionAll() const;
	const char* getType() const;
	const char* getTkClass() const;

	TObject* clone();

	/**
	 * Spinbox will roll this enumeration of values. This is mutually exclusive
	 * to any "range" settings of spinbox
	 * \param values[] list of values, use NULL to signalize last parameter
	 */
	void setValues(const char* values[]);


	/**
	 * Spinbox will roll this enumeration of values
	 * \param values list of values
	 */
	void setValues(const list<string>& values);

	/**
	 * Return index of active field if in values "mode" and value is from the value list.
	 * otherwise return -1.
	 * \return 
	 */
	int getValuesIndex() const;

	/**
	 * Set spinbox actual value to value
	 * \param value 
	 */
	void setValue(double value);
	
	/**
	 * Set spinbox actual value to value
	 * \param value 
	 */
	void setValue(int value);
	void setText(const string& text);
	
	/**
	 * Return actual value of spinbox, converted to integer
	 * \return actual value
	 */
	int intValue() const;


	/**
	 * Return actual value of spinbox, converted to double
	 * \return actual value
	 */
	double doubleValue() const;
	const string& getText() const;
	
	/**
	 * Set minimal limit for spinbox value. This is mutually exclusive
	 * to using enumeration of values.
	 * \param value minimal number to display
	 */
	void setLimitFrom(double value);

	/**
	 * Set maximal limit for spinbox value. This is mutually exclusive
	 * to using enumeration of values.
	 * \param value maximal number to display
	 */
	void setLimitTo(double value);
	
	
	/**
	 * Set speed of incrementation. Default is 1. This is mutually exclusive
	 * to using enumeration of values.
	 * \param value speed of incrementation
	 */
	void setIncrement(double value);
		
	/**
	 * Set range for spinbox values. This is mutually exclusive
	 * to using enumeration of values.
	 * \param from minimal number
	 * \param to maximal number
	 * \param increment speed of incrementation
	 */
	void setRange(double from,double to,double increment);

	void addValueListener(TclVarListener* listener);
   
	TkSpinBox(Ptr<TclInterp> interp);

	void setEnabled(bool value);
	bool isEnabled() const;
	void setReadonly();

	TclVar* getDefaultVar()
	{
		return &defaultVar;
	}

	void setEventsEnabled(bool value)
	{
		TkBase::setEventsEnabled(value);
		defaultVar.setEventsEnabled(value);
	}

	void setBackgroundColor(TkColorOption* color);
	Ptr<TkColorOption>& getBackgroundColor() const;
	void create();
};

#endif/*_TK_SPINBOX_H_*/
