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

  \author Satofumi KAMIMURA

  $Id: TextInput.cpp 854 2009-05-11 09:52:18Z 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;
}
