//
// C++ Implementation: textedit
//
// Description:
//
//
// Author: Denis A. Birukov <denis.birukov@gmail.com>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "textedit.h"
#include "video.h"
#include "video_int.h"
#include "event.h"
#include "textrenderer.h"
#include "signal_manager.h"

ObjectFabric<TextEdit> TextEditFabric;

TextEdit::TextEdit()
        : SceneObject(),
        SceneImage(),
        INIT_SLOT ( TextEdit, this, _on_activate ),
        INIT_SLOT ( TextEdit, this, _on_deactivate ),
        INIT_SLOT ( TextEdit, this, _on_key_press ),
        INIT_SLOT ( TextEdit, this, _on_character ),
        INIT_SLOT ( TextEdit, this, _on_get_value )

{}


TextEdit::~TextEdit()
{}


bool TextEdit::load ( std::string storage_name, std::string storage_prefix, std::string scene_name, std::string object_name )
{
    if ( !SceneObject::load ( storage_name, storage_prefix, scene_name, object_name ) ) return false;
    if ( !SceneImage::load ( storage_name, storage_prefix, scene_name, object_name ) ) return false;

    storage_prefix += "textedit->";
    Config_Interface *intf = config_get_interface ( storage_name );
    if ( !intf )
    {
        _set_error ( "Can't get config interface:" + config_error() );
        return false;
    }

    _renderer_type_ = intf->_get_value ( storage_prefix + "renderer", "" );
    _font_ = intf->_get_value ( storage_prefix + "font", "" );
    _font_size_ = atol ( intf->_get_value ( storage_prefix + "font_size", "" ).c_str() );

    _clr_.set_r ( atol ( intf->_get_value ( storage_prefix + "r_color", "" ).c_str() ) );
    _clr_.set_g ( atol ( intf->_get_value ( storage_prefix + "g_color", "" ).c_str() ) );
    _clr_.set_b ( atol ( intf->_get_value ( storage_prefix + "b_color", "" ).c_str() ) );
    _clr_.set_a ( atol ( intf->_get_value ( storage_prefix + "a_color", "" ).c_str() ) );
    _xb_ = atof ( intf->_get_value ( storage_prefix + "x_base", "0.5" ).c_str() );
    _yb_ = atof ( intf->_get_value ( storage_prefix + "y_base", "0.5" ).c_str() );
    _max_len_ = atol ( intf->_get_value ( storage_prefix + "max_len", "0" ).c_str() );
    _replace_ = ( unsigned int ) intf->_get_value ( storage_prefix + "replace", "" ) [0];

    SlotName slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_character";
    register_slot(slot_name_t, &_on_character);
    
    slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_get_value";
    register_slot(slot_name_t, &_on_get_value);


    return true;
}

void TextEdit::draw()
{
    SceneImage::draw();
    if ( _text_.empty() ) return;
    std::vector<int> replace_string;
    if ( _replace_ != 0 )
    {
        for ( unsigned int a = 0;a < _text_.size();a++ ) replace_string.push_back ( _replace_ );
    }

    Video_Interface *vid = video_get_interface ( _video_name_ );
    if ( !vid )
    {
        _set_error ( "Can't get video interface:" + video_error() );
        return;
    }

    Text_Renderer *renderer;
    renderer = textrenderer_get ( _renderer_type_ );
    if ( !renderer )
    {
        _set_error ( "Can't get renderer:" + textrenderer_error() );
        return;
    }

    if ( !renderer->render_text_line_to_sprite ( _video_name_, _font_, ( _replace_ == 0 ) ? _text_ : replace_string, _clr_, _font_size_, _object_name_ + "txt", _scene_name_, true ) )
    {
        _set_error ( "Can't render text:" + renderer->_get_error() );
        return;
    }

    Video_Sprite *spr = vid->_get_sprite ( _object_name_ + "txt", _scene_name_ );
    if ( !spr )
    {
        _set_error ( "Can't get sprite: " + vid->_get_error() );
        return;
    }
    Video_Sprite *img = vid->_get_sprite ( _object_name_ , _scene_name_ );
    if ( !img )
    {
        _set_error ( "Can't get sprite: " + vid->_get_error() );
        return;
    }
    spr->_set_base_point ( _xb_, _yb_ );
    spr->_set_coord ( img->_get_x() - img->_get_base_x(), img->_get_y() - img->_get_base_y() );
    vid->_add_sprite ( _object_name_ + "txt", _scene_name_ );
}

void TextEdit::_get_active_area_rect ( VideoRect* rect )
{
    SceneObject::_get_active_area_rect ( rect );
}
DEFINE_SLOT ( TextEdit, _on_activate )
{
    Video_Interface *vid = video_get_interface ( _video_name_ );
    if ( !vid )
    {
        _set_error ( "Can't get video interface:" + video_error() );
        return false;
    }
    Video_Sprite *spr = vid->_get_sprite ( _object_name_, _scene_name_ );
    if ( !spr )
    {
        _set_error ( "Can't get sprite: " + vid->_get_error() );
        return false;
    }
    spr->_set_blend_color ( 0.5, 0.5, 0.5 );
    SignalName signal_name_t = _video_name_+"->character";
    SlotName slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_character";
    connect(signal_name_t, slot_name_t);
    
    signal_name_t = _video_name_ + "->keyboard_release";
    slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_key_press";
    connect(signal_name_t, slot_name_t);

    return false;
}
DEFINE_SLOT ( TextEdit, _on_deactivate )
{
    Video_Interface *vid = video_get_interface ( _video_name_ );
    if ( !vid )
    {
        _set_error ( "Can't get video interface:" + video_error() );
        return false;
    }
    Video_Sprite *spr = vid->_get_sprite ( _object_name_, _scene_name_ );
    if ( !spr )
    {
        _set_error ( "Can't get sprite: " + vid->_get_error() );
        return false;
    }
    spr->_set_blend_color ( 1.0, 1.0, 1.0 );
    
    SignalName signal_name_t = _video_name_+"->character";
    SlotName slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_character";
    disconnect(signal_name_t, slot_name_t);
    
    signal_name_t = _video_name_+"->activate";
    slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_activate";
    disconnect(signal_name_t, slot_name_t);
    
    signal_name_t = _video_name_ + "->keyboard_release";
    slot_name_t = _scene_name_ + "->" + _object_name_ + "->on_key_press";
    disconnect(signal_name_t, slot_name_t);
    return true;
}

DEFINE_SLOT ( TextEdit, _on_character )
{
    std::cerr<<__FUNCTION__<<std::endl;
    int character='v';
    try
    {
        character = args->int_args.at(0);
    }
    catch(...){}
    if ( _text_.size() < _max_len_ ) _text_.push_back ( character );
    return true;
}

DEFINE_SLOT ( TextEdit, _on_key_press )
{
    int key;
    try
    {
        key = args->int_args.at(0);
    }
    catch(...){return true;};
    switch(key)
    {
        case KEY_BACKSPACE: { _text_.pop_back();break;}
        default:return true;
    }
    return true;
}

DEFINE_SLOT ( TextEdit, _on_get_value )
{
    Signal value;
    SignalName signal_name_t = _scene_name_ + "->" + _object_name_ + "->set_value";
    std::string txt;
    for (unsigned int a=0;a<_text_.size(); a++)txt.push_back(_text_[a]);
    value.set_name(signal_name_t);
    value.add_params(txt);
    value.rise();
    _text_.clear();
    return true;
}

