#include "CheckBox.h"

class CheckBox::_CheckBox : public Window {
    friend class CheckBox;
public:
    enum {
        NORMAL,
        HIGHLIGHTED,
        CHECKED,
        CHECKED_HIGHLIGHTED,
        CHECKED_DISABLED,
        DISABLED
    };

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

    void enable(bool enabled);

    bool isHit(float x, float y);
    Window* getHitWindow(float x, float y);

    bool isChecked();
    void check(bool checked);

protected:
    void onMouseEnter(Event& event);
    void onMouseLeave(Event& event);
    void onMouseLeftDown(Event& event);
    void onMouseLeftUp(Event& event);

    int _state;

    bool _pressed;
    bool _checked;

    Texture *_normalTexture,
            *_highlightedTexture,
            *_checkedTexture,
            *_checkedHighlightedTexture,
            *_checkedDisabledTexture,
            *_disabledTexture;
};


CheckBox::_CheckBox::_CheckBox(Window* parent)
: Window(parent), _state(NORMAL), _checked(false), _pressed(false),
_normalTexture(0), _highlightedTexture(0), _checkedTexture(0), 
_checkedHighlightedTexture(0), _checkedDisabledTexture(0), _disabledTexture(0)
{
    setPosition(Point(0.0f, 0.0f));
    setSize(Size(13.0f, 13.0f));

    _normalTexture = ResourceManager::instance().loadTexture(L"textures/gui/checkbox.dds");
    _highlightedTexture = ResourceManager::instance().loadTexture(L"textures/gui/checkbox_highlighted.dds");
    _checkedTexture = ResourceManager::instance().loadTexture(L"textures/gui/checkbox_checked.dds");
    _checkedHighlightedTexture = ResourceManager::instance().loadTexture(L"textures/gui/checkbox_checked_highlighted.dds");
    _checkedDisabledTexture = ResourceManager::instance().loadTexture(L"textures/gui/checkbox_checked_disabled.dds");
    _disabledTexture = ResourceManager::instance().loadTexture(L"textures/gui/checkbox_disabled.dds");

    _texture = _normalTexture;
}

CheckBox::_CheckBox::~_CheckBox()
{

}

bool CheckBox::_CheckBox::isHit(float x, float y)
{
    return false;
}

Window* CheckBox::_CheckBox::getHitWindow(float x, float y)
{
    return 0;
}

bool CheckBox::_CheckBox::isChecked()
{
    return _checked;
}

void CheckBox::_CheckBox::check(bool checked)
{
    if (_enabled) {
        if (checked) {
            _state = CHECKED;
            _texture = _checkedTexture;
            _checked = true;
        }
        else {
            _state = NORMAL;
            _texture = _normalTexture;
            _checked = false;
        }
    }
    else {
        if (checked) {
            _state = CHECKED_DISABLED;
            _texture = _checkedDisabledTexture;
            _checked = true;
        }
        else {
            _state = DISABLED;
            _texture = _disabledTexture;
            _checked = false;
        }
    }
}

void CheckBox::_CheckBox::enable(bool enabled)
{
    Window::enable(enabled);
    
    if (_enabled) {
        if (_checked) {
            _state = CHECKED;
            _texture = _checkedTexture;
        }
        else {
            _state = NORMAL;
            _texture = _normalTexture;
        }
    }
    else {
        if (_checked) {
            _state = CHECKED_DISABLED;
            _texture = _checkedDisabledTexture;
        }
        else {
            _state = DISABLED;
            _texture = _disabledTexture;
        }
    }
}

void CheckBox::_CheckBox::onMouseEnter(Event& event)
{
    if (_enabled) {
        if (_checked) {
            _state = CHECKED_HIGHLIGHTED;
            _texture = _checkedHighlightedTexture;
        }
        else {
            _state = HIGHLIGHTED;
            _texture = _highlightedTexture;
        }
    }
}

void CheckBox::_CheckBox::onMouseLeave(Event& event)
{
    if (_enabled) {
        _pressed = false;

        if (_checked) {
            _state = CHECKED;
            _texture = _checkedTexture;
        }
        else {
            _state = NORMAL;
            _texture = _normalTexture;
        }
    }
}

void CheckBox::_CheckBox::onMouseLeftDown(Event& event)
{
    if (_enabled) {
        _pressed = true;
    }
}

void CheckBox::_CheckBox::onMouseLeftUp(Event& event)
{
    if (_enabled) {
        if (_pressed) {
            _pressed = false;

            if (_checked) {
                _state = HIGHLIGHTED;
                _texture = _highlightedTexture;
                _checked = false;
            }
            else {
                _state = CHECKED_HIGHLIGHTED;
                _texture = _checkedHighlightedTexture;
                _checked = true;
            }

            Event clickEvent = event;
            clickEvent.type = Event::MOUSE_LEFT_CLICK;
            _parent->handleEvent(clickEvent);
        }
    }
}



CheckBox::CheckBox(Window* parent)
: Window(parent), _checkBox(0)
{
    setPosition(Point(0.0f, 0.0f));
    setSize(Size(128.0f, 24.0f));

    _caption->setFont(L"Microsoft Sans Serif", L"000000", 13.0f, Text::FONT_STYLE_REGULAR, Text::H_ALIGN_LEFT | Text::V_ALIGN_CENTER);
    _caption->setPosition(Vector3(18.0f / _size.w(), 0.0f, 0.0f));
    _caption->setScale(Vector3((_size.w() - 18.0f) / _size.w(), 1.0f, 1.0f));
    _caption->setMaxWidth(_size.w() - 18.0f);
    _caption->setMaxHeight(_size.h());

    _checkBox = new _CheckBox(this);
    _checkBox->setPosition(Point(0.0f, floor((_size.h() - 13.0f) / 2.0f)));

    connectEvent(Event::MOUSE_ENTER,     this, (EventHandler)&CheckBox::onMouseEnter);
    connectEvent(Event::MOUSE_LEAVE,     this, (EventHandler)&CheckBox::onMouseLeave);
    connectEvent(Event::MOUSE_LEFT_DOWN, this, (EventHandler)&CheckBox::onMouseLeftDown);
    connectEvent(Event::MOUSE_LEFT_UP,   this, (EventHandler)&CheckBox::onMouseLeftUp);
}

CheckBox::~CheckBox()
{
    delete _checkBox;
}

void CheckBox::setSize(Size& size)
{
    Window::setSize(size);
   
    if (_checkBox != 0) {
        _checkBox->setPosition(Point(0.0f, floor((_size.h() - 13.0f) / 2.0f)));
        _checkBox->setSize(Size(13.0f, 13.0f));
    }

    _caption->setPosition(Vector3(18.0f / _size.w(), 0.0f, 0.0f));
    _caption->setScale(Vector3((_size.w() - 18.0f) / _size.w(), 1.0f, 1.0f));
    _caption->setMaxWidth(_size.w() - 18.0f);
    _caption->setMaxHeight(_size.h());
}

bool CheckBox::isChecked()
{
    return _checkBox->isChecked();
}

void CheckBox::check(bool checked)
{
    _checkBox->check(checked);
}

void CheckBox::onMouseEnter(Event& event)
{
    _checkBox->onMouseEnter(event);
}

void CheckBox::onMouseLeave(Event& event)
{
    _checkBox->onMouseLeave(event);
}

void CheckBox::onMouseLeftDown(Event& event)
{
    _checkBox->onMouseLeftDown(event);
}

void CheckBox::onMouseLeftUp(Event& event)
{
    _checkBox->onMouseLeftUp(event);
}