#ifndef World_H
#define World_H

#ifdef _WIN32
#include <windows.h>
#endif

#include "Configuration.h"
#include "CurrentImpact.h"
#include "RigidBody.h" //includes Edge.h and Vertex.h

class World
{
private:
	//made private because it is a singleton
	World();
	/** Singleton instance of the World class*/
	static World* instance;

	/** Holds the current direction of gravity in the World **/
	Vec2 gravity;
	/** Holds data about the last impact detected in the World so it can be handled. **/
	CurrentImpact currentImpact;

	/** Number of RigidBodies of type OBSTACLE in the ObstacleArray **/
	int totalObstacles;
	/** Number of RigidBodies of any type in the RigidBodyArray. **/
	int totalBodies;
	/** Number of vertices that make up the RigidBodies in the RigidBodyArray **/
	int totalVertices;
	/** Number of edges that make up the RigidBodies in the RigidBodyArray **/
	int totalEdges;

	/** Holds RigidBodies of type OBSTACLE in the World. These do not move when collided with. **/
	RigidBody* ObstacleArray[MAX_OBSTACLES];
	/** Holds RigidBodies of any type that are affected by collsions in the World. **/
	RigidBody* RigidBodyArray[MAX_OBJECTS];
	/** The amount of time between ticks. **/
	float tick;
	/**
	*	The number of times to run the edge correction step each update. Increasing the number
	*	reduces the amount of edge length deformation caused by collisions moving seperate vertices,
	*	but increases the amount of computation needed each update.
	*/
	int iterations;

	//Update Methods
	void updateForces();
	void updateVerlet();
	void updateEdges();
	bool didCollide(RigidBody* pb1, RigidBody* pb2);
	bool overlapping(RigidBody* pb1, RigidBody* pb2);
	void handleCollision();
	void processAllCollisions();
	float getDistance(float minA, float maxA, float minB, float maxB);

public:
	static World* getInstance();

	void Destroy();

	void Update();
	void Render();
	void AddBody(RigidBody* Body);
	void AddObstacle(RigidBody* obstacle);
	void setGravity(Vec2 newGravity);
	int getIterations();
	void increaseIterations();
	void decreaseIterations();
};

#endif World_H
#include "World.h"

//initialize instance to nothing
World* World::instance = NULL;

/**
*	Returns the Singleton instance of the World
*/
World* World::getInstance()
{
	if(!instance)
		instance = new World();

	return instance;
}

/**
*	Constructor for a World object
*	Sets gravity to the bottom of the screen
*	No bodies, edges, or vertices in the world
*/
World::World()
{
	gravity = Vec2(0.0f, 0.2f);
	totalObstacles = 0;
	totalBodies = 0;
	totalVertices = 0;
	totalEdges = 0;

	tick = TICK;
	iterations = 12;//number of times to re-run the updateEdges function per tick
}

void World::Destroy()
{
	for(int i = 0; i < totalBodies; ++i)
		delete RigidBodyArray[i];

	for(int i = 0; i < totalObstacles; ++i)
		delete ObstacleArray[i];
}

int World::getIterations()
{
	return iterations;
}

void World::increaseIterations()
{
	if(iterations < MAX_ITERATIONS)
	{
		iterations++;
	}
}

void World::decreaseIterations()
{
	if(iterations > 1)
	{
		iterations--;
	}
}

void World::setGravity(Vec2 newGravity)
{
	gravity = newGravity;
}

/**
*	Add a RigidBody to the World
*	body1:	RigidBody object to add
*/
void World::AddBody(RigidBody* body1) 
{
	if(totalBodies + 1 < MAX_OBJECTS)
	{
		RigidBodyArray[totalBodies++] = body1;
	}
}

/**
*	Add an Obstacle to the World
*	body1: RigidBody obstacle to add
*/
void World::AddObstacle(RigidBody* obstacle)
{
	if(totalObstacles + 1 < MAX_OBSTACLES)
	{
		obstacle->CalculateCenter();
		ObstacleArray[totalObstacles++] = obstacle;
	}
}

/**
*	Updates each Vertex in the World based on the forces in the World
*	Currently, the only force applied is gravity
*/
void World::updateForces() 
{
	for(int i = 0; i < totalBodies; i++)
	{
		RigidBody* rb = RigidBodyArray[i];
		for(int j = 0; j < rb->vertexCount; j++)
		{
			rb->vertexArray[j]->accel = gravity;
		}
	}
}

/**
*	Updates the position of each Vertex in the World
*/
void World::updateVerlet() 
{
	for(int i = 0; i < totalBodies; i++)
	{
		RigidBody* rb = RigidBodyArray[i];

		for(int j = 0; j < rb->vertexCount; j++)
		{
			Vertex& v = *(rb->vertexArray[j]);

			//xNew = 2 * x(Current) – x(Old) + a(Current) * t2
			//wikipedia.org/wiki/Verlet_integration

			Vec2 temp = v.pos;
			v.pos = (v.pos * 2) - v.oldPos + v.accel * tick * tick;
			v.oldPos = temp;
		}
	}
}

/**
*	Updates the length of every Edge in the World.
*	Each update causes the length of the edge to change.
*	This method adjusts the positions of the vertices of an edge to maintain
*	the original length.
*/
void World::updateEdges() 
{
	//loop through all possible edges
	for(int i = 0; i < totalBodies; i++)
	{
		RigidBody* rb = RigidBodyArray[i];

		for(int j = 0; j < rb->edgeCount; j++)
		{
			Edge& e = *(rb->edgeArray[j]);

			Vec2 edgeVector = e.vertex2->pos - e.vertex1->pos;

			//move the positions of both vertices so the length of the edge is maintained
			float edgeVectorLength = edgeVector.length();
			float d = edgeVectorLength - e.length;
		
			edgeVector.normalize();

			//shift each vertex over half the total while maintaining length
			e.vertex1->pos += edgeVector * d * 0.5f;
			e.vertex2->pos -= edgeVector * d * 0.5f;
		}
	}
}

/**
*	Iterates through every RigidBody in the World, updates their edges, keeps them inside the screen,
*	and handles any collisions that occur.
*/
void World::processAllCollisions() {
	//the more times we iterate through all the edges and adjust them, the more accurate the result is
	//use the iterations variable to determine how many times to iterate
	for(int i = 0; i < iterations; i++) 
	{
		//if vertices are outside of screen, move them back inside
		for(int j = 0; j < totalBodies; j++)
		{
			RigidBody* rb = RigidBodyArray[j];
			for(int k = 0; k < rb->vertexCount; k++)
			{
				Vec2& position = rb->vertexArray[k]->pos;
	
				position.x = max(min(position.x, (float)SCREEN_WIDTH), 0.0f);
				position.y = max(min(position.y, (float)SCREEN_HEIGHT), 0.0f);
			}
		}

		updateEdges();

		for(int k = 0; k < totalBodies; k++)
		{
			RigidBodyArray[k]->CalculateCenter();
		}

		//iterate through every body in the word
		for(int body1 = 0; body1 < totalBodies; body1++) 
		{
			for(int body2 = 0; body2 < totalBodies; body2++) 
			{
				if(body1 != body2)
				{
					if(didCollide(RigidBodyArray[body1], RigidBodyArray[body2]))
					{
						handleCollision();
					}
				}
			}

			//check against obstacles
			for(int i = 0; i < totalObstacles; i++)
			{
				if(didCollide(RigidBodyArray[body1], ObstacleArray[i]))
				{
					handleCollision();
				}
			}
		}
	}
}

/**
*	Takes two RigidBodies and determines whether they are overlapping.
*	body1:	First body to check for overlap
*	body2:	Second body to check for overlap
*	return:	true if RigidBodies are overlapping
*			false if RigidBodies are not overlapping
*/
bool World::overlapping(RigidBody* body1, RigidBody* body2)
{

	if ((body1->minX > (body2->maxX)) || ((body1->maxX) < body2->minX))
		return false;
	
	if((body1->minY > (body2->maxY)) || ((body1->maxY) < body2->minY))
		return false;

	return true;
}

/**
*	Takes two RigidBodies and determines whether the two collided
*	body1:	First RigidBody to check for collision
*	body2:	Second RigidBody to check for collision
*	return:	true if RigidBodies are colliding
*			false if RigidBodies are not colliding
*/
bool World::didCollide(RigidBody* body1, RigidBody* body2)
{
	//if they aren't overlapping, they didn't collide
	if(!overlapping(body1, body2))
		return false;

	//set the minDist to an extreme value
	float minDist = 10000.0f;

	//iterate through the edges of both bodies
	for(int i = 0; i < body1->edgeCount + body2->edgeCount; i++)
	{
		Edge* e;

		if(i < body1->edgeCount)
		{
			e = body1->edgeArray[i];
			currentImpact.edgeParent = body1;
		}
		else
		{
			e = body2->edgeArray[i - body1->edgeCount];
			currentImpact.edgeParent = body2;
		}

		//This will skip edges that lie totally inside the bodies, as they don't matter.
		if(e->isBorder)
		{
			Vec2 axis(e->vertex1->pos.y - e->vertex2->pos.y,
					  e->vertex2->pos.x - e->vertex1->pos.x);
			axis.normalize();

			//project the two bodies
			float minA, minB, maxA, maxB;
			body1->ProjectToAxis(axis, minA, maxA);
			body2->ProjectToAxis(axis, minB, maxB);

			float dist = getDistance(minA, maxA, minB, maxB);

			if(dist > 0.0f)
				return false;//no overlap = no collision
			else if(abs(dist) < minDist) {
				minDist = abs(dist);

				currentImpact.normal = axis;
				currentImpact.edge = e;
			}
		}
	}

	currentImpact.depth = minDist;

	if(currentImpact.edgeParent != body2) 
	{
		RigidBody* temp = body2;
		body2 = body1;
		body1 = temp;
	}

	int sign = sgn(currentImpact.normal * (body1->center - body2->center));

	if(sign != 1)
		currentImpact.normal = -currentImpact.normal;//if the normal points away from the other body, switch it

	Vec2 CollisionVector = currentImpact.normal * currentImpact.depth;

	//set minDist2 to an extreme value
	float minDist2 = 10000.0f;
	for(int j = 0; j < body1->vertexCount; j++)
	{
		//get distance of vertex to line
		float dist2 = currentImpact.normal * (body1->vertexArray[j]->pos);

		if(dist2 < minDist2)
		{
			minDist2 = dist2;
			currentImpact.vertex = body1->vertexArray[j];
		}
	}

	//objects collided
	return true;
}

/**
*	Called after a collision between a vertex and an edge has been detected and both structs have been
*	stored in currentImpact. handleCollision calculates a vector which will push the vertex and the edge apart
*	so they are no longer touching. If the vertex or edge belongs to a RigidBody of type OBSTACLE, it will not be moved.
*	Once the vector has been calculated, it will be applied to the appropriate vertex and/or edge.
*/
void World::handleCollision() 
{
	Vertex* vertex1 = currentImpact.edge->vertex1;
	Vertex* vertex2 = currentImpact.edge->vertex2;

	Vec2 CollisionVector = currentImpact.normal * currentImpact.depth;


	//the vertex can hit at any point along the vertex, find out where it hit
	float edgePos;
	if(abs(vertex1->pos.x - vertex2->pos.x ) > abs(vertex1->pos.y - vertex2->pos.y))
	{//check for divide by 0 error
		edgePos = (currentImpact.vertex->pos.x - CollisionVector.x - vertex1->pos.x) / (vertex2->pos.x - vertex1->pos.x);
	}
	else
	{
		edgePos = (currentImpact.vertex->pos.y - CollisionVector.y - vertex1->pos.y) / (vertex2->pos.y - vertex1->pos.y);
	}

	//calculate an offset scale so the vertex on the edge closest to the collision vertex is most strongly affected
	float scale = 1.0f/(edgePos*edgePos + (1 - edgePos) * (1 - edgePos));

	//apply vectors for impact
	if(currentImpact.edgeParent->shape != OBSTACLE)
	{
		vertex1->pos -= CollisionVector * (1 - edgePos) * 0.5f * scale;
		vertex2->pos -= CollisionVector * edgePos * 0.5f * scale;
	}
	
	currentImpact.vertex->pos += CollisionVector * 0.5f;
}

/**
*	Returns the distance between a Body at minA and maxA and a Body at minB and maxB
*/
float World::getDistance(float minA, float maxA, float minB, float maxB)
{
	if(minA < minB)
		return minB - maxA;
	else
		return minA - maxB;
}

/**
*	The update loop for the world. For each RigidBody in the world, applies
*	gravity, updates positions, and handles collision detection and collision
*	responses.
*/
void World::Update() 
{
	updateForces();
	updateVerlet();
	processAllCollisions();
}

/**
*	Draws each RigidBody present in the World
*	Squares are drawn in blue, triangles in green
*	Call each update to redraw the scene
*/
void World::Render() {
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_LINE_SMOOTH);

	//draw quads and tris for each shape
	for(int j = 0; j < totalBodies; j++)
	{
			switch(RigidBodyArray[j]->shape)
			{
			case TRIANGLE:
				glColor3f(0.53f, 0.8f, 0.53f);
				glBegin(GL_TRIANGLES);
					glVertex2f(RigidBodyArray[j]->vertexArray[0]->pos.x, RigidBodyArray[j]->vertexArray[0]->pos.y);
					glVertex2f(RigidBodyArray[j]->vertexArray[1]->pos.x, RigidBodyArray[j]->vertexArray[1]->pos.y);
					glVertex2f(RigidBodyArray[j]->vertexArray[2]->pos.x, RigidBodyArray[j]->vertexArray[2]->pos.y);
				glEnd();
				break;
			case SQUARE:
				glColor3f(0.53f, 0.8f, 1.0f);
				glBegin(GL_QUADS);
					glVertex2f(RigidBodyArray[j]->vertexArray[0]->pos.x, RigidBodyArray[j]->vertexArray[0]->pos.y);
					glVertex2f(RigidBodyArray[j]->vertexArray[1]->pos.x, RigidBodyArray[j]->vertexArray[1]->pos.y);
					glVertex2f(RigidBodyArray[j]->vertexArray[2]->pos.x, RigidBodyArray[j]->vertexArray[2]->pos.y);
					glVertex2f(RigidBodyArray[j]->vertexArray[3]->pos.x, RigidBodyArray[j]->vertexArray[3]->pos.y);
				glEnd();
				break;
			default:
				break;
			}
	}

	//draw outlines of each shape
	glLineWidth(2.0f);
	for(int i = 0; i < totalBodies; i++)
	{
		RigidBody* rb = RigidBodyArray[i];

		switch(rb->shape)
		{
		case TRIANGLE:
			glColor3f(0.0f, 0.55f, 0.0f);//light green
			break;
		case SQUARE:
			glColor3f(0.0f, 0.5f, 1.0f);//light blue
			break;
		default:
			glColor3f(0.0f, 0.5f, 1.0f);//same as square, light blue
			break;
		}

		for(int j = 0; j < rb->edgeCount; j++)
		{
			glBegin(GL_LINES);
			if(rb->edgeArray[j]->isBorder)
			{
				glVertex2f(rb->edgeArray[j]->vertex1->pos.x, rb->edgeArray[j]->vertex1->pos.y);
				glVertex2f(rb->edgeArray[j]->vertex2->pos.x, rb->edgeArray[j]->vertex2->pos.y);
			}
		glEnd();
		}
	}

	//draw Obstacles in Obstacle Array
	for(int i = 0; i < totalObstacles; i++)
	{
		switch(ObstacleArray[i]->shape)
		{
		case OBSTACLE:
				glColor3f(0.52f, 0.37f, 0.26f);//light brown
				glBegin(GL_QUADS);
					glVertex2f(ObstacleArray[i]->vertexArray[0]->pos.x, ObstacleArray[i]->vertexArray[0]->pos.y);
					glVertex2f(ObstacleArray[i]->vertexArray[1]->pos.x, ObstacleArray[i]->vertexArray[1]->pos.y);
					glVertex2f(ObstacleArray[i]->vertexArray[2]->pos.x, ObstacleArray[i]->vertexArray[2]->pos.y);
					glVertex2f(ObstacleArray[i]->vertexArray[3]->pos.x, ObstacleArray[i]->vertexArray[3]->pos.y);
				glEnd();
			break;
		default:
			break;
		}
	}

	//print obstacle edges
	for(int i = 0; i < totalObstacles; i++)
	{
		RigidBody* rb = ObstacleArray[i];

		switch(rb->shape)
		{
		case OBSTACLE:
			glColor3f(0.65f, 0.5f, 0.39f);//light brown
			break;
		default:
			glColor3f(1.0f, 1.0f, 1.0f);//white
			break;
		}

		for(int j = 0; j < rb->edgeCount; j++)
		{
			glBegin(GL_LINES);
			if(rb->edgeArray[j]->isBorder)
			{
				glVertex2f(rb->edgeArray[j]->vertex1->pos.x, rb->edgeArray[j]->vertex1->pos.y);
				glVertex2f(rb->edgeArray[j]->vertex2->pos.x, rb->edgeArray[j]->vertex2->pos.y);
			}
		glEnd();
		}
	}
}
#ifndef RIGIDBODY_H
#define RIGIDBODY_H

#include "Edge.h" //includes Vertex.h

/** enum for RigidBody types **/
enum Shape {OBSTACLE, //Rectangle which is not affected by physics, holds other shapes
			TRIANGLE,
			SQUARE};

struct RigidBody
{
	/** 2D point describing the center of the RigidBody **/
	Vec2 center;

	/** Creates a square bounding box around the rigidbody **/
	int minX, minY, maxX, maxY;

	/** The maximum number of vertices in the RigidBody. Based on the shape. **/
	int maxVerts;
	/** The maximum number of edges in the RigidBody. Based on the shape. **/
	int maxEdges;
	/** The current number of vertices in the RigidBody. Must not exceed maxVerts **/
	int vertexCount;
	/** The current number of edges in the RigidBody. Must not exceed maxEdges **/
	int edgeCount;
	/** Enum describing the shape of the RigidBody **/
	Shape shape;

	//The number of edges and vertices changes depending on the type of shape
	//We will initialize these arrays in the constructor
	Vertex* vertexArray[4];
	Edge*  edgeArray[6];

	/**
	*	Constructor
	*/
	RigidBody(Shape s);
	~RigidBody();

	void finishRigidBody(int x, int y);

	void AddEdge(Edge* e);
	void AddVertex(Vertex* v);
	void ProjectToAxis(Vec2& axis, float& min, float& max);
	void CalculateCenter();
};

#endif RIGIDBODY_H
#include "RigidBody.h"

/**
*	Constructor for a RigidBody object.
*	Sets the shape of the RigidBody and the maxVerts and maxEdges based on the shape.
*	Does not create Vertices or Edges for the shape. This can be done with the finishRigidBody method.
*/
RigidBody::RigidBody(Shape s)
{
	shape = s;
	vertexCount = 0;
	edgeCount = 0;

	switch(shape)
	{
	case OBSTACLE:
		maxVerts = 4;
		maxEdges = 6;
		break;
	case TRIANGLE:
		maxVerts = 3;
		maxEdges = 3;
		break;
	case SQUARE:
		maxVerts = 4;
		maxEdges = 6;
		break;
	default:
		cout << "Error: Cannot create RigidBody of type " << shape << endl;
		exit(1);
		break;
	}
}

RigidBody::~RigidBody()
{
	for(int i = 0; i < vertexCount; ++i)
		delete vertexArray[i];

	for(int i = 0; i < edgeCount; ++i)
		delete edgeArray[i];
}

/**
*	Creates the edges and vertices for the RigidBody based on the shape of the RigidBody.
*	Also sets the positions of the edges and vertices based on x and y position values.
*	x: x coordinate of RigidBody in world
*	y: y coordinate of RigidBody in world
*/
void RigidBody::finishRigidBody(int x, int y)
{
	switch(shape)
	{
	case OBSTACLE:
		{
			Vertex* v1 = new Vertex(x, y);
			Vertex* v2 = new Vertex(x + OBSTACLE_WIDTH, y);
			Vertex* v3 = new Vertex(x + OBSTACLE_WIDTH, y + OBSTACLE_HEIGHT);
			Vertex* v4 = new Vertex(x, y + OBSTACLE_HEIGHT);

			vertexArray[0] = v1;
			vertexArray[1] = v2;
			vertexArray[2] = v3;
			vertexArray[3] = v4;

			//create border edges
			edgeArray[0] = new Edge(v1, v2, true);
			edgeArray[1] = new Edge(v2, v3, true);
			edgeArray[2] = new Edge(v3, v4, true);
			edgeArray[3] = new Edge(v4, v1, true);

			//create cross section edges (non-border)
			edgeArray[4] = new Edge(v1, v3, false);
			edgeArray[5] = new Edge(v2, v4, false);

			vertexCount = 4;
			edgeCount = 6;
			break;
		}
	case TRIANGLE:
		{
			Vertex* v1 = new Vertex(x, y);
			Vertex* v2 = new Vertex(x - 25, y - 25);
			Vertex* v3 = new Vertex(x - 50, y);
	
			vertexArray[0] = v1;
			vertexArray[1] = v2;
			vertexArray[2] = v3;

			edgeArray[0] = new Edge(v1, v2);
			edgeArray[1] = new Edge(v2, v3);
			edgeArray[2] = new Edge(v3, v1);

			vertexCount = 3;
			edgeCount = 3;
		}
		break;
	case SQUARE:
		{
			Vertex* v1 = new Vertex(x, y);
			Vertex* v2 = new Vertex(x + SQUARE_LENGTH, y);
			Vertex* v3 = new Vertex(x + SQUARE_LENGTH, y + SQUARE_LENGTH);
			Vertex* v4 = new Vertex(x, y + SQUARE_LENGTH);

			vertexArray[0] = v1;
			vertexArray[1] = v2;
			vertexArray[2] = v3;
			vertexArray[3] = v4;

			//create border edges
			edgeArray[0] = new Edge(v1, v2, true);
			edgeArray[1] = new Edge(v2, v3, true);
			edgeArray[2] = new Edge(v3, v4, true);
			edgeArray[3] = new Edge(v4, v1, true);

			//create cross section edges (non-border)
			edgeArray[4] = new Edge(v1, v3, false);
			edgeArray[5] = new Edge(v2, v4, false);

			vertexCount = 4;
			edgeCount = 6;
		}
		break;
	default:
		{
			cout << "Error: Cannot create RigidBody of type " << shape << endl;
			exit(1);
		}
		break;//should never reach
	}
}

/**
*	Adds the specified edge to the RigidBody. Increases the edge count.
*	e: Edge to add
*/
void RigidBody::AddEdge(Edge* e) {
	if(edgeCount + 1 <= maxEdges) {
		edgeArray[edgeCount] = e;
		edgeCount++;
	}
}

/**
*	Adds the specified Vertex to the RigidBody. Increases the vertex count.
*	v: Vertex to add
*/
void RigidBody::AddVertex(Vertex *v) {
	if(vertexCount + 1 <= maxVerts) {
		vertexArray[vertexCount] = v;
		vertexCount++;
	}
}

/**
*	Projects the Rigid body to the specified axis. Then stores the min and max
*	values calculated in the specified min and max variables.
*/
void RigidBody::ProjectToAxis(Vec2& axis, float& min, float& max) {
	float DotProduct = axis * vertexArray[0]->pos;

	//Set the min and max values based on the new projection

	//start by setting to projection of first vert
	min = DotProduct;
	max = DotProduct;

	//then iterate through remaining verts and update if necessary
	for(int i = 0; i < vertexCount; i++) {
		DotProduct = axis * vertexArray[i]->pos;

		min = min(DotProduct, min);
		max = max(DotProduct, max);
	}
}

/**
*	Determines the center of the RigidBody and sets the center field.
*/
void RigidBody::CalculateCenter() 
{
	center = Vec2(0.0f, 0.0f);

	//initialize min and max values to extreme values
	minX = minY =  10000.0f;
	maxX = maxY = -10000.0f;

	//loop through all vertices in the array
	for(int i = 0; i < vertexCount; i++)
	{
		//add the pos of the vertex to the center
		center += vertexArray[i]->pos;

		//adjust the min and max x,y values
		minX = min(minX, vertexArray[i]->pos.x);
		minY = min(minY, vertexArray[i]->pos.y);
		maxX = max(maxX, vertexArray[i]->pos.x);
		maxY = max(maxY, vertexArray[i]->pos.y);
	}

	//divide by the number of vertices to find the average, which is the center
	center = center / vertexCount;
}
#ifndef EDGE_H
#define EDGE_H

#include "Vertex.h"

struct RigidBody;

struct Edge
{
	/** First vertex that defines the edge **/
	Vertex* vertex1;
	/** Second vertex that defines the edge **/
	Vertex* vertex2;

	/** Length of the edge **/
	float length;

	//a border is an edge that defines the shape of the object
	//some edges connect points, but do not contribute to the shape
	//		----
	//		|\/|		The diagonal lines are not borders
	//      |/\|		The horizonal and vertical lines are borders
	//      ----
	bool isBorder;

	/**
	*	Constructor
	*/
	Edge();
	Edge(Vertex* pVertex1, Vertex* pVertex2, bool pBorder = true);
};
#endif
#include "Edge.h"

/**
*	Default constructor for an Edge object.
*	Does not set positions for the two vertices. Length of the edge is set to 0.
*	Does not mark the edge as a border.
*/
Edge::Edge()
{
	vertex1 = NULL;
	vertex2 = NULL;

	length = 0;
	isBorder = false;
}

/**
*	Constructor for an Edge object.
*	Uses the specified vertices to calculate the edge length.
*	pVertex1: First vertex that defines the edge
*	pVertex2: Second vertex that defines the edge
*	pBorder: boolean indicating whether the edge is a border edge or not
*/
Edge::Edge(Vertex* pVertex1, Vertex* pVertex2, bool pBorder) 
{
	vertex1 = pVertex1; //Set boundary vertices
	vertex2 = pVertex2;

	length = (pVertex2->pos - pVertex1->pos).length();
	isBorder = pBorder;
}
#ifndef VERTEX_H
#define VERTEX_H

#include "Configuration.h"
struct RigidBody;

struct Vertex 
{
	/** Current position in the World **/
	Vec2 pos;
	/** Previous position in the World **/
	Vec2 oldPos;
	/** Current acceleration **/
	Vec2 accel;

	/**
	*	Default Constructor
	*/
	Vertex();
	Vertex(float PosX, float PosY);
};

#endif
#include "Vertex.h"

/**
*	Default Vertex constructor. Sets pos and oldPos to (0,0)
*	All other values are set to default variable values
*/
Vertex::Vertex()
{
	pos = Vec2(0, 0);
	oldPos = Vec2(0, 0);
}

/**
*	Constructor for Vertex object.
*	Sets current position and old position to specified values.
*	All other values set to defaul variable values.
*	posX: x coordinate of Vertex
*	posY: y coordinate of Vertex
*/
Vertex::Vertex(float posX, float posY)
{
	pos = Vec2(posX, posY);
	oldPos = Vec2(posX, posY);
}
#ifndef CURRENT_IMPACT_H
#define CURRENT_IMPACT_H

struct CurrentImpact
{
	float depth;
	Vec2  normal;

	RigidBody* edgeParent;
	Edge* edge;
	Vertex* vertex;
};

#endif