#pragma once

//classes for generic interface objects that we use
class CInterfaceControl {
public:
    CInterfaceControl();
    ~CInterfaceControl();

    //resets the controls state
    virtual void Reset();

    //allows the control to process its animations.
    virtual void Animate(int elapsed_time);

    //lets the control draw any 2d artwork that will be behind the 3d models.
    virtual void DrawBackground();
    //places the 3d models.
    virtual void PlaceEntities();
    //lets the control draw any 2d artwork that will be in front of the 3d models.
    virtual void DrawForground();
    //tells the control that the mouse is moving
    virtual bool MousePos(int x, int y);
    //tells the control that the mouse is being pressed or released.
    virtual bool MouseUp(int x, int y);
    virtual bool MouseDown(int x, int y);
};

typedef enum {
    IBS_UP,
    IBS_GOING_DOWN,
    IBS_DOWN,
    IBS_GOING_UP,
} interface_button_state;

#define IB_ANIMATION_TIME 70

class CInterfaceButton {
public:
    CInterfaceButton();
    ~CInterfaceButton();

    virtual void Reset();

    //positions the button on the screen and resets it's state.
    void Init(int x, int y, int w, int h, const char *skin_name = NULL);

protected:
    //the position and size info for the button.
    int x, y;
    int w, h;

    //the skin we use for this button.
    const char *skin;

    //true if the button has mouse capture.
    bool have_capture;

    //the state of the button.
    interface_button_state state;

    //the time elapsed in our current state.
    int animation_time;

    //true if the mouse cursor was over this button last frame.
    bool under_cursor;

    //starts moving the button to the up state.
    void Up();
    //starts moving the button to the down state.
    void Down();

public:
    virtual void Animate(int elapsed_time);
    virtual void PlaceEntities();
    virtual bool MousePos(int x, int y);
    virtual bool MouseDown(int x, int y);
    //a return value of true means this button was pressed by the user.
    virtual bool MouseUp(int x, int y);
};

class CInterfaceBox : public CInterfaceControl {
public:
    void Init(int left, int top, int right, int bottom, int thickness);

    virtual void PlaceEntities();

protected:
    int left, top, right, bottom;
    int thickness;
};

class CInterfaceLine : public CInterfaceControl {
public:
    void Init(int left, int top, int right, int thickness);

    virtual void PlaceEntities();

protected:
    int left, top, right;
    int thickness;
};

#define SLIDER_MAX_STEPS 128
#define SLIDER_FLIP_TIME 250.0f
#define SLIDER_PROPAGATE_THRESH 0.05f

class CInterfaceSlider : public CInterfaceControl {
public:
    CInterfaceSlider();

    //sets the position of the slider on the screen.
    void Init(int x, int y, int w, int h);
    //sets the linear scale.
    void InitLinear(int steps, float low, float high);
    //sets the exponential scale.
    void InitExp(int steps, float log_low, float log_high);

protected:
    //the position of each tick mark.
    float tick_pos[SLIDER_MAX_STEPS];

    //our geometry.
    int x, y, w, h;
    int steps;
    //true if we are log.
    bool log_scale;
    float low;
    float high;

    //the current position, how many ticks are up.
    int position;

    //true if we have the mouse captured.
    bool have_capture;

public:
    virtual void Animate(int elapsed_time);
    virtual void PlaceEntities();
    virtual bool MousePos(int x, int y);
    virtual bool MouseDown(int x, int y);
    //a return value of true means this button was pressed by the user.
    virtual bool MouseUp(int x, int y);

    //returns the current value of the slider.
    float Position();
    //sets the position of the slider.
    void Position(float pos);
};