#include "VectorMath.h"
#include "../Logger.h"
#include <ctime>
#include <cstdlib>

int randomIntInRange(int lowest, int highest)
{ 
    srand((unsigned)time(0));
    return (rand()%(highest-lowest))+lowest;
}

IntersectResult intersect(const Line &l1, const Line &l2, Vector3r &intersection)
{
	return intersect(l1._a, l1._b, l2._a, l2._b, intersection);
}

IntersectResult intersect(const Vector3r &l1a, const Vector3r &l1b, const Vector3r &l2a, const Vector3r &l2b, Vector3r &intersection)
{
dReal denom = (l2b.y - l2a.y) * (l1b.x - l1a.x) - (l2b.x - l2a.x) * (l1b.y - l1a.y);
dReal nume_a = (l2b.x - l2a.x) * (l1a.y - l2a.y) - (l2b.y - l2a.y) * (l1a.x - l2a.x);
dReal nume_b = (l1b.x - l1a.x) * (l1a.y - l2a.y) - (l1b.y - l1a.y) * (l1a.x - l2a.x);

if (denom == 0.0f) {
	if (nume_a == 0.0f && nume_b == 0.0f) return COINCIDENT;
	return PARALLEL;
}

dReal ua = nume_a / denom;
dReal ub = nume_b / denom;

if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
	// Get the intersection point.
	intersection.x = l1a.x + ua * (l1b.x - l1a.x);
	intersection.y = l1a.y + ua * (l1b.y - l1a.y);
	intersection.z = 0;
	return INTERESECTING;
}

return NOT_INTERESECTING;
}

unsigned IntersectPolygon(const Polygon &p, const Line &l, Vector3r* intersections, unsigned* intersected)
{
	return IntersectPolygon(p, l._a, l._b, intersections, intersected);
}

unsigned IntersectPolygon(const Polygon* p, const Line &l, Vector3r* intersections, unsigned* intersected)
{
	return IntersectPolygon(p, l._a, l._b, intersections, intersected);
}

unsigned IntersectPolygon(const Polygon &p, const Vector3r &la, const Vector3r &lb, Vector3r* intersections, unsigned* intersected)
{
	unsigned count = 0;
	Vector3r intersection;
	for (unsigned i = 0; i < p.size()-1 && count < 32; i++) {
		if (intersect(la, lb, p[i], p[i+1], intersection) == INTERESECTING) {
			intersections[count] = intersection;
			intersected[count] = i;
			count++;
		}
	}
	return count;
}

unsigned IntersectPolygon(const Polygon* p, const Vector3r &la, const Vector3r &lb, Vector3r* intersections, unsigned* intersected)
{
	unsigned count = 0;
	Vector3r intersection;
	for (unsigned i = 0; i < p->size()-1 && count < 32; i++) {
		if (intersect(la, lb, p->at(i), p->at(i+1), intersection) == INTERESECTING) {
			intersections[count] = intersection;
			intersected[count] = i;
			count++;
		}
	}
	return count;
}

dReal orientedDistFromLine(const Line &l, const Vector3r p)
{
	Vector3r v = l._b - l._a;
	Vector3r w = p - l._a;
//	_DEBUG("w=" << w << "; v=" << v);
	
	dReal b = w.dotProduct(v) / v.dotProduct(v);
	Vector3r pb = l._a + v * b;
	Vector3r s = p - pb;
	Vector3r n = v.getPerpendicular();
	n.normalize();
	s.normalize();
//	_DEBUG("n=" << n << "; s=" << s);
	return (n == s) ? -(p - pb).length() : (p - pb).length();
}

bool pointInPolygon(const Polygon &polygon, const Vector3r &point)
{
	bool c = false;
	unsigned i, j = 0;
	for (i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) {
		if ((((polygon.at(i).y <= point.y) && (point.y < polygon.at(j).y)) ||
			((polygon.at(j).y <= point.y) && (point.y < polygon.at(i).y))) &&
			(point.x < (polygon.at(j).x - polygon.at(i).x) * (point.y - polygon.at(i).y) / (polygon.at(j).y - polygon.at(i).y) + polygon.at(i).x))
			c = !c;
	}
	return c;
}
