/*
 * Copyright (c) 2008-2009 Bill Whitacre http://rampancy.g0dsoft.com
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
*/

#include "line.h"

void line2_init(line2 *line)
{
	line->a.x=0;
	line->a.y=0;
	line->b.x=0;
	line->b.y=0;
}

void line2_set(line2 *line,vector2 a,vector2 b)
{
	line->a=a;
	line->b=b;
}

rat_real line2_length(line2 line)
{
	return vector2_magnitude(vector2_sub(line.b,line.a));
}

vector2 line2_getnormal(line2 line,int reverse)
{
	vector2 normal;

	if (reverse)
		vector2_set(&normal,-line.a.x+line.b.x,line.a.y-line.b.y);
	else
		vector2_set(&normal,line.a.x-line.b.x,-line.a.y+line.b.y);
	
	vector2_normalize(&normal);
	return normal;
}

vector2 line2_vector2project(line2 line,vector2 vector)
{
	vector2 projectingvector,linevector,projectedvector;

	linevector=vector2_sub(line.b,line.a);
	projectingvector=vector2_sub(vector,line.a);

	projectedvector=vector2_project(projectingvector,linevector);

	return vector2_add(projectedvector,line.a);
}

int line2_intersection(line2 line_a,line2 line_b,vector2 *intersection)
{
	rat_real denom=((line_b.b.y-line_b.a.y)*(line_a.b.x-line_a.a.x))-
				   ((line_b.b.x-line_b.a.x)*(line_a.b.y-line_a.a.y));

    rat_real nume_a=((line_b.b.x-line_b.a.x)*(line_a.a.y-line_b.a.y))-
					((line_b.b.y-line_b.a.y)*(line_a.a.x-line_b.a.x));

    rat_real nume_b=((line_a.b.x-line_a.a.x)*(line_a.a.y-line_b.a.y))-
					((line_a.b.y-line_a.a.y)*(line_a.a.x-line_b.a.x));

	rat_real unknown_a,unknown_b;

	if (denom==0.0)
		return 0;

	unknown_a=nume_a/denom;
    unknown_b=nume_b/denom;

	if (unknown_a>=0.0&&unknown_a<=1.0&&unknown_b>=0.0&&unknown_b<=1.0)
	{
		intersection->x=line_a.a.x+unknown_a*(line_a.b.x-line_a.a.x);
        intersection->y=line_a.a.y+unknown_a*(line_a.b.y-line_a.a.y);

		return 1;
	}
	
	return 0;
}

line2 line2_getrotated(line2 line,rat_real angle)
{
	line2 newline;
	rotate_points2(angle,(rat_real *)&line.a.x,(rat_real *)&newline.a.x,2);
	return newline;
}

line2 line2_getscaled(line2 line,vector2 scalar)
{
	line2 newline;
	scale_points2((rat_real *)&scalar.x,(rat_real *)&line.a.x,(rat_real *)&newline.a.x,2);
	return newline;
}

line2 line2_gettranslated(line2 line,vector2 trans)
{
	line2 newline;
	translate_points2((rat_real *)&trans.x,(rat_real *)&line.a.x,(rat_real *)&newline.a.x,2);
	return newline;
}

void line2_rotate(line2 *self,rat_real angle)
	{*self=line2_getrotated(*self,angle);}

void line2_scale(line2 *self,vector2 scalar)
	{*self=line2_getscaled(*self,scalar);}

void line2_translate(line2 *self,vector2 trans)
	{*self=line2_gettranslated(*self,trans);}

