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

import java.rmi.*; 
import java.rmi.server.*; 

public class Client extends JFrame implements KeyListener, ClientExports 

{    
    static Image small[]; 
    
    int cellWidth = 30, cellHeight = 30; 
    
    Penguin[] players = new Penguin[100]; 
    
    public Client (int columns, int rows, int x, int y, ServerExports far) {
	
	this.x = x * cellWidth; this.y = y * cellHeight; 
	
	String pictureURL = "http://www.cs.indiana.edu/classes" + 
	    "/a348/CTED/moduleFour/lectures/iceblox/iceblox.gif"; 

	MediaTracker tracker = new MediaTracker(this); 

	Image collection; 

	try { 
	    collection = 
		Toolkit.getDefaultToolkit().getImage(new URL(pictureURL));
	} catch (Exception e) { 
	    collection = 
		Toolkit.getDefaultToolkit().getImage("iceblox.gif");
	}

	tracker.addImage(collection, 0); 

	try { tracker.waitForID(0); } catch (InterruptedException e) { } 

	ImageProducer collectionProducer = collection.getSource(); 

	int smalls = 48; 

	small = new Image[smalls]; 

	int k = 0, i = 0, j = 0; 

	ImageFilter filter; 

	while (k < smalls) {
	    filter = new CropImageFilter(j*30, i*30, 30, 30);   
	    small[k] = 
		createImage(new FilteredImageSource(collectionProducer, 
						    filter)); 
	    tracker.addImage(small[k], 1); 
	    k++; j++; if (j == 8) { j = 0; i++; } 
	}

	try { tracker.waitForID(1); } catch (InterruptedException e) { } 

	this.setSize(columns * cellWidth + cellWidth / 2, 
		     (1 + rows) * cellHeight + cellHeight / 2); 

	addWindowListener(new WindowCloser()); 
	
	addKeyListener(this); 
	
	server = far; 

	getContentPane().add(ceiling = new Surface(columns, rows), "Center"); 
	setTitle("Lab One: The Wrong Trousers (RMI)"); 
	this.show();       
	
    }
    
    ServerExports server; 

    /*****************************
    
    public void register(ServerExports far) throws RemoteException {
	
	// server = far; 
	
	this.id = far.register(this); 

	System.out.println("I have received: " + this.id + " back."); 
	
        far.broadcast(this.id, this.x, this.y, "happy to be here"); 
	
    }
    
    ******************************/ 

    public void update(int player, int x, int y, String action) {
	
	System.out.println("Player " + this.id + " updated by player " + 
			   player + " with (" + x + ", " + y + ") " + action); 
	
	
	if (players[player] == null) {
	    players[player] = 
		new Penguin(x, y, 
			    30, 30, 
			    "(" + this.id + ", " + player + ")"); 
	    
	    players[player].placeIn(this); 
	    
	} else { 
            players[player].perform(action);
	    // players[player].moveTo(x, y); 
	} 
	
	repaint(); 
	
    }
    
    int id = -1, x, y; 
    
    Surface ceiling; 
    
    public void keyTyped(KeyEvent e) { }
    
    public void keyPressed(KeyEvent e) { 
	
	int val = e.getKeyCode(); 

	try { 

	    System.out.println("I am here!!"); 

	    
	    if (val == 38) {
		server.broadcast(id, x, --y, "up"); 
	    } else if (val == 39) {
		server.broadcast(id, ++x, y, "right"); 
	    } else if (val == 40) {
		server.broadcast(id, x, ++y, "down"); 
	    } else if (val == 37) {
		server.broadcast(id, --x, y, "left"); 
	    } 
	    
	} catch (Exception ex) { 
	    System.out.println("This is the error: " + e); 
        } 

    }
    
    public void keyReleased(KeyEvent e) { }
    
    private class WindowCloser extends WindowAdapter { 
	public void windowClosing(WindowEvent event) { 
	    System.exit(0); 
	}
    }
    
    public class Surface extends JPanel {
	
	int columns, rows; 
	
	Surface(int columns, int rows) { 
	    this.columns = columns; 
	    this.rows = rows; 
	}
	
	int fontSize = 10; // in pixels 
	
	Font digitsFont = 
	    new Font("Serif", Font.PLAIN, fontSize); 
	
	public void paintComponent(Graphics g) {
	    
	    super.paintComponent(g); 
	    
	    ((Graphics2D)g).setFont(digitsFont); 
	    
	    g.setColor(Color.black); 
	    g.fillRect(0, 0, columns * cellWidth, rows * cellHeight); 
	    
	    g.setColor(Color.gray); 
	    
	    for (int i = 0; i <= rows; i++) {
		g.drawLine(0, 
                           i * cellHeight, 
                           columns * cellWidth, 
                           i * cellHeight); 
	    }
	    
	    for (int i = 0; i < columns; i++) {
		g.drawLine(i * cellWidth, 
                           0, 
                           i * cellWidth, 
                           rows * cellHeight); 
	    } 
	    
	    g.drawRect(0, 0, cellWidth * columns, cellHeight * rows); 
	    
	    g.setColor(Color.gray); 
	    
	    for (int j = 0; j < columns; j = j + 1) 
		for (int i = 0; i < rows; i++)  
		    g.drawString(i + ", " + j, 
				 j * cellWidth + 2, 
				 i * cellHeight + fontSize); 	   
	    
	    
	    System.out.println("Yeah, right!"); 
	    
	    for (int i = 0; i < players.length; i++)
		if (players[i] != null) 
		    players[i].draw(g, i == id); 	    
	    
	}
	
    }
    

    public static void main(String[] args) {
	
	try {
	    
	    
	    ServerExports far = 
		(ServerExports)Naming.lookup("rmi://" + 
					     args[0] + 
					     ":" + 
					     args[1] + 
					     "/Dirac");
	    
	    int cols = 10, rows = 10; 
	    
	    Client here = new Client
		(cols, 
		 rows, 
		 (int)(Math.random() * cols), 
		 (int)(Math.random() * rows), 
		 far);
	    	    
	    UnicastRemoteObject.exportObject(here); 
	    
	    // here.register(far); 

	    here.id = far.register(here); 

	    System.out.println("I have received: " + here.id + " back."); 
	
	    far.broadcast(here.id, here.x, here.y, "happy to be here");
	    
	} catch (Exception e) {
	    System.out.println("Error in client..." + e); 
	    e.printStackTrace();
	}
    }
    
    

    
    
}

