import java.util.ArrayList;
import java.lang.annotation.*;
import java.applet.Applet;
import java.awt.Graphics;
import java.util.ArrayList;
import java.awt.Color;
import java.awt.*;
import java.awt.event.*;

public class JaDEN_App extends JaDEN implements emDependent{
	public int x = 9;
	@EDEN_DESCRIPTION(definition = "(x * 3)")
	private int y = (x * 3);
	@EDEN_DESCRIPTION(definition = "new Rect(mouseX, mouseY, 100, 100)")
	private emRect r1 = new emRect(new Rect(mouseX, mouseY, 100, 100));
	@EDEN_DESCRIPTION(definition = "new Rect(mouseX, mouseY, 50, 50)")
	private emRect r2 = new emRect(new Rect(mouseX, mouseY, 50, 50));
	@EDEN_DESCRIPTION(definition = "new Line(0, 0, mouseX, mouseY)")
	private emLine l1 = new emLine(new Line(0, 0, mouseX, mouseY));
	@EDEN_DESCRIPTION(definition = "new Line(0, 0, (mouseX + 100), mouseY)")
	private emLine l2 = new emLine(new Line(0, 0, (mouseX + 100), mouseY));
	@EDEN_DESCRIPTION(definition = "new Line(0, 0, (mouseX + 100), (mouseY + 100))")
	private emLine l3 = new emLine(new Line(0, 0, (mouseX + 100), (mouseY + 100)));
	@EDEN_DESCRIPTION(definition = "new Line(0, 0, mouseX, (mouseY + 100))")
	private emLine l4 = new emLine(new Line(0, 0, mouseX, (mouseY + 100)));
	@EDEN_DESCRIPTION(definition = "new Group()")
	private emGroup g1 = new emGroup(new Group());
	@EDEN_DESCRIPTION(definition = "new Group()")
	private emGroup agents = new emGroup(new Group());
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public void init(){
		super.init();
		g1.item.addShape(r1.item);
		g1.item.addShape(r2.item);
		picture.add(g1);
		picture.add(agents);
		picture.add(l1);
		picture.add(l2);
		picture.add(l3);
		picture.add(l4);

	}

	public void paint(Graphics g){
		super.paint(g);
		ArrayList list;
		list = agents.item.getShapes();
		for(int i = 0; (i < list.size()); i = (i + 1)){
			((emAgent) (list.get(i))).thrust();

		}


	}

	private void mouseClickX_updated(){
		Agent ag;
		ag = new emAgent(new Agent(0, mouseX, mouseY)).item;
		agents.item.addShape(ag);

	}

	public JaDEN_App(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	


	public JaDEN_App registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("mouseX")){em_updateR1(); em_updateR2(); em_updateL1(); em_updateL2(); em_updateL3(); em_updateL4(); }
		else if(property.equals("mouseY")){em_updateR1(); em_updateR2(); em_updateL1(); em_updateL2(); em_updateL3(); em_updateL4(); }
		else if(property.equals("mouseClickX")){mouseClickX_updated();}
		else if(property.equals("mouseClickY")){}
		else if(property.equals("mousePressed")){}
		else if(property.equals("picture")){}
		emTriggerUpdateJaDEN_App(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateJaDEN_App(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticJaDEN_App(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	public void setX(int em_x){
		if(x != em_x){
			x = em_x;
			em_updateY();
			emTriggerUpdateJaDEN_App("x");
			emTriggerUpdateJaDEN_App("JaDEN_App.x");
		}
	}
	public int getX(){
		return x;
	}
	private void em_updateY(){
		try{
			int new_y = (x * 3);
			setY(new_y);
		}catch(Exception e){
			y = 0;
		}
	}
	public void setY(int em_y){
		if(y != em_y){
			y = em_y;
			emTriggerUpdateJaDEN_App("y");
			emTriggerUpdateJaDEN_App("JaDEN_App.y");
		}
	}
	public int getY(){
		return y;
	}
	private void em_updateR1(){
		try{
			emRect new_r1 = new emRect(new Rect(mouseX, mouseY, 100, 100));
			setR1(new_r1.item);
		}catch(Exception e){
			r1.item = null;
		}
	}
	public void setR1(Rect em_r1){
		if(r1.item == null || !r1.item.equals(em_r1)){
			r1.item = em_r1;
			emTriggerUpdateJaDEN_App("r1");
			emTriggerUpdateJaDEN_App("JaDEN_App.r1");
		}
	}
	public Rect getR1(){
		return r1.item;
	}
	private void em_updateR2(){
		try{
			emRect new_r2 = new emRect(new Rect(mouseX, mouseY, 50, 50));
			setR2(new_r2.item);
		}catch(Exception e){
			r2.item = null;
		}
	}
	public void setR2(Rect em_r2){
		if(r2.item == null || !r2.item.equals(em_r2)){
			r2.item = em_r2;
			emTriggerUpdateJaDEN_App("r2");
			emTriggerUpdateJaDEN_App("JaDEN_App.r2");
		}
	}
	public Rect getR2(){
		return r2.item;
	}
	private void em_updateL1(){
		try{
			emLine new_l1 = new emLine(new Line(0, 0, mouseX, mouseY));
			setL1(new_l1.item);
		}catch(Exception e){
			l1.item = null;
		}
	}
	public void setL1(Line em_l1){
		if(l1.item == null || !l1.item.equals(em_l1)){
			l1.item = em_l1;
			emTriggerUpdateJaDEN_App("l1");
			emTriggerUpdateJaDEN_App("JaDEN_App.l1");
		}
	}
	public Line getL1(){
		return l1.item;
	}
	private void em_updateL2(){
		try{
			emLine new_l2 = new emLine(new Line(0, 0, (mouseX + 100), mouseY));
			setL2(new_l2.item);
		}catch(Exception e){
			l2.item = null;
		}
	}
	public void setL2(Line em_l2){
		if(l2.item == null || !l2.item.equals(em_l2)){
			l2.item = em_l2;
			emTriggerUpdateJaDEN_App("l2");
			emTriggerUpdateJaDEN_App("JaDEN_App.l2");
		}
	}
	public Line getL2(){
		return l2.item;
	}
	private void em_updateL3(){
		try{
			emLine new_l3 = new emLine(new Line(0, 0, (mouseX + 100), (mouseY + 100)));
			setL3(new_l3.item);
		}catch(Exception e){
			l3.item = null;
		}
	}
	public void setL3(Line em_l3){
		if(l3.item == null || !l3.item.equals(em_l3)){
			l3.item = em_l3;
			emTriggerUpdateJaDEN_App("l3");
			emTriggerUpdateJaDEN_App("JaDEN_App.l3");
		}
	}
	public Line getL3(){
		return l3.item;
	}
	private void em_updateL4(){
		try{
			emLine new_l4 = new emLine(new Line(0, 0, mouseX, (mouseY + 100)));
			setL4(new_l4.item);
		}catch(Exception e){
			l4.item = null;
		}
	}
	public void setL4(Line em_l4){
		if(l4.item == null || !l4.item.equals(em_l4)){
			l4.item = em_l4;
			emTriggerUpdateJaDEN_App("l4");
			emTriggerUpdateJaDEN_App("JaDEN_App.l4");
		}
	}
	public Line getL4(){
		return l4.item;
	}
	private void em_updateG1(){
		try{
			emGroup new_g1 = new emGroup(new Group());
			setG1(new_g1.item);
		}catch(Exception e){
			g1.item = null;
		}
	}
	public void setG1(Group em_g1){
		if(g1.item == null || !g1.item.equals(em_g1)){
			g1.item = em_g1;
			emTriggerUpdateJaDEN_App("g1");
			emTriggerUpdateJaDEN_App("JaDEN_App.g1");
		}
	}
	public Group getG1(){
		return g1.item;
	}
	private void em_updateAgents(){
		try{
			emGroup new_agents = new emGroup(new Group());
			setAgents(new_agents.item);
		}catch(Exception e){
			agents.item = null;
		}
	}
	public void setAgents(Group em_agents){
		if(agents.item == null || !agents.item.equals(em_agents)){
			agents.item = em_agents;
			emTriggerUpdateJaDEN_App("agents");
			emTriggerUpdateJaDEN_App("JaDEN_App.agents");
		}
	}
	public Group getAgents(){
		return agents.item;
	}

}
class Agent extends Group implements emDependent{
	private static double speed;
	private double health = 1.0;
	@EDEN_DESCRIPTION(definition = "(health > 0)")
	private boolean isAlive = (health > 0);
	private double x = 0;
	private double y = 0;
	@EDEN_DESCRIPTION(definition = "((int) (x))")
	private int ix = ((int) (x));
	@EDEN_DESCRIPTION(definition = "((int) (y))")
	private int iy = ((int) (y));
	private int id = 0;
	private int heading = 30;
	private int fov = 25;
	private int range = 100;
	@EDEN_DESCRIPTION(definition = "toRadians(heading)")
	private double headingRad = toRadians(heading);
	@EDEN_DESCRIPTION(definition = "toRadians((heading + fov))")
	private double fovUpRad = toRadians((heading + fov));
	@EDEN_DESCRIPTION(definition = "toRadians((heading - fov))")
	private double fovDownRad = toRadians((heading - fov));
	@EDEN_DESCRIPTION(definition = "new Rect((ix - 5), (iy - 5), 10, 10, Color.BLACK)")
	private emRect body = new emRect(new Rect((ix - 5), (iy - 5), 10, 10, Color.BLACK));
	@EDEN_DESCRIPTION(definition = "new Text((ix - 5), (iy - 10), String.valueOf(id))")
	private emText name = new emText(new Text((ix - 5), (iy - 10), String.valueOf(id)));
	@EDEN_DESCRIPTION(definition = "new Line(ix, iy, ((int) ((ix + (range * Math.cos(fovUpRad))))), ((int) ((y - (range * Math.sin(fovUpRad))))))")
	private emLine fovUpLine = new emLine(new Line(ix, iy, ((int) ((ix + (range * Math.cos(fovUpRad))))), ((int) ((y - (range * Math.sin(fovUpRad)))))));
	@EDEN_DESCRIPTION(definition = "new Line(ix, iy, ((int) ((ix + (range * Math.cos(fovDownRad))))), ((int) ((y - (range * Math.sin(fovDownRad))))))")
	private emLine fovDownLine = new emLine(new Line(ix, iy, ((int) ((ix + (range * Math.cos(fovDownRad))))), ((int) ((y - (range * Math.sin(fovDownRad)))))));
	@EDEN_DESCRIPTION(definition = "new Arc((ix - range), (iy - range), (range * 2), (range * 2), (heading - fov), (2 * fov))")
	private emArc fovArc = new emArc(new Arc((ix - range), (iy - range), (range * 2), (range * 2), (heading - fov), (2 * fov)));
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public Agent(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Agent(int i, int a, int b){
		super();
		picture.add(body);
		picture.add(name);
		picture.add(fovUpLine);
		picture.add(fovDownLine);
		picture.add(fovArc);
		setId(i);
		setX(a);
		setY(b);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	private static double toRadians(int deg){
		return (deg * (Math.PI / 180));

	}

	public void changeHeading(int h){
		setHeading((heading + h));

	}

	public void thrust(){
		setX((x + (speed * Math.cos(headingRad))));
		setY((y - (speed * Math.sin(headingRad))));

	}

	public void rotateLeft(){
		rotate(5);

	}

	public void rotateRight(){
		rotate((0 - 5));

	}

	public void rotate(int r){
		setHeading((heading + r));

	}


	public Agent registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("picture")){}
		emTriggerUpdateAgent(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateAgent(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticAgent(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	private void setHealth(double em_health){
		if(health != em_health){
			health = em_health;
			em_updateIsAlive();
			emTriggerUpdateAgent("health");
			emTriggerUpdateAgent("Agent.health");
		}
	}
	private void em_updateIsAlive(){
		try{
			boolean new_isAlive = (health > 0);
			setIsAlive(new_isAlive);
		}catch(Exception e){
			isAlive = false;
		}
	}
	public void setIsAlive(boolean em_isAlive){
		if(isAlive != em_isAlive){
			isAlive = em_isAlive;
			emTriggerUpdateAgent("isAlive");
			emTriggerUpdateAgent("Agent.isAlive");
		}
	}
	public boolean getIsAlive(){
		return isAlive;
	}
	private void setX(double em_x){
		if(x != em_x){
			x = em_x;
			em_updateIx();
			emTriggerUpdateAgent("x");
			emTriggerUpdateAgent("Agent.x");
		}
	}
	private void setY(double em_y){
		if(y != em_y){
			y = em_y;
			em_updateIy();
			em_updateFovUpLine();
			em_updateFovDownLine();
			emTriggerUpdateAgent("y");
			emTriggerUpdateAgent("Agent.y");
		}
	}
	private void em_updateIx(){
		try{
			int new_ix = ((int) (x));
			setIx(new_ix);
		}catch(Exception e){
			ix = 0;
		}
	}
	private void setIx(int em_ix){
		if(ix != em_ix){
			ix = em_ix;
			em_updateBody();
			em_updateName();
			em_updateFovUpLine();
			em_updateFovDownLine();
			em_updateFovArc();
			emTriggerUpdateAgent("ix");
			emTriggerUpdateAgent("Agent.ix");
		}
	}
	private void em_updateIy(){
		try{
			int new_iy = ((int) (y));
			setIy(new_iy);
		}catch(Exception e){
			iy = 0;
		}
	}
	private void setIy(int em_iy){
		if(iy != em_iy){
			iy = em_iy;
			em_updateBody();
			em_updateName();
			em_updateFovUpLine();
			em_updateFovDownLine();
			em_updateFovArc();
			emTriggerUpdateAgent("iy");
			emTriggerUpdateAgent("Agent.iy");
		}
	}
	private void setId(int em_id){
		if(id != em_id){
			id = em_id;
			em_updateName();
			emTriggerUpdateAgent("id");
			emTriggerUpdateAgent("Agent.id");
		}
	}
	private void setHeading(int em_heading){
		if(heading != em_heading){
			heading = em_heading;
			em_updateHeadingRad();
			em_updateFovUpRad();
			em_updateFovDownRad();
			em_updateFovArc();
			emTriggerUpdateAgent("heading");
			emTriggerUpdateAgent("Agent.heading");
		}
	}
	private void setFov(int em_fov){
		if(fov != em_fov){
			fov = em_fov;
			em_updateFovUpRad();
			em_updateFovDownRad();
			em_updateFovArc();
			emTriggerUpdateAgent("fov");
			emTriggerUpdateAgent("Agent.fov");
		}
	}
	private void setRange(int em_range){
		if(range != em_range){
			range = em_range;
			em_updateFovUpLine();
			em_updateFovDownLine();
			em_updateFovArc();
			emTriggerUpdateAgent("range");
			emTriggerUpdateAgent("Agent.range");
		}
	}
	private void em_updateHeadingRad(){
		try{
			double new_headingRad = toRadians(heading);
			setHeadingRad(new_headingRad);
		}catch(Exception e){
			headingRad = 0;
		}
	}
	private void setHeadingRad(double em_headingRad){
		if(headingRad != em_headingRad){
			headingRad = em_headingRad;
			emTriggerUpdateAgent("headingRad");
			emTriggerUpdateAgent("Agent.headingRad");
		}
	}
	private void em_updateFovUpRad(){
		try{
			double new_fovUpRad = toRadians((heading + fov));
			setFovUpRad(new_fovUpRad);
		}catch(Exception e){
			fovUpRad = 0;
		}
	}
	private void setFovUpRad(double em_fovUpRad){
		if(fovUpRad != em_fovUpRad){
			fovUpRad = em_fovUpRad;
			em_updateFovUpLine();
			emTriggerUpdateAgent("fovUpRad");
			emTriggerUpdateAgent("Agent.fovUpRad");
		}
	}
	private void em_updateFovDownRad(){
		try{
			double new_fovDownRad = toRadians((heading - fov));
			setFovDownRad(new_fovDownRad);
		}catch(Exception e){
			fovDownRad = 0;
		}
	}
	private void setFovDownRad(double em_fovDownRad){
		if(fovDownRad != em_fovDownRad){
			fovDownRad = em_fovDownRad;
			em_updateFovDownLine();
			emTriggerUpdateAgent("fovDownRad");
			emTriggerUpdateAgent("Agent.fovDownRad");
		}
	}
	private void em_updateBody(){
		try{
			emRect new_body = new emRect(new Rect((ix - 5), (iy - 5), 10, 10, Color.BLACK));
			setBody(new_body.item);
		}catch(Exception e){
			body.item = null;
		}
	}
	private void setBody(Rect em_body){
		if(body.item == null || !body.item.equals(em_body)){
			body.item = em_body;
			emTriggerUpdateAgent("body");
			emTriggerUpdateAgent("Agent.body");
		}
	}
	private void em_updateName(){
		try{
			emText new_name = new emText(new Text((ix - 5), (iy - 10), String.valueOf(id)));
			setName(new_name.item);
		}catch(Exception e){
			name.item = null;
		}
	}
	private void setName(Text em_name){
		if(name.item == null || !name.item.equals(em_name)){
			name.item = em_name;
			emTriggerUpdateAgent("name");
			emTriggerUpdateAgent("Agent.name");
		}
	}
	private void em_updateFovUpLine(){
		try{
			emLine new_fovUpLine = new emLine(new Line(ix, iy, ((int) ((ix + (range * Math.cos(fovUpRad))))), ((int) ((y - (range * Math.sin(fovUpRad)))))));
			setFovUpLine(new_fovUpLine.item);
		}catch(Exception e){
			fovUpLine.item = null;
		}
	}
	private void setFovUpLine(Line em_fovUpLine){
		if(fovUpLine.item == null || !fovUpLine.item.equals(em_fovUpLine)){
			fovUpLine.item = em_fovUpLine;
			emTriggerUpdateAgent("fovUpLine");
			emTriggerUpdateAgent("Agent.fovUpLine");
		}
	}
	private void em_updateFovDownLine(){
		try{
			emLine new_fovDownLine = new emLine(new Line(ix, iy, ((int) ((ix + (range * Math.cos(fovDownRad))))), ((int) ((y - (range * Math.sin(fovDownRad)))))));
			setFovDownLine(new_fovDownLine.item);
		}catch(Exception e){
			fovDownLine.item = null;
		}
	}
	private void setFovDownLine(Line em_fovDownLine){
		if(fovDownLine.item == null || !fovDownLine.item.equals(em_fovDownLine)){
			fovDownLine.item = em_fovDownLine;
			emTriggerUpdateAgent("fovDownLine");
			emTriggerUpdateAgent("Agent.fovDownLine");
		}
	}
	private void em_updateFovArc(){
		try{
			emArc new_fovArc = new emArc(new Arc((ix - range), (iy - range), (range * 2), (range * 2), (heading - fov), (2 * fov)));
			setFovArc(new_fovArc.item);
		}catch(Exception e){
			fovArc.item = null;
		}
	}
	private void setFovArc(Arc em_fovArc){
		if(fovArc.item == null || !fovArc.item.equals(em_fovArc)){
			fovArc.item = em_fovArc;
			emTriggerUpdateAgent("fovArc");
			emTriggerUpdateAgent("Agent.fovArc");
		}
	}

}
class JaDEN extends Applet implements MouseListener, MouseMotionListener, emDependent{
	public int mouseX = 0;
	public int mouseY = 0;
	public int mouseClickX = 0;
	public int mouseClickY = 0;
	public boolean mousePressed = false;
	public ArrayList picture = new ArrayList();
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public void init(){
		addMouseListener(this);
		addMouseMotionListener(this);
		System.out.println("JaDEN Applet Initialised");

	}

	public void paint(Graphics g){
		for(int i = 0; (i < picture.size()); i = (i + 1)){
			((emShape) (picture.get(i))).draw(g);

		}


	}

	public void mouseEntered(MouseEvent e){

	}

	public void mouseExited(MouseEvent e){

	}

	public void mouseClicked(MouseEvent e){
		setMouseClickX(e.getX());
		setMouseClickY(e.getY());
		setMousePressed(true);
		repaint();

	}

	public void mousePressed(MouseEvent e){

	}

	public void mouseReleased(MouseEvent e){

	}

	public void mouseMoved(MouseEvent e){
		setMouseX(e.getX());
		setMouseY(e.getY());
		repaint();

	}

	public void mouseDragged(MouseEvent e){

	}

	public JaDEN(){
		super();

	
		Evaluator.addInstance(this);
}	


	public JaDEN registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("g")){}
		else if(property.equals("a")){}
		else if(property.equals("ml")){}
		else if(property.equals("mml")){}
		else if(property.equals("kl")){}
		else if(property.equals("back")){}
		else if(property.equals("forward")){}
		else if(property.equals("code")){}
		else if(property.equals("WIDTH")){}
		else if(property.equals("HEIGHT")){}
		emTriggerUpdateJaDEN(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateJaDEN(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticJaDEN(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	public void setMouseX(int em_mouseX){
		if(mouseX != em_mouseX){
			mouseX = em_mouseX;
			emTriggerUpdateJaDEN("mouseX");
			emTriggerUpdateJaDEN("JaDEN.mouseX");
		}
	}
	public int getMouseX(){
		return mouseX;
	}
	public void setMouseY(int em_mouseY){
		if(mouseY != em_mouseY){
			mouseY = em_mouseY;
			emTriggerUpdateJaDEN("mouseY");
			emTriggerUpdateJaDEN("JaDEN.mouseY");
		}
	}
	public int getMouseY(){
		return mouseY;
	}
	public void setMouseClickX(int em_mouseClickX){
		if(mouseClickX != em_mouseClickX){
			mouseClickX = em_mouseClickX;
			emTriggerUpdateJaDEN("mouseClickX");
			emTriggerUpdateJaDEN("JaDEN.mouseClickX");
		}
	}
	public int getMouseClickX(){
		return mouseClickX;
	}
	public void setMouseClickY(int em_mouseClickY){
		if(mouseClickY != em_mouseClickY){
			mouseClickY = em_mouseClickY;
			emTriggerUpdateJaDEN("mouseClickY");
			emTriggerUpdateJaDEN("JaDEN.mouseClickY");
		}
	}
	public int getMouseClickY(){
		return mouseClickY;
	}
	public void setMousePressed(boolean em_mousePressed){
		if(mousePressed != em_mousePressed){
			mousePressed = em_mousePressed;
			emTriggerUpdateJaDEN("mousePressed");
			emTriggerUpdateJaDEN("JaDEN.mousePressed");
		}
	}
	public boolean getMousePressed(){
		return mousePressed;
	}
	public void setPicture(ArrayList em_picture){
		if(picture == null || !picture.equals(em_picture)){
			picture = em_picture;
			emTriggerUpdateJaDEN("picture");
			emTriggerUpdateJaDEN("JaDEN.picture");
		}
	}
	public ArrayList getPicture(){
		return picture;
	}

}
class Group extends Shape implements emDependent{
	public ArrayList picture = new ArrayList();
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public void addShape(Shape shape){
		picture.add(shape);

	}

	public void draw(Graphics g){
		for(int i = 0; (i < picture.size()); i = (i + 1)){
			((emShape) (picture.get(i))).draw(g);

		}


	}

	public ArrayList getShapes(){
		return picture;

	}

	public Group(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	


	public Group registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("x1")){}
		else if(property.equals("x2")){}
		else if(property.equals("y1")){}
		else if(property.equals("y2")){}
		else if(property.equals("color")){}
		emTriggerUpdateGroup(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateGroup(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticGroup(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	public void setPicture(ArrayList em_picture){
		if(picture == null || !picture.equals(em_picture)){
			picture = em_picture;
			emTriggerUpdateGroup("picture");
			emTriggerUpdateGroup("Group.picture");
		}
	}
	public ArrayList getPicture(){
		return picture;
	}

}
class Shape extends Object implements emDependent{
	public int x1 = 0;
	public int x2 = 0;
	public int y1 = 0;
	public int y2 = 0;
	public Color color;
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public Shape(){
		super();

	
		Evaluator.addInstance(this);
}	

	public Shape(int a, int b, int c, int d){
		super();
		setX1(a);
		setY1(b);
		setX2(c);
		setY2(d);

	
		Evaluator.addInstance(this);
}	

	public Shape(int a, int b, int c, int d, Color col){
		super();
		setX1(a);
		setY1(b);
		setX2(c);
		setY2(d);
		setColor(col);

	
		Evaluator.addInstance(this);
}	

	public void draw(Graphics g){

	}

	public String toString(){
		return (("Shape(" + (x1 + (", " + (y1 + (", " + (x2 + (", " + (x2 + (", " + color))))))))) + ")");

	}


	public Shape registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		emTriggerUpdateShape(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateShape(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticShape(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	public void setX1(int em_x1){
		if(x1 != em_x1){
			x1 = em_x1;
			emTriggerUpdateShape("x1");
			emTriggerUpdateShape("Shape.x1");
		}
	}
	public int getX1(){
		return x1;
	}
	public void setX2(int em_x2){
		if(x2 != em_x2){
			x2 = em_x2;
			emTriggerUpdateShape("x2");
			emTriggerUpdateShape("Shape.x2");
		}
	}
	public int getX2(){
		return x2;
	}
	public void setY1(int em_y1){
		if(y1 != em_y1){
			y1 = em_y1;
			emTriggerUpdateShape("y1");
			emTriggerUpdateShape("Shape.y1");
		}
	}
	public int getY1(){
		return y1;
	}
	public void setY2(int em_y2){
		if(y2 != em_y2){
			y2 = em_y2;
			emTriggerUpdateShape("y2");
			emTriggerUpdateShape("Shape.y2");
		}
	}
	public int getY2(){
		return y2;
	}
	public void setColor(Color em_color){
		if(color == null || !color.equals(em_color)){
			color = em_color;
			emTriggerUpdateShape("color");
			emTriggerUpdateShape("Shape.color");
		}
	}
	public Color getColor(){
		return color;
	}

}
class Rect extends Shape implements emDependent{
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public Rect(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Rect(int a, int b, int c, int d){
		super(a, b, c, d);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Rect(int a, int b, int c, int d, Color col){
		super(a, b, c, d, col);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public void draw(Graphics g){
		if((color == null)) g.drawRect(x1, y1, x2, y2);
		else {
			g.setColor(color);
			g.fillRect(x1, y1, x2, y2);

		}


	}

	public String toString(){
		return (("Rect(" + (x1 + (", " + (y1 + (", " + (x2 + (", " + (x2 + (", " + color))))))))) + ")");

	}


	public Rect registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("x1")){}
		else if(property.equals("x2")){}
		else if(property.equals("y1")){}
		else if(property.equals("y2")){}
		else if(property.equals("color")){}
		emTriggerUpdateRect(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateRect(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticRect(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}

}
class Arc extends Shape implements emDependent{
	public int startAngle = 0;
	public int endAngle = 0;
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public Arc(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Arc(int a, int b, int c, int d, int as, int ae){
		super(a, b, c, d);
		setStartAngle(as);
		setEndAngle(ae);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Arc(int a, int b, int c, int d, int as, int ae, Color col){
		super(a, b, c, d, col);
		setStartAngle(as);
		setEndAngle(ae);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public void draw(Graphics g){
		g.setColor(Color.BLACK);
		if((color == null)) g.drawArc(x1, y1, x2, y2, startAngle, endAngle);
		else {
			g.setColor(color);
			g.fillArc(x1, y1, x2, y2, startAngle, endAngle);

		}


	}

	public String toString(){
		return (("Arc(" + (x1 + (", " + (y1 + (", " + (x2 + (", " + (x2 + (", " + (startAngle + (", " + (endAngle + (", " + color))))))))))))) + ")");

	}


	public Arc registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("x1")){}
		else if(property.equals("x2")){}
		else if(property.equals("y1")){}
		else if(property.equals("y2")){}
		else if(property.equals("color")){}
		emTriggerUpdateArc(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateArc(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticArc(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	public void setStartAngle(int em_startAngle){
		if(startAngle != em_startAngle){
			startAngle = em_startAngle;
			emTriggerUpdateArc("startAngle");
			emTriggerUpdateArc("Arc.startAngle");
		}
	}
	public int getStartAngle(){
		return startAngle;
	}
	public void setEndAngle(int em_endAngle){
		if(endAngle != em_endAngle){
			endAngle = em_endAngle;
			emTriggerUpdateArc("endAngle");
			emTriggerUpdateArc("Arc.endAngle");
		}
	}
	public int getEndAngle(){
		return endAngle;
	}

}
class Text extends Shape implements emDependent{
	public String label;
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public Text(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Text(int a, int b, String str){
		super(a, b, 0, 0);
		setLabel(str);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public void draw(Graphics g){
		g.setColor(Color.BLACK);
		g.drawString(label, x1, y1);

	}

	public String toString(){
		return (("Text(" + (x1 + (", " + (y1 + (", \"" + label))))) + "\")");

	}


	public Text registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("x1")){}
		else if(property.equals("x2")){}
		else if(property.equals("y1")){}
		else if(property.equals("y2")){}
		else if(property.equals("color")){}
		emTriggerUpdateText(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateText(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticText(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}
	public void setLabel(String em_label){
		if(label == null || !label.equals(em_label)){
			label = em_label;
			emTriggerUpdateText("label");
			emTriggerUpdateText("Text.label");
		}
	}
	public String getLabel(){
		return label;
	}

}
class Line extends Shape implements emDependent{
	private ArrayList<emDependent> emDependents = new ArrayList<emDependent>();
	private static ArrayList<emDependent> emDependentsStatic = new ArrayList<emDependent>();

	public Line(){
		super();

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Line(int a, int b, int c, int d){
		super(a, b, c, d);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public Line(int a, int b, int c, int d, Color col){
		super(a, b, c, d, col);

	
		super.emAddDependent(this);
		Evaluator.addInstance(this);
}	

	public void draw(Graphics g){
		g.setColor(color);
		g.drawLine(x1, y1, x2, y2);

	}

	public String toString(){
		return (("Line(" + (x1 + (", " + (y1 + (", " + (x2 + (", " + (x2 + (", " + color))))))))) + ")");

	}


	public Line registerDependent(emDependent depend){
		emDependents.add(depend);
		return this;
	}

	public void emAddDependent(emDependent depend){
		emDependents.add(depend);
	}

	public void emUpdate(Object obj, String property) {
		if(property.equals("x1")){}
		else if(property.equals("x2")){}
		else if(property.equals("y1")){}
		else if(property.equals("y2")){}
		else if(property.equals("color")){}
		emTriggerUpdateLine(property);
	}

	public void emUpdate(String property) {
	}

	private void emTriggerUpdateLine(String property){
		for(int i = 0; i < emDependents.size(); i++){
			emDependents.get(i).emUpdate(this, property);
		}
	}

	public static void emTriggerUpdateStaticLine(String property){
		for(int i = 0; i < emDependentsStatic.size(); i++){
			emDependentsStatic.get(i).emUpdate(property);
		}
	}

}

//Interface for classes to send / receive variable update events
interface emDependent{
	public void emUpdate(String property);
	public void emUpdate(Object obj, String property);
}

//Wrapper classes for all objects who are the results of dependencies
class emRect extends emShape{
	public Rect item;

	public emRect (Rect obj){
		 super(obj);
		 item = obj;
	}

	public emRect (){}
	public void draw(Graphics g){item.draw(g);}
	public String toString(){return item.toString();}
}
class emShape extends Object{
	public Shape item;

	public emShape (Shape obj){
		 super();
		 item = obj;
	}

	public emShape (){}
	public void draw(Graphics g){item.draw(g);}
	public String toString(){return item.toString();}
	public  void  setX1(int obj){item.setX1(obj);}
	public int getX1(){return item.getX1();}
	public  void  setX2(int obj){item.setX2(obj);}
	public int getX2(){return item.getX2();}
	public  void  setY1(int obj){item.setY1(obj);}
	public int getY1(){return item.getY1();}
	public  void  setY2(int obj){item.setY2(obj);}
	public int getY2(){return item.getY2();}
	public  void  setColor(Color obj){item.setColor(obj);}
	public Color getColor(){return item.getColor();}
}
class emGroup extends emShape{
	public Group item;

	public emGroup (Group obj){
		 super(obj);
		 item = obj;
	}

	public emGroup (){}
	public void addShape(Shape shape){item.addShape(shape);}
	public void draw(Graphics g){item.draw(g);}
	public ArrayList getShapes(){return item.getShapes();}
	public  void  setPicture(ArrayList obj){item.setPicture(obj);}
	public ArrayList getPicture(){return item.getPicture();}
}
class emAgent extends emGroup{
	public Agent item;

	public emAgent (Agent obj){
		 super(obj);
		 item = obj;
	}

	public emAgent (){}
	public void changeHeading(int h){item.changeHeading(h);}
	public void thrust(){item.thrust();}
	public void rotateLeft(){item.rotateLeft();}
	public void rotateRight(){item.rotateRight();}
	public void rotate(int r){item.rotate(r);}
	public  void  setIsAlive(boolean obj){item.setIsAlive(obj);}
	public boolean getIsAlive(){return item.getIsAlive();}
}
class emArc extends emShape{
	public Arc item;

	public emArc (Arc obj){
		 super(obj);
		 item = obj;
	}

	public emArc (){}
	public void draw(Graphics g){item.draw(g);}
	public String toString(){return item.toString();}
	public  void  setStartAngle(int obj){item.setStartAngle(obj);}
	public int getStartAngle(){return item.getStartAngle();}
	public  void  setEndAngle(int obj){item.setEndAngle(obj);}
	public int getEndAngle(){return item.getEndAngle();}
}
class emText extends emShape{
	public Text item;

	public emText (Text obj){
		 super(obj);
		 item = obj;
	}

	public emText (){}
	public void draw(Graphics g){item.draw(g);}
	public String toString(){return item.toString();}
	public  void  setLabel(String obj){item.setLabel(obj);}
	public String getLabel(){return item.getLabel();}
}
class emLine extends emShape{
	public Line item;

	public emLine (Line obj){
		 super(obj);
		 item = obj;
	}

	public emLine (){}
	public void draw(Graphics g){item.draw(g);}
	public String toString(){return item.toString();}
}

//Annotation interface for dependency labelling
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface EDEN_DESCRIPTION {
	String definition();
}
