#ifndef DateiSystem_H
#define DateiSystem_H

#include <fstream>
#include "Array.h"

namespace Framework
{
	class Bild; // Bild.h
	class Text; // Text.h
	class Punkt; // Punkt.h
	class Farbe; // Farbe.h
	class Buchstabe; // Schrift.h
	class Alphabet; // Schrift.h
	class Schrift; // Schrift.h
	class FBalken; // Fortschritt.h
	class LTDSPixel; // aus dieser Datei
	class LTDSDateiKopf; // aus dieser Datei
	class LTDSSchriftKopf; // aus dieser Datei
	class LTDSBuchstabenKopf; // aus dieser Datei
	class LTDSBuchstabenKörper; // aus dieser Datei
	class LTDSDatei; // aus dieser Datei

	// LTDS Dateivormat --- Dient zum speichern von Schriftarten
	class LTDSPixel
	{
	private:
		int ref;
		char index;
		char iA;
		char miA;
		char maxIndex; // Länge des Pixels
		bool änder;
		bool änderA;
		unsigned char komp : 3; // Komprimierung der Farbwerte
		unsigned char alpha;
		LTDSPixel * davor;
		bool addBitZuFarbe( unsigned char bit ); // Fügt den Farbwerten ein Bit hinzu
		bool getNextFarbeBit( char &byte, int i ); // Speichert das nächste Farbbit in byte

	public:
		// Konstruktor 
		LTDSPixel( LTDSPixel *davor );
		// Destruktor 
		~LTDSPixel();
		// nicht constant 
		// zum Laden gedacht
		char addByte( char byte, char begin ); // gibt ende des Pixels zurück, -1 wenn nicht zu ende
		// zum speichern gedacht
		void setAlpha( unsigned char alpha ); // setzt die Farbe des Pixels
		void Komp(); // Komprimiert den Pixel
		char getNextByte( char &byte, int bbegin ); // Gibt die nächsten Bits Zurück, -1 wenn der Pixel nicht zu ende ist
		// constant 
		unsigned char getKomp() const; // hat sich die Komprimierung geändert
		bool getÄnderA() const;
		unsigned char getA() const; // gibt Alpha zurück
		// Reference Counting 
		LTDSPixel *getThis();
		LTDSPixel *release();
	};

	class LTDSDateiKopf
	{
	private:
		int ref;
		unsigned char sganzahl;
		unsigned char *gr;
		int *pos;

	public:
		// Konstruktor 
		LTDSDateiKopf();
		// Destruktor 
		~LTDSDateiKopf();
		// nicht constant 
		void laden( std::ifstream *inF ); // Lät aus inF
		void addSG( char sg ); // Schriftgröße hinzufügen
		void removeSG( char sg ); // Schriftgröße entfernen
		// constant 
		void speichern( std::ofstream *outF ) const; // Speichert nach outF
		unsigned char *getSchriftGrößeList() const; // gibt eine Liste mit gespeicherten Schriftgrößen zurück
		int *getPositionList() const; // gibt eine Positionsliste der gespeicherten Schriftgrößen zurück
		int getSchriftGrößeAnzahl() const; // gibt die Anzahl der gespeicherten Schriftgrößen zurück
		// Reference Counting 
		LTDSDateiKopf *getThis();
		LTDSDateiKopf *release();
	};

	class LTDSSchriftKopf
	{
	private:
		int ref;
		unsigned char schriftGröße;
		unsigned char *zeichen;
		int *pos;
		unsigned char zeichenAnzahl;

	public:
		// Konstruktor 
		LTDSSchriftKopf();
		// Destruktor 
		~LTDSSchriftKopf();
		// nicht constant 
		void laden( std::ifstream *inF ); // läht von inF
		void setSchriftgröße( unsigned char gr ); // setze schriftgröße
		void setZeichenAlphabet( Alphabet *alphabet ); // setzt die Zeichen von alphabet
		void addZeichen( unsigned char zeichen ); // Zeichen hinzufügen
		void removeZeichen( unsigned char zeich ); // Zeichen entfernen
		// constant 
		void speichern( std::ofstream *outF ) const; // speichert nach outF
		unsigned char getSchriftGröße() const; // gibt die Schriftgröße zurück
		unsigned char getZeichenAnzahl() const; // gibt die Zeichenanzahl zurück
		int *getPositionen() const; // gibt die Zeichenpositionen zurück
		unsigned char *getZeichen() const; // gibt die zeichen zurück
		// Reference Counting 
		LTDSSchriftKopf *getThis();
		LTDSSchriftKopf *release();
	};

	class LTDSBuchstabenKopf
	{
	private:
		int ref;
		unsigned char zeichen;
		Punkt *größe;

	public:
		// Konstruktor 
		LTDSBuchstabenKopf();
		// Destruktor 
		~LTDSBuchstabenKopf();
		// nicht constant 
		void laden( std::ifstream *inF ); // lät aus inF
		void init( unsigned char zeichen, Punkt *größe ); // initialisierung( für speichern )
		void init( unsigned char zeichen, int br, int hö );
		// constant 
		void speichern( std::ofstream *outF ) const; // speichertn nach outF
		unsigned char getZeichen() const; // gibt das Zeichen zurück
		int getBreite() const; // gibt die Breite zurück
		int getHöhe() const; // gibt die höhe zurück
		Punkt *getGröße() const; // gibt die Größe zurück
		// Reference Counting 
		LTDSBuchstabenKopf *getThis();
		LTDSBuchstabenKopf *release();
	};

	class LTDSBuchstabenKörper
	{
	private:
		int ref;
		Punkt *größe;
		unsigned char zeichen;
		Buchstabe *buchstabe;

	public:
		// Konstruktor 
		LTDSBuchstabenKörper( LTDSBuchstabenKopf *kopf );
		// Destruktor 
		~LTDSBuchstabenKörper();
		// nicht constant 
		void setBuchstabe( Buchstabe *zeichen ); // setzt den Buchstaben
		void laden( std::ifstream *inF ); // Läht aus inF
		// constant 
		void speichern( std::ofstream *outF ) const; // speichert nach outF
		Buchstabe *getBuchstabe() const; // gibt den Buchstaben zurück
		unsigned char getZeichen() const; // gibt das Zeichen zurück
		// Reference Counting 
		LTDSBuchstabenKörper *getThis();
		LTDSBuchstabenKörper *release();
	};

	class LTDSDatei
	{
	private:
		int ref;
		Text *pfad;
		LTDSDateiKopf *dateiKopf;
		CRITICAL_SECTION thread_Save;

	public:
		// Konstruktor 
		LTDSDatei();
		// Destruktor 
		~LTDSDatei();
		// nicht constant 
		void lockDatei();
		void unlockDatei();
		void setPfad( Text *txt ); // setzt den Pfad zur Datei
		void leseDaten(); // ließt den Dateikopf
		void addSchriftgröße( Alphabet *alphabet ); // fügt eine Schriftgröße hinzu
		void addBuchstabe( int gr, Buchstabe *zeich, unsigned char zeichen ); // Fügt einer Schriftgröße einen Buchstaben hinzu
		void löscheSchrifrGröße( int gr ); // Löscht eine Schriftgröße aus der Datei
		void löscheBuchstabe( int gr, unsigned char zeichen ); // Löscht einen Buchstaben aus der Datei
		void löscheDatei(); // Löscht die gesamte Datei
		void erstelleDatei(); // erstellt die Datei
		void speicherSchrift( Schrift *schrift ); // Speichert die übergebene Schrift
		// constant 
		Schrift *ladeSchrift(); // gibt die geladene Schrift zurück
		Alphabet *ladeAlphabet( int schriftgröße ); // gibt eine geladene Schrift nur mit der angegebenen Schriftgröße zurück
		Buchstabe *ladeBuchstabe( int schriftgröße, unsigned char zeichen ); // Läd einen bestimmten Buchstaben
		Text *getPfad() const; // gibt den Dateipfad zurück
		int getAnzahlSchriftgrößen() const; // gibt die Anzahl der Schriftgrößen aus der Datei zurück
		unsigned char *getSchriftGrößen() const; // gibt einen Array von Schriftgrößen zurück
		unsigned char getAnzahlBuchstaben( int sg ); // gibt die anzahl gespeicherter Buchstaben einer Schriftgröße zurück
		unsigned char *getBuchstaben( int sg ); // gibt einen Array von Buchstaben einer Schriftgröße zurück
		// Reference Counting 
		LTDSDatei *getThis();
		LTDSDatei *release();
	};

	// Bit Funktionen 
	int Bits( int a ); // gibt 1-bits in gewinschter anzahl zurück
	int getBits( char c ); // gibt zurück, wie viele Bits c benötigt
}
#endif