#include "Resource.h"
#include <DateiSystem.h>


ColorMode::ColorMode()
{
    ref = 1;
}

Bild *ColorMode::colorImage( Bild *zImg, int color )
{
    Bild *result = new Bild();
    result->neuBild( zImg->getBreite(), zImg->getHeight(), 0 );
    result->drawBild( 0, 0, zImg->getBreite(), zImg->getHeight(), *zImg );
    return result;
}

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

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


AlphaColorMode::AlphaColorMode( unsigned char alpha )
{
    this->alpha = alpha;
}

Bild *AlphaColorMode::colorImage( Bild *zImg, int color )
{
    Bild *result = ColorMode::colorImage( zImg, color );
    result->alphaRegion( 0, 0, result->getBreite(), result->getHeight(), ( (int)alpha << 24 ) | ( color & 0xFFFFFF ) );
    return result;
}


MaskColorMode::MaskColorMode( int colorToReplace )
{
    this->colorToReplace = colorToReplace;
}

Bild *MaskColorMode::colorImage( Bild *zImg, int color )
{
    Bild *result = ColorMode::colorImage( zImg, color );
    int *buffer = result->getBuffer();
    int size = result->getBreite() * result->getHeight();
    for( int i = 0; i < size; i++ )
    {
        if( ( buffer[ i ] & 0xFFFFFF ) == colorToReplace )
            buffer[ i ] = ( buffer[ i ] & 0xFF000000 ) | ( color & 0xFFFFFF );
    }
    return result;
}


Resource::Resource( ResourceIds id, int color )
{
    this->id = id;
    this->color = color;
    ref = 1;
}

Resource *Resource::createColoredResource( int color, ColorMode *mode ) const
{
    Resource *r = new Resource( id, color );
    for( auto i = images.getIterator(); i; i++ )
        r->images.add( mode->colorImage( i, color ) );
    mode->release();
    return r;
}

Iterator< Bild * > Resource::getImages() const
{
    return images.getIterator();
}

ResourceIds Resource::getId() const
{
    return id;
}

int Resource::getColor() const
{
    return color;
}

Bild *Resource::zImage( int id ) const
{
    return images.z( id );
}

Bild *Resource::getImage( int id ) const
{
    return images.get( id );
}

int Resource::getImageCount() const
{
    return images.getEintragAnzahl();
}

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

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


ResourceRegistry::ResourceRegistry( Text spielPfad, Text mapPfad )
{
    this->spielPfad = spielPfad;
    this->mapPfad = mapPfad;
    ref = 1;
}

ResourceRegistry::~ResourceRegistry()
{
    if( schrift )
        schrift->release();
}

void ResourceRegistry::setSchrift( Schrift *schrift )
{
    if( this->schrift )
        this->schrift->release();
    this->schrift = schrift;
}

Schrift *ResourceRegistry::zSchrift() const
{
    return schrift;
}

Schrift *ResourceRegistry::getSchrift() const
{
    return schrift ? schrift->getThis() : 0;
}

Resource *ResourceRegistry::getResource( ResourceIds id, int color, ColorMode *mode, Text path )
{
    Resource *r = zResource( id, color, mode, path );
    return r ? r->getThis() : 0;
}

Resource *ResourceRegistry::zResource( ResourceIds id, int color, ColorMode *mode, Text path )
{
    path.ersetzen( "map:", mapPfad );
    path.ersetzen( "spiel:", spielPfad );
    for( auto r = resources.getIterator(); r; r++ )
    {
        if( r->getId() == id && r->getColor() == color )
        {
            if( mode )
                mode->release();
            return r;
        }
    }
    if( !mode )
        return 0;
    for( auto r = resources.getIterator(); r; r++ )
    {
        if( r->getId() == id )
        {
            Resource *nr = r->createColoredResource( color, mode );
            resources.add( nr );
            return nr;
        }
    }
    if( path.hat( ".ltdb/" ) && path.positionVon( "/", path.anzahlVon( "/" ) - 1 ) == path.positionVon( ".ltdb/", path.anzahlVon( ".ltdb/" ) - 1 ) + 5 )
    {
        LTDBDatei dat;
        dat.setDatei( path.getTeilText( 0, path.positionVon( ".ltdb/", path.anzahlVon( ".ltdb/" ) - 1 ) + 5 ) );
        Bild *b = dat.laden( 0, path.getTeilText( path.positionVon( ".ltdb/", path.anzahlVon( ".ltdb/" ) - 1 ) + 6 ) );
        if( b )
        {
            Resource *r = new Resource( id, color );
            resources.add( r );
            r->images.add( mode->colorImage( b, color ) );
            b->release();
            mode->release();
            return r;
        }
        mode->release();
        return 0;
    }
    LTDBDatei dat;
    dat.setDatei( path.getThis() );
    dat.leseDaten( 0 );
    if( !dat.getBildAnzahl() )
    {
        mode->release();
        return 0;
    }
    Resource *r = new Resource( id, color );
    resources.add( r );
    for( int i = 0; i < dat.getBildAnzahl(); i++ )
    {
        Bild *b = dat.laden( 0, dat.zBildListe()->get( i ) );
        r->images.add( mode->colorImage( b, color ) );
        b->release();
    }
    mode->release();
    return r;
}

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

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