import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class RobotAgentGUI extends JFrame {
	
	//Size of the RobotAgentMap
	private String fieldSize;
	
	//reference to the RobotAgent
	//is set by the constructor
	private RobotAgent myRobotAgent;
	
	//EnergieBar indicating energy ressource for specific action
	private JProgressBar energyBar;
	
	private JLabel energyLevel = new JLabel("100");
	
	private double energieStand = 100;
	
	// Legt fest, ob ein Buttonfeld erstellt werden soll
	boolean buttonsErzeugen = true;
	
	//status field of RobotAgent displaying events
	private JTextArea statusField;

	// Blickrichtung
	int view = 4;
	//Feldgroesse
	int anzahlX, anzahlY;
	// aktuelle Position (Roboterkarte)
	int x = 0; int y = 0;
	
	// Field
	feldObjekt objektArray[][];
	JButton buttonArray[][];
	JScrollPane feldScroll = new JScrollPane();
	JPanel feld = new JPanel();
	
	// Frame 
	 private JFrame frame; //= new JFrame();
	 private WindowListener wl = new WindowAdapter() {
	   public void windowClosing( WindowEvent e) {
	      myRobotAgent.deregister();}
	 };
	 
	 // Objektinfos
    String inListe[];
  	JPanel kommunikation = new JPanel();
  	JList alleRoboter = new JList();
  	JTextArea antworten = new JTextArea();
	 
	 JButton fotoNormal = new JButton();
	 	JPanel untenLinks = new JPanel();
		JPanel objektInfos = new JPanel();
		JLabel lab_position = new JLabel("Position:");
		JLabel position = new JLabel("keine Angabe");
		JLabel lab_feldtyp = new JLabel("Feldtyp:");
		JLabel feldtyp = new JLabel("keine Angabe");
		JLabel lab_metall = new JLabel("Metall:");
		JLabel metall = new JLabel("keine Angabe");
		JLabel lab_mine = new JLabel("Mine:");
		JLabel mine = new JLabel("keine Angabe");
		JLabel lab_hoehe = new JLabel("Höhenebene:");
		JLabel hoehe = new JLabel("keine Angabe");
		ImageIcon markierung = new ImageIcon("Icons/markierung.jpg");
	
	
	public RobotAgentGUI(RobotAgent robot, String fieldSize) {
		
		super("RobotAgent: "+robot.getLocalName());
				
		this.fieldSize = fieldSize;
		anzahlX = new Integer(fieldSize.substring(0, fieldSize.indexOf(";")) ).intValue();
		anzahlY = new Integer(fieldSize.substring(fieldSize.indexOf(";") + 1, fieldSize.length() )).intValue();
		if ( (anzahlX * anzahlY) > 2500 ) {
			buttonsErzeugen = false;	
		}
		System.out.println(fieldSize);
		
		//
		//this.getContentPane().setSize(800, 600);
		//this.getContentPane().setSize(800, 600);
		frameErstellen();
		
		myRobotAgent = robot;
		
		Container contentPane = frame.getContentPane();
		contentPane.setLayout(null);
		//contentPane.setLayout(new FlowLayout());
		
		JLabel statusLabel = new JLabel(); //"Statusbericht", SwingConstants.CENTER);
		JLabel energyLabel = new JLabel(); //"Energie-Level", SwingConstants.CENTER);
		JScrollPane statusPane;
		JPanel statusPanel, instruments;
		
		energyLabel.setText("Energie-Level");
		energyLabel.setBounds(10,5,100,20);
		statusLabel.setText("Statusbericht");
		statusLabel.setBounds(10,0,120,20);
		
		statusField = new JTextArea("Robot "+myRobotAgent.getLocalName()+" started!", 4, 25);
		statusField.setBackground(new Color(135, 146, 239));
		statusField.setForeground(Color.darkGray);
		statusField.setEditable(false);
		//statusField.setBounds(0,0,170,100);
		
		energyBar = new JProgressBar(0, 100);
		energyBar.setForeground(Color.green);
		energyBar.setBackground(Color.white);
		energyBar.setValue(100);
		energyBar.setBounds(110,5,150,20);
		instruments = new JPanel();
		instruments.setBounds(500,280,280,50);
		instruments.add(energyLabel);
		instruments.add(energyBar);
		instruments.add(energyLevel);
		
		statusPane = new JScrollPane(statusField, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		//statusPane.getViewport().setLayout(null);
		statusPane.setBounds(95,0,180,90);
		//statusPane.getViewport().setBackground ( Color.blue);
		//statusPane.getViewport().add(statusField);
		//statusPane.setViewportBorder( BorderFactory.createLineBorder(Color.black) );
		statusPanel = new JPanel();
		statusPanel.setLayout(null);
		statusPanel.setBounds(500,330,280,100);
		//statusPanel.setLayout(new);
		statusPanel.add(statusLabel);
		statusPanel.add(statusPane);
		
		energyLabel.setBounds(0,0,100,200);
		
		// erstellt das Panel um Anzeigen von Objektinformationen

		
		untenLinksErstellen();
		kommunikationsPanel();
				
		contentPane.add(untenLinks);
		contentPane.add(statusPanel); //, BorderLayout.SOUTH);
		contentPane.add(instruments); //, BorderLayout.CENTER);
		
		//statusPanel.setBackground( Color.red);
		instruments.setBackground(SystemColor.info);
		statusPanel.setBackground(SystemColor.info);
		objektInfos.setBackground(SystemColor.info);
		untenLinks.setBackground(SystemColor.info);
		kommunikation.setBackground(SystemColor.info);
		// Create Field
		
		
		
		feldScroll.setBounds(new Rectangle(500,0,280,280));
		feldScroll.getViewport().setLayout(null);
		feld.setLayout(null);
		
		
		contentPane.add(feldScroll, null);
		contentPane.add(kommunikation);
				
		//setLocationRelativeTo(null);
		//setVisible(true);
		frame.show();
		if (buttonsErzeugen) {
			feldErstellen(anzahlX,anzahlY);
		}
		feldScroll.getViewport().add(feld, null);
	
		
		/*
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				myRobotAgent.deregister();
			}
		});
		*/
	}
	
	
	
	//loescht die AgentGUI (bei Derigistrierung)
	public void loeschen() {
		frame.dispose();
	}


	public void bewegen(final String moveData) {
		Runnable addIt = new Runnable() {
			public void run() {
				move(moveData);
			}
		};
		SwingUtilities.invokeLater(addIt);
	}
	
	public void drehen(final String turnData) {
		Runnable addIt = new Runnable() {
			public void run() {
				int drehung = new Integer(turnData).intValue();
				turn(drehung);
			}
		};
		SwingUtilities.invokeLater(addIt);
	}
	
	
	public void turn(int direction) {
		
		view = direction;
		buttonArray[x][y].setIcon(new ImageIcon ("Icons/pfeil_"+direction+".jpg"));	
	}
	
	public void move(String moveData) {
		
		int distance = new Integer(moveData.substring(0, moveData.indexOf(";"))).intValue();
		
		buttonArray[x][y].setIcon(new ImageIcon (""));
		neuePosition(distance);
		buttonArray[x][y].setIcon(new ImageIcon ("Icons/pfeil_" + view +".jpg"));
			
	}
	
	public void addRobotToList(String s) { };
	
	public void addStatus(final String status) {
		Runnable addIt = new Runnable() {
			public void run() {
				statusField.append(status);
			}
		};
		SwingUtilities.invokeLater(addIt);
	}
	
		public void addAntwort(final String sender, final String message) {
		Runnable addIt = new Runnable() {
			public void run() {
				antworten.append("\n" + sender +": " + message );
			}
		};
		SwingUtilities.invokeLater(addIt);
	}
	
	public void changeEnergyBar(final double value) {
		Runnable addIt = new Runnable() {
			public void run() {
				double old = energieStand;
				
				System.out.println("alter Wert: "+old);
				
				if (((int)(old+value)<energyBar.getMaximum()) && ((int)(old+value)>0) ) {
					energyBar.setValue((int)(old+value));
					energieStand = energieStand + value;
				} else if ((int)(old+value)>energyBar.getMaximum()) {
					energyBar.setValue(energyBar.getMaximum());
					energieStand = 100;
				} else {
					energyBar.setValue(0);
					energieStand = 0;
					//Roboter is im Arsch
				}
				
				int wert = energyBar.getValue();
				
				if (wert > 67) {
					
					energyBar.setForeground(Color.green);
				} else if (wert < 33) {
					
					energyBar.setForeground(Color.red);
				} else {
					
					energyBar.setForeground(Color.yellow);
				}
				
				energyLevel.setText(""+energyBar.getValue());
			}
		};
		SwingUtilities.invokeLater(addIt);
	}
	
	
	public double getEnergyLevel() {
		return energieStand;
	}
	
  // erstellt einen Frame
  public void frameErstellen() {
    //Make sure we have nice window decorations.
      JFrame.setDefaultLookAndFeelDecorated(true);
      frame = new JFrame("RobotAgent GUI");
      frame.addWindowListener( wl );
      frame.setSize(800,450);
      frame.getContentPane().setBackground(SystemColor.textHighlightText);

  }
  
  // erstellt ein Feld mit der übergebenen Parameterzahl
  private void feldErstellen(int anzahlX, int anzahlY) {
  	  
	

	System.out.println("x: " +anzahlX + "  y: "+anzahlY);
     // erstellt neue Buttons und schreibt sie in ein Array
     //Berechnet die Anzahl edr zu erstellenden Knöpfe
     buttonArray = new JButton[anzahlX][anzahlY];
	objektArray = new feldObjekt[anzahlX][anzahlY];
     //Berechnet die Größe der Knöpfe
     int knopfGroesse = 26;
     
     
     System.out.println("Knopf " + knopfGroesse);
     // aktualisiert die Panel im ScrollPane
     feld.setPreferredSize(new Dimension(knopfGroesse * anzahlX, knopfGroesse * anzahlY));
     feld.setBounds(new Rectangle(0,0,knopfGroesse * anzahlX, knopfGroesse * anzahlY));




      for (int y = 0; y < anzahlY; y++) {	
             for (int x = 0; x < anzahlX; x++) {
                 objektArray[x][y]= new feldObjekt();
                 buttonArray[x][y] = new JButton();
                 buttonArray[x][y].setBorder(BorderFactory.createRaisedBevelBorder());
                 buttonArray[x][y].setName("(" + ((int)x+1) + ";" + ((int)y +1) + ")");
                 buttonArray[x][y].addActionListener(new java.awt.event.ActionListener() {
                   public void actionPerformed(ActionEvent e) {

                     	objektinfosAnzeigen_actionPerformed(e);
                         }
                     });
                     buttonArray[x][y].setBounds(new Rectangle(x*knopfGroesse, y*knopfGroesse, knopfGroesse , knopfGroesse));
                     buttonArray[x][y].setToolTipText(((int) x+1) +","+ ((int)y +1));
                     feld.add(buttonArray[x][y], null);
                     buttonArray[x][y].setBackground(Color.darkGray);
                     buttonArray[x][y].setForeground( Color.gray );
                     //System.out.println("x:" +x*knopfGroesse + ", y:" +y*knopfGroesse);
             
             }
     }

	buttonArray[0][0].setIcon(new ImageIcon ("Icons/pfeil_4.jpg"));
  }
  
  // erstellt das Panel mit den Objektinfos
  private void untenLinksErstellen() {
  		objektInfos.setBounds(5,5,215,140);
		objektInfos.setBorder(BorderFactory.createLineBorder(Color.black));
		lab_position.setBounds(10,10,100,20);
		position.setBounds(110,10,100,20);
		lab_feldtyp.setBounds(10,30,100,20);
		feldtyp.setBounds(110,30,100,20);
		lab_metall.setBounds(10,50,100,20);
		metall.setBounds(110,50,100,20);
		lab_mine.setBounds(10,70,100,20);
		mine.setBounds(110,70,100,20);
		lab_hoehe.setBounds(10,90,100,20);
		hoehe.setBounds(110,90,100,20);
		
		objektInfos.setLayout(null);
		objektInfos.add(lab_position);
		objektInfos.add(position);
		objektInfos.add(lab_feldtyp);
		objektInfos.add(feldtyp);
		objektInfos.add(lab_metall);
		objektInfos.add(metall);
		objektInfos.add(lab_mine);
		objektInfos.add(mine);
		objektInfos.add(lab_hoehe);
		objektInfos.add(hoehe);
		untenLinks.setBounds(0,280,500,150);
		untenLinks.setLayout(null);
		untenLinks.add(objektInfos);
		untenLinks.setBorder(BorderFactory.createLineBorder(Color.black));
		//Bilderpanel
		//fotos.setBounds(240,5,170,140);
		fotoNormal.setBounds(240,5,160,120);
		//fotos.add("Foto", fotoNormal);
		//fotos.add("IR", fotoIR);
		untenLinks.add(fotoNormal);
		untenLinks.setBackground(SystemColor.info);


  }
  public void neuePosition(int anzahl) {
 // Richtung und neue Position berechnenberechnen
	
	for (int i = 0; i < anzahl; i++) {
	switch (view) {
        case 1 :  //NORTH
          y = y - 1;
          break;
        case 2 :  // NORTHEAST
          y = y - 1;
          x = x + 1;
          break;
        case 3 :  //EAST
          x = x + 1;
          break;
        case 4 :  // SOUTHEAST
          y = y + 1;
          x = x + 1;
          break;
        case 5 : // SOUTH
          y = y + 1;
          break;
        case 6 :  // SOUTHWEST
          y = y + 1;
          x = x - 1;
          break;
        case 7 :  //WEST
          x = x - 1;
          break;
        case 8 :  // NORTHWEST
          y = y - 1;
          x = x - 1;
          break;

        default:
          System.out.println("Operand nicht gefunden");
      }
      }
  	
  }
  
  public void touch(String s) {
  	if (buttonsErzeugen) {
	  	boolean b = new Boolean(s).booleanValue();
	  	int xS = 0; int yS =0;
	  	// gesensortes Feld berechnen
	  	switch (view) {
	        case 1 :  //NORTH
	          yS = y - 1;
	          xS = x;
	          break;
	        case 2 :  // NORTHEAST
	          yS = y - 1;
	          xS = x + 1;
	          break;
	        case 3 :  //EAST
	          xS = x + 1;
	          yS = y;
	          break;
	        case 4 :  // SOUTHEAST
	          yS = y + 1;
	          xS = x + 1;
	          break;
	        case 5 : // SOUTH
	          yS = y + 1;
	          xS = x;
	          break;
	        case 6 :  // SOUTHWEST
	          yS = y + 1;
	          xS = x - 1;
	          break;
	        case 7 :  //WEST
	          xS = x - 1;
	          yS = y;
	          break;
	        case 8 :  // NORTHWEST
	          yS = y - 1;
	          xS = x - 1;
	          break;
	
	        default:
	          System.out.println("Operand nicht gefunden");
	      }
	      
		  if ( (xS >= 0) && (xS < anzahlX) &&(yS >=0)  && (yS<anzahlY) ) {    
		  	if (b) {
		  		buttonArray[xS][yS].setBackground(Color.red);
		  		objektArray[xS][yS].setRobFeldtyp("Hindernis");	
		  	}
		  	else {
		  		buttonArray[xS][yS].setBackground(Color.green);	
		  		objektArray[xS][yS].setRobFeldtyp("Frei");
		  	}
		  }
		  else { System.out.println(" Feld ausßerhalb des Bereichs! :" +xS +","+yS); }
	}
  }
  
  public void humidity(String s) {
  	if (buttonsErzeugen) {
	  	boolean b = new Boolean(s).booleanValue();
	  	int xS = 0; int yS =0;
	  	// gesensortes Feld berechnen
	  	switch (view) {
	        case 1 :  //NORTH
	          yS = y - 1;
	          xS = x;
	          break;
	        case 2 :  // NORTHEAST
	          yS = y - 1;
	          xS = x + 1;
	          break;
	        case 3 :  //EAST
	          xS = x + 1;
	          yS = y;
	          break;
	        case 4 :  // SOUTHEAST
	          yS = y + 1;
	          xS = x + 1;
	          break;
	        case 5 : // SOUTH
	          yS = y + 1;
	          xS = x;
	          break;
	        case 6 :  // SOUTHWEST
	          yS = y + 1;
	          xS = x - 1;
	          break;
	        case 7 :  //WEST
	          xS = x - 1;
	          yS = y;
	          break;
	        case 8 :  // NORTHWEST
	          yS = y - 1;
	          xS = x - 1;
	          break;
	
	        default:
	          System.out.println("Operand nicht gefunden");
	      }
	      
		  if ( (xS >= 0) && (xS < anzahlX) &&(yS >=0)  && (yS<anzahlY) ) {    
		  	if (b) {
		  		buttonArray[xS][yS].setBackground(Color.blue);
		  		objektArray[xS][yS].setRobFeldtyp("Fluß");	
		  	}
		  }
		  else { System.out.println(" Feld ausßerhalb des Bereichs! :" +xS +","+yS); }
	}
  }

 public void metall(String s) {
  	if (buttonsErzeugen) {
	  	boolean b = new Boolean(s).booleanValue();
	  	int xS = 0; int yS =0;
	  	// gesensortes Feld berechnen
	  	switch (view) {
	        case 1 :  //NORTH
	          yS = y - 1;
	          xS = x;
	          break;
	        case 2 :  // NORTHEAST
	          yS = y - 1;
	          xS = x + 1;
	          break;
	        case 3 :  //EAST
	          xS = x + 1;
	          yS = y;
	          break;
	        case 4 :  // SOUTHEAST
	          yS = y + 1;
	          xS = x + 1;
	          break;
	        case 5 : // SOUTH
	          yS = y + 1;
	          xS = x;
	          break;
	        case 6 :  // SOUTHWEST
	          yS = y + 1;
	          xS = x - 1;
	          break;
	        case 7 :  //WEST
	          xS = x - 1;
	          yS = y;
	          break;
	        case 8 :  // NORTHWEST
	          yS = y - 1;
	          xS = x - 1;
	          break;
	
	        default:
	          System.out.println("Operand nicht gefunden");
	      }
	      
		  if ( (xS >= 0) && (xS < anzahlX) &&(yS >=0)  && (yS<anzahlY) ) {    
		  	if (b) {
		  		buttonArray[xS][yS].setBackground(Color.red);
		  		objektArray[xS][yS].setRobMetall("Ausschlag");	
		  	}
		  	else {
		  		buttonArray[xS][yS].setBackground(Color.green);	
		  		objektArray[xS][yS].setRobMetall("Kein Ausschlag");
		  	}
		  }
	}
  }
  public void setFoto(ImageIcon foto) {
  	// String mittels Base64 decodieren
  	//byte buffer_back[]=Base64.decode(code);
    //ImageIcon foto = new ImageIcon(buffer_back);
  	
  	// Bild wird nur kurzfristig angezeigt und nicht
  	// gespeichert.
  	fotoNormal.setIcon(foto);
  	
  	// Dialog anzeigen, ob Mine erkennbar ist
  	//JOptionPane.showMessageDialog(frame, "\nRoboter '"+name+"' existiert bereits!", "Warung!", JOptionPane.INFORMATION_MESSAGE);
  	//System.out.println( JOptionPane.showConfirmDialog(frame, "Ist auf diesem Feld eine Mine erkennbar?", "Manuelle Bildauswertung", JOptionPane.YES_NO_OPTION   ) );
  	
  	
  	
  }
  
    public void setIR(ImageIcon foto) {
  	// String mittels Base64 decodieren
  	//byte buffer_back[]=Base64.decode(code);
    //ImageIcon foto = new ImageIcon(buffer_back);
  	
  	// Bild wird nur kurzfristig angezeigt und nicht
  	// gespeichert.
  	fotoNormal.setIcon(foto);
  	
  	// Dialog anzeigen, ob Mine erkennbar ist
  	//JOptionPane.showMessageDialog(frame, "\nRoboter '"+name+"' existiert bereits!", "Warung!", JOptionPane.INFORMATION_MESSAGE);
  	//int i = JOptionPane.showConfirmDialog(frame, "Ist auf diesem Feld eine Mine erkennbar?", "Manuelle Bildauswertung", JOptionPane.YES_NO_OPTION   ) ;
  	
  	// Sensorposition
    int xS = 0; int yS = 0;
  	switch (view) {
	        case 1 :  //NORTH
	          yS = y - 1;
	          xS = x;
	          break;
	        case 2 :  // NORTHEAST
	          yS = y - 1;
	          xS = x + 1;
	          break;
	        case 3 :  //EAST
	          xS = x + 1;
	          yS = y;
	          break;
	        case 4 :  // SOUTHEAST
	          yS = y + 1;
	          xS = x + 1;
	          break;
	        case 5 : // SOUTH
	          yS = y + 1;
	          xS = x;
	          break;
	        case 6 :  // SOUTHWEST
	          yS = y + 1;
	          xS = x - 1;
	          break;
	        case 7 :  //WEST
	          xS = x - 1;
	          yS = y;
	          break;
	        case 8 :  // NORTHWEST
	          yS = y - 1;
	          xS = x - 1;
	          break;
	
	        default:
	          System.out.println("Operand nicht gefunden");
	      }				

  	
  	// Falls Mine
  	//if (i == 0) {
  	// markieren();
  	// objektArray[xS][yS].setRobMine("Mine");	
  	//}
  	//else {
  	
	//	buttonArray[xS][yS].setBackground(Color.green);
	//	objektArray[xS][yS].setRobMine("Keine Mine");
  	
  	//}
  	
  	
  }

 public void markieren() {
  	int xS = 0; int yS = 0;
		if (buttonsErzeugen) {		
				switch (view) {
			        case 1 :  //NORTH
			          yS = y - 1;
			          xS = x;
			          break;
			        case 2 :  // NORTHEAST
			          yS = y - 1;
			          xS = x + 1;
			          break;
			        case 3 :  //EAST
			          xS = x + 1;
			          yS = y;
			          break;
			        case 4 :  // SOUTHEAST
			          yS = y + 1;
			          xS = x + 1;
			          break;
			        case 5 : // SOUTH
			          yS = y + 1;
			          xS = x;
			          break;
			        case 6 :  // SOUTHWEST
			          yS = y + 1;
			          xS = x - 1;
			          break;
			        case 7 :  //WEST
			          xS = x - 1;
			          yS = y;
			          break;
			        case 8 :  // NORTHWEST
			          yS = y - 1;
			          xS = x - 1;
			          break;
			
			        default:
			          System.out.println("Operand nicht gefunden");
			      }				
				buttonArray[xS][yS].setIcon(markierung);
				buttonArray[xS][yS].setBackground(Color.red);
			}
  }
  public void kommunikationsPanel() {

  	
  	
  	kommunikation.setLayout(null);
  	kommunikation.setBounds(0,150,500,150);
  	kommunikation.setBorder(BorderFactory.createLineBorder(Color.black));
  	
  	//antworten.setBounds(310, 5, 285,140);

  	
  	antworten.setBackground(new Color(135, 146, 239));
  	antworten.append("Communication History");
  	
	JScrollPane antwortenPane = new JScrollPane(antworten);
	antwortenPane.setBounds(310, 5, 150,100);
	 
	kommunikation.add(antwortenPane);


  	

  	
  }

  private void objektinfosAnzeigen_actionPerformed(ActionEvent e) {
  	JButton temp = new JButton();
    temp = (JButton) e.getSource();
    String s = temp.getName();
	s = s.substring(1, s.length()-1);

	int xS = new Integer (s.substring(0, s.indexOf(";"))).intValue() - 1;
	int yS = new Integer (s.substring(s.indexOf(";") +1 , s.length() )).intValue() - 1;

  	
  	
  	metall.setText(objektArray[xS][yS].getRobMetall() );
  	mine.setText(objektArray[xS][yS].getRobMine() );
  	hoehe.setText(objektArray[xS][yS].getRobHoehenstufe());
  	feldtyp.setText(objektArray[xS][yS].getRobFeldtyp());
  	frame.getContentPane().repaint();
  }


	public void addOwnAntwort(final String message) {
		Runnable addIt = new Runnable() {
			public void run() {
				
				antworten.append("\n->" + myRobotAgent.getLocalName() +": " + message );
			}
		};
		SwingUtilities.invokeLater(addIt);
	}	
}
		