#include "Behaviors/StateMachine.h"

// Lab4 - Polygon exercise.
// Looks for three ellipses of one color, forming a polygon, and a
// fourth ellipse of a different color.  Determines whether the fourth
// ellipse is inside or outside of the polygon.

$nodeclass Lab4Polygon {

  $nodeclass FindEllipses : MapBuilderNode : doStart {
    mapreq.addObjectColor(ellipseDataType, "red");
    mapreq.addObjectColor(ellipseDataType, "green");
    mapreq.addObjectColor(ellipseDataType, "blue");
  }

	struct ColorLessThan : public BinaryShapeRootPred {
		bool operator() (const ShapeRoot &shape1, const ShapeRoot &shape2) const {
			return ProjectInterface::getColorName(shape1->getColor()) <
				ProjectInterface::getColorName(shape2->getColor());
		}
	};

  $nodeclass ShowResults : doStart {
    NEW_SHAPEVEC(ellipses, EllipseData, select_type<EllipseData>(camShS));
    if ( ellipses.size() != 4 ) {
      cout << "Found " << ellipses.size() << " ellipses; wanted 4." << endl;
			return;
		}

		// Sort ellipses by color and make sure the last ellipse is the oddball
		NEW_SHAPEVEC(sortedEllipses, EllipseData, stable_sort(ellipses, ColorLessThan()));
		if ( sortedEllipses[0]->getColor() != sortedEllipses[1]->getColor() )
			swap(sortedEllipses[0], sortedEllipses[3]);
		if ( sortedEllipses[0]->getColor() != sortedEllipses[1]->getColor() ||
				 sortedEllipses[0]->getColor() != sortedEllipses[2]->getColor() ) {
			cout << "Can't find three ellipses of the same color to form a polygon." << endl;
			return;
		}

		// Make the polygon from ellipses 0-2 and test ellipse 3 for inclusion
		vector<Point> polyPoints;
		for (int i=0; i<=2; i++)
			polyPoints.push_back(sortedEllipses[i]->getCentroid());
		NEW_SHAPE(poly, PolygonData, new PolygonData(camShS, polyPoints, true));
		cout << "The " << ProjectInterface::getColorName(sortedEllipses[3]->getColor())
				 << " ellipse is "
				 << ( (poly->isInside(sortedEllipses[3]->getCentroid())) ? "inside" : "outside" )
				 << " the polygon." << endl;
	}

  $setupmachine{
    FindEllipses =C=> ShowResults
	}

}    

REGISTER_BEHAVIOR(Lab4Polygon);
