//Vac Man 
//becca shostak
//desma 28
//11.28.04

//A Roomba automated robotic vacuum cleaner attempts to swipe up all the dust
//balls on the floor and avoid the ottoman furniture in the meantime. The vacuum 
//changes direction upon detecting the walls or a piece of furniture. When it
//encounters dust, it swallows the grime up and continues on its journey. Once the 
//dirt has been devoured and Roomba is useless, it shuts itself down.

Room		room;

void setup()
{
	size(300, 300);
	background(255);
	framerate(20);

	room		=	new Room();
}

void draw()
{
	background(255);

	room.vacuum();
	room.draw();
}


// Base class for furniture & dirt

class Disc
{
	PImage			im;

	float			xpos;
	float			ypos;
	float			radius;

	Disc(float x, float y, float r, PImage i)
	{
		xpos		=	x;
		ypos		=	y;
		radius		=	r;
		im              =       i;
	}

	// Returns true if this Disc touches disc d.

	boolean isTouching(Disc d)
	{
		return sq(xpos - d.xpos) + sq(ypos - d.ypos) <= sq(radius + d.radius);
	}

	void draw()
	{  
		image(im, xpos-radius, ypos-radius);
	}
}


class Furniture extends Disc
{
	Furniture(float x, float y)
	{
		super(x, y, 50, loadImage("ottoman.gif"));
	}
}

class Dirt extends Disc
{
	boolean		isPickedUp;

	Dirt(float x, float y)
	{
		super(x, y, 10, loadImage("dirt.gif"));

		isPickedUp		=	false;
	}

	void draw()
	{
		if (!isPickedUp)
		{
			super.draw();
		}
	}
}

// The vacuum cleaner itself

class Roomba extends Disc
{
	float			speed;						// Speed
	float			angle;						// Angle in radians

	Roomba(float x, float y, float s, float a)
	{
		super(x, y, 40, loadImage("roomba.gif"));

		speed	=	s;
		angle	=	a;
	}

	// Moves Roomba according to its current speed and directional
	// angle

	void	move()
	{
		xpos	=	min(300 - radius , max(xpos + speed * cos(angle), radius));
		ypos	=	min(300 - radius, max(ypos + speed * sin(angle), radius));
	}

	void	checkTouchingShortWall()
	{
		if((xpos - radius <= 0) || (xpos + radius >= 300))			// Touching the short wall
			angle	=	PI - angle;
	}

	void	checkTouchingLongWall()
	{
		if ((ypos - radius <= 0) || (ypos + radius >= 300))			// Touching the long wall
			angle	=	2 * PI - angle;
	}

	void	checkTouchingFurniture(Furniture[] furn)
	{
		for (int i = 0; i < furn.length; ++i)
		{
			if (isTouching(furn[i]))
			{
				angle	=	PI + angle + random(0, 1);
				move();
				break;
			}
		}
	}

	void  checkPickingUpDirt(Dirt[] dirt)
	{
		for (int i = 0; i < dirt.length; ++i)
		{
			if (isTouching(dirt[i]))
				dirt[i].isPickedUp		=	true;
		}
	}

	void draw()
	{
		push();
		translate(xpos,ypos);
		rotate(PI/2 + angle);
		image(im,-radius,-radius);
		pop();
	}
}

class Room
{
	Roomba				r;
	Furniture			furn[];
	Dirt				dirt[];

	Room()
	{
		furn			=   new Furniture[2];
		furn[0]			=	new Furniture(150, 150);
		furn[1]			=	new Furniture(450, 150);

		dirt			=   new Dirt[10];
		dirt[0]			=	new Dirt(140, 50);
		dirt[1]			=	new Dirt(80, 200);
		dirt[2]         =   new Dirt(250, 250);
		dirt[3]			=	new Dirt(30, 30);
		dirt[4]			=	new Dirt(40, 100);
		dirt[5]			=	new Dirt(50, 70);
		dirt[6]			=	new Dirt(160, 80);
		dirt[7]			=	new Dirt(280, 140);
		dirt[8]			=	new Dirt(140, 40);
		dirt[9]			=	new Dirt(250,30);

		r				=	new Roomba(300, 150, 8, PI/6);
	}

	void draw()
	{
		rect(0,0,300,300);								        // Draw room boundaries

		for (int i = 0; i < furn.length; ++i)							// Draw furniture
			furn[i].draw();

		for (int i = 0; i < dirt.length; ++i)
			dirt[i].draw();

		r.draw();										// Draw roomba
	}

	void vacuum()
	{
		if (isAllDirtPickedUp())
			return;

		r.checkTouchingShortWall();

		r.checkTouchingLongWall();

		r.checkTouchingFurniture(furn);

		r.checkPickingUpDirt(dirt);

		r.move();
	}

	boolean isAllDirtPickedUp()
	{
		for (int i = 0; i < dirt.length; ++i)
		{
			if (!dirt[i].isPickedUp)
				return false;
		}

		return true;
	}
}

Exercise 4.C: Objects
Design a class which displays, animates, and defines the behavior of a machine or organism. Give your invention a goal (e.g. finding other creatures, searching for food, climbing the screen) and have it react when it reaches its goal.