#ifndef __grahamScan
#define __grahamScan
// file grahamScan.h
#include <algo.h>

template<class Point> // Points must have .x .y and friend theta
struct PolarAngleComparator
/* An instance of PolarAngleComparator is created by a point a.
   The object is then a predicate function object which compares points p,q
   according to the angles (a+(1,0), a, p) and (a+(1,0), a, q).
   (true iff p's angle is smaller)
      p
   q /
   |/  
   a----------a+(1,0)
   */
{  Point apex;
   PolarAngleComparator(const Point& a) {apex.x = a.x; apex.y = a.y;}

   bool operator()(const Point& p, const Point& q)
   {  return polar_angle(apex, p) < polar_angle(apex, q); }
};


template<class Point> // Points must have .x .y 
int Graham_scan(Point* p, int n)
/* Assumes points are in positions 1..n
   Graham_scan swaps the corners of the convex hull into the first m positions
   and returns their number, m.  */
{   int min = 1, m = 3;
L1: /* Let min be the index of the point with least y-coordinate,
       the rightmost of those if there is a tie. Put it in position 1.  */
    for (int i = 2; i <= n; i++)
        if (p[i].y < p[min].y || (p[i].y == p[min].y && p[i].x > p[min].x)) 
            min = i;
    swap(p[1], p[min]); 

L2: PolarAngleComparator less_for_Graham_scan(p[1]);
    sort(p+1, p+n+1, less_for_Graham_scan); 

L3: p[0] = p[n]; // a technicality: for when first 3 are co-linear.

	for (int i = 4; i <= n; i++) 
    {   // back off if it is straight or a left turn
        while (clockwise(p[m-1], p[m], p[i])) 
			m--;
        // It is a right turn, so move on.
        m++; swap(p[i], p[m]); 
    }
    return m;
}
#endif
