import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;



public class GridDisplay extends JPanel implements Runnable {
    /*@non_null@*/ private Grid grid;
    /*@non_null@*/ private SimObjectChooser simobjchooser;
    /*@non_null@*/ private TeamChooser teamchooser;
    /*@non_null@*/ private GameSpeedChooser gamespeedchooser;
    private boolean stopThread;
   
    final static int SLEEP_DELAY = 200;

    GridDisplay (/*@non_null@*/ Grid grid, /*@non_null@*/ SimObjectChooser simobjchooser,TeamChooser teamchooser,GameSpeedChooser gamespeedchooser) {
        this.grid = grid;
	this.simobjchooser = simobjchooser;
	this.teamchooser = teamchooser;
        this.gamespeedchooser = gamespeedchooser;
        this.stopThread = true;
       
        setOpaque (false); // This is necessary to make painting work
    }

    
  
    private int getSquareWidth ()
	//@ensures \result > 0
    {
	int swidth = getWidth() / grid.numColumns ();

	if (swidth > 0) {
	    return swidth;
	} else {
	    return 1;
	}
    }

    private int getSquareHeight () 
	//@ensures \result > 0
    {
        int sheight = (getHeight()-10) / grid.numRows ();

	if (sheight > 0) {
	    return sheight;
	} else {
	    return 1;
	}
    }

    private int getHorizontalOffset () {
        return (getWidth() - (getSquareWidth () * grid.numColumns ())) / 2;
    }

    private int getVerticalOffset () {
        return (getHeight() - (getSquareHeight () * grid.numRows ())) / 2;
    }
    
    public void setObjectAt (int x, int y) {
	if (stopThread) { 
	    // Only allow grid locations to be set if
	    // the simulation is stopped.
	    int row = (y - getVerticalOffset ()) / getSquareHeight ();
	    int col = (x - getHorizontalOffset ()) / getSquareWidth ();
	    
            grid.setGameSpeed(gamespeedchooser.getSelectedClass());
            
	    grid.setObjectAt(row, col, simobjchooser.getSelectedClass(), teamchooser.getSelectedClass());
	    repaint ();
	}
    }
    
    public void startObjects () {
	grid.startObjects (); // Start SimObject threads.
	Thread displayThread = new Thread(this);
	displayThread.start();
    }

    public void run() {
	stopThread = false;

	while (!stopThread) {
	    repaint ();
            try { 	
	    	Thread.sleep (SLEEP_DELAY);
	    } catch (java.lang.InterruptedException e) {
                System.out.println("Display thread interrupted.");
	        break;
            }
	}
    }

    public void pauseObjects () {
	grid.pauseObjects (); // Pause SimObject threads.
	this.stopThread = true;
    }
    
    public void paintComponent (Graphics g) throws RuntimeException
    {
	//@ assume g != null;
        int squarewidth = getSquareWidth ();
        int squareheight = getSquareHeight ();

        int hoffset = getHorizontalOffset ();
        int voffset = getVerticalOffset ();

	for (int row = 0; row < grid.numRows (); row++) {
	    for (int col = 0; col < grid.numColumns (); col++) {
		SimObject tmp = grid.grabObjectAt (row,col);

		if (tmp == null) {
		    g.setColor (Color.gray);
		} else {
		    g.setColor (tmp.getColor());
		}
		
                int x=hoffset + col * squarewidth;
                int y=voffset + row * squareheight;
                int h=squareheight;
                int w=squarewidth;
                
                g.setColor (Color.gray);
		g.fillRect (x, y,squarewidth - 1, squareheight - 1);
                
              
                if(tmp != null){
                tmp.drawMan(g,x,y,w,h);   
             
                  
                    
                }
             }
	}
    }
}