import java.lang.Math;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.*;
import javax.swing.*;
import java.util.*;

class Spiel implements ActionListener {
	Border linie;
	Border rand3D;
	
	static JTextArea chronik;
	JFrame fenster;
	
	JLabel jahresAnzeige;
	static int jahr = 0;
	static int faktor = 0;
	
  static JTextField benoetigtesEssenAnzeige;
	static JTextField geldAnzeige;
	static long geld = 10000;
	
	static Ware menschen;
	static JTextField menschenAnzeige;
	static JTextField menschenPreisAnzeige;
	static Ware land;
	static JTextField landAnzeige;
	static JTextField landPreisAnzeige;	
	static Ware essen;
	static JTextField essenAnzeige;
	static JTextField essenPreisAnzeige;	
	static Ware maerkte;
	static JTextField maerkteAnzeige;
	static JTextField maerktePreisAnzeige;	
	static Ware muehlen;
	static JTextField muehlenAnzeige;
	static JTextField muehlenPreisAnzeige;	
	
	static Random zufall;
	
	HandelsDialog menschenHandel;
	HandelsDialog landHandel;
	HandelsDialog essenHandel;
	HandelsDialog marktHandel;
	HandelsDialog muehleHandel;
			
	
	public Spiel() {
    zufall = new Random();
    
    // Waren deklarieren und initialisieren		
    menschen = new Ware("Mensch","Menschen",(Math.round(20+(2*zufall.nextGaussian()))),100);
    land = new Ware("Land","Land",(Math.round(30+(5*zufall.nextGaussian()))),1000);
    essen = new Ware("Essen","Scheffel Essen",(Math.round(60+(8*zufall.nextGaussian()))),100);
    maerkte = new Ware("Markt","Märkte",(Math.round(1000+(80*zufall.nextGaussian()))),0);
    muehlen = new Ware("Mühle","Mühlen",(Math.round(2000+(80*zufall.nextGaussian()))),0);
        
    // Hauptfenster aufbauen
    baueFenster();
    
    // einzelne Dialogboxen definieren 
    menschenHandel = new HandelsDialog(fenster,"Menschenhandel",menschen,zufall.nextInt(15),geld); 
		menschenHandel.setVisible(false);
		menschenHandel.pack();	
		
    landHandel = new HandelsDialog(fenster,"Landhandel",land,(zufall.nextInt(3500)+1500),geld);
		landHandel.setVisible(false);
		landHandel.pack();			
		
    essenHandel = new HandelsDialog(fenster,"Essensrationen kaufen",essen,(zufall.nextInt(7000)+3000),geld);   
    essenHandel.setVisible(false);
		essenHandel.pack();					
		
		marktHandel = new HandelsDialog(fenster,"Märkte bauen",maerkte,zufall.nextInt(18)+2,geld);
		marktHandel.setVisible(false);
		marktHandel.pack();					
		
		muehleHandel = new HandelsDialog(fenster,"Mühlen bauen",muehlen,(zufall.nextInt(15)+5),geld);
		muehleHandel.setVisible(false);
		muehleHandel.pack();									
	}
	
	  
  public void baueFenster() {
		fenster = new JFrame("Ein Spiel");
		fenster.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		
		fenster.setLocation(200,200);
		fenster.setVisible(true);
		
		JPanel rahmen = new JPanel(new BorderLayout());
		
		rand3D = BorderFactory.createEtchedBorder();
	  linie = BorderFactory.createLineBorder(Color.black);
		Border jahrBorder = BorderFactory.createTitledBorder(linie, "Datum");
		Border chronikBorder = BorderFactory.createTitledBorder(linie, "Chronik");
		Border preisBorder = BorderFactory.createTitledBorder(linie, "Preise");
		Border statusBorder = BorderFactory.createTitledBorder(linie, "Status");
		
		// Anzeige der Jahre
		jahresAnzeige = new JLabel(" Es wird geschrieben das Jahr: "+String.valueOf(jahr));
		jahresAnzeige.setBorder(jahrBorder);
		rahmen.add("North",jahresAnzeige);
		
		// 3 AnzeigeFelder Logbuch, Preise und Status
		JPanel anzeigeFelder =  new JPanel(new BorderLayout());

    // Logbuch		
		JPanel textFeld = new JPanel();
		chronik = new JTextArea("Herzlich willkommen bei Kaiser,\ndem Spiel um Geld und Macht\n",8,20);
		textFeld.add("South",new JScrollPane(chronik));
		textFeld.setBorder(chronikBorder);
		
		anzeigeFelder.add("West",textFeld);

    // Preise
		JPanel preisFeld = new JPanel(new GridLayout(5,2));
		
		JButton buttonMenschen = new JButton("Menschen");
		buttonMenschen.addActionListener(this);
		preisFeld.add(buttonMenschen);
		menschenPreisAnzeige = new JTextField(menschen.gibPreisString());
		menschenPreisAnzeige.setEditable(false);
		preisFeld.add(menschenPreisAnzeige);

		JButton buttonLand = new JButton("Land");
		buttonLand.addActionListener(this);
		preisFeld.add(buttonLand);
		landPreisAnzeige = new JTextField(land.gibPreisString());
		landPreisAnzeige.setEditable(false);
		preisFeld.add(landPreisAnzeige);

		JButton buttonEssen = new JButton("Essen");
		buttonEssen.addActionListener(this);
		preisFeld.add(buttonEssen);
		essenPreisAnzeige = new JTextField(essen.gibPreisString());
		essenPreisAnzeige.setEditable(false);
    preisFeld.add(essenPreisAnzeige);

		JButton buttonMaerkte = new JButton("Märkte");
		buttonMaerkte.addActionListener(this);
		preisFeld.add(buttonMaerkte);
		maerktePreisAnzeige = new JTextField(maerkte.gibPreisString());
		maerktePreisAnzeige.setEditable(false);
		preisFeld.add(maerktePreisAnzeige);

		JButton buttonMuehlen = new JButton("Mühlen");
		buttonMuehlen.addActionListener(this);
		preisFeld.add(buttonMuehlen);
		muehlenPreisAnzeige = new JTextField(muehlen.gibPreisString());
		muehlenPreisAnzeige.setEditable(false);
		preisFeld.add(muehlenPreisAnzeige);
		
		preisFeld.setBorder(preisBorder);

    anzeigeFelder.add("Center",preisFeld);
    
    // Statusanzeige
		JPanel statusFeld = new JPanel(new GridLayout(7,2));
		
		statusFeld.add(new JLabel(" Einwohner"));
		menschenAnzeige = new JTextField(menschen.gibAnzahlString());
		menschenAnzeige.setEditable(false);
		statusFeld.add(menschenAnzeige);

		statusFeld.add(new JLabel(" Essen: "));
		essenAnzeige = new JTextField(essen.gibAnzahlString());
		essenAnzeige.setEditable(false);
		statusFeld.add(essenAnzeige);
		
		statusFeld.add(new JLabel(" benötigtes Essen: "));
    benoetigtesEssenAnzeige = new JTextField(String.valueOf(menschen.gibAnzahl()));
		benoetigtesEssenAnzeige.setEditable(false);
		statusFeld.add(benoetigtesEssenAnzeige);		

		statusFeld.add(new JLabel(" Land: "));	
		landAnzeige = new JTextField(land.gibAnzahlString());
		landAnzeige.setEditable(false);
		statusFeld.add(landAnzeige);

		statusFeld.add(new JLabel(" Märkte"));
		maerkteAnzeige = new JTextField(maerkte.gibAnzahlString());
		maerkteAnzeige.setEditable(false);
		statusFeld.add(maerkteAnzeige);

		statusFeld.add(new JLabel(" Mühlen"));
		muehlenAnzeige = new JTextField(muehlen.gibAnzahlString());
		muehlenAnzeige.setEditable(false);
		statusFeld.add(muehlenAnzeige);
		
		statusFeld.add(new JLabel(" Geld"));
    geldAnzeige = new JTextField(String.valueOf(geld));
		geldAnzeige.setEditable(false);
		statusFeld.add(geldAnzeige);		
		
		statusFeld.setBorder(statusBorder);

    anzeigeFelder.add("East",statusFeld);    
    rahmen.add("Center",anzeigeFelder);

    // Buttons		
		JPanel buttonFeld = new JPanel(new FlowLayout());
		JButton weiter = new JButton("Weiter");
		weiter.addActionListener(this);
		buttonFeld.add(weiter);
		JButton ende = new JButton("Ende");
		ende.addActionListener(this);
		buttonFeld.add(ende);

		rahmen.add("South",buttonFeld);

		fenster.getContentPane().add(rahmen);
		fenster.pack();  	
  }
	
		
	static void berechneJahresResultate() {
		// Berechnung der Preise
    land.setzePreis(Math.round(30+(5*zufall.nextGaussian())));
    landPreisAnzeige.setText(land.gibPreisString());
		essen.setzePreis(Math.round(60+(8*zufall.nextGaussian())));
		essenPreisAnzeige.setText(essen.gibPreisString());
		maerkte.setzePreis(Math.round(1000+(80*zufall.nextGaussian())));
		maerktePreisAnzeige.setText(maerkte.gibPreisString());
		muehlen.setzePreis(Math.round(2000+(80*zufall.nextGaussian())));
		muehlenPreisAnzeige.setText(muehlen.gibPreisString());
		menschen.setzePreis(Math.round(20+(2*zufall.nextGaussian())));
		menschenPreisAnzeige.setText(menschen.gibPreisString());
		
		// Berechnung der Kapitalveränderung
		if (geld >= 0) geld = geld + Math.round(geld * 0.013); 
		else geld = geld + Math.round(geld*0.0125);
		if (maerkte.gibAnzahl() > 0) geld = geld + maerkte.gibAnzahl()*100;
		if (muehlen.gibAnzahl() > 0) geld = geld + muehlen.gibAnzahl()*150;
		
		// Berechnung der Bevölkerungsänderung
		long alt = menschen.gibAnzahl();
		float essenfaktor =  ((float)essen.gibAnzahl()/(float)alt);
		System.out.println("Faktor "+essenfaktor);

		essen.setzeAnzahl(essen.gibAnzahl() - menschen.gibAnzahl());
		if (essen.gibAnzahl() < 0) essen.setzeAnzahl(0);
		if ((essenfaktor > .5)&(essenfaktor < .8)) 
		  menschen.setzeAnzahl(Math.round(menschen.gibAnzahl()*essenfaktor));
		if (essenfaktor < .5) 
		  menschen.setzeAnzahl(Math.round(menschen.gibAnzahl() * 5 /10));
		if ((essenfaktor >= 0.8)& (essenfaktor <= 1)) System.out.println("Bevoelkerung bleibt gleich");
    if ((essenfaktor > 1)&(essenfaktor <= 1.3)) 
      menschen.setzeAnzahl(menschen.gibAnzahl() + Math.round(menschen.gibAnzahl()*(essenfaktor-1)));
		if (essenfaktor > 1.3) {
			essenfaktor = 0.3f;
			menschen.setzeAnzahl(menschen.gibAnzahl() + Math.round(menschen.gibAnzahl()*essenfaktor));
		}
		
		System.out.println("Zuwachs "+(menschen.gibAnzahl()-alt));
    benoetigtesEssenAnzeige.setText(String.valueOf(menschen.gibAnzahl()));
    
    // Berechnung der Essenernte
    essen.setzeAnzahl(Math.round(land.gibAnzahl()* (0.1 + zufall.nextGaussian()*0.01)) + essen.gibAnzahl());
    
    // AnzahlAnzeigen frisch setzen
    menschenAnzeige.setText(menschen.gibAnzahlString());
    essenAnzeige.setText(essen.gibAnzahlString());
    maerkteAnzeige.setText(maerkte.gibAnzahlString());
    muehlenAnzeige.setText(muehlen.gibAnzahlString());
    landAnzeige.setText(land.gibAnzahlString());
    geldAnzeige.setText(String.valueOf(geld));
  }
	
	public static void main (String[] args) {
    Spiel spiel = new Spiel();
	}
	
	public void actionPerformed (ActionEvent e) {
		long result;
		
		if (e.getActionCommand()== "Weiter") {
			jahr++;
			if ((jahr % 5) == 0) faktor++;
		  jahresAnzeige.setText(" Es wird geschrieben das Jahr: "+String.valueOf(jahr));
			berechneJahresResultate();
		}
		
		if (e.getActionCommand()=="Ende") System.exit(0);
		if (e.getActionCommand()== "Menschen") {
		  menschenHandel.zeigeDialog(menschen,zufall.nextInt(15),geld);
		  result = menschenHandel.getInput();
		  if (result != 0) {
		  	menschen.setzeAnzahl(menschen.gibAnzahl()+result);
		  	menschenAnzeige.setText(menschen.gibAnzahlString());
		    geld = geld - (menschen.gibPreis()*result);
		    geldAnzeige.setText(String.valueOf(geld)); 
		    benoetigtesEssenAnzeige.setText(String.valueOf(menschen.gibAnzahl()));
		    if (result > 0) chronik.append(String.valueOf(jahr)+" Kauf von "+result+" Mensch(en) für "+(menschen.gibPreis()*result)+" Gold\n");
		    else chronik.append(String.valueOf(jahr)+" Verkauf von "+Math.abs(result)+" Mensch(en) für "+Math.abs(menschen.gibPreis()*result)+" Gold\n");		  
		  }
		}
		if (e.getActionCommand()== "Land") {
		  landHandel.zeigeDialog(land,(zufall.nextInt(5000)+2000),geld);
		  
		  result = landHandel.getInput();
		  if (result != 0) {
		  	land.setzeAnzahl(land.gibAnzahl()+result);
		  	landAnzeige.setText(land.gibAnzahlString());
		    geld = geld - (land.gibPreis()*result);
		    geldAnzeige.setText(String.valueOf(geld)); 
		    if (result > 0) chronik.append(String.valueOf(jahr)+" Kauf von "+result+" ha Land für "+(land.gibPreis()*result)+" Gold\n");
		    else chronik.append(String.valueOf(jahr)+" Verkauf von "+Math.abs(result)+" ha Land für "+Math.abs(land.gibPreis()*result)+" Gold\n");		  
		  }
		}			
		if (e.getActionCommand()== "Essen") {
		  essenHandel.zeigeDialog(essen,(zufall.nextInt(700)+300),geld);
		  result = essenHandel.getInput();
		  if (result != 0) {
		  	essen.setzeAnzahl(essen.gibAnzahl()+result);
		  	essenAnzeige.setText(essen.gibAnzahlString());
		    geld = geld - (essen.gibPreis()*result);
		    geldAnzeige.setText(String.valueOf(geld)); 
		    if (result > 0) chronik.append(String.valueOf(jahr)+" Kauf von "+result+" Rationen Essen für "+(essen.gibPreis()*result)+" Gold\n");
		    else chronik.append(String.valueOf(jahr)+" Verkauf von "+Math.abs(result)+" Rationen Essen für "+Math.abs(essen.gibPreis()*result)+" Gold\n");		  
		  }			
		}
		 
		if (e.getActionCommand()== "Märkte") {
		  marktHandel.zeigeDialog(maerkte,(zufall.nextInt(18)+2),geld);
		  result = marktHandel.getInput();
		  if (result != 0) {
		  	maerkte.setzeAnzahl(maerkte.gibAnzahl()+result);
		  	maerkteAnzeige.setText(maerkte.gibAnzahlString());
		    geld = geld - (maerkte.gibPreis()*result);
		    geldAnzeige.setText(String.valueOf(geld)); 
		    if (result > 0) chronik.append(String.valueOf(jahr)+" Kauf von "+result+" ha Märkten für "+(maerkte.gibPreis()*result)+" Gold\n");
		    else chronik.append(String.valueOf(jahr)+" Verkauf von "+Math.abs(result)+" ha Märkten für "+Math.abs(maerkte.gibPreis()*result)+" Gold\n");		  
		  }			
		}

		if (e.getActionCommand()== "Mühlen") {
		  muehleHandel.zeigeDialog(muehlen,(zufall.nextInt(15)+5),geld);
		  
		  result = muehleHandel.getInput();
		  if (result != 0) {
		  	muehlen.setzeAnzahl(muehlen.gibAnzahl()+result);
		  	muehlenAnzeige.setText(muehlen.gibAnzahlString());
		    geld = geld - (muehlen.gibPreis()*result);
		    geldAnzeige.setText(String.valueOf(geld)); 
		    if (result > 0) chronik.append(String.valueOf(jahr)+" Kauf von "+result+" Mühle(n) für "+(muehlen.gibPreis()*result)+" Gold\n");
		    else chronik.append(String.valueOf(jahr)+" Verkauf von "+Math.abs(result)+" Mühle(n) für "+Math.abs(muehlen.gibPreis()*result)+" Gold\n");		  
		  }
		}
	}
}
  
