#ifndef __STK_WINDOW
#define __STK_WINDOW

#include <list>
#include <string>
using namespace std;

#include "../kernel/kernel.h"


// Stk Position flag
#define STK_GUI_RIGHT  0
#define STK_GUI_LEFT   1
#define STK_GUI_CENTER 2

// Stk Size of widget
#define STK_GUI_SIZE_AUTO 0
#define STK_GUI_SIZE_NOAUTO 1


/** A Rectangle for the Gui.
 */
class Stk_Gui_Rect
{
public:
        /// Default constructor
    Stk_Gui_Rect(float xa,float ya,float size_xa,float size_za);
        /// Copy constructor
    Stk_Gui_Rect(const Stk_Gui_Rect &);
        /// Null constructor
    Stk_Gui_Rect();
    
        /// Resize with a Rectangle
    virtual void Resize(const Stk_Gui_Rect &);
        /// Default resize
    virtual void Resize(float xa,float ya,float size_xa,float size_za);

        /// Get x
    float GetX() const;
        /// Get y
    float GetY() const;
        /// Get width
    float GetWidth() const;
        /// Get height
    float GetHeight() const;
    
private:
        /// coord x of upper left corner
    float x;
        /// coord y of upper left corner
    float y;
        /// width of rectangle
    float width;
        /// height of rectangle
    float height;
};






/** This is a graphical context
 */
class Stk_Gui_GContext:public Stk_Gui_Rect
{
public:
        /// Constructor: need width & height
    Stk_Gui_GContext(const Stk_Gui_Rect &r);
        /// Destructor
    virtual ~Stk_Gui_GContext();
        /// Lock this context
    void Lock();
        /// Free this context
    void Free();
};






/** This is the basis class of all widget object.
 */
class Stk_Gui_Widget: public Stk_Gui_Rect, public Stk_Handler
{
public:
        /// Null constructor
    Stk_Gui_Widget();
        /// Default constructor
    Stk_Gui_Widget(const Stk_Gui_Rect &);
    
        /// Destructor
    virtual ~Stk_Gui_Widget();

        /// attach a widget
    virtual void Attach(Stk_Handler *father);
        /// remove the widget
    virtual void Unfasten();
    
        /// Draw function
    virtual void Draw();
};

/**  This is the basis of button.
 */
class Stk_Gui_Button: public Stk_Gui_Widget
{
public:
        /// Default constructor 
    Stk_Gui_Button(const Stk_Gui_Rect &);
    
        /// Destructor 
    virtual ~Stk_Gui_Button();
        /// Draw function 
    void Draw();
        /// Message Received 
    void MessageReceived(Stk_Message *msg);
    
        /// DrawButton function: You must surcharge it 
    virtual void DrawButton();
    
            /// Click function: Event function
    virtual void Click();
};



/** This is a container. It could contain only one element.
 */
class Stk_Gui_Container: public Stk_Gui_Widget
{
public:
        /// Constructor
    Stk_Gui_Container(const Stk_Gui_Rect &);
        /// Destructor
    virtual ~Stk_Gui_Container();
    
        /// Draw 
    virtual void Draw();

        /// Resize it & its widget attached
    virtual void Resize(const Stk_Gui_Rect &);
    
        /** add a widget (Warning: This class contains one element).\\
            When we attach a widget, it takes the size imposed by the container.
         */
    virtual void Attach(Stk_Gui_Widget *);
        /// remove the widget
    virtual void Unfasten();
        /// widget attached
    Stk_Gui_Widget *widget;
};


/** This a Static placement Widget. It could contain many elements.
 */
class Stk_Gui_Static: public Stk_Gui_Widget
{
public:
        /// Null constructor. The Size will be computed when it will be attached.
    Stk_Gui_Static();
        /// Destructor
    virtual ~Stk_Gui_Static();

            /// Draw 
    virtual void Draw();

        /// Resize it & its widget attached
    virtual void Resize(const Stk_Gui_Rect &);

    
         /// Add a widget in the list.
    virtual void Attach(Stk_Gui_Widget *);
        /// Remove the widget in the list
    virtual void Unfasten(Stk_Gui_Widget *);
        /// list of widgets
    list<Stk_Gui_Widget *> widgets;
};



/** This is a VBox. It could contain many elements. There are represented
    vertically.*/
class Stk_Gui_VBox: public Stk_Gui_Widget
{
public:
        /// Null Constructor. Mode is auto
    Stk_Gui_VBox();
        /** Constructor with mode selection: \\
            - STK_GUI_SIZE_AUTO ( Size of child will be computed when it will be attached. ) \\
            - STK_GUI_SIZE_NOAUTO ( Vertical size is imposed by child )
        */
    Stk_Gui_VBox(int md);
        /// Destructor
    virtual ~Stk_Gui_VBox();

        /// Draw 
    virtual void Draw();

        /// Resize it & its widget attached
    virtual void Resize(const Stk_Gui_Rect &);

    
         /// Add a widget in the list. This VBox Must be attached before!
    virtual void Attach(Stk_Gui_Widget *);
        /// Remove the widget in the list
    virtual void Unfasten(Stk_Gui_Widget *);
        /// list of widgets
    list<Stk_Gui_Widget *> widgets;
private:
    void function1();
        // flag to set mode
    int mode;
};




/** This is a VBox. It could contain many elements. There are represented
    vertically.*/
class Stk_Gui_HBox: public Stk_Gui_Widget
{
public:
        /// Null Constructor. The Size will be computed when it will be attached.
    Stk_Gui_HBox();
        /** Constructor with mode selection: \\
            - STK_GUI_SIZE_AUTO ( Size of child will be computed when it will be attached. ) \\
            - STK_GUI_SIZE_NOAUTO ( Vertical size is imposed by child )
        */
    Stk_Gui_HBox(int md);
        /// Destructor
    virtual ~Stk_Gui_HBox();

        /// Draw 
    virtual void Draw();

        /// Resize it & its widget attached
    virtual void Resize(const Stk_Gui_Rect &);

    
         /// Add a widget in the list. This VBox Must be attached before!
    virtual void Attach(Stk_Gui_Widget *);
        /// Remove the widget in the list
    virtual void Unfasten(Stk_Gui_Widget *);
        /// list of widgets
    list<Stk_Gui_Widget *> widgets;
private:
    void function1();
    int mode;
};




/** This is the root of STK widget hiearchy. You must create it before
    doing anything else.
 */
class Stk_Gui_Window:public Stk_Gui_Container
{
public:
        /// Constructor (width & height)
    Stk_Gui_Window(Stk_Handler *handler,const Stk_Gui_Rect &);
        /// Destructor: all the hiearchie is destroyed
    ~Stk_Gui_Window();

        /// Draw a BackGround
    virtual void DrawBackGround();
        /// Draw
    virtual void Draw();
        /// Message received
    virtual void MessageReceived(Stk_Message *msg);

        /// Show Cursor
    void ShowCursor();
        /// Hide Cursor
    void HideCursor();
    
private:
        /// the graphical context connected with this window
    Stk_Gui_GContext *gc;
        /// state of cursor
    int cursor;
        /// position x of cursor
    int cur_x;
        /// position y of cursor
    int cur_y;

    void DrawCursor();
};

#endif
