#include "Variablen.h"
#include "Gegenstand.h"


GeschossTyp getGeschossTypFromString( Text str )
{
    if( str.istGleich( "KUGEL" ) )
        return GESCHOSS_KUGEL;
    if( str.istGleich( "DRACHENAUGE" ) )
        return GESCHOSS_DRACHENAUGE;
    if( str.istGleich( "FEUERBALL" ) )
        return GESCHOSS_FEUERBALL;
    if( str.istGleich( "MINE" ) )
        return GESCHOSS_MINE;
    return GESCHOSS_PFEIL;
}


Richtung invert( Richtung r )
{
    if( r == OBEN )
        return UNTEN;
    if( r == UNTEN )
        return OBEN;
    if( r == LINKS )
        return RECHTS;
    if( r == RECHTS )
        return LINKS;
    return r;
}


Richtung getRichtungFromString( Text str )
{
    if( str.istGleich( "OBEN" ) )
        return OBEN;
    if( str.istGleich( "LINKS" ) )
        return LINKS;
    if( str.istGleich( "UNTEN" ) )
        return UNTEN;
    if( str.istGleich( "RECHTS" ) )
        return RECHTS;
    return MITTE;
}


bool operator==( VariableTyp a, VariableTyp b )
{
    if( a == GAME_OBJEKT || b == GAME_OBJEKT )
    {
        return ( a == BARIERE || a == BASE || a == DROP || a == GEGENSTAND || a == GESCHOSS ||
                 a == SCHALTER || a == SCHIENE || a == SPIELER || a == TIMER ||
                 a == TUNNEL || a == UMLENKUNG || a == GAME_OBJEKT || a == ALLE ) &&
                 ( b == BARIERE || b == BASE || b == DROP || b == GEGENSTAND || b == GESCHOSS ||
                   b == SCHALTER || b == SCHIENE || b == SPIELER || b == TIMER || b == TUNNEL ||
                   b == UMLENKUNG || b == GAME_OBJEKT || b == ALLE );
    }
    if( a == ALLE || b == ALLE )
        return 1;
    return (int)a == (int)b;
}

bool operator!=( VariableTyp a, VariableTyp b )
{
    return !( a == b );
}


Variable::Variable( VariableTyp typ )
{
    this->typ = typ;
    ref = 1;
}

Variable::~Variable()
{}

VariableTyp Variable::getVariableTyp() const
{
    return typ;
}

Variable *Variable::getThis()
{
    ref++;
    return this;
}

Variable *Variable::release()
{
    if( !--ref )
        delete this;
    return 0;
}

bool isTrue( Variable *v )
{
    if( !v )
        return 0;
    switch( v->getVariableTyp() )
    {
    case NICHTS:
        return 0;
    case INTEGER:
        return ( (Integer *)v )->getValue() != 0;
    case BOOLEAN:
        return ( (Boolean *)v )->getValue();
    case STRING:
        return ( (String *)v )->getValue().getLength();
    case FLOAT:
        return ( (Float *)v )->getValue() != 0;
    case TASTE:
        return ( (Integer *)v )->getValue() != 0;
    case GEGENSTAND_TYP:
        return ( (GegenstandTypVar *)v )->getValue() != KEIN_GEGENSTAND;
    default:
        return 1;
    }
}


Integer::Integer( int value, bool taste )
    : Variable( taste ? TASTE : INTEGER )
{
    this->value = value;
}

void Integer::setValue( int value )
{
    this->value = value;
}

int Integer::getValue() const
{
    return value;
}


Boolean::Boolean( bool value )
    : Variable( BOOLEAN )
{
    this->value = value;
}

void Boolean::setValue( bool value )
{
    this->value = value;
}

bool Boolean::getValue() const
{
    return value;
}


String::String( const char *value )
    : Variable( STRING )
{
    this->value = value;
}

String::String( Richtung r )
    : Variable( RICHTUNG )
{
    switch( r )
    {
    case OBEN:
        value = "OBEN";
        break;
    case UNTEN:
        value = "UNTEN";
        break;
    case LINKS:
        value = "LINKS";
        break;
    case RECHTS:
        value = "RECHTS";
        break;
    case MITTE:
        value = "MITTE";
        break;
    default:
        break;
    }
}

String::String( GeschossTyp typ )
    : Variable( GESCHOSS_TYP )
{
    switch( typ )
    {
    case GESCHOSS_PFEIL:
        value = "PFEIL";
        break;
    case GESCHOSS_KUGEL:
        value = "KUGEL";
        break;
    case GESCHOSS_FEUERBALL:
        value = "FEUERBALL";
        break;
    case GESCHOSS_DRACHENAUGE:
        value = "DRACHENAUGE";
        break;
    case GESCHOSS_MINE:
        value = "MINE";
        break;
    }
}

void String::setValue( Text value )
{
    this->value = value;
}

const Text &String::getValue() const
{
    return value;
}


Float::Float( float value )
    : Variable( FLOAT )
{
    this->value = value;
}

void Float::setValue( float value )
{
    this->value = value;
}

float Float::getValue() const
{
    return value;
}