#include "Programm.h"
#include <Punkt.h>
#include <Rahmen.h>

// Inhalt der Programm Klasse aus Programm.h
// Konstruktor
Programm::Programm( Bildschirm *b, Schrift *s )
{
	bildschirm = b;
	schrift = s;

	Punkt bg = b->getBackBufferSize();
	kFenster = new Fenster();
	kFenster->setStyle( Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::VScroll );
	kFenster->setRFarbe( 0xFFFFFFFF );
	kFenster->setRBreite( 1 );
	kFenster->setPosition( bg.x - 200, 0 );
	kFenster->setSize( 200, bg.y );
	kFenster->setVSBMax( 0 );
	bildschirm->addMember( kFenster );

	mFenster = new Fenster();
	mFenster->setStyle( Fenster::Style::Erlaubt | Fenster::Style::Sichtbar );
	mFenster->setSize( bg.x - 200, bg.y );
	bildschirm->addMember( mFenster );

	auswahlRahmen = new LRahmen();
	auswahlRahmen->setPosition( 0, -30 );
	auswahlRahmen->setSize( 182, 30 );
	auswahlRahmen->setRamenBreite( 1 );
	auswahlRahmen->setFarbe( 0xFFFFFFFF );
	kFenster->addMember( auswahlRahmen );

	sichtbar = -1;

	name = new RCArray< Text >();
	knopf = new RCArray< Knopf >();
	abschnitte = new RCArray< Abschnitt >();

	abschnittAnzahl = 0;

	ref = 1;
}

// Destruktor
Programm::~Programm()
{
	bildschirm->removeMember( kFenster );
	bildschirm->removeMember( mFenster );
	name->release();
	knopf->release();
	abschnitte->release();
	bildschirm->release();
	schrift->release();
}

// nicht constant
bool Programm::addAbschnitt( const char *name, Abschnitt *abschnitt )
{
	bool hat = 0;
	for( int i = 0; i < abschnittAnzahl; i++ )
	{
		if( this->name->z( i )->istGleich( name ) )
		{
			hat = 1;
			break;
		}
	}
	if( hat )
	{
		abschnitt->release();
		return 0;
	}
	Knopf *k = new Knopf();
	k->setStyle( Knopf::Style::Normal );
	k->setSize( 150, 20 );
	k->setPosition( 16, abschnittAnzahl * 30 + 5 );
	k->setSchriftZ( schrift->getThis() );
	k->setText( name );
	k->setMausEreignisParameter( this );
	k->setMausEreignis( programmAbschnittME );
	kFenster->addMember( k->getThis() );

	this->name->add( new Text( name ), abschnittAnzahl );
	knopf->add( k, abschnittAnzahl );
	abschnitte->add( abschnitt, abschnittAnzahl );
	abschnittAnzahl++;

	abschnitt->setFenster( (Fenster*)mFenster->getThis() );

	if( sichtbar < 0 )
	{
		sichtbar = 0;
		auswahlRahmen->setPosition( 0, 0 );
		abschnitt->setSichtbar( 1 );
	}
	kFenster->setVSBMax( abschnittAnzahl * 30 );
	return 1;
}

bool Programm::removeAbschnitt( const char *name )
{
	for( int i = 0; i < abschnittAnzahl; i++ )
	{
		if( this->name->z( i )->istGleich( name ) )
		{
			if( sichtbar == i )
				abschnitte->z( i )->setSichtbar( 0 );
			this->name->remove( i );
			kFenster->removeMember( knopf->z( i ) );
			knopf->remove( i );
			abschnitte->remove( i );
			abschnittAnzahl--;
			if( sichtbar >= abschnittAnzahl )
				sichtbar = abschnittAnzahl - 1;
			if( sichtbar > i )
				sichtbar--;
			if( sichtbar >= 0 && !abschnitte->z( sichtbar )->istSichtbar() )
				abschnitte->z( i )->setSichtbar( 1 );
			auswahlRahmen->setPosition( auswahlRahmen->getX(), sichtbar * 30 );
			kFenster->setVSBMax( abschnittAnzahl * 30 );
			return 1;
		}
	}
	return 0;
}

bool Programm::renameAbschnitt( const char *name, const char *newName )
{
	for( int i = 0; i < abschnittAnzahl; i++ )
	{
		if( this->name->z( i )->istGleich( name ) )
		{
			this->name->z( i )->setText( newName );
			knopf->z( i )->setText( newName );
			return 1;
		}
	}
	return 0;
}

bool Programm::abschnittAuswählen( const char *name )
{
	for( int i = 0; i < abschnittAnzahl; i++ )
	{
		if( this->name->z( i )->istGleich( name ) )
		{
			if( sichtbar == i )
				break;
			abschnitte->z( sichtbar )->setSichtbar( 0 );
			sichtbar = i;
			abschnitte->z( i )->setSichtbar( 1 );
			auswahlRahmen->setPosition( auswahlRahmen->getX(), sichtbar * 30 );
			return 1;
		}
	}
	return 0;
}

bool Programm::abschnittMausEreignis( void *obj, MausEreignis me )
{
	if( me.id == ME_RLinks )
		abschnittAuswählen( ( (Knopf*)obj )->zText()->getText() );
	return 1;
}

// constant
Text *Programm::getSichtbarAbschnittName() const
{
	if( sichtbar >= abschnittAnzahl )
		return 0;
	return name->get( sichtbar );
}

Text *Programm::zSichtbarAbschnittName() const
{
	if( sichtbar >= abschnittAnzahl )
		return 0;
	return name->z( sichtbar );
}

// Reference Counting
Programm *Programm::getThis()
{
	ref++;
	return this;
}

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

// Ereignis
bool programmAbschnittME( void *p, void *obj, MausEreignis me )
{
	if( p )
		return ( (Programm*)p )->abschnittMausEreignis( obj, me );
	return 0;
}