#include "main.h"
#include "Fenster.h"
#include <tlhelp32.h>
#include "Punkt.h"
#include "Bildschirm.h"
#include "TextFeld.h"
#include "DateiSystem.h"
#include "Text.h"
#include "Fortschritt.h"
#include "Schrift.h"
#include "Datei.h"
#include "Maus.h"
#include "Globals.h"
#include <tchar.h>

using namespace Framework;

Bildschirm *screen;
TextFeld *output;
FBalken *balken;
bool exitB2 = 0;
bool warten = 0;
WFenster *fenster;

void textOut( const char *txt )
{
	output->zText()->anhängen( txt );
	if( output->zText()->anzahlVon( '\n' ) > 7 )
		output->zText()->löschen( 0, output->zText()->positionVon( '\n', output->zText()->anzahlVon( '\n' ) - 7 ) + 1 );
	screen->render();
}

void fensterSchließenME( WFenster *f )
{
	textOut( "Vorgang wird beendet...\n" );
	exitB2 = 1;
	if( !warten )
		PostQuitMessage( 0 );
};

DWORD WINAPI übernehmen( void *args )
{
	warten = 1;
	Datei *liste = new Datei();
	liste->setDatei( "data/update/unable/list.patch" );
	if( !liste->existiert() )
	{
		liste->release();
		DateiLöschen( new Text( "data/update/download" ) );
		balken->setAktionAnzahl( 1 );
		balken->aktionPlus( 1 );
		textOut( "Vorgang abgeschlossen\n" );
		warten = 0;
		StopNachrichtenSchleife( fenster->getFensterHandle() );
		return 0;
	}
	liste->öffnen( D_Style::lesen );
	int count = 0;
	Text *zeile = liste->leseZeile();
	while( zeile )
	{
		count++;
		zeile->release();
		zeile = liste->leseZeile();
	}
	liste->schließen();
	balken->setAktionAnzahl( count );
	for( int i = 0; i < count; i++ )
	{
		liste->öffnen( D_Style::lesen );
		zeile = liste->leseZeile();
		if( !zeile )
			break;
		char aktion = zeile->getText()[ 0 ];
		switch( aktion )
		{
		case 1: // Datei erstellen
			{
				Text *pfad = zeile->getTeilText( 1, zeile->getLänge() - 1 );
				textOut( "Erstelle: " );
				textOut( pfad->getText() );
				textOut( "\n" );
				DateiLöschen( pfad->getThis() );
				DateiPfadErstellen( pfad );
			}
			break;
		case 2: // Datei umbenennen
			{
				Text *pfad1 = zeile->getTeilText( 1, zeile->positionVon( "=>" ) );
				Text *pfad2 = zeile->getTeilText( zeile->positionVon( "=>" ) + 2, zeile->getLänge() - 1 );
				textOut( "Ersetze: " );
				textOut( pfad1->getText() );
				textOut( "\n" );
				DateiLöschen( pfad1->getThis() );
				DateiUmbenennen( pfad2, pfad1 );
			}
			break;
		case 3: // Datei löschen
			{
				Text *pfad = zeile->getTeilText( 1, zeile->getLänge() - 1 );
				textOut( "Lösche: " );
				textOut( pfad->getText() );
				textOut( "\n" );
				DateiLöschen( pfad->getThis() );
			}
			break;
		}
		Datei *liste2 = new Datei();
		liste2->setDatei( "data/update/unable/list.patch$" );
		liste2->öffnen( D_Style::schreiben );
		for( __int64 ii = liste->getLPosition(); ii < liste->getGröße(); ii++ )
		{
			char c = 0;
			liste->lese( &c, 1 );
			liste2->schreibe( &c, 1 );
		}
		liste->schließen();
		liste2->schließen();
		liste->löschen();
		liste2->umbenennen( "data/update/unable/list.patch" );
		liste2->release();
		balken->aktionPlus();
		if( exitB2 )
		{
			liste->release();
			warten = 0;
			StopNachrichtenSchleife( fenster->getFensterHandle() );
			return 0;
		}
	}
	liste->schließen();
	liste->release();
	DateiLöschen( new Text( "data/update/download" ) );
	DateiLöschen( new Text( "data/update/unable" ) );
	textOut( "Vorgang abgeschlossen\n" );
	warten = 0;
	StopNachrichtenSchleife( fenster->getFensterHandle() );
	return 0;
}

int LTStart Framework::Start( Startparam p )
{
	Framework::initFramework();

	WNDCLASS wc = F_Normal( p.hinst );
	wc.lpszClassName = "Übernehme Änderungen...";
	fenster = new WFenster();
	fenster->erstellen( WS_SYSMENU, wc );
	fenster->setGröße( 310, 185 );
	fenster->setPosition( Bildschirmmitte( fenster->getThis() ) );
	fenster->setVSchließAktion( fensterSchließenME );
	fenster->setAnzeigeModus( 1 );

	screen = new Bildschirm( fenster->getThis() );
	screen->setBackBufferGröße( new Punkt( 300, 150 ) );
	screen->update();
	screen->render();
	fenster->setBildschirm( screen->getThis() );

	LTDSDatei *schriftD = new LTDSDatei();
	schriftD->setPfad( new Text( "data/schriften/normal.ltds" ) );
	schriftD->leseDaten();
	Schrift *schrift = schriftD->ladeSchrift();
	schriftD->release();

	output = new TextFeld();
	output->setSchriftZ( schrift->getThis() );
	output->setStyle( TF_Style::Sichtbar | TF_Style::Mehrzeilig );
	output->setSchriftFarbe( 0xFFFFFFFF );
	output->setGröße( 300, 130 );
	output->setText( "Initialisierung...\n" );
	screen->addMember( output );

	balken = new FBalken();
	balken->setSchriftZ( schrift );
	balken->setStyle( FB_Style::Sichtbar | FB_Style::Rahmen | FB_Style::Prozent | FB_Style::FFarbe | FB_Style::L_R );
	balken->setGröße( 300, 20 );
	balken->setPosition( 0, 130 );
	balken->setRFarbe( 0xFFFFFFFF );
	balken->setSFarbe( 0xFFFFFFFF );
	balken->setFBgFarbe( 0xFF00FF00 );
	balken->reset();
	balken->setSGröße( 12 );
	screen->addMember( balken );
	screen->render();

	PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
	Text *startexe = new Text( "start.exe" );
    if( Process32First( snapshot, &entry ) == TRUE )
    {
        while( Process32Next( snapshot, &entry ) == TRUE )
        {
            if( startexe->istGleich( entry.szExeFile ) )
            {  
                HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID );
                WaitForSingleObject( hProcess, INFINITE );
                CloseHandle( hProcess );
            }
        }
    }
	startexe->release();
    CloseHandle( snapshot );
	HANDLE mutex = OpenMutex( MUTEX_ALL_ACCESS, false, "KSG_Client" );

	DWORD threadId;
	CreateThread( NULL, 0, übernehmen, 0, 0, &threadId);

	StartNachrichtenSchleife();
	
	balken->release();
	output->release();
	screen->release();
	fenster->setBildschirm( 0 );
	fenster->zerstören();
	fenster->release();
	
	ReleaseMutex( mutex );

	PROCESS_INFORMATION prozessinfo1;
	STARTUPINFO startinfo1;
	startinfo1.cb = sizeof( STARTUPINFOW );
	ZeroMemory( &startinfo1, sizeof( STARTUPINFOW ) );
	if( CreateProcess( 0, "start.exe", 0, 0, 0, 0, 0, 0, &startinfo1, &prozessinfo1 ) == 1 )
	{
		CloseHandle( prozessinfo1.hThread );
	}
	return 0;
}