#include <Network.h>
#include <main.h>
#include "Start.h"
#include <Punkt.h>
#include <MausEreignis.h>
#include <Bildschirm.h>
#include <DateiSystem.h>
#include <Text.h>
#include <TextFeld.h>
#include <Bild.h>
#include <InitDatei.h>
#include <Datei.h>
#include "..\Render\Render.h"
#include "..\Programm\Programm.h"
#include "..\Programm\Beenden\Beenden.h"
#include "..\Programm\Login\Login.h"

// Laden Fenster Ereignis
bool lFMausEreignis( void *p, void *f, MausEreignis me )
{
	return 1;
}

void lFVorSchließEreignis( void *p, void *f )
{
	// Fenster nicht close
}

// Haupt Fenster Maus Ereignis
bool hFMausEreignis( void *p, void *f, MausEreignis me )
{
	return 1;
}

bool hFTastaturEreignis( void *p, void *f, TastaturEreignis me )
{
	return 1;
}

void hFVorSchließEreignis( void *p, void *f )
{
	// Programm beenden
	PostQuitMessage( 0 );
}

// Inhalt der LedeBildschirm Klasse aus Start.h
// Konstruktor
LadeBildschirm::LadeBildschirm( Schrift *s, InitDatei *d, WFenster *f )
: Thread()
{
	bilder = new RessourceBild();
	schriften = new RessourceSchrift();
	schrift = s;
	iD = d;
	lF = f;
	start();
}

// Destruktor
LadeBildschirm::~LadeBildschirm()
{
	schrift->release();
	iD->release();
	lF->release();
	bilder->release();
	schriften->release();
}

// nicht constant
void LadeBildschirm::thread()
{
	// Fenster ertellen;
	lF->setVerschiebbar( 1 );
	lF->setSize( 300, 150 );
	lF->setPosition( Bildschirmmitte( lF->getThis() ) );
	lF->setMausAktion( lFMausEreignis );
	lF->setVSchließAktion( lFVorSchließEreignis );
	Bildschirm *lB = new Bildschirm3D( lF->getThis() );
	lF->setBildschirm( lB->getThis() );
	lB->setdeckFarbe( 0x00000000 );
	lB->setRenderZeichnungen( 1 );
	lB->update();
	lF->setAnzeigeModus( 1 );
	lB->render();
	lB->tick( 0 );
	// Tetfeld erstellen
	TextFeld *lTF = new TextFeld();
	lTF->setStyle( TextFeld::Style::Hintergrund | TextFeld::Style::HAlpha | TextFeld::Style::Sichtbar || TextFeld::Style::VCenter || TextFeld::Style::Rahmen );
	lTF->setSchriftZ( schrift->getThis() );
	lTF->setText( "Initialisierung..." );
	lTF->setSize( 300, 20 );
	lTF->setPosition( 0, 130 );
	lTF->setHintergrundFarbe( 0x88000000 );
	lTF->setSchriftFarbe( 0xFFFFFFFF );
	lTF->setRahmenFarbe( 0xFF808080 );
	lB->addMember( lTF->getThis() );
	lB->render();
	lB->tick( 0 );
	// Hintergrund laden
	LTDBDatei *bD = new LTDBDatei();
	bD->setDatei( iD->getWert( "LadenHintergrundDatei" ) );
	bD->leseDaten( 0 );
	BildZ *lBgB = new BildZ();
	lBgB->setStyle( BildZ::Style::Sichtbar );
	lBgB->setBildZ( bD->laden( 0, iD->getWert( "LadenHintergrundBild" ) ) );
	lBgB->setSize( 300, 150 );
	bD->release();
	// rendern
    lB->removeMember( lTF );
	lB->addMember( lBgB );
	lB->addMember( lTF );
	lB->render();
	lB->tick( 0 );
	// laden
	InitDatei *lBD = new InitDatei( iD->zWert( "LadeBilder" )->getText() );
	lBD->laden();
	int anz = lBD->getWertAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		lTF->setText( lBD->zWert( i )->getText() );
		lB->render();
		lB->tick( 0 );
		Text *w = lBD->zWert( i );
		LTDBDatei *ltdb = new LTDBDatei();
		ltdb->setDatei( w->getTeilText( 0, w->positionVon( '/', w->anzahlVon( '/' ) - 1 ) ) );
		ltdb->leseDaten( 0 );
		bilder->add( w->getTeilText( w->positionVon( '/', w->anzahlVon( '/' ) - 1 ) + 1 ), ltdb->laden( 0, w->getTeilText( w->positionVon( '/', w->anzahlVon( '/' ) - 1 ) + 1 ) ) );
		ltdb->release();
	}
	lBD->release();
	InitDatei *lSD = new InitDatei( iD->zWert( "LadeSchriften" )->getText() );
	lSD->laden();
	anz = lSD->getWertAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		lTF->setText( lSD->zWert( i )->getText() );
		lB->render();
		lB->tick( 0 );
		LTDSDatei *ltds = new LTDSDatei();
		ltds->setPfad( lSD->getWert( i ) );
		ltds->leseDaten();
		schriften->add( lSD->zName( i )->getText(), ltds->ladeSchrift() );
		ltds->release();
	}
	lSD->release();
	// Speicher freigeben
	lF->setAnzeigeModus( 0 );
	StopNachrichtenSchleife( lF->getFensterHandle() );
	lF->zerstören();
	lF->setBildschirm( 0 );
	lB->release();
}

// constant
RessourceBild *LadeBildschirm::getBilder()
{
	return bilder->getThis();
}

RessourceSchrift *LadeBildschirm::getSchriften()
{
	return schriften->getThis();
}

// Start des Programms
int KSGStart Framework::Start( Startparam p )
{
	Network::Start( 20 );
	// Erstellen eines Fensters
	WNDCLASS wc = F_Normal( p.hinst );
	wc.lpszClassName = "SMP";
	WFenster *lF = new WFenster();
	lF->erstellen( WS_POPUP, wc );
	// Laden von Schrift und Optionen
	InitDatei *iD = new InitDatei( "data/start/optionen.ini" );
	iD->laden();
	LTDSDatei *sD = new LTDSDatei();
	sD->setPfad( iD->getWert( "LadenSchriftDatei" ) );
	sD->leseDaten();
	Schrift *schrift = sD->ladeSchrift();
	sD->release();
	// Laden anderer Dateien
	LadeBildschirm *lb = new LadeBildschirm( schrift, iD->getThis(), lF );
	StartNachrichtenSchleife();
	lb->warteAufThread( 1000 );
	// Fortsetzung nach laden
	RessourceBild *bilder = lb->getBilder();
	RessourceSchrift *schriften = lb->getSchriften();
    lF->zerstören();
	lb->release();
	// Haupt Fenster erstellen
	if( !iD->wertExistiert( "DisplayMonitor" ) )
		iD->addWert( "DisplayMonitor", "0" );
	int monitorId = TextZuInt( iD->zWert( "DisplayMonitor" )->getText(), 10 );
	Monitor mon = getMonitor( monitorId );
	if( !mon.existiert )
		mon = getMonitor( 0 );
	WFenster *hF = new WFenster();
	hF->erstellen( WS_POPUP, wc );
	hF->setPosition( Punkt( mon.x, mon.y ) );
	hF->setSize( mon.breite, mon.height );
	hF->setMausAktion( hFMausEreignis );
	hF->setTastaturAktion( hFTastaturEreignis );
	hF->setVSchließAktion( hFVorSchließEreignis );
	Bildschirm *hB = new Bildschirm2D( hF->getThis() );
	hF->setBildschirm( hB->getThis() );
	hB->setdeckFarbe( 0x00000000 );
	hB->setRenderZeichnungen( 1 );
    hB->setTestRend( 0 );
	hB->update();
	hF->setAnzeigeModus( 1 );
	hB->render();
	hB->tick( 0 );

	Programm *prog = new Programm( hB->getThis(), schriften->get( iD->zWert( "Schrift" )->getText() ) );

	// Renderer erstellen
	Render *r = new Render( hB->getThis() );
	// Beenden Abschnitt Erstellen
	Beenden *beenden = new Beenden( schriften->get( iD->zWert( "Schrift" )->getText() ), hB->getThis() );
	prog->addAbschnitt( "Beenden", beenden );
	// Mit Datenbank verbinden
	// Login Abschnitt erstellen
	Login *login = new Login( schriften->get( iD->zWert( "Schrift" )->getText() ), prog, iD->getThis(), bilder->getThis(), hB->getThis() );
	prog->addAbschnitt( "Login", login );
	prog->abschnittAuswählen( "Login" );
	// Nachrichten verarbeiten
	r->start();
	StartNachrichtenSchleife();
	r->beenden();

	// Speicher freigeben
	prog->release();

	r->release();
	hB->release();
	hF->setBildschirm( 0 );
	hF->release();

	bilder->release();
	schriften->release();
	iD->release();

	Network::Exit();

	return 0;
}