#ifndef Schrift_H
#define Schrift_H

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

namespace Framework
{
	class Farbe; // Farbe.h
	class Punkt; // Punkt.h
	class Bild; // Bild.h
	class Text; // Text.h
	class Buchstabe; // aus dieser Datei
	class Alphabet; // aus dieser Datei
	class Schrift; // aus dieser Datei

	class Buchstabe
	{
	private:
		Punkt *größe;
		Punkt *pos;
		unsigned char *alpha;
		Farbe *f;
		int schriftGröße;
		int drawSg;
		int ref;

	public:
		// Konstruktor 
		Buchstabe();
		// Destruktor 
		~Buchstabe();
		// nicht constant 
		void NeuBuchstabe( Punkt *größe ); // Initialisierung
		void setPixel( Punkt *pos, unsigned char alpha ); // setzt den alphawert des Pixels
		void setPixel( int x, int y, unsigned char alpha );
		void setPixel( int i, unsigned char alpha );
		void setPosition( Punkt *pos ); // setzt die Buchstabenposition
		void setPosition( int x, int y );
		void setFarbe( int fc ); // setzt die Buchstabenfarbe
		void setFarbe( Farbe *f );
		void setSchriftGröße( int sg ); // setzt die Schriftgröße des Buchstaben
		void setDrawSchriftGröße( int dsg ); // setzt die Zeichengröße des Buchstaben
		// constant 
		unsigned char *getBuff() const;
		Farbe *getFarbe() const; // gibt die Buchstabenfarbe zurück
		Punkt *getGröße() const; // gibt die Buchstabenbildgröße zurück
		int getBreite() const; // Buchstabenbreite
		int getHöhe() const; // Buchstabenhöhe
		void render( Bild *zrObj ) const; // Zeichnet nach rObj
		// Reference Counting 
		Buchstabe *getThis();
		Buchstabe *release();
	};

	class Alphabet
	{
	private:
		Buchstabe **zeichen;
		int schriftGröße;
		int drawSchriftGröße;
		Punkt *pos;
		int zeilenHöhe;
		int zeilenAbstand;
		Farbe *f;
		int ref;

	public:
		// Konstruktor 
		Alphabet();
		// Destruktor 
		~Alphabet();
		// nicht constant 
		void NeuAlphabet(); // Initialisierung 
		void setBuchstabe( unsigned char i, Buchstabe *buchstabe ); // setzt einen Buchstaben
		void setSchriftgröße( int gr ); // setzt die Schriftgröße
		void setDrawSchriftgröße( int gr ); // setzt die Zeichengröße
		void setZeilenAbstand( int za ); // setzt den Zeilenabstand
		void setDrawPosition( Punkt *pos ); // setzt die Draw Position
		void setDrawPosition( int x, int y );
		void setFarbe( Farbe *f ); // setzt die Schriftfarbe
		void setFarbe( int fc );
		// constant 
		Buchstabe *getBuchstabe( unsigned char i ) const; // gibt einen Buchstaben zurück
		int getSchriftgröße() const; // gibt die Schriftgröße zurück
		int getDrawSchriftGröße() const; // gibt die Zeichengröße zurück
		int getZeilenAbstand() const; // gibt den Zeilenabstand zurück
		int getZeilenHöhe() const; // gibt die Höhe des höchsten Zeichens zurück
		Punkt *getPosition() const; // gibt die DrawPosition zurück
		Farbe *getFarbe() const; // gibt die Farbe zurück
		int getTextBreite( Text *txt ) const; // gibt die Breite des Textes zurück
		int getTextHöhe( Text *txt ) const; // gibt die Höhe des Textes zurück
		int textPos( Text *txt, int mausX, int mausY ) const; // gibt den Buchstaben zurück, auf den die Maus zeigt
		void render( Text *txt, Bild *zrObj ) const; // Zeichnet txt nach renderObj
		void render( int xOff, int yOff, int bOff, int hOff, Text *txt, Bild *zrObj ) const;
		void render( Text *txt, Bild *zrObj, int cpos, int cf, int fbeg, int ff ) const;
		void render( int xOff, int yOff, int bOff, int hOff, Text *txt, Bild *zrObj, int cpos, int cf, int fbeg, int ff ) const;
		// Reference Counting 
		Alphabet *getThis();
		Alphabet *release();
	};

	class AlphabetArray
	{
	private:
		AlphabetArray *next;
		Alphabet *This;

	public:
		// Konstruktor 
		AlphabetArray();
		// Destruktor 
		~AlphabetArray();
		// nicht constant 
		void addAlphabet( Alphabet *alphabet ); // Fügt ein Alphabet hinzu
		bool removeAlphabet( int sg ); // entfernt ein Alphabet
		void setDrawSchriftGröße( int sg ); // Setzt die Draw Schriftgröße aller Alphabete
		void setZeilenAbstand( int za ); // setzt den Zeilenabstant aller Alphabete
		void setSchriftFarbe( Farbe *farbe ); // setzt die Schriftfarbe aller Alphabete
		void setSchriftFarbe( int fc );
		void setNext0(); // setzt den next Zeiger zu 0
		// constant 
		Alphabet *getAlphabet( unsigned char sg ) const; // gibt getThis von einem Alphabet zurück
		Alphabet *zAlphabet( unsigned char sg ) const; // gibt ein Alphabet zurück
		Alphabet *getAlphabetI( int index, int count ) const;
		AlphabetArray *getNext() const; // gibt das nächste Alphabet zurück
	};

	class Schrift
	{
	private:
		unsigned char alphabetAnzahl;
		AlphabetArray *alphabet;
		int schriftGröße;
		int zeilenAbstand;
		Punkt *drawPos;
		Farbe *farbe;
		CRITICAL_SECTION threadSave;
		int ref;

	public:
		// Konstruktor 
		Schrift();
		// Destruktor 
		~Schrift();
		// nicht constant 
		void addAlphabet( Alphabet *alphabet ); // Fügt der Schrift ein Alphabet hinzu
		void removeAlphabet( int sg ); // Entfernt ein Alphabet
		void setDrawPosition( int x, int y ); // setzt die Zeichenposition
		void setDrawPosition( Punkt *pos );
		void setSchriftGröße( int sg ); // setzt die Schriftgröße
		void setZeilenAbstand( int za ); // setzt den Zeilenabstand
		void setFarbe( Farbe *f ); // setzt die Schriftfarbe
		void setFarbe( int fc );
		void renderText( Text *txt, Bild *zrObj ); // zeichnet txt nach rObj
		void renderText( int xOff, int yOff, int bOff, int hOff, Text *txt, Bild *zrObj );
		void renderText( Text *txt, Bild *zrObj, int cpos, int cf, int fbeg, int ff );
		void renderText( int xOff, int yOff, int bOff, int hOff, Text *txt, Bild *zrObj, int cpos, int cf, int fbeg, int ff );
		void lockSchrift(); // blockiert die Schrift für andere Threads
		void unlockSchrift(); // gibt die Schrift für andere Threads frei
		// constant 
		Alphabet *getAlphabet( int sg ) const; // gibt einen Alphaberarray zurück
		Alphabet *getAlphabetI( int index ) const;
		unsigned char getAlphabetAnzahl() const; // gibt die anzahl von in der Schrift enthaltenen Alphabeten zurück
		int getSchriftGröße() const; // gibt die Schriftgröße zurück
		int getZeilenabstand() const; // gibt den Zeilenabstand zurück
		int getDrawX() const; // gibt die Zeichenposition zurück
		int getDrawY() const;
		Punkt *getDrawPosition() const;
		Farbe *getFarbe() const; // gibt die Farbe zurück
		unsigned int getFarbeCode() const;
		int getTextBreite( Text *txt ) const; // gibt die Breite des Textes zurück
		int getTextHöhe( Text *txt ) const; // gibt die Höhe des Textes zurück
		int textPos( Text *txt, int mausX, int mausY ) const; // gibt den Buchstaben zurück, auf den die Maus zeigt
		// Reference Counting 
		Schrift *getThis();
		Schrift *release();
	};
}

#endif