#include "RadioButton.h"

RadioGroup::RadioGroup(Window* parent)
: Label(parent), _selected(0)
{
}

RadioGroup::~RadioGroup()
{
}

RadioButton* RadioGroup::getSelected()
{
    return _selected;
}

void RadioGroup::select(RadioButton* radioButton)
{
    if (_selected != 0)
        _selected->select(false);

    _selected = radioButton;
    
    if (_selected != 0)
        _selected->select(true);
}


class RadioButton::_RadioButton : public Window {
    friend class RadioButton;
public:
    enum {
        NORMAL,
        HIGHLIGHTED,
        SELECTED,
        SELECTED_HIGHLIGHTED,
        SELECTED_DISABLED,
        DISABLED
    };

    _RadioButton(RadioGroup* radioGroup, Window* parent);
    virtual ~_RadioButton();

    void enable(bool enabled);

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

    bool isSelected();
    void select(bool checked);

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

    int _state;

    bool _pressed;
    bool _selected;

    Texture *_normalTexture,
            *_highlightedTexture,
            *_selectedTexture,
            *_selectedHighlightedTexture,
            *_selectedDisabledTexture,
            *_disabledTexture;

    RadioGroup* _radioGroup;
};


RadioButton::_RadioButton::_RadioButton(RadioGroup* radioGroup, Window* parent)
: Window(parent), _radioGroup(radioGroup), _state(NORMAL), _selected(false), _pressed(false),
_normalTexture(0), _highlightedTexture(0), _selectedTexture(0), 
_selectedHighlightedTexture(0), _selectedDisabledTexture(0), _disabledTexture(0)
{
    setPosition(Point(0.0f, 0.0f));
    setSize(Size(13.0f, 13.0f));

    _normalTexture = ResourceManager::instance().loadTexture(L"textures/gui/radiobutton.dds");
    _highlightedTexture = ResourceManager::instance().loadTexture(L"textures/gui/radiobutton_highlighted.dds");
    _selectedTexture = ResourceManager::instance().loadTexture(L"textures/gui/radiobutton_selected.dds");
    _selectedHighlightedTexture =ResourceManager::instance().loadTexture(L"textures/gui/radiobutton_selected_highlighted.dds");
    _selectedDisabledTexture = ResourceManager::instance().loadTexture(L"textures/gui/radiobutton_selected_disabled.dds");
    _disabledTexture = ResourceManager::instance().loadTexture(L"textures/gui/radiobutton_disabled.dds");

    _texture = _normalTexture;
}

RadioButton::_RadioButton::~_RadioButton()
{

}

bool RadioButton::_RadioButton::isHit(float x, float y)
{
    return false;
}

Window* RadioButton::_RadioButton::getHitWindow(float x, float y)
{
    return 0;
}

bool RadioButton::_RadioButton::isSelected()
{
    return _selected;
}

void RadioButton::_RadioButton::select(bool selected)
{
    if (_enabled) {
        if (selected) {
            _state = SELECTED;
            _texture = _selectedTexture;
            _selected = true;
        }
        else {
            _state = NORMAL;
            _texture = _normalTexture;
            _selected = false;
        }
    }
    else {
        if (selected) {
            _state = SELECTED_DISABLED;
            _texture = _selectedDisabledTexture;
            _selected = true;
        }
        else {
            _state = DISABLED;
            _texture = _disabledTexture;
            _selected = false;
        }
    }
}

void RadioButton::_RadioButton::enable(bool enabled)
{
    Window::enable(enabled);
    
    if (_enabled) {
        if (_selected) {
            _state = SELECTED;
            _texture = _selectedTexture;
        }
        else {
            _state = NORMAL;
            _texture = _normalTexture;
        }
    }
    else {
        if (_selected) {
            _state = SELECTED_DISABLED;
            _texture = _selectedDisabledTexture;
        }
        else {
            _state = DISABLED;
            _texture = _disabledTexture;
        }
    }
}

void RadioButton::_RadioButton::onMouseEnter(Event& event)
{
    if (_enabled) {
        if (_selected) {
            _state = SELECTED_HIGHLIGHTED;
            _texture = _selectedHighlightedTexture;
        }
        else {
            _state = HIGHLIGHTED;
            _texture = _highlightedTexture;
        }
    }
}

void RadioButton::_RadioButton::onMouseLeave(Event& event)
{
    if (_enabled) {
        _pressed = false;

        if (_selected) {
            _state = SELECTED;
            _texture = _selectedTexture;
        }
        else {
            _state = NORMAL;
            _texture = _normalTexture;
        }
    }
}

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

void RadioButton::_RadioButton::onMouseLeftUp(Event& event)
{
    if (_enabled) {
        if (_pressed) {
            _pressed = false;

            _radioGroup->select(dynamic_cast<RadioButton*>(_parent));

            _state = SELECTED_HIGHLIGHTED;
            _texture = _selectedHighlightedTexture;

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



RadioButton::RadioButton(RadioGroup* radioGroup, Window* parent)
: Window(parent), _radioGroup(radioGroup), _radioButton(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());

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

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

RadioButton::~RadioButton()
{
    delete _radioButton;
}

void RadioButton::setSize(Size& size)
{
    Window::setSize(size);

    if (_radioButton != 0) {
        _radioButton->setPosition(Point(0.0f, floor((_size.h() - 13.0f) / 2.0f)));
        _radioButton->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 RadioButton::isSelected()
{
    return _radioButton->isSelected();
}

void RadioButton::select(bool selected)
{
    _radioButton->select(selected);
}

void RadioButton::onMouseEnter(Event& event)
{
    _radioButton->onMouseEnter(event);
}

void RadioButton::onMouseLeave(Event& event)
{
    _radioButton->onMouseLeave(event);
}

void RadioButton::onMouseLeftDown(Event& event)
{
    _radioButton->onMouseLeftDown(event);
}

void RadioButton::onMouseLeftUp(Event& event)
{
    _radioButton->onMouseLeftUp(event);
}