//********************//
//Memory © t.heyn 2000//
//********************//

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

public class MemoryApplet extends Applet implements Runnable, ActionListener, ItemListener
	{
	final int GROESSE=75, HOEHE=6, ZU=0, AUF=1, AUFDECKEN=2, ZUDECKEN=3; //einige konstanten
	int breite=8;
	int drehzahl=1;
	int steps=10;
	long startzeit, endzeit;
	int richtig[] = new int[2];
	int feld[][] = new int[HOEHE][breite];
	int status[][] = new int[HOEHE][breite];
	String kommentar = new String();
   TextArea text= new TextArea("",15,12,TextArea.SCROLLBARS_NONE);
   Choice auswahl = new Choice();
	boolean aufgedeckt, amDrehen;
	int spieler,versuche;
	int z1, s1, z2, s2, z3, s3;
	Image bild[] = new Image[25];
	AudioClip yahoo, oops;
	Image HintergrundBild = null;
   Graphics HintergrundGrafik = null;
   Dimension HintergrundGroesse = null;
	Thread thread;

	public void init()
		{
		showStatus("Bilder/Töne werden geladen, bitte Geduld!");	//daten laden
		laden();
		showStatus("Memory © t.heyn 2000");
    	addMouseListener(new MyMouse());									//GUI erstellen
    	setLayout(new BorderLayout());
    	Panel anzeige = new Panel();
    		anzeige.setLayout(new BorderLayout());
    		add("East",anzeige);
    	Panel controls = new Panel();
    		controls.setLayout(new BorderLayout());
    		anzeige.add("South",controls);
    	Label titel = new Label("Memory",Label.CENTER);
			titel.setBackground(Color.yellow);
			titel.setFont(new Font("SansSerif",Font.BOLD,18));
			anzeige.add("North",titel);
    	anzeige.add("Center",text);
    		text.setEnabled(false);
      	auswahl.add("24 Paare");
      	auswahl.add("21 Paare");
      	auswahl.add("18 Paare");
      	auswahl.add("15 Paare");
      	auswahl.addItemListener(this);
      	controls.add("North",auswahl);
     	Button neu= new Button("Neues Spiel");
    		neu.addActionListener(this);
    		controls.add("South",neu);
  		neuesSpiel();
		}

	public void paint(Graphics g)											//aktuelles applet zeichnen
		{
		for (int z=0;z<HOEHE;z++)
			{
			for (int s=0;s<breite;s++)
    			{
    			//bild zeichnen
    			if (status[z][s]==AUF) g.drawImage(bild[(feld[z][s])],GROESSE*s,GROESSE*z,this);
     			//rücken zeichnen
     			if (status[z][s]==ZU) g.drawImage(bild[24],GROESSE*s,GROESSE*z,this);
				//aufdecken
    			if (status[z][s]==AUFDECKEN && drehzahl<=steps/2)
    				g.drawImage(bild[24],GROESSE*s+GROESSE/2-GROESSE/drehzahl/2,GROESSE*z,GROESSE/drehzahl,GROESSE,this);
    			if (status[z][s]==AUFDECKEN && drehzahl> steps/2)
    				g.drawImage(bild[(feld[z][s])],GROESSE*s+GROESSE/2-GROESSE/(steps-drehzahl)/2,GROESSE*z,GROESSE/(steps-drehzahl),GROESSE,this);
				//zudecken
    			if (status[z][s]==ZUDECKEN && drehzahl<=steps/2)
    				g.drawImage(bild[(feld[z][s])],GROESSE*s+GROESSE/2-GROESSE/drehzahl/2,GROESSE*z,GROESSE/drehzahl,GROESSE,this);
    			if (status[z][s]==ZUDECKEN && drehzahl> steps/2)
    				g.drawImage(bild[24],GROESSE*s+GROESSE/2-GROESSE/(steps-drehzahl)/2,GROESSE*z,GROESSE/(steps-drehzahl),GROESSE,this);
    			}
    		}
    	g.clearRect(GROESSE*breite,0,GROESSE*(8-breite),GROESSE*HOEHE);
     	schreiben();
		}

	public void itemStateChanged(ItemEvent e)							// all die doofen listener
		{
		String anzahl=(String) auswahl.getSelectedItem();
		if (anzahl=="24 Paare") breite=8;
		if (anzahl=="21 Paare") breite=7;
		if (anzahl=="18 Paare") breite=6;
		if (anzahl=="15 Paare") breite=5;
		neuesSpiel();
		}
		
	public void actionPerformed(ActionEvent e)
		{
		neuesSpiel();
		}
		
	private void neuesSpiel()
		{
		spieler=0;																// daten restore
		aufgedeckt=false;
		amDrehen=false;
		versuche=0;
		kommentar="";
		richtig[0]=0;
		richtig[1]=0;
		for (int s=0;s<breite;s++)											//feld füllen mit zahlen
			{
			for (int z=0;z<(HOEHE/2);z++)
    			{
    			feld[z][s]=(breite*z)+s;
    			feld[z+(HOEHE/2)][s]=(breite*z)+s;
    			status[z][s]=ZU;
    			status[z+(HOEHE/2)][s]=ZU;
    			}
    		}
		for(int i=0;i<100;i++)												//mischen durch tauschen
			{
			int y1=(int)(Math.random()*breite);
			int y2=(int)(Math.random()*breite);
			int x1=(int)(Math.random()*HOEHE);
			int x2=(int)(Math.random()*HOEHE);
			int temp[][] = new int[1][1];
    		temp[0] [0] =feld[x1][y1];
    		feld[x1][y1]=feld[x2][y2];
    		feld[x2][y2]=temp[0] [0];
			}
		java.awt.Toolkit.getDefaultToolkit().beep();
		repaint();
		}

	private class MyMouse extends MouseAdapter
		{
		public void mousePressed(MouseEvent e)
			{
			int z=(int)(e.getY()/GROESSE);
			int s=(int)(e.getX()/GROESSE);
			if(z>=HOEHE || s>=breite || status[z][s]>ZU || amDrehen) return;
			z1=z;
			s1=s;
			if(! aufgedeckt) 													//1. aufdecken
				{
				status[z1][s1]=AUFDECKEN;
				z2=z1;
				s2=s1;
				aufgedeckt=true;
				start();
				}
			if(aufgedeckt && !(z1==z2 && s1==s2)) 						//2. aufdecken
				{
				aufgedeckt=false;
				status[z1][s1]=AUFDECKEN;
				start();
				if (feld[z1][s1]==feld[z2][s2])
					{
	  				yahoo.play();
					richtig[spieler]++;
					}
				else
					{
					oops.play();
					pause(1200);
					status[z1][s1]=ZUDECKEN;
					status[z2][s2]=ZUDECKEN;
					start();
					spieler=1-spieler;//spielerwechsel
					}
				schreiben();
				versuche++;
				}
			}
		}

	private void schreiben()
		{
		text.setText("\n\n"+"Spieler 1: "+richtig[0]
						+"\n\n"+"Spieler 2: "+richtig[1]
						+"\n\n\n\n"+"Spieler "+(spieler+1)+" ist dran"+"\n\n\n\n"
						+"Total Versuche: "+versuche);
		if (richtig[0]+richtig[1]==(breite*HOEHE/2))
			{
			if (richtig[0]> richtig[1]) kommentar="Spieler 1 gewinnt";
			if (richtig[0]< richtig[1]) kommentar="Spieler 2 gewinnt";
			if (richtig[0]==richtig[1]) kommentar="Unentschieden";
			text.appendText("\n\n\n"+kommentar);
			}
		}		

	private void pause(int zeit)
		{
		long startzeit=System.currentTimeMillis();
		while ((System.currentTimeMillis() - startzeit) <=zeit) {}
		}

	private void laden()
		{
		yahoo= getAudioClip(getCodeBase(),"yahoo.au");
		oops= getAudioClip(getCodeBase(),"oops.au");
    	MediaTracker tracker=new MediaTracker(this);
    	for (int i=0;i<25;i++)
    		{
    		bild[i] = getImage(getCodeBase(),i+".gif");
    		tracker.addImage(bild[i],1);
    		}
    	try
    		{
    		tracker.waitForAll();
    		}
    	catch(InterruptedException e) {}
		}

	//methoden fürs multithreading
	public void run()
		{
		while (true)
			{
			startzeit = System.currentTimeMillis();
			drehzahl++;
			if (drehzahl==steps)
				{
				if (status[z1][s1]==AUFDECKEN) status[z1][s1]=AUF;
				if (status[z1][s1]==ZUDECKEN ) status[z1][s1]=ZU;
				if (status[z2][s2]==AUFDECKEN) status[z2][s2]=AUF;
				if (status[z2][s2]==ZUDECKEN ) status[z2][s2]=ZU;
				drehzahl=1;
				amDrehen=false;
				thread.stop();
				}
			update(getGraphics());
			//schlafen
			try
            {
         	endzeit = System.currentTimeMillis();	//nur solange schlafen wie noetig
				if (endzeit - startzeit < 200/steps) Thread.sleep(200/steps - endzeit + startzeit);  
				}
			catch (InterruptedException e)
				{
				break;
				}
			}
		}

	public void start()
		{
		amDrehen=true;
		thread = new Thread(this);
		thread.start();
		}

	public void stop()
		{
		thread.stop();
		thread=null;
		}

	public final void update(Graphics g) //Flimmerfreie Grafik mit Double Buffering
		{
		Dimension dim = getSize();
		if((HintergrundBild==null) || (dim.width != HintergrundGroesse.width) || (dim.height != HintergrundGroesse.height))
			{
			HintergrundBild = createImage(dim.width, dim.height);
			HintergrundGroesse = dim;
			HintergrundGrafik = HintergrundBild.getGraphics();
			}
		HintergrundGrafik.clearRect(0, 0, HintergrundGroesse.width, HintergrundGroesse.height);
		paint(HintergrundGrafik);
		g.drawImage(HintergrundBild,0,0,null);
		}
	}