import java.awt.*;
import java.awt.event.*;

public class Game extends Frame implements Runnable,KeyListener
{
	Image offscreenImage;	//Für die doppelte Pufferung
	Graphics offscreen;

	Thread gameThread;		//zeigt auf den Thread, wenn das Spiel gestartet

	Karte gameKarte; 		//ein Objekt der Kartenklasse
	Gegner gameGegner[] = new Gegner[Konst.maxGegner];	//Ein Objekt für jeden Gegner
	Spieler gameSpieler;	//Ein Objekt für den Spieler
	Schild gameSchild;		//Ein Objekt des Schildes

	int aktLevel;			//in welchem Level ist man gerade
	Image frontBild;		//Der Rahmen
	boolean schild;			//Wird gerade das Schild angezeigt?
	int lifes;				//Wieviele Leben noch?

    public Game()			//Konstruktor
    {
		super("Fressman");	//Titelleiste benennen

		setSize(Konst.maxX,Konst.maxY);				//Fenster auf die richtige Größe bringen
		setResizable(false);						//Fenster soll nicht in der Größe veränderbar sein
		setVisible(true);							//Fenster anzeigen

		WindowListener l = new WindowAdapter()		//Den Zustand des Fensters überwachen
		{
			public void windowClosing(WindowEvent e)//Wenn das Fenster geschlossen wird
			{
				gameThread = null;					//Den Thread schliessen
				if (Gameapplet.applet == null)	System.exit(0); //Wenn kein Applet, dann einfach raus
				Gameapplet.applet.stop();			//sonst die Stop-Routine vom Applet aufrufen
			}
		};
		addWindowListener(l);						//Den Listener zum Fenster hinzufügen
		addKeyListener(this);						//Die Tastenabfrage aktivieren

		frontBild = Helps.loadImage("front.gif",this); //den Rahmen laden

	    offscreenImage = createImage(getSize().width,getSize().height);	//Ein imaginäres Bild im Speicher erstellen
		offscreen = offscreenImage.getGraphics();	//Den Handle von dem Bild offscreen hinzufügen

		aktLevel = 0;								//Das erste Level ist Level 0
		gameKarte = new Karte();					//Das Kartenobjekt erzeugen
		gameKarte.init(aktLevel);					//Level 0 laden
		gameSpieler = new Spieler(gameKarte); 		//Den Spieler erzeugen
		for (int i=0;i<Konst.maxGegner;i++) gameGegner[i] = new Gegner(gameKarte,gameSpieler); //Jeden Gegner erzeugen
		gameSchild = new Schild();					//das Schild erzeugen
		gameSchild.init("Fressman","dP-Software");	//Das Schild mit dem Intro beschreiben
		schild = true;								//Schild aktivieren
		lifes = 3;									//zu Beginn hat man 3 Leben

		gameThread = new Thread(this);				//neuen Thread für das Spiel erzeugen
		gameThread.start();							//Thread starten (weiter gehts dann in run())
	}

	public void newLevel()							//Lädt ein Level neu
	{
		if (lifes <= 0)								//Wenn Tod
		{
			aktLevel = 0;							//Dann in Level 0 weitermachen
			lifes = 3;								//Wieder mit 3 Leben
			gameSpieler.killed = false;				//Und Spieler wiederbeleben
		}

		if (!gameSpieler.killed) gameKarte.init(aktLevel); 		//Karte nur neuladen, wenn Spieler nicht getötet wurde
		gameSpieler.init();							//Den Spieler initialisieren
		for (int i=0;i<Konst.maxGegner;i++) gameGegner[i].init();//Die Gegner initialisieren
	}

    public void run()		//wird von thread.start aufgerufen
    {
		Thread thisThread = Thread.currentThread(); //den namen des aktuellen Threads speichern
		while(gameThread == thisThread)				//solange wiederholen, bis Thread nicht mehr vorhanden
		{
			Helps.wait(Konst.fpsTime);				//pausieren
			repaint();								//jedes mal das Bild neu zeichnen

			if (schild)								//Wenn gerade das Schild angezeigt wird
			{
				if (gameSchild.fertig)				//Schaun, ob's schon fertig ist
				{
					schild = false;					//dann Schild ausschalten
					newLevel();						//und Level neu laden
				}
			}
			else if (gameSpieler.geschafft)			//Level fertig?
			{
				aktLevel++;							//ins nächste Level schalten
				if (aktLevel >= Levels.maxLevel)	//letzte Level erreicht
				{
					lifes = 3;						//wieder auf 3 Leben schalten
					aktLevel = 0;					//und wieder im ersten Level beginnen
					gameSchild.init("You completed","all Level"); //Schild beschreiben
				}
				else								//sonst
				{
					lifes++;						//ein Bonusleben geben
					gameSchild.init("You reached","Level "+String.valueOf(aktLevel+1)); //Schild beschreiben
				}
				schild = true;						//immer das Schild aktivieren
			}
			else if (gameSpieler.killed)			//Tod?
			{
				lifes--;							//ein Leben abziehen
				if (lifes <= 0)						//wenn kein Leben mehr vorhanden
				{
					gameSchild.init("You died","in Level "+String.valueOf(aktLevel+1));	//Schild beschreiben
				}
				else gameSchild.init("You have",String.valueOf(lifes)+ " lifes now");	//Schild beschreiben
				schild = true;						//Schild aktivieren

			}
		}
	}

	public void update(Graphics screen) //wird von repaint aufgerufen
	{
		paint(screen);					//Bildschirm nicht löschen, sondern einfach wieder Paint
	}

    public void paint(Graphics screen)	//wird von update aufgerufen
	{
		int i;

		if (gameThread == null) return; //noch nicht initialisiert, also raus

		gameKarte.display(offscreen);										//die Karte malen
		gameSpieler.display(offscreen);										//Spieler malen
		for (i=0;i<Konst.maxGegner;i++) gameGegner[i].display(offscreen);	//Gegner malen
		if (schild) gameSchild.display(offscreen);							//das Schild malen
		offscreen.drawImage(frontBild,Konst.korrX,Konst.korrY, this);		//die Front malen
		screen.drawImage(offscreenImage, 0, 0, this); 						//offscreen auf screen malen
	}

	public void keyPressed(KeyEvent event)				//Wenn eine Taste gedrückt wurde
	{
		if (!schild)									//im normalen Spiel
		{
			if (event.getKeyCode() == KeyEvent.VK_LEFT)	//Pfeil nach links gedrückt
			{
				gameSpieler.wunschRichtung = 3;
				gameSpieler.taste = true;
			}
			if (event.getKeyCode() == KeyEvent.VK_RIGHT)//Pfeil nach rechts gedrückt
			{
				gameSpieler.wunschRichtung = 1;
				gameSpieler.taste = true;
			}
			if (event.getKeyCode() == KeyEvent.VK_UP)	//Pfeil nach oben gedrückt
			{
				gameSpieler.wunschRichtung = 0;
				gameSpieler.taste = true;
			}
			if (event.getKeyCode() == KeyEvent.VK_DOWN) //Pfeil nach unten gedrückt
			{
				gameSpieler.wunschRichtung = 2;
				gameSpieler.taste = true;
			}
		}
		else											//Wenn das Schild angezeigt wird
		{
			if (event.getKeyCode() == KeyEvent.VK_ENTER)//Enter gedrückt
			{
				gameSchild.hoch = true;					//Schild wieder nach oben bewegen
			}
		}
	}

	public void keyReleased(KeyEvent event)	//Wenn eine Taste losgelassen wurde (nicht benutzt)
	{
	}

	public void keyTyped(KeyEvent event)	//Funktion zwar überschrieben, aber nichts damit gemacht
	{
	}

	public static void main(String[] args)	//Hauptprogramm
	{
		Game frame = new Game();			//das GameObjekt erzeugen (zieht alles andere nach sich)
	}
}
