/*
 * Audin Malmin
 * 4-20-98
 * Java programming assignment 3.
 *
 * Last week I was still throwing around the idea of having each on-screen object
 * running in a seperate thread.  However, java's thread mechanism isn't really up
 * to this.  (I don't know that any thread mechanism is...)  So we've abandoned
 * that idea.
 *
 * This week I've mainly been working on the general layout of our program.
 *
 * We've worked out that we will employ around 6 threads:
 *
 * * Event handling
 * * Local player's Dudes.  (Movement and probably learning.)
 * * Remote player's Dudes.  (Movement and probably learning.)
 * * Temples.  (Animation, mainly.)
 * * Network daemon.  (send out the local movements.  Maybe recieve the incomming.)
 * * Reproduction.  (I haven't decided yet, but this may be handled by its own thread.)
 *
 * On the data structure side of things:
 *
 * * Linked list of local user's Dudes.
 * * Linked list of remote user's Dudes.
 * * Linked list of temples.
 *
 * These three lists are each animated by one of the threads layed out above.
 *
 * * 1024 x 768 2D array of integers.  We may use something like this to
 *   keep track of where people are.  This will help with figuring out which Dude
 *   was clicked on, and also help prevent a moving Dude from running right over
 *   another non-moving Dude.
 *
 ********************************************************************************
 *
 * Below is the second version of my DudeList class.  Two instances of this class
 * handle the local user's and the remote user's Dudes.
 *
 * I have yet to completely figure out how to cordinate access to these lists.  Both
 * the update (movement) processes, the event handling process and perhapse the
 * reproduction process have to be able to access them.  Currently I'm thinking that
 * I can suspend the update process, update the list, and then resume the process.
 * However I am still working on getting it to work correctly.  (Attached you will
 * find my current trial code.  Depending on one's timing the code works fine.  There
 * is a race conditon somewhere that I have yet to find.
 *
 * This code can be found on my web page.  I will also set up a runnable binary.
 */

import java.awt.event.*;
import java.awt.*;
import java.lang.*;
import java.util.*;
import java.applet.*;

public class ColonyApplet extends Applet {
	public void init() {
		System.out.println("Init\n");
		setLayout(new BorderLayout());
		DrawPanel dp = new DrawPanel();
		add("Center", dp);
	}

	public static void main(String args[]) {
		Frame f = new Frame("wow");
		ColonyApplet drawtest = new ColonyApplet();
		drawtest.init();
		drawtest.start();

		f.add("Center", drawtest);
		f.setSize(640, 480);
		f.show();
	}
}

class DrawPanel extends Panel implements MouseListener, MouseMotionListener {
	DudeList d, c;
	
	public DrawPanel() {
		setBackground(Color.green);
		addMouseMotionListener(this);
		addMouseListener(this);
		d = new DudeList(Color.red);
		c = new DudeList(Color.blue);
	}

	public void mouseDragged(MouseEvent e) {
		e.consume();
//		repaint();
	}

	public void mouseMoved(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	    e.consume();

	}

	public void mouseReleased(MouseEvent e) {
//	    e.consume();

		if(e.isPopupTrigger()) {
			System.out.println("Popup menu");

		} else if (e.getClickCount() > 1) {
			System.out.println("Multiclick");
		} else if (e.getClickCount() == 1) {
			d.add(e.getX(), e.getY());
			c.add((int)(Math.random() * 640), (int)(Math.random() * 480));
		}
	    repaint();
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
	}

    public void paint(Graphics g) {
		for(d.reset(); d.current() != null; d.next()) {
			d.current().draw(g);
		}
		for(c.reset(); c.current() != null; c.next()) {
			c.current().draw(g);
		}
    }
}

class DudeList {
	Dude first;
	Dude curr;
	Dude last;
	Dude previous;

	Color col;

	public DudeList(Color dudecolor) {
		col = dudecolor;
		first = curr = last = null;
	}

	public boolean add(int x_pos, int y_pos) {
		if(first == null) {
			first = curr = last = new Dude(x_pos, y_pos, col);
		} else {
			previous = curr;
			curr = new Dude(x_pos, y_pos, col);
			last.next = curr;
			last = curr;
		}
		return (curr != null);
	}

	public Dude current() {
		return curr;
	}

	public Dude reset() {
		curr = first;
		return curr;
	}

	public Dude next() {
		curr = curr.next;
		return curr;
	}
}

class Dude {
	int x, y;
	Color col;
	Dude next;	

	Dude(int x1, int y1, Color color) {
		int funny;
		x = x1;
		y = y1;
		col = color;
		next = null;
	
		// This "funny" stuff randomly assigns a shade to the new Dude.
		
		if((funny = (int)((Math.random() - 0.5) * 7)) > 0)
			for(; funny > 0; funny--)
			    col = col.brighter();
		else
			for(; funny < 0; funny++)
				col = col.darker();
	}

	void move() {
		int direction = (int)Math.random() * 360;
		int distance  = (int)Math.random() * 50;
	}

	void draw(Graphics g) {
		g.setColor(Color.black);
		g.drawLine(x, y , x, y + 10);
		g.drawLine(x, y + 10, x - 3, y + 17);
		g.drawLine(x, y + 10, x + 3, y + 17);
		g.drawLine(x, y + 2, x - 4, y + 10);
		g.drawLine(x, y + 2, x + 4, y + 10);
		g.setColor(col);
		g.fillOval(x - 4, y - 4, 8, 8);
	}

	public String toString() {
		return ("Dude[col=" + col + ", X=" + x + ", Y=" + y + "]");
	}

}

