#include "Slider.h"

class Slider::_Slider : public Window {
    friend class Slider;
public:
    enum {
        NORMAL,
        ACTIVE,
        DISABLED
    };

    _Slider(Window* parent = 0);
    virtual ~_Slider();

    void enable(bool enabled);

protected:
    void onMouseLeftDown(Event& event);
    void onMouseLeftUp(Event& event);
    void onDrag(Event& event);
    void onEndDrag(Event& event);

    int _state;

    Texture *_normalTexture,
            *_activeTexture,
            *_disabledTexture;
};


Slider::_Slider::_Slider(Window* parent)
: Window(parent), _state(NORMAL),
_normalTexture(0), _activeTexture(0)
{
    setPosition(Point(0.0f, 0.0f));
    setSize(Size(10.0f, 18.0f));

    _normalTexture = ResourceManager::instance().loadTexture(L"textures/gui/slider.dds");
    _activeTexture = ResourceManager::instance().loadTexture(L"textures/gui/slider_active.dds");
    _disabledTexture = ResourceManager::instance().loadTexture(L"textures/gui/slider_disabled.dds");

    _texture = _normalTexture;

    connectEvent(Event::MOUSE_LEFT_DOWN, this, (EventHandler)&Slider::_Slider::onMouseLeftDown);
    connectEvent(Event::MOUSE_LEFT_UP,   this, (EventHandler)&Slider::_Slider::onMouseLeftUp);
    connectEvent(Event::DRAG,            this, (EventHandler)&Slider::_Slider::onDrag);
    connectEvent(Event::DRAG_END,        this, (EventHandler)&Slider::_Slider::onEndDrag);

    _draggable = true;
}

Slider::_Slider::~_Slider()
{

}


void Slider::_Slider::enable(bool enabled)
{
    Window::enable(enabled);
    
    if (_enabled) {
        _state = NORMAL;
        _texture = _normalTexture;
    }
    else {
        _state = DISABLED;
        _texture = _disabledTexture;
    }
}


void Slider::_Slider::onMouseLeftDown(Event& event)
{
    if (_enabled) {
        _state = ACTIVE;
        _texture = _activeTexture;
    }
}

void Slider::_Slider::onMouseLeftUp(Event& event)
{
    if (_enabled) {
        _state = NORMAL;
        _texture = _normalTexture;
    }
}

void Slider::_Slider::onDrag(Event& event)
{
    if (_enabled) {
        Slider* parent = (Slider*)_parent;
        Event evtValueChanged;
        memset(&evtValueChanged, 0, sizeof(Event));
        evtValueChanged.type = Event::VALUE_CHANGED;
        parent->handleEvent(evtValueChanged);
    }
}

void Slider::_Slider::onEndDrag(Event& event)
{
    if (_enabled) {
        _state = NORMAL;
        _texture = _normalTexture;
    }
}


Slider::Slider(Window* parent)
: Window(parent), _slider(0)
{
    setPosition(Point(0.0f, 0.0f));
    setSize(Size(210.0f, 18.0f));
    
    _texture = ResourceManager::instance().loadTexture(L"textures/gui/slider_background.dds");

    _slider = new _Slider(this);

    connectEvent(Event::MOUSE_LEFT_DOWN, this, (EventHandler)&Slider::onMouseLeftDown);
}

Slider::~Slider()
{
    delete _slider;
}

float Slider::getValue()
{
    return _slider->getPosition().x() / (_size.w() - 10.0f);
}

void Slider::setValue(float value)
{
    if (value <= 0.0f) value = 0.0f;
    if (value >= 1.0f) value = 1.0f;

    _slider->setPosition(Point(value * (_size.w() - 10.0f), 0.0f));

    Event evtValueChanged;
    memset(&evtValueChanged, 0, sizeof(Event));
    evtValueChanged.type = Event::VALUE_CHANGED;
    handleEvent(evtValueChanged);
}

void Slider::onMouseLeftDown(Event& event)
{
    if (_enabled) {
        float sliderPosition = event.mouseX - getTranslatedPosition().x();

        if (sliderPosition + 10.0f > _size.w())
            sliderPosition = _size.w() - 10.0f;
     
        _slider->setPosition(Point(sliderPosition, 0.0f));

        Event evtValueChanged;
        memset(&evtValueChanged, 0, sizeof(Event));
        evtValueChanged.type = Event::VALUE_CHANGED;
        handleEvent(evtValueChanged);
    }
}