//
// C++ Implementation: numeric
//
// Description:
//
//
// Author: Messenger of death aka Denis A. Birukov <messengerofdeath@gmail.com>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "numeric.h"
#include "video.h"
#include "video_int.h"
#include "event.h"
#include "textrenderer.h"
#include "signal_manager.h"
#include <stdio.h>

ObjectFabric<Numeric> NumericObjectFabric;

Numeric::Numeric() :
        TextObject(),
        INIT_SLOT( Numeric, this, increment_value ),
        INIT_SLOT( Numeric, this, decrement_value ),
        INIT_SLOT( Numeric, this, add_value ),
        INIT_SLOT( Numeric, this, sub_value ),
        INIT_SLOT( Numeric, this, set_value ),
        _value_( 0 ),
        _value_length_( 0 ),
        _value_changed_( false ),
        _xb_( 0.0 ),
        _yb_( 0.0 )
{
}


Numeric::~Numeric()
{
}

void Numeric::draw()
{
    if ( _value_changed_ )
    {
        char buf[_value_length_+2];
        snprintf( buf, _value_length_ + 1, _value_spec_, _value_ );
        _text_ = buf;
        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 of type \"" + _renderer_type_ + " :" + textrenderer_error() );
            return;
        }
        if ( !renderer->render_text_line( _video_name_, _font_, _text_, _clr_, _font_size_, _object_name_, _scene_name_, true ) )
        {
            _set_error( "Can't render text:" + renderer->_get_error() );
            return;
        }
        if ( !vid->_create_sprite( _object_name_, _scene_name_, _object_name_, _scene_name_, true ) )
        {
            _set_error( "Can't create sprite: " + vid->_get_error() );
            return;
        }

        Video_Sprite *spr = vid->_get_sprite( _object_name_, _scene_name_ );
        if ( !spr )
        {
            _set_error( "Can't get sprite: " + vid->_get_error() );
            return;
        }
        spr->_set_base_point( _xb_, _yb_ );
        spr->_set_coord( _x_, _y_ );
        _value_changed_ = false;
    }
    TextObject::draw();

}



bool Numeric::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;

    register_slot( scene_name + "->" + object_name + "->" + "increment_value", &increment_value );
    register_slot( scene_name + "->" + object_name + "->" + "decrement_value", &decrement_value );
    register_slot( scene_name + "->" + object_name + "->" + "add_value", &add_value );
    register_slot( scene_name + "->" + object_name + "->" + "sub_value", &sub_value );
    register_slot( scene_name + "->" + object_name + "->" + "set_value", &set_value );


    storage_prefix += "numeric->";
    Config_Interface *intf = config_get_interface( storage_name );
    if ( !intf )
    {
        _set_error( "Can't get config interface:" + config_error() );
        return false;
    }
    _value_ = atoi( intf->_get_value( storage_prefix + "start_value", "0" ).c_str() );
    _value_length_ = atoi( intf->_get_value( storage_prefix + "value_length", "0" ).c_str() );
    snprintf( _value_spec_, 9, "%%0%dd", _value_length_ );
    _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() );
    _value_changed_ = true;

    return true;
}

DEFINE_SLOT( Numeric, increment_value )
{
    _value_++;
    _value_changed_ = true;
    return false;
}
DEFINE_SLOT( Numeric, decrement_value )
{
    _value_--;
    _value_changed_ = true;
    return false;
}
DEFINE_SLOT( Numeric, add_value )
{
    int new_value = 0;
    try
    {
        new_value = args->int_args.at( 0 );
    }
    catch ( ... )
    {
        return false;
    }
    _value_ += new_value;
    _value_changed_ = true;
    return false;
}
DEFINE_SLOT( Numeric, sub_value )
{
    int new_value = 0;
    try
    {
        new_value = args->int_args.at( 0 );
    }
    catch ( ... )
    {
        return false;
    }
    _value_ -= new_value;
    _value_changed_ = true;
    return false;
}
DEFINE_SLOT( Numeric, set_value )
{
    int new_value = 0;
    try
    {
        new_value = args->int_args.at(0);
    }
    catch ( ... )
    {
        return false;
    }
    _value_ = new_value;
    _value_changed_ = true;
    return false;
}
