//---Include---
#include "DateiSystem.h"
#include "Bild.h"
#include "Text.h"
#include "Farbe.h"
#include "Punkt.h"
#include <Windows.h>
#include <iostream>
#include "Fenster.h"
#include "Schrift.h"
#include "Datei.h"
#include "Fortschritt.h"

using namespace Framework;

// LTDS Dateivormat 
// Inhalt der LTDSPixel Klasse aus DateiSystem.h
// Konstruktor 
LTDSPixel::LTDSPixel( LTDSPixel *davor )
{
	this->davor = davor;
	index = 0, maxIndex = 1;
	änder = 0, änderA = 0, komp = 0;
	iA = 0;
	miA = 8;
	alpha = 0;
	ref = 1;
}

// Destruktor 
LTDSPixel::~LTDSPixel()
{
	if( davor )
		davor->release();
}

// nicht constant 
// zum Laden gedacht 
bool LTDSPixel::addBitZuFarbe( unsigned char bit )
{
	if( änderA && iA != miA ) // Das Bit gehört zu Alpha
	{
		alpha |= ( ( bit & Bits( 1 ) ) ) << ( 7 - komp - iA );
		iA++;
	}
	else // Das Bit gehört zum nächsten Pixel
		return false;
	return true;
}

char LTDSPixel::addByte( char byte, char begin ) // gibt ende des Pixels zurück, -1 wenn nicht zu ende
{
	if( begin >= 8 || begin < 0 )
		return -1;
	for( int i = begin; i < 8; i++ )
	{
		switch( index )
		{
		case 0:
			// Das erste Bit eines Pixels speichert, ob sich an der Komprimierung etwas änderte
			änder = ( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) == 1;
			if( !änder ) // Ändert sich nichts an der Komprimierung, so werden die Werte vom vorherigen Pixel übernommen
			{
				if( !davor ) // Die Datei ist beschädigt ( Der erste Pixel kann nicht von dem davor Übernemen )
				{
					MessageBox( NULL, "Fehler, die Bilddatei ist beschädigt", "Fehler", MB_ICONERROR );
					exit( 0 );
				}
				änderA = davor->getÄnderA();
				komp = davor->getKomp();
				miA -= komp;
				if( !änderA )
					alpha = davor->getA();
				maxIndex += änderA * ( 8 - komp ); // Bestimmung der Länge
				// des Pixels in Bits. Jede Farbe hat von grund auf 8 Bits, durch komprimierung kanns kleiner sein
			}
			else
				maxIndex += 4; // Da der Pixel nicht die Werte des vorherigen übernimmt, wird er um 6 Bits größer
			break;
		case 1: // Das zweite Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
				änderA = ( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) == 1;
			else
			{
				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
					return i;
			}
			break;
		case 2: // Das sechste Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) << 2;
			else
			{
				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
					return i;
			}
			break;
		case 3: // Das siebte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) << 1;
			else
			{
				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
					return i;
			}
			break;
		case 4: // Das achte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
			{
				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & Bits( 1 ) );
				// Das war das letzte Komprimierungsbit
				// Komprimierung auswerten 
				miA -= komp;
				if( !änderA )
					alpha = davor->getA();
				maxIndex += änderA * ( 8 - komp ); // Bitlänge des Pixels
			}
			else
			{
				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
					return i;
			}
			break;
		default: // Die restlichen Bits speichern alle die Farbwerte des Pixels
			if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
				return i;
			break;
		}
		index++;
		if( index >= maxIndex )
		{
			if( davor )
			{
				if( änderA )
					alpha = davor->getA() + alpha;
				davor = davor->release();
			}
			return i + 1;
		}
	}
	return -1;
}

// zum speichern gedacht 
void LTDSPixel::setAlpha( unsigned char alpha ) // setzt die Farbe des Pixels
{
	this->alpha = alpha;
}

void LTDSPixel::Komp() // Komprimiert den Pixel
{
	maxIndex = 1;
	if( !davor )
	{// Das ist der erste Pixel
		änder = 1;
		änderA = 1;
		maxIndex += 4;
		miA = getBits( alpha );
	}
	else
	{ // Es wird die differenz zum vorrigen Pixel gespeichert
		miA = getBits( alpha - davor->getA() );
		if( alpha != davor->getA() )
			änderA = 1;
		else
			änderA = 0;
	}// Prüfen ob sich etwas ändert
	if( !miA && änderA )
		miA++;
	komp = 8 - miA;
	maxIndex += änderA * miA;
	if( davor )
	{
		if( änderA != davor->getÄnderA() ||
			komp != davor->getKomp() )
		{ // Es ändert sich etwas
			änder = 1;
			maxIndex += 4;
		}
		else
		{ // Es ändert sich nichts
			änder = 0;
		}
	}
}

bool LTDSPixel::getNextFarbeBit( char &byte, int i )
{
	unsigned char AA = alpha;
	if( davor )
	{
		AA -= davor->getA();
	}
	if( änderA && iA != miA ) // Das Bit gehört zu Alpha
	{
		byte |= ( ( AA >> ( 7 - komp - iA ) ) & Bits( 1 ) ) << ( 7 - i );
		iA++;
	}
	else // Der Pixel ist bereits zu ende
		return false;
	return true;
}

char LTDSPixel::getNextByte( char &byte, int bbegin ) // Gibt die nächsten Bits Zurück, -1 wenn der Pixel nicht zu ende ist
{
	// bbegin gibt an wohin in die byte-variable geschrieben werden soll
	// die Funktion gibt das ende des Pixels in der byte-variable zurück
	// -1 heißt, dass der Pixel nicht zu ende ist
	for( int i = bbegin; i < 8; i++ )
	{
		switch( index )
		{
		case 0: // Das erste Bit des Pixels speichert, ob sich etwas an der Komprimierung ändert
			byte |= ( (int)änder & Bits( 1 ) ) << ( 7 - i );
			break;
		case 1: // Das zweite Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
			if( änder ) // Komprimierung
				byte |= ( (int)änderA & Bits( 1 ) ) << ( 7 - i );
			else // Farbe
				if( !getNextFarbeBit( byte, i ) )
					return i;
			break;
		case 2: // Das zweite Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
			if( änder ) // Komprimierung
				byte |= ( ( komp >> 2 ) & Bits( 1 ) ) << ( 7 - i );
			else // Farbe
				if( !getNextFarbeBit( byte, i ) )
					return i;
			break;
		case 3: // Das dritte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
			if( änder ) // Komprimierung
				byte |= ( ( komp >>1 ) & Bits( 1 ) ) << ( 7 - i );
			else // Farbe
				if( !getNextFarbeBit( byte, i ) )
					return i;
			break;
		case 4: // Das vierte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
			if( änder ) // Komprimierung
				byte |= ( komp & Bits( 1 ) ) << ( 7 - i );
			else // Farbe
				if( !getNextFarbeBit( byte, i ) )
					return i;
			break;
		default: // Die restlichen Bits speichern die Farbe des Pixels
			if( !getNextFarbeBit( byte, i ) )
				return i;
			break;
		}
		index++;
		if( index >= maxIndex )
		{
			if( davor )
				davor = davor->release();
			return i + 1;
		}
	}
	return -1;
}

// constant 
unsigned char LTDSPixel::getKomp() const // hat sich die Komprimierung geändert
{
	return komp;
}

bool LTDSPixel::getÄnderA() const // gibt zurück, ob sich der alphawert ändert
{
	return änderA;
}

unsigned char LTDSPixel::getA() const // gibt Alpha zurück
{
	return alpha;
}

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

LTDSPixel *LTDSPixel::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}

// Inhalt der LTDSDateiKopf Klasse aus Dateisystem.h
// Konstruktor 
LTDSDateiKopf::LTDSDateiKopf()
{
	ref = 1;
	sganzahl = 0;
	gr = 0;
	pos = 0;
}

// Destruktor 
LTDSDateiKopf::~LTDSDateiKopf()
{
	delete []gr;
	delete []pos;
}

// nicht constant 
void LTDSDateiKopf::laden( std::ifstream *inF ) // Lät aus inF
{
	if( inF->good() && inF->is_open() )
	{
		inF->read( (char *)&sganzahl, 1 );
		if( sganzahl > 0 )
		{
			delete []gr;
			delete []pos;
			gr = new unsigned char[ sganzahl + 1 ];
			gr[ sganzahl ] = '\0';
			pos = new int[ sganzahl ];
		}
		for( int i = 0; i < sganzahl; i++ )
		{
			inF->read( (char*)&gr[ i ], 1 );
			inF->read( (char*)&pos[ i ], 4 );
		}
	}
}

void LTDSDateiKopf::addSG( char sg ) // Schriftgröße hinzufügen
{
	sganzahl++;
	unsigned char *gr_tmp = gr;
	int *pos_tmp = pos;
	gr = new unsigned char[ sganzahl ];
	pos = new int[ sganzahl ];
	if( sganzahl - 1 > 0 )
	{
		memcpy( gr, gr_tmp, 1 * ( sganzahl - 1 ) );
		memcpy( pos, pos_tmp, 4 * ( sganzahl - 1 ) );
	}
	delete []gr_tmp;
	delete []pos_tmp;
	pos[ sganzahl - 1 ] = 0;
	gr[ sganzahl - 1 ] = sg;
}

void LTDSDateiKopf::removeSG( char sg ) // Schriftgröße entfernen
{
	bool hatsg = 0;
	int sgpos = 0;
	for( int i = 0; i < sganzahl; i++ )
	{
		hatsg = gr[ i ] == sg;
		sgpos = i;
		if( hatsg )
			break;
	}
	if( hatsg )
	{
		sganzahl--;
		unsigned char *gr_tmp = gr;
		int *pos_tmp = pos;
		gr = new unsigned char[ sganzahl ];
		pos = new int[ sganzahl ];
		for( int i = 0; i < sgpos; i++ )
		{
			gr[ i ] = gr_tmp[ i ];
			pos[ i ] = pos_tmp[ i ];
		}
		for( int i = sgpos + 1; i < sganzahl; i++ )
		{
			gr[ i - 1 ] = gr_tmp[ i ];
			pos[ i - 1 ] = pos_tmp[ i ];
		}
		delete []gr_tmp;
		delete []pos_tmp;
	}
}

// constant 
void LTDSDateiKopf::speichern( std::ofstream *outF ) const // Speichert nach outF
{
	if( outF->is_open() && outF->good() )
	{
		outF->write( (char*)&sganzahl, 1 );
		for( int i = 0; i < sganzahl; i++ )
		{
			outF->write( (char*)&gr[ i ], 1 );
			outF->write( (char*)&pos[ i ], 4 );
		}
	}
}

unsigned char *LTDSDateiKopf::getSchriftGrößeList() const // gibt eine Liste mit gespeicherten Schriftgrößen zurück
{
	return gr;
}

int *LTDSDateiKopf::getPositionList() const // gibt eine Positionsliste der gespeicherten Schriftgrößen zurück
{
	return pos;
}

int LTDSDateiKopf::getSchriftGrößeAnzahl() const // gibt die Anzahl der gespeicherten Schriftgrößen zurück
{
	return sganzahl;
}

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

LTDSDateiKopf *LTDSDateiKopf::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}

// Inhalt der LTDSSchriftKopf Klasse aus Dateisystem.h
// Konstruktor 
LTDSSchriftKopf::LTDSSchriftKopf()
{
	ref = 1;
	schriftGröße = 0;
	zeichen = 0;
	pos = 0;
	zeichenAnzahl = 0;
}

// Destruktor 
LTDSSchriftKopf::~LTDSSchriftKopf()
{
	delete []pos;
	delete []zeichen;
}

// nicht constant 
void LTDSSchriftKopf::laden( std::ifstream *inF ) // läht von inF
{
	if( inF->good() && inF->is_open() )
	{
		inF->read( (char*)&schriftGröße, 1 );
		inF->read( (char*)&zeichenAnzahl, 1 );
		delete []pos;
		delete []zeichen;
		zeichen = new unsigned char[ zeichenAnzahl ];
		pos = new int[ zeichenAnzahl ];
		for( int i = 0; i < zeichenAnzahl; i++ )
		{
			inF->read( (char*)&zeichen[ i ], 1 );
			inF->read( (char*)&pos[ i ], 4 );
		}
	}
}

void LTDSSchriftKopf::setSchriftgröße( unsigned char gr ) // setze schriftgröße
{
	schriftGröße = gr;
}

void LTDSSchriftKopf::setZeichenAlphabet( Alphabet *alphabet ) // setzt die Zeichen von alphabet
{
	int count = 0;
	for( int i = 0; i < 256; i++ )
	{
		Buchstabe *zeich = alphabet->getBuchstabe( i );
		if( zeich )
			count++;
	}
	delete []zeichen;
	delete []pos;
	zeichen = new unsigned char[ count ];
	pos = new int[ count ];
	count = 0;
	for( int i = 0; i < 256; i++ )
	{
		Buchstabe *zeich = alphabet->getBuchstabe( i );
		if( zeich )
		{
			zeichen[ count ] = i;
			pos[ count ] = 0;
			count++;
			zeich->release();
		}
	}
	schriftGröße = alphabet->getSchriftgröße();
	alphabet->release();
}

void LTDSSchriftKopf::addZeichen( unsigned char zeichen ) // Zeichen hinzufügen
{
	zeichenAnzahl++;
	unsigned char *zeichen_tmp = this->zeichen;
	int *pos_tmp = pos;
	this->zeichen = new unsigned char[ zeichenAnzahl ];
	pos = new int[ zeichenAnzahl ];
	if( zeichenAnzahl - 1 > 0 )
	{
		memcpy( this->zeichen, zeichen_tmp, 1 * ( zeichenAnzahl - 1 ) );
		memcpy( pos, pos_tmp, 4 * ( zeichenAnzahl - 1 ) );
	}
	delete []zeichen_tmp;
	delete []pos_tmp;
	this->zeichen[ zeichenAnzahl - 1 ] = zeichen;
	pos[ zeichenAnzahl - 1 ] = 0;
}

void LTDSSchriftKopf::removeZeichen( unsigned char zeich ) // Zeichen entfernen
{
	bool hatZ = 0;
	int zPos = 0;
	for( int i = 0; i < zeichenAnzahl; i++ )
	{
		hatZ = zeichen[ i ] == zeich;
		zPos = i;
		if( hatZ )
			break;
	}
	if( hatZ )
	{
		zeichenAnzahl--;
		unsigned char *zeichen_tmp = zeichen;
		int *pos_tmp = pos;
		zeichen = new unsigned char[ zeichenAnzahl ];
		pos = new int[ zeichenAnzahl ];
		for( int i = 0; i < zPos; i++ )
		{
			zeichen[ i ] = zeichen_tmp[ i ];
			pos[ i ] = pos_tmp[ i ];
		}
		for( int i = zPos + 1; i < zeichenAnzahl; i++ )
		{
			zeichen[ i - 1 ] = zeichen_tmp[ i ];
			pos[ i - 1 ] = pos_tmp[ i ];
		}
		delete []zeichen_tmp;
		delete []pos_tmp;
	}
}

// constant 
void LTDSSchriftKopf::speichern( std::ofstream *outF ) const // speichert nach outF
{
	if( outF->good() && outF->is_open() )
	{
		outF->write( (char*)&schriftGröße, 1 );
		outF->write( (char*)&zeichenAnzahl, 1 );
		for( int i = 0; i < zeichenAnzahl; i++ )
		{
			outF->write( (char*)&zeichen[ i ], 1 );
			outF->write( (char*)&pos[ i ], 4 );
		}
	}
}

unsigned char LTDSSchriftKopf::getSchriftGröße() const // gibt die Schriftgröße zurück
{
	return schriftGröße;
}

unsigned char LTDSSchriftKopf::getZeichenAnzahl() const // gibt die Zeichenanzahl zurück
{
	return zeichenAnzahl;
}

int *LTDSSchriftKopf::getPositionen() const // gibt die Zeichenpositionen zurück
{
	return pos;
}

unsigned char *LTDSSchriftKopf::getZeichen() const // gibt die zeichen zurück
{
	return zeichen;
}

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

LTDSSchriftKopf *LTDSSchriftKopf::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}

// Inhalt der LTDSBuchstabenKopf Klasse aus Dateisystem.h
// Konstruktor 
LTDSBuchstabenKopf::LTDSBuchstabenKopf()
{
	ref = 1;
	zeichen = 0;
	größe = new Punkt();
}

// Destruktor 
LTDSBuchstabenKopf::~LTDSBuchstabenKopf()
{
	größe->release();
}

// nicht constant 
void LTDSBuchstabenKopf::laden( std::ifstream *inF ) // lät aus inF
{
	if( inF->good() && inF->is_open() )
	{
		inF->read( (char*)&zeichen, 1 );
		inF->read( (char*)&größe->x, 1 );
		inF->read( (char*)&größe->y, 1 );
	}
}

void LTDSBuchstabenKopf::init( unsigned char zeichen, Punkt *größe ) // initialisierung( für speichern )
{
	this->zeichen = zeichen;
	this->größe->setP( größe->x, größe->y );
	größe->release();
}

void LTDSBuchstabenKopf::init( unsigned char zeichen, int br, int hö )
{
	this->zeichen = zeichen;
	größe->x = br, größe->y = hö;
}

// constant 
void LTDSBuchstabenKopf::speichern( std::ofstream *outF ) const // speichertn nach outF
{
	if( outF->good() && outF->is_open() )
	{
		outF->write( (char*)&zeichen, 1 );
		outF->write( (char*)&größe->x, 1 );
		outF->write( (char*)&größe->y, 1 );
	}
}

unsigned char LTDSBuchstabenKopf::getZeichen() const // gibt das Zeichen zurück
{
	return zeichen;
}

int LTDSBuchstabenKopf::getBreite() const // gibt die Breite zurück
{
	return größe->x;
}

int LTDSBuchstabenKopf::getHöhe() const // gibt die höhe zurück
{
	return größe->y;
}

Punkt *LTDSBuchstabenKopf::getGröße() const // gibt die Größe zurück
{
	return größe->getThis();
}

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

LTDSBuchstabenKopf *LTDSBuchstabenKopf::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}

// Inhalt der LTDSBuchstabenKörper Klasse aus Dateisystem.h
// Konstruktor 
LTDSBuchstabenKörper::LTDSBuchstabenKörper( LTDSBuchstabenKopf *kopf )
{
	ref = 1;
	größe = new Punkt( kopf->getBreite(), kopf->getHöhe() );
	zeichen = kopf->getZeichen();
	buchstabe = new Buchstabe();
	buchstabe->NeuBuchstabe( größe->getThis() );
	kopf->release();
}

// Destruktor 
LTDSBuchstabenKörper::~LTDSBuchstabenKörper()
{
	größe->release();
	if( buchstabe )
		buchstabe->release();
}

// nicht constant 
void LTDSBuchstabenKörper::setBuchstabe( Buchstabe *zeichen ) // setzt den Buchstaben
{
	if( buchstabe )
		buchstabe->release();
	buchstabe = zeichen;
}

void LTDSBuchstabenKörper::laden( std::ifstream *inF ) // Läht aus inF
{
	if( inF->good() && inF->is_open() )
	{
		LTDSPixel *vorher = 0;
		LTDSPixel *jetzt = new LTDSPixel( vorher );
		char byte = 0;
		int beg = 0;
		int ende = -1;
		for( int i = 0; i < größe->x * größe->y; i++ )
		{
			if( !jetzt ) // wenn es nicht der erste Pixel ist
				jetzt = new LTDSPixel( vorher->getThis() );
			int ende = -1;
			while( ende < 0 ) // Pixel laden
			{
				if( beg == 0 )
					inF->read( &byte, 1 );
				ende = jetzt->addByte( byte, beg ); // byte auswerten
				beg = 0;
			}
			beg = ende;
			if( beg == 8 )
				beg = 0;
			if( buchstabe )
				buchstabe->setPixel( i, jetzt->getA() );
			if( vorher )
				vorher = vorher->release();
			vorher = jetzt->getThis();
			jetzt = jetzt->release();
		}
		if( vorher )
			vorher->release();
	}
}

// constant 
void LTDSBuchstabenKörper::speichern( std::ofstream *outF ) const // speichert nach outF
{
	if( outF->good() && outF->is_open() )
	{
		LTDSPixel *vorher = 0; // Letzter gespeicherter Pixel
		LTDSPixel *jetzt = new LTDSPixel( 0 ); // Der momentan zu speichernde Pixel
		int begin = 0, ende = 0; // Pixelbeginn, endposition in der byte variable
		char byte = 0; // Der nächste byte der Datei
		bool w = 0;
		unsigned char *alphaBuff = buchstabe->getBuff();
		for( int i = 0; i < größe->getX() * größe->getY(); i++ ) // für jeden Pixel
		{
			if( !jetzt ) // wenn es nicht der erste Pixel ist
				jetzt = new LTDSPixel( vorher->getThis() );
			jetzt->setAlpha( alphaBuff[ i ] ); // Farbe des Pixels setzen
			jetzt->Komp(); // Pixel komprimieren
			ende = -1;
			while( ende < 0 ) // byte befüllen
			{
				ende = jetzt->getNextByte( byte, begin );
				begin = 0;
				w = 0;
				if( ende == -1 || ende == 8 ) // byte speichern
				{
					outF->write( &byte, 1 );
					w = 1;
					byte = 0;
				}
			} // Pixel fertig
			begin = ende;
			if( begin == 8 )
				begin = 0;
			if( vorher )
				vorher->release();
			vorher = jetzt->getThis(); // dieser wird zu letzter
			jetzt = jetzt->release();
		}
		if( vorher )
			vorher = vorher->release();
		if( !w )
		{
			outF->write( &byte, 1 ); // Das letzte byte speichern
		}
		outF->flush(); // dateistream speichern
	}
}

Buchstabe *LTDSBuchstabenKörper::getBuchstabe() const // gibt den Buchstaben zurück
{
	return buchstabe->getThis();
}

unsigned char LTDSBuchstabenKörper::getZeichen() const // gibt das Zeichen zurück
{
	return zeichen;
}

// Reference Counting 
LTDSBuchstabenKörper *LTDSBuchstabenKörper::getThis()
{
	ref++;
	return this;
}

LTDSBuchstabenKörper *LTDSBuchstabenKörper::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}

// Inhalt der LTDSDatei Klasse aus DAteisystem.h
// Konstruktor 
LTDSDatei::LTDSDatei()
{
	ref = 1;
	pfad = new Text("");
	dateiKopf = 0;
	InitializeCriticalSection( &thread_Save );
}

// Destruktor 
LTDSDatei::~LTDSDatei()
{
	if( dateiKopf )
		dateiKopf->release();
	pfad->release();
	DeleteCriticalSection( &thread_Save );
}

// nicht constant 
void LTDSDatei::lockDatei()
{
	EnterCriticalSection( &thread_Save );
}

void LTDSDatei::unlockDatei()
{
	LeaveCriticalSection( &thread_Save );
}

void LTDSDatei::setPfad( Text *txt ) // setzt den Pfad zur Datei
{
	lockDatei();
	if( dateiKopf )
		dateiKopf = dateiKopf->release();
	pfad->setText( txt->getText() );
	txt->release();
	unlockDatei();
}

void LTDSDatei::leseDaten() // ließt den Dateikopf
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return;
	}
	if( dateiKopf )
		dateiKopf->release();
	dateiKopf = new LTDSDateiKopf();
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
	dateiKopf->laden( inF );
	inF->close();
	unlockDatei();
	delete inF;
}

void LTDSDatei::addSchriftgröße( Alphabet *alphabet ) // fügt eine Schriftgröße hinzu
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) ) // prüfen, ob die Datei existiert
	{
		unlockDatei();
		return;
	}
	if( !dateiKopf ) // prüfen, ob der Dateikopf schon gelesen wurde
		leseDaten();
	int sgröße = alphabet->getSchriftgröße(); // Schriftgröße die hinzugefügt werden soll
	unsigned char *sglist = dateiKopf->getSchriftGrößeList(); // Liste von bereits vorhandenen Schriftgrößen
	int *sgPosList = dateiKopf->getPositionList(); // Liste mit positionen der Schriftgrößen
	unsigned char sganzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der bereits vorhandenen Schriftgrößen
	for( int i = 0; i < sganzahl; i++ ) // prüfen, ob die Schriftgröße bereits existiert
	{
		if( sglist[ i ] == sgröße )
		{
			unlockDatei();
			return;
		}
	}
	dateiKopf->addSG( sgröße ); // Schriftgröße dem Dateikopf hinzufügen
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // alte Datei
	pfad->anhängen( "0" );
	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // neue Datei
	dateiKopf->speichern( outF ); // Dateikopf in neue datei speichern
	inF->seekg( 1 + 5 * sganzahl, std::ios::beg ); // Position der ersten Schriftgröße in der alten Datei
	for( int i = 0; i < sganzahl; i++ ) // Buchstabenpositionen aller Schriftgrößen aktualisieren
	{
		LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
		sgKpf_tmp->laden( inF ); // aus alter Datei laden
		int *zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße
		unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße
		for( int i1 = 0; i1 < zeichA_tmp; i1++ )
			zeichP_tmp[ i1 ] += 5; // Buchstabenpositionen aktualisieren
		sgKpf_tmp->speichern( outF ); // Schriftgröße Kopf in neue Datei speichern
		int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
		int endByte = sgPosList[ i + 1 ];
		if( !endByte )
		{
			inF->seekg( 0, std::ios::end );
			endByte = (int)inF->tellg();
			inF->seekg( beginByte, std::ios::beg );
		}
		char byte;
		for( int i1 = beginByte; i1 < endByte; i1++ ) // Kopiervorgang
		{
			inF->read( &byte, 1 );
			outF->write( &byte, 1 );
		}
		sgKpf_tmp->release();
	}
	inF->close(); // Alte datei schließen
	sgPosList[ sganzahl ] = (int)outF->tellp();
	outF->seekp( 0, std::ios::beg );
	for( int i = 0; i < sganzahl; i++ ) // Positionen im Dateikopf aktualisieren
		sgPosList[ i ] += 5;
	dateiKopf->speichern( outF ); // aktualisierter Dateikopf speichern
	outF->seekp( sgPosList[ sganzahl ], std::ios::beg );
	LTDSSchriftKopf *sgkopf = new LTDSSchriftKopf(); // Kopf der neuen Schriftgröße
	sgkopf->setZeichenAlphabet( alphabet->getThis() ); // Kopf der Schriftgröße initialisieren
	sgkopf->speichern( outF ); // Kopf der Schriftgröße speichern
	int *BuchstabenPosList = sgkopf->getPositionen(); // positionen der verschiedenen Zeichen in der Datei( nuch 0 )
	int count = 0;
	for( int i = 0; i < 256; i++ )
	{
		Buchstabe *zeich = alphabet->getBuchstabe( i );
		if( zeich )
		{
			BuchstabenPosList[ count ] = (int)outF->tellp(); // position des Zeichens setzen
			LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf(); // Zeichenkopf
			zeichKpf->init( i, zeich->getBreite(), zeich->getHöhe() );
			zeichKpf->speichern( outF ); // Zeichenkopf speichern
			LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() ); // Zeichenkörper
			zeichKpf->release();
			zeichKörp->setBuchstabe( zeich->getThis() );
			zeichKörp->speichern( outF ); // Zeichenkörper speichern
			zeich->release();
			count++;
		}
	}
	outF->seekp( sgPosList[ sganzahl ], std::ios::beg );
	sgkopf->speichern( outF ); // aktualisierter Schriftgrößen Kopf speichern
	outF->close();
	Text *pfad2 = new Text();
	pfad2->setText( pfad->getText() );
	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
	DateiLöschen( pfad->getThis() ); // Alte datei Löschen
	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // neue Datei nach alte umbenennen
	pfad->release(); // Speicher freigeben
	sgkopf->release();
	delete inF;
	delete outF;
	alphabet->release();
	unlockDatei();
}

void LTDSDatei::addBuchstabe( int gr, Buchstabe *zeich, unsigned char zeichen ) // Fügt einer Schriftgröße einen Buchstaben hinzu
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) ) // prüfen ob Datei existiert
	{
		unlockDatei();
		return;
	}
	if( !dateiKopf ) // prüfen, ob der DAteikopf geladen wurde
		leseDaten();
	unsigned char *sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen aus der Datei
	int *sgPosList = dateiKopf->getPositionList(); // Liste mit Schriftgrößen positionen aus Datei
	unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl von Schriftgrößen aus der Datei
	int sgNum = -1;
	for( int i = 0; i < sgAnzahl; i++ ) // Position der richtigen Schriftgröße ermitteln
	{
		if( sgList[ i ] == gr )
		{
			sgNum = i;
			break;
		}
	}
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // Alte Datei
	pfad->anhängen( "0" );
	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // Neue Datei
	inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg );
	if( sgNum == -1 ) // Die Schriftgröße existiert noch nicht und wird erstellt
	{
		dateiKopf->addSG( gr ); // Schriftgröße dem Dateikopf hinzufügen
		sgPosList = dateiKopf->getPositionList();
		sgList = dateiKopf->getSchriftGrößeList();
		dateiKopf->speichern( outF ); // Dateikopf speichern
		inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg ); // Position der ersten Schriftgröße in der alten Datei
		for( int i = 0; i < sgAnzahl; i++ ) // Buchstabenpositionen aller Schriftgrößen aktualisieren
		{
			LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
			sgKpf_tmp->laden( inF ); // aus alter Datei laden
			int *zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße
			unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße
			for( int i1 = 0; i1 < zeichA_tmp; i1++ )
				zeichP_tmp[ i1 ] += 5; // Buchstabenpositionen aktualisieren
			sgKpf_tmp->speichern( outF ); // Schriftgröße Kopf in neue Datei speichern
			int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
			int endByte = sgPosList[ i + 1 ];
			if( i + 1 >= sgAnzahl )
			{
				inF->seekg( 0, std::ios::end );
				endByte = (int)inF->tellg();
				inF->seekg( beginByte, std::ios::beg );
			}
			char byte;
			for( int i1 = beginByte; i1 < endByte; i1++ ) // Kopiervorgang
			{
				inF->read( &byte, 1 );
				outF->write( &byte, 1 );
			}
			sgKpf_tmp->release();
		}
		sgPosList[ sgAnzahl ] = (int)outF->tellp();
		outF->seekp( 0, std::ios::beg );
		for( int i = 0; i < sgAnzahl; i++ ) // Positionen im Dateikopf aktualisieren
			sgPosList[ i ] += 5;
		dateiKopf->speichern( outF ); // aktualisierter Dateikopf speichern
		outF->seekp( sgPosList[ sgAnzahl ], std::ios::beg );
		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf(); // Schriftgröße Kopf initialisiern
		sgKpf->setSchriftgröße( gr );
		sgKpf->addZeichen( zeichen );
		sgKpf->getPositionen()[ 0 ] = (int)outF->tellp() + 7;
		sgKpf->speichern( outF ); // Schriftgröße Kopf speichern
		sgKpf->release();
		LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf(); // Buchstabenkopf
		zeichKpf->init( zeichen, zeich->getBreite(), zeich->getHöhe() );
		zeichKpf->speichern( outF ); // Buchstabenkopf speichern
		LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() ); // Buchstabenkörper
		zeichKpf->release();
		zeichKörp->setBuchstabe( zeich->getThis() );
		zeichKörp->speichern( outF ); // Buchstabenkörper speichern
		zeichKörp->release();
	}
	else
	{
		dateiKopf->speichern( outF ); // Dateikopf speichern
		int beginByte = 1 + 5 * sgAnzahl; // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
		int endByte = sgPosList[ sgNum ];
		char byte;
		for( int i1 = beginByte; i1 < endByte; i1++ ) // Kopiervorgang bis zur angegebenen größe
		{
			inF->read( &byte, 1 );
			outF->write( &byte, 1 );
		}
		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf(); // Schriftgröße Kopf
		sgKpf->laden( inF );
		for( int i = 0; i < sgKpf->getZeichenAnzahl(); i++ )
			sgKpf->getPositionen()[ i ] += 5;
		sgKpf->addZeichen( zeichen );
		int indexPlus = 5;
		int zeichenPos = sgPosList[ sgNum + 1 ]; // positione des neuen Zeichens
		if( sgNum + 1 >= sgAnzahl )
		{
			int tmp = (int)inF->tellg();
			inF->seekg( 0, std::ios::end );
			zeichenPos = (int)inF->tellg();
			inF->seekg( tmp, std::ios::beg );
		}
		zeichenPos += indexPlus;
		sgKpf->getPositionen()[ sgKpf->getZeichenAnzahl() - 1 ] = zeichenPos;
		sgKpf->speichern( outF ); // Schriftgröße Kopf speichern
		sgKpf->release();
		for( int i = (int)inF->tellg() + indexPlus; i < zeichenPos; i++ ) // Kopiervorgang bis zum Zeichenbeginn
		{
			inF->read( &byte, 1 );
			outF->write( &byte, 1 );
		}
		LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf(); // Zeichenkopf
		zeichKpf->init( zeichen, zeich->getBreite(), zeich->getHöhe() );
		zeichKpf->speichern( outF ); // Zeichenkopf speichern
		LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() ); // Zeichenkörper
		zeichKpf->release();
		zeichKörp->setBuchstabe( zeich->getThis() );
		zeichKörp->speichern( outF ); // Zeichenkörper speichern
		zeichKörp->release();
		int nowPos = (int)outF->tellp();
		indexPlus += nowPos - zeichenPos;
		for( int i = sgNum + 1; i < sgAnzahl; i++ ) // Dateikopf aktualisieren
			sgPosList[ i ] += indexPlus;
		outF->seekp( 0, std::ios::beg );
		dateiKopf->speichern( outF ); // Dateikopf speichern
		outF->seekp( nowPos, std::ios::beg );
		for( int i = sgNum + 1; i < sgAnzahl; i++ ) // Restliche Schriftgrößen aktualisieren
		{
			LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
			sgKpf_tmp->laden( inF ); // aus alter Datei laden
			int *zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße
			unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße
			for( int i1 = 0; i1 < zeichA_tmp; i1++ )
				zeichP_tmp[ i1 ] += indexPlus; // Buchstabenpositionen aktualisieren
			sgKpf_tmp->speichern( outF ); // Schriftgröße Kopf in neue Datei speichern
			int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
			int endByte = sgPosList[ i + 1 ];
			if( i + 1 >= sgAnzahl )
			{
				inF->seekg( 0, std::ios::end );
				endByte = (int)inF->tellg();
				inF->seekg( beginByte, std::ios::beg );
			}
			char byte;
			for( int i1 = beginByte; i1 < endByte; i1++ ) // Kopiervorgang
			{
				inF->read( &byte, 1 );
				outF->write( &byte, 1 );
			}
			sgKpf_tmp->release();
		}
	}
	inF->close();
	outF->close();
	Text *pfad2 = new Text( pfad->getText() );
	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
	DateiLöschen( pfad->getThis() ); // Alte Datei löschen
	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // Neue Datei in alte umbenennen
	pfad2->release();// Speicher freigeben
	delete inF;
	delete outF;
	zeich->release();
	unlockDatei();
}

void LTDSDatei::löscheSchrifrGröße( int gr ) // Löscht eine Schriftgröße aus der Datei
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) ) // prüfen, ob Datei existiert
	{
		unlockDatei();
		return;
	}
	if( !dateiKopf ) // prüfen, ob der Dateikopf geladen wurde
		leseDaten();
	unsigned char *sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen
	unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der Schriftgrößen
	int sgNum = -1;
	for( int i = 0; i < sgAnzahl; i++ ) // zu löschende Schriftgröße suchen
	{
		if( sgList[ i ] == gr )
		{
			sgNum = i;
			break;
		}
	}
	if( sgNum == -1 ) // Die Schriftgröße ist nicht vorhanden
	{
		unlockDatei();
		return;
	}
	int *sgPosList = dateiKopf->getPositionList();  // Liste von Positionen der Schriftgrößen
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // alte Datei
	pfad->anhängen( "0" );
	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // neue Datei
	outF->seekp( 1 + 5 * (sgAnzahl-1), std::ios::beg );
	inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg );
	for( int i = 0; i < sgNum; i++ ) // Schriftgrößen vor der zu löschenden Schriftgröße aktualisieren
	{
		LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
		sgKpf_tmp->laden( inF ); // Schriftgrößen Kopf laden
		int *zeichPosLTmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen
		unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // Zeichenanzahl
		for( int i1 = 0; i1 < zeichATmp; i1++ ) // Position der Zeichen um 5 bytes zurücksetzen
			zeichPosLTmp[ i1 ] -= 5;
		sgKpf_tmp->speichern( outF ); // speichern in Neue Datei
		char byte = 0;
		for( int i1 = (int)inF->tellg(); i1 < sgPosList[ i+1 ]; i1++ ) // Den Körper des Zeichens Kopieren
		{
			inF->read( &byte, 1 );
			outF->write( &byte, 1 );
		}
	}
	int indexMinus = 5 + sgPosList[ sgNum + 1 ] - (int) inF->tellg();
	inF->seekg( sgPosList[ sgNum + 1 ], std::ios::beg );
	for( int i = sgNum + 1; i < sgAnzahl; i++ ) // Die Schriftgröße nach der zu löschenden Schriftgröße
	{
		LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
		sgKpf_tmp->laden( inF ); // Schriftgrößen Kopf laden
		int *zeichPosLTmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen
		unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // Zeichenanzahl
		for( int i1 = 0; i1 < zeichATmp; i1++ ) // Position der Zeichen aktualisieren
			zeichPosLTmp[ i1 ] -= indexMinus;
		sgKpf_tmp->speichern( outF ); // speichern in Neue Datei
		char byte = 0;
		int BeginByte = (int)inF->tellg();
		int EndByte = sgPosList[ i+1 ];
		if( !EndByte )
		{
			inF->seekg( 0, std::ios::end );
			EndByte = (int)inF->tellg();
			inF->seekg( BeginByte, std::ios::beg );
		}
		for( int i1 = BeginByte; i1 < EndByte; i1++ ) // Den Körper des Zeichens Kopieren
		{
			inF->read( &byte, 1 );
			outF->write( &byte, 1 );
		}
	}
	for( int i = 0; i < sgNum; i++ ) // Dateikopf aktualisieren
		sgPosList[ i ] -= 5;
	for( int i = sgNum + 1; i < sgAnzahl; i++ )
		sgPosList[ i ] -= indexMinus;
	dateiKopf->removeSG( gr );
	outF->seekp( 0, std::ios::beg );
	dateiKopf->speichern( outF ); // Dateikopf speichern
	inF->close();
	outF->close();
	Text *pfad2 = new Text( pfad->getText() );
	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
	DateiLöschen( pfad->getThis() ); // alte Datei löschen
	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // neue Datei zu alter umbenennen
	pfad2->release();
	delete inF;
	delete outF;
	unlockDatei();
}

void LTDSDatei::löscheBuchstabe( int gr, unsigned char zeichen ) // Löscht einen Buchstaben aus der Datei
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) ) // prüfen, ob die Datei existiert
	{
		unlockDatei();
		return;
	}
	if( !dateiKopf ) // prüfen, ob der Dateikopf gelesen wurde
		leseDaten();
	unsigned char *sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen
	unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der Schriftgrößen
	int *sgPosList = dateiKopf->getPositionList(); // Liste mit Positionen der Schriftgrößen
	int sgNum = -1;
	for( int i = 0; i < sgAnzahl; i++ ) // Schriftgröße suchen
	{
		if( sgList[ i ] == gr )
		{
			sgNum = i;
			break;
		}
	}
	if( sgNum == -1 ) // Schriftgröße nicht gefunden
	{
		unlockDatei();
		return;
	}
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // alte Datei
	pfad->anhängen( "0" );
	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // neue Datei
	int indexMinus = 0;
	inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg );
	dateiKopf->speichern( outF ); // DateiKopf peichern
	for( int i = 0; i < sgAnzahl; i++ )
	{
		LTDSSchriftKopf *sgKopf = new LTDSSchriftKopf(); // Schriftkopf
		sgKopf->laden( inF ); // Schriftkopf laden
		unsigned char sgZeichAnzahl = sgKopf->getZeichenAnzahl(); // Zeichenanzahl
		unsigned char *sgZeichenList = sgKopf->getZeichen(); // Zeichen Liste
		int *sgZPosList = sgKopf->getPositionen(); // Positions Liste
		if( i == sgNum ) // Zeichen befindet sich in dieser Schriftgröße
		{
			int sgZNum = -1;
			for( int i1 = 0; i1 < sgZeichAnzahl; i1++ ) // Zeichen suchen
			{
				if( sgZeichenList[ i1 ] == zeichen )
				{
					sgZNum = i1;
					break;
				}
			}
			if( sgZNum == -1 ) // Zeichen nicht gefunden
			{
				sgKopf->release();
				inF->close();
				outF->close();
				delete inF;
				delete outF;
				DateiLöschen( pfad->getThis() );
				pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
				unlockDatei();
				return; // abbruch
			}
			outF->seekp( 2 + 5 * (sgZeichAnzahl-1), std::ios::cur );
			indexMinus += 5;
			for( int i1 = 0; i1 < sgZNum; i1++ ) // Zeichen vor dem zu löschenden Zeichen
			{
				char byte = 0;
				for( int i2 = sgZPosList[ i1 ]; i2 < sgZPosList[ i1 + 1 ]; i2++ ) // Kopieren
				{
					inF->read( &byte, 1 );
					outF->write( &byte, 1 );
				}
				sgZPosList[ i1 ] -= indexMinus; // Schriftgröße Kopf aktualisieren
			}
			indexMinus += sgZPosList[ sgZNum + 1 ] - sgZPosList[ sgZNum ];
			if( sgZNum + 1 < sgZeichAnzahl )
				inF->seekg( sgZeichenList[ sgZNum + 1 ], std::ios::beg );
			for( int i1 = sgZNum + 1; i1 < sgZeichAnzahl; i1++ ) // Zeichen nach dem gelöschten Zeichen
			{
				int beginByte = (int)inF->tellg();
				int endByte = sgZPosList[ i1 + 1 ];
				if( !endByte )
				{
					inF->seekg( 0, std::ios::end );
					endByte = (int)inF->tellg();
					inF->seekg( beginByte, std::ios::beg );
				}
				char byte = 0;
				for( int i2 = beginByte; i2 < endByte; i2++ ) // Kopieren
				{
					inF->read( &byte, 1 );
					outF->write( &byte, 1 );
				}
				sgZPosList[ i1 ] -= indexMinus; // Schriftgröße Kopf aktualisieren
			}
			sgKopf->removeZeichen( zeichen );
		}
		else
		{
			for( int i1 = 0; i1 < sgZeichAnzahl; i1++ ) // Schriftgröße Kopf aktualisieren
				sgZPosList[ i ] -= indexMinus;
			sgKopf->speichern( outF ); // Schriftgröße Kopf speichern
			int beginByte = (int)inF->tellg();
			int endByte = sgPosList[ i + 1 ];
			if( !endByte )
			{
				inF->seekg( 0, std::ios::end );
				endByte = (int)inF->tellg();
				inF->seekg( beginByte, std::ios::beg );
			}
			char byte;
			for( int i1 = beginByte; i1 < endByte; i1++ ) // Kopieren
			{
				inF->read( &byte, 1 );
				outF->write( &byte, 1 );
			}
			sgPosList[ i ] -= indexMinus;
		}
		outF->seekp( sgPosList[ i ], std::ios::beg );
		sgKopf->speichern( outF ); // Schriftgröße Kopf speichern
		outF->seekp( sgPosList[ i + 1 ], std::ios::beg );
		sgKopf->release();
	}
	inF->close();
	outF->close();
	Text *pfad2 = new Text( pfad->getText() );
	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
	DateiLöschen( pfad->getThis() ); // alte Datei löschen
	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // neue Datei nach alte umbenennen
	pfad2->release(); // Speicher freigeben
	delete inF;
	delete outF;
	unlockDatei();
}

void LTDSDatei::löscheDatei() // Löscht die gesamte Datei
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return;
	}
	if( !dateiKopf )
		leseDaten();
	DateiLöschen( pfad->getThis() );
	unlockDatei();
}

void LTDSDatei::erstelleDatei() // erstellt die Datei
{
	lockDatei();
	DateiPfadErstellen( pfad->getThis() );
	if( dateiKopf )
		dateiKopf->release();
	dateiKopf = new LTDSDateiKopf();
	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary );
	dateiKopf->speichern( outF );
	outF->close();
	unlockDatei();
	delete outF;
}

void LTDSDatei::speicherSchrift( Schrift *schrift ) // Speichert die übergebene Schrift
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return;
	}
	löscheDatei();
	if( dateiKopf )
		dateiKopf->release();
	dateiKopf = new LTDSDateiKopf();
	for( int i = 0; i < schrift->getAlphabetAnzahl(); i++ )
	{
		Alphabet *alp = schrift->getAlphabet( i );
		dateiKopf->addSG( alp->getSchriftgröße() );
		alp->release();
	}
	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary );
	dateiKopf->speichern( outF );
	for( int i = 0; i < schrift->getAlphabetAnzahl(); i++ )
	{
		dateiKopf->getPositionList()[ i ] = (int)outF->tellp();
		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
		sgKpf->setZeichenAlphabet( schrift->getAlphabetI( i ) );
		sgKpf->speichern( outF );
		Alphabet *alp = schrift->getAlphabetI( i );
		for( int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); i++ )
		{
			sgKpf->getPositionen()[ i1 ] = (int)outF->tellp();
			LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf();
			Buchstabe *zeichen = alp->getBuchstabe( sgKpf->getZeichen()[ i1 ] );
			zeichKpf->init( sgKpf->getZeichen()[ i1 ], zeichen->getBreite(), zeichen->getHöhe() );
			zeichKpf->speichern( outF );
			LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() );
			zeichKörp->setBuchstabe( zeichen->getThis() );
			zeichKörp->speichern( outF );
			zeichKörp->release();
			zeichen->release();
			zeichKpf->release();
		}
		alp->release();
		outF->seekp( dateiKopf->getPositionList()[ i ], std::ios::beg );
		sgKpf->speichern( outF );
		outF->seekp( 0, std::ios::beg );
		sgKpf->release();
	}
	outF->seekp( 0, std::ios::beg );
	dateiKopf->speichern( outF );
	outF->close();
	delete outF;
	unlockDatei();
}

// constant 
Schrift *LTDSDatei::ladeSchrift() // gibt die geladene Schrift zurück
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return 0;
	}
	if( !dateiKopf )
	{
		unlockDatei();
		return 0;
	}
	Schrift *ret = new Schrift();
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
	inF->seekg( dateiKopf->getPositionList()[ 0 ], std::ios::beg );
	for( int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); i++ )
	{
		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
		sgKpf->laden( inF );
		Alphabet *alphabet = new Alphabet();
		alphabet->setSchriftgröße( sgKpf->getSchriftGröße() );
		alphabet->setDrawSchriftgröße( sgKpf->getSchriftGröße() );
		for( int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); i1++ )
		{
			LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf();
			zeichKpf->laden( inF );
			LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() );
			zeichKörp->laden( inF );
			alphabet->setBuchstabe( zeichKpf->getZeichen(), zeichKörp->getBuchstabe() );
			zeichKörp->release();
			zeichKpf->release();
		}
		ret->addAlphabet( alphabet->getThis() );
		alphabet->release();
		sgKpf->release();
	}
	inF->close();
	delete inF;
	return ret;
	unlockDatei();
}

Alphabet *LTDSDatei::ladeAlphabet( int schriftgröße ) // gibt eine geladene Schrift nur mit der angegebenen Schriftgröße zurück
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return 0;
	}
	if( !dateiKopf )
	{
		unlockDatei();
		return 0;
	}
	Alphabet *ret = 0;
	int sgNum = -1;
	for( int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); i++ )
	{
		if( dateiKopf->getSchriftGrößeList()[ i ] == schriftgröße )
		{
			sgNum = i;
			break;
		}
	}
	if( sgNum == -1 )
	{
		unlockDatei();
		return 0;
	}
	ret = new Alphabet();
	ret->NeuAlphabet();
	ret->setSchriftgröße( schriftgröße );
	ret->setDrawSchriftgröße( schriftgröße );
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
	inF->seekg( dateiKopf->getPositionList()[ sgNum ], std::ios::beg );
	LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
	sgKpf->laden( inF );
	for( int i = 0; i < sgKpf->getZeichenAnzahl(); i++ )
	{
		LTDSBuchstabenKopf *sgZKpf = new LTDSBuchstabenKopf();
		sgZKpf->laden( inF );
		LTDSBuchstabenKörper *sgZKörp = new LTDSBuchstabenKörper( sgZKpf->getThis() );
		sgZKörp->laden( inF );
		ret->setBuchstabe( sgZKpf->getZeichen(), sgZKörp->getBuchstabe() );
		sgZKörp->release();
		sgZKpf->release();
	}
	sgKpf->release();
	inF->close();
	delete inF;
	unlockDatei();
	return ret;
}

Buchstabe *LTDSDatei::ladeBuchstabe( int schriftgröße, unsigned char zeichen )// Läd einen bestimmten Buchstaben
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return 0;
	}
	if( !dateiKopf )
	{
		unlockDatei();
		return 0;
	}
	Buchstabe *ret = 0;
	int sgNum = -1;
	for( int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); i++ )
	{
		if( dateiKopf->getSchriftGrößeList()[ i ] == schriftgröße )
		{
			sgNum = i;
			break;
		}
	}
	if( sgNum == -1 )
	{
		unlockDatei();
		return 0;
	}
	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
	inF->seekg( dateiKopf->getPositionList()[ sgNum ], std::ios::beg );
	LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
	sgKpf->laden( inF );
	int sgZNum = -1;
	for( int i = 0; i < sgKpf->getZeichenAnzahl(); i++ )
	{
		if( sgKpf->getZeichen()[ i ] == zeichen )
		{
			sgZNum = i;
			break;
		}
	}
	if( sgZNum != -1 )
	{
		inF->seekg( sgKpf->getPositionen()[ sgZNum ], std::ios::beg );
		LTDSBuchstabenKopf *sgZKpf = new LTDSBuchstabenKopf();
		sgZKpf->laden( inF );
		LTDSBuchstabenKörper *sgZKörp = new LTDSBuchstabenKörper( sgZKpf->getThis() );
		sgZKörp->laden( inF );
		ret = sgZKörp->getBuchstabe();
		sgZKörp->release();
		sgZKpf->release();
	}
	sgKpf->release();
	inF->close();
	delete inF;
	unlockDatei();
	return ret;
}

Text *LTDSDatei::getPfad() const // gibt den Dateipfad zurück
{
	return pfad->getThis();
}

int LTDSDatei::getAnzahlSchriftgrößen() const // gibt die Anzahl der Schriftgrößen aus der Datei zurück
{
	if( !DateiExistiert( pfad->getThis() ) )
		return 0;
	if( !dateiKopf )
		return 0;
	return dateiKopf->getSchriftGrößeAnzahl();
}

unsigned char *LTDSDatei::getSchriftGrößen() const // gibt einen Array von Schriftgrößen zurück
{
	if( !DateiExistiert( pfad->getThis() ) )
		return 0;
	if( !dateiKopf )
		return 0;
	return dateiKopf->getSchriftGrößeList();
}

unsigned char LTDSDatei::getAnzahlBuchstaben( int sg ) // gibt die anzahl gespeicherter Buchstaben einer Schriftgröße zurück
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return 0;
	}
	if( !dateiKopf )
	{
		unlockDatei();
		return 0;
	}
	int ret = 0;
	unsigned char *größen = dateiKopf->getSchriftGrößeList();
	unsigned char granzahl = dateiKopf->getSchriftGrößeAnzahl();
	int grpos = -1;
	for( int i = 0; i < granzahl; i++ )
	{
		if( größen[ i ] == sg )
		{
			grpos = i;
			break;
		}
	}
	if( grpos != -1 )
	{
		int *grposlist = dateiKopf->getPositionList();
		LTDSSchriftKopf *sgkpf = new LTDSSchriftKopf();
		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
		inF->seekg( grposlist[ grpos ], std::ios::beg );
		sgkpf->laden( inF );
		ret = sgkpf->getZeichenAnzahl();
		sgkpf->release();
		inF->close();
		delete inF;
	}
	unlockDatei();
	return ret;
}

unsigned char *LTDSDatei::getBuchstaben( int sg ) // gibt einen Array von Buchstaben einer Schriftgröße zurück
{
	lockDatei();
	if( !DateiExistiert( pfad->getThis() ) )
	{
		unlockDatei();
		return 0;
	}
	if( !dateiKopf )
	{
		unlockDatei();
		return 0;
	}
	unsigned char *ret = 0;
	unsigned char *größen = dateiKopf->getSchriftGrößeList();
	unsigned char granzahl = dateiKopf->getSchriftGrößeAnzahl();
	int grpos = -1;
	for( int i = 0; i < granzahl; i++ )
	{
		if( größen[ i ] == sg )
		{
			grpos = i;
			break;
		}
	}
	if( grpos != -1 )
	{
		int *grposlist = dateiKopf->getPositionList();
		LTDSSchriftKopf *sgkpf = new LTDSSchriftKopf();
		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
		inF->seekg( grposlist[ grpos ], std::ios::beg );
		sgkpf->laden( inF );
		ret = new unsigned char[ sgkpf->getZeichenAnzahl() ];
		for( int i = 0; i < sgkpf->getZeichenAnzahl(); i++ )
			ret[ i ] = sgkpf->getZeichen()[ i ];
		sgkpf->release();
		inF->close();
		delete inF;
	}
	unlockDatei();
	return ret;
}

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

LTDSDatei *LTDSDatei::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}

// Bit Funktionen
int Framework::Bits( int a ) // gibt 1-bits in gewinschter anzahl zurück
{
	int ret = 0;
	for( int i = 0; i < a; i++ )
	{
		ret <<= 1;
		ret += 1;
	}
	return ret;
}

int Framework::getBits( char c ) // gibt zurück, wie viele Bits c benötigt
{
	int ret = 0;
	for( int i = 0; ( c & ( char )Bits( i ) ) != c ; i++ )
	{
		ret++;
	}
	return ret;
}