#ifndef SHAPE_H
#define SHAPE_H

/*
** Shape defines a basic object used in the physics simulation.
*/

namespace Salamander
{

struct Pick;

class Shape
{
public:
	/*
	** Destructor.
	*/
	virtual ~Shape();

	/*
	** Some shapes must be handled as special cases, so the ID is useful for type detection.
	*/
	registerInterfaceUniqueId();

public:
	// the actual shape
	virtual bool addVertex(Vec2 vertex);
	virtual Vec2 getVertex(unsigned int i);
	virtual Vec2 getLocalVertex(unsigned int i);
	virtual void removeVertex(unsigned int i);
	virtual void setLocalVertex(unsigned int i, Vec2 position);
	virtual std::vector<Vec2> getVertices();
	virtual unsigned int getNumVertices();
	virtual Vec2 normal(unsigned int i);
	virtual Vec2 edge(unsigned int i);

	// update the rotation/translation
	virtual void applyMatrix(Mat2 matrix);
	virtual void clearMatrix();

	// get the bounding circle for the object
	virtual double radius();
	virtual double radiusSquared();

	// other properties
	virtual double momentOfInertia();

	// Check if a point is inside the bounds of the polygon. Note that the point must
	// be in the local frame of reference
	virtual bool isPointInside(Vec2 point){return false;}// = 0; todo : why can't we do this?

	// cast a ray through the shape and find the first intersection
	virtual Pick getRayIntersection(Vec2 location, Vec2 direction);

	// generate properties 
	virtual Vec2 generateCentroid();

protected:
	/*
	** This is an abstract base class, specific shapes must be implemented on top of this.
	*/
	Shape();

protected :

	// data for the shape
	double radius_;
	double radiusSquared_;
	double momentOfInertia_;
	std::vector<Vec2> vworld_;
	std::vector<Vec2> edges_;
	std::vector<Vec2> normals_;
	std::vector<Vec2> vlocal_;	// stores the vertices in local coordinates when a matrix is applied

	typedef std::vector<Vec2>::iterator Vec2Iterator;

	// update data members
	virtual void generateProperties();
	virtual void generateRadius();
	virtual void generateEdges();
	virtual void generateNormals();

};

}

#endif // SHAPE_H
