/*!
  \file
  \brief 入力文字の取得

  \author Satofumi KAMIMURA

  $Id: TextInput.cpp 1811 2010-04-30 16:12:05Z satofumi $
*/

#include "TextInput.h"
#include "LayerManager.h"
#include "CallbackEvent.h"
#include <string>

using namespace qrk;
using namespace std;


struct TextInput::pImpl
{
    LayerManager layer_manager_;
    CallbackEvent* backspace_event_;
    CallbackEvent* decide_event_;

    string text_;
    bool is_changed_;


    pImpl(void)
        : backspace_event_(NULL), decide_event_(NULL), is_changed_(false)
    {
    }


    void checkKey(SDLKey key, Uint8 type, SDLMod mod, Uint16 unicode)
    {
        if ((type == SDL_KEYDOWN) && (isprint(unicode))) {
            is_changed_ = true;
            text_.push_back(unicode & 0xff);
        }

        // 決定の検出
        if (decide_event_) {
            decide_event_->checkKey(key, type, mod, unicode);
        }

        // 末尾の１文字を削除
        if (backspace_event_ && (! text_.empty())) {
            backspace_event_->checkKey(key, type, mod, unicode);
            if (backspace_event_->isActive()) {
                text_.resize(text_.length() - 1);
                is_changed_ = true;
            }
        }
    }
};


TextInput::TextInput(void) : pimpl(new pImpl)
{
}


TextInput::~TextInput(void)
{
}


void TextInput::setEventAcceptable(bool acceptable)
{
    static_cast<void>(acceptable);
    // !!!
}


void TextInput::clearEvent(void)
{
}


void TextInput::checkKey(SDLKey key, Uint8 type, SDLMod mod, Uint16 unicode)
{
    return pimpl->checkKey(key, type, mod, unicode);
}


void TextInput::checkClick(Uint8 mouse_button, Uint8 type)
{
    static_cast<void>(mouse_button);
    static_cast<void>(type);

    // 実装しない
}


void TextInput::checkEnterCursor(const Point<long>& current,
                                 const Point<long>& previous)
{
    static_cast<void>(current);
    static_cast<void>(previous);

    // 実装しない
}


void TextInput::cursorMoved(void)
{
    // 実装しない
}


void TextInput::clear(void)
{
    pimpl->is_changed_ = true;
    pimpl->text_.clear();
}


bool TextInput::empty(void) const
{
    return pimpl->text_.empty();
}


const char* TextInput::text(void) const
{
    return pimpl->text_.c_str();
}


bool TextInput::isChanged(void) const
{
    bool is_changed = pimpl->is_changed_;
    pimpl->is_changed_ = false;
    return is_changed;
}


void TextInput::setBackspaceEvent(CallbackEvent* event)
{
    pimpl->backspace_event_ = event;
}


void TextInput::setDecideEvent(CallbackEvent* event)
{
    pimpl->decide_event_ = event;
}
