import struct Vector2
{
	import var X : Float;
	import var Y : Float;
}

import struct Vector3
{
	import var X : Float;
	import var Y : Float;
	import var Z : Float;

	public static function Lerp( a : Vector3, b : Vector3, t : Float ) : Vector3
	{
		var x : Float;
		var y : Float;
		var z : Float;
		x = a.X + ( ( b.X - a.X ) * t );
		y = a.Y + ( ( b.Y - a.Y ) * t );
		z = a.Z + ( ( b.Z - a.Z ) * t );
		return Vector3( x, y, z );
	}

}

import struct Vector4
{
	import var X : Float;
	import var Y : Float;
	import var Z : Float;
	import var W : Float;

	public import static function Dot2D( a, b : Vector4 ) : Float;
	public import static function Dot( a, b : Vector4 ) : Float;
	public import static function Cross( a, b : Vector4 ) : Vector4;
	public import static function Length2D( a : Vector4 ) : Float;
	public import static function LengthSquared( a : Vector4 ) : Float;
	public import static function Length( a : Vector4 ) : Float;
	public import static function Normalize2D( a : Vector4 ) : Vector4;
	public import static function Normalize( a : Vector4 ) : Vector4;
	public import static function Rand2D() : Vector4;
	public import static function Rand() : Vector4;

	public static function UP() : Vector4
	{
		var v : Vector4;
		v.Z = 1.0;
		return v;
	}

	public static function FRONT() : Vector4
	{
		var v : Vector4;
		v.Y = 1.0;
		return v;
	}

	public static function RIGHT() : Vector4
	{
		var v : Vector4;
		v.X = 1.0;
		return v;
	}

	public static function RandRing( minRadius, maxRadius : Float ) : Vector4
	{
		var r, angle : Float;
		r = RandRangeF( minRadius, maxRadius );
		angle = RandRangeF( 0.0, 6.28318548 );
		return Vector4( r * CosF( angle ), r * SinF( angle ), 0.0, 1.0 );
	}

	public static function RandCone( coneDir, coneAngle, minRadius, maxRadius : Float ) : Vector4
	{
		var r, angle, angleMin, angleMax : Float;
		r = RandRangeF( minRadius, maxRadius );
		angleMin = Deg2Rad( ( coneDir - ( coneAngle * 0.5 ) ) + 90.0 );
		angleMax = Deg2Rad( ( coneDir + ( coneAngle * 0.5 ) ) + 90.0 );
		angle = RandRangeF( angleMin, angleMax );
		return Vector4( r * CosF( angle ), r * SinF( angle ), 0.0, 1.0 );
	}

	public static function RandRingStatic( seed : Int32, minRadius, maxRadius : Float ) : Vector4
	{
		var r, angle : Float;
		r = RandNoiseF( seed, maxRadius, minRadius );
		angle = RandNoiseF( seed, 6.28318548 );
		return Vector4( r * CosF( angle ), r * SinF( angle ), 0.0, 1.0 );
	}

	public import static function Mirror( dir, normal : Vector4 ) : Vector4;
	public import static function Distance( from, to : Vector4 ) : Float;
	public import static function DistanceSquared( from, to : Vector4 ) : Float;
	public import static function Distance2D( from, to : Vector4 ) : Float;
	public import static function DistanceSquared2D( from, to : Vector4 ) : Float;
	public import static function DistanceToEdge( point, a, b : Vector4 ) : Float;
	public import static function NearestPointOnEdge( point, a, b : Vector4 ) : Vector4;
	public import static function ToRotation( dir : Vector4 ) : EulerAngles;
	public import static function Heading( dir : Vector4 ) : Float;
	public import static function FromHeading( heading : Float ) : Vector4;
	public import static function Transform( m : Matrix, point : Vector4 ) : Vector4;
	public import static function TransformDir( m : Matrix, point : Vector4 ) : Vector4;
	public import static function TransformH( m : Matrix, point : Vector4 ) : Vector4;
	public import static function GetAngleBetween( from : Vector4, to : Vector4 ) : Float;
	public import static function GetAngleDegAroundAxis( dirA : Vector4, dirB : Vector4, axis : Vector4 ) : Float;
	public import static function ProjectPointToPlane( p1 : Vector4, p2 : Vector4, p3 : Vector4, toProject : Vector4 ) : Vector4;
	public import static function RotateAxis( vector : Vector4, axis : Vector4, angle : Float ) : Vector4;
	public import static function RotByAngleXY( vec : Vector4, angleDeg : Float ) : Vector4;
	public import static function Interpolate( v1, v2 : Vector4, ratio : Float ) : Vector4;

	public static function ToString( vec : Vector4 ) : String
	{
		return ( ( ( ( ( FloatToString( vec.X ) + " " ) + FloatToString( vec.Y ) ) + " " ) + FloatToString( vec.Z ) ) + " " ) + FloatToString( vec.W );
	}

	public static function ToStringPrec( vec : Vector4, precision : Int32 ) : String
	{
		return ( ( ( ( ( FloatToStringPrec( vec.X, precision ) + " " ) + FloatToStringPrec( vec.Y, precision ) ) + " " ) + FloatToStringPrec( vec.Z, precision ) ) + " " ) + FloatToStringPrec( vec.W, precision );
	}

	public import static function Zero( out self : Vector4 );
	public import static function IsZero( self : Vector4 ) : Bool;
	public import static function IsXYZZero( self : Vector4 ) : Bool;

	public static function EmptyVector() : Vector4
	{
		var vec : Vector4;
		return vec;
	}

	public import static function ClampLength( self : Vector4, min : Float, max : Float ) : Vector4;
	public import static function Vector3To4( v3 : Vector3 ) : Vector4;
	public import static function Vector4To3( v4 : Vector4 ) : Vector3;
}

import operator-( b : Vector4 ) : Vector4;
import operator+( a : Vector4, b : Vector4 ) : Vector4;
import operator-( a : Vector4, b : Vector4 ) : Vector4;
import operator*( a : Vector4, b : Vector4 ) : Vector4;
import operator/( a : Vector4, b : Vector4 ) : Vector4;
import operator+=( out a : Vector4, b : Vector4 ) : Vector4;
import operator-=( out a : Vector4, b : Vector4 ) : Vector4;
import operator*=( out a : Vector4, b : Vector4 ) : Vector4;
import operator/=( out a : Vector4, b : Vector4 ) : Vector4;
import operator+( a : Vector4, b : Float ) : Vector4;
import operator-( a : Vector4, b : Float ) : Vector4;
import operator*( a : Vector4, b : Float ) : Vector4;
import operator*( a : Float, b : Vector4 ) : Vector4;
import operator/( a : Vector4, b : Float ) : Vector4;
import operator+=( out a : Vector4, b : Float ) : Vector4;
import operator-=( out a : Vector4, b : Float ) : Vector4;
import operator*=( out a : Vector4, b : Float ) : Vector4;
import operator/=( out a : Vector4, b : Float ) : Vector4;

function VectorToString( vec : Vector4 ) : String
{
	var str : String;
	str = ( ( ( ( "x: " + FloatToString( vec.X ) ) + " y: " ) + FloatToString( vec.Y ) ) + " z: " ) + FloatToString( vec.Z );
	return str;
}

import cast ( a : Vector3 ) : Vector4;
import cast ( a : Vector4 ) : Vector3;
