import java.awt.*;
import java.applet.*;
import java.lang.*;
import java.util.*;
import java.io.*;
import java.net.*;
 
public class Display extends java.applet.Applet {

  
  /******** DEFINE VARIABLES ********/
  Panel panel1;
  Environ envDisplay;
  Panel panel2;
  Panel panel21, panel22, panel221, panel222;
  TitleCanvas titleBar1, titleBar2;
  // Jsimulator sim = new Jsimulator(false);

  Random r;
  public Predator Robs[] = new Predator[useful.MAXBOTS];
  public Prey Food[] = new Prey[useful.MAXFOOD];
  public Obstacle Obs[] = new Obstacle[useful.MAXOBS];  

  newsim sim;
  Frame fnew;
  Socket simsock;

  globals G = new globals();

  // = new simx(envDisplay, rob, Eval);

  public static void main(String args[]){
    
    Frame f = new Frame("Simulator Display Interface");
    //    fnew = f;
    Display g = new Display();
    
    //  g._notAnApplet = true;
    g.init();
    
    f.add("Center", g);
    f.pack();
    f.show();
  }

  public void setsockup(int port)
  {

    try {

      System.out.println("setsockup");

      simsock = (new ServerSocket(port, 1)).accept();
      G.in = new DataInputStream(simsock.getInputStream());
      G.out = new DataOutputStream(simsock.getOutputStream());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  
  public void setdispup()
  {
    setsockup(G.port);
    GetInitState();
    G.EnvX = Obs[0].width;
    G.EnvY = Obs[0].height;

    System.out.print("finished initializing simulation objects\n");
    envDisplay = new Environ(Robs, Food, Obs, G);
    sim = new newsim(Robs, Food, Obs, envDisplay, G);   

  }

  public void GetInitState() 
  {
    String S;
    try 
      {
	while(true) {
	  S = (G.in).readLine();
	  S.trim();
	  if(S.charAt(0) == 'O')  // Obstacle data
	    {
	      getObs(Obs, S.substring(1));
	    }
	  else if (S.charAt(0) == 'F')  // prey data
	    {
	      getPrey(Food, S.substring(1));
	    }
	  else if (S.charAt(0) == 'N')  // prey data
	    {
	      getNbots(Robs, S.substring(1));
	      return;
	    }
	  else
	    {
	    return;
	    }
	}
      }
    catch(IOException ioe)
      {
	ioe.printStackTrace();
      }
  }
  
  void getNbots(Predator p[], String S)
  {
    StringTokenizer st;
    int i;

    st = new StringTokenizer(S);
    G.nbots = Integer.valueOf(st.nextToken()).intValue();

    System.out.println("NBOTS :" + G.nbots);

    for(i = 0; i < G.nbots; i++)
      {
	p[i] = new Predator(G);
      }

    G.simiterations = Integer.valueOf(st.nextToken()).intValue();
    System.out.println("Simiterations :" + G.simiterations);
  }

  void getObs(Obstacle Obs[], String S)
  {
    int i, x, y, width, height;
    StringTokenizer st;

    st = new StringTokenizer(S);

    i = Integer.valueOf(st.nextToken()).intValue();
    G.nobs++;
    System.out.println("Nobs :" + G.nobs);
    x = Integer.valueOf(st.nextToken()).intValue();
    y = Integer.valueOf(st.nextToken()).intValue();
    width = Integer.valueOf(st.nextToken()).intValue();
    height = Integer.valueOf(st.nextToken()).intValue();
    Obs[i] = new Obstacle(x, y, width, height);
    System.out.println("New object " + i + ":" + 
		       x + " " + y + " " + width
		       + " " +  height);
  }
    
  
  void getPrey(Prey Food[], String S)
  {
    int i, x, y;
    StringTokenizer st;

    st = new StringTokenizer(S);

    i = Integer.valueOf(st.nextToken()).intValue();
    G.nfood++;
    System.out.println("Nfood :" + G.nfood);

    x = Integer.valueOf(st.nextToken()).intValue();
    y = Integer.valueOf(st.nextToken()).intValue();
    Food[i] = new Prey(x, y);
    System.out.println("New Food " + i + ":" + 
		       x + " " + y);
  }
    
  /********************************************************************/
  /* init()								*/
  /********************************************************************/

  public void init() {
    int i;

    r = new Random(System.currentTimeMillis());
    
    setdispup();    

    setLayout(new GridLayout(1,2, 1, 1));
    panel1 = new Panel();
    add(panel1);
    
    panel1.setLayout(new GridLayout(1,2,1,1));    // panel1 for env display 
    envDisplay.setBackground(Color.gray);
    panel1.add(envDisplay);

    panel2 = new Panel();
    add(panel2);
    panel2.setLayout(new GridLayout(0,2,1,1));    // panel1 for env display 
    panel2.add(new Button("Start"));    
    panel2.add(new Button("Reset"));
    panel2.add(new Button("Don't Show Path"));
    panel2.add(new Button("Show Path"));
    panel2.add(new Button("Quit"));


    envDisplay.repaint();

    // sim.run();     

  }
  
  /********************************************************************/
  /* handleEvent()							*/
  /********************************************************************/
  public boolean handleEvent(Event evt) {
    if (evt.id == Event.WINDOW_DESTROY) 
      System.exit(0);
    return super.handleEvent(evt);
  }
  
  /********************************************************************/
  /* action()								*/
  /********************************************************************/

  private void SendMessage(String s, DataOutputStream out) 
  {
    try {
      int len = s.length();
      byte[] b = new byte[len];
      s.getBytes(0, len, b, 0);
      out.write(b, 0, b.length);
      out.flush();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }



  public boolean action(Event evt, Object arg) 
  {
    if(arg.equals("Start"))
      {
	String s = "(Start)";
	SendMessage(s, G.out);

	sim.run();
	System.out.println("Finished Simulation");
	envDisplay.repaint();
      }
    else if (arg.equals("Reset"))
      {
	System.out.println("Reset");
	
	try
	  {
	    simsock.close();
	  }
	catch (IOException e) 
	  {
	    e.printStackTrace();
	  }
	
	G = new globals();
	G.nobs =  0;
	G.nbots = 0;
	G.nfood = 0;
	setdispup();
	envDisplay.setBackground(Color.gray);
	panel1.add(envDisplay);
	envDisplay.repaint();
	  
      }
    else if (arg.equals("Don't Show Path"))
      {
	envDisplay.path = false;
	envDisplay.repaint();
	envDisplay.newpaint();
      }
    else if (arg.equals("Show Path"))
      {
	envDisplay.path = true;
	envDisplay.repaint();
	envDisplay.newpaint();
      }
    else if (arg.equals("Quit"))
      {
	try 
	  {
	    System.out.println("dieing");
	    System.exit(0);
	  } catch (SecurityException e)
	    {
	      System.out.println("dieing");
	    }
      }
    else
      {
	envDisplay.repaint();
      }
    envDisplay.repaint();
    return true;
  }
  
  int GetObs(String s)
  {
    int i, x, y, width, height;
    FileInputStream fin;
    DataInputStream dis;
    StringTokenizer st;
    try 
      {
	fin = new FileInputStream(s);
	dis = new DataInputStream(fin);
	st = new StringTokenizer(dis.readLine());
	G.nobs = Integer.valueOf(st.nextToken()).intValue();
	G.nobs++;
	System.out.println("Nobs :" + G.nobs);
	for(i = 1; i < G.nobs; i++)
	  {
	    st = new StringTokenizer(dis.readLine());
	    x = Integer.valueOf(st.nextToken()).intValue();
	    y = Integer.valueOf(st.nextToken()).intValue();
	    width = Integer.valueOf(st.nextToken()).intValue();
	    height = Integer.valueOf(st.nextToken()).intValue();
	    Obs[i] = new Obstacle(x, y, width, height);
	    System.out.println("New object " + i + ":" + 
			   x + " " + y + " " + width
			   + " " +  height);
	  }
      }
    catch(IOException ioe)
      {
	ioe.printStackTrace();
      }
    return G.nobs;
  }

}  







