//-----------------------------------------------------------------------------------------------
// GeometricQueries2D.hpp
//
#pragma once
#ifndef include_GeometricQueries2D
#define include_GeometricQueries2D

//-----------------------------------------------------------------------------------------------
#include "Engine/Core/AABB2.hpp"
#include "Engine/Core/Vector3.hpp"
#include "Engine/Core/Vector2.hpp"
#include "Engine/Core/Disc2D.hpp"
#include "Engine/Core/LineSegment2D.hpp"
#include "Engine/Core/ConvexPolygon2D.hpp"


//-----------------------------------------------------------------------------------------------
bool DoDiscsOverlap2D( const Vector2& centerA, float radiusA, const Vector2& centerB, float radiusB );
bool DoDiscsOverlap2D( const Disc2D& discA, const Disc2D& discB );
float CalcDistanceSquaredPointToLineSegment2D( const Vector2& point, const Vector2& lineSegmentStart, const Vector2& lineSegmentEnd );
const Vector2 FindClosestPointOnLineSegment2D( const Vector2& point, const Vector2& lineSegmentStart, const Vector2& lineSegmentEnd );
float CalcDistanceSquaredPointToLineSegment2D( const Vector2& point, const LineSegment2D& lineSegment );
const Vector2 FindClosestPointOnLineSegment2D( const Vector2& point, const LineSegment2D& lineSegment );
float CalcDistanceSquaredPointToLine2D( const Vector2& point, const Vector2& firstPointOnLine, const Vector2& secondPointOnLine );
const Vector2 FindClosestPointOnLine2D( const Vector2& point, const Vector2& firstPointOnLine, const Vector2& secondPointOnLine );
float CalcDistanceSquaredPointToLine2D( const Vector2& point, const LineSegment2D& lineSegmentOnLine );
const Vector2 FindClosestPointOnLine2D( const Vector2& point, const LineSegment2D& lineSegmentOnLine );
const Vector2 CalcLargestRectThatFitsWithinArea( float rectAspect, const Vector2& containingAreaSize );


//-----------------------------------------------------------------------------------------------
inline bool DoDiscsOverlap2D( const Vector2& centerA, float radiusA, const Vector2& centerB, float radiusB )
{
	float sumOfRadii = radiusA + radiusB;
	float displacementCenterToCenterX = centerB.x - centerA.x;
	float displacementCenterToCenterY = centerB.y - centerA.y;
	float distanceSquaredCenterToCenter = (displacementCenterToCenterX * displacementCenterToCenterX) + (displacementCenterToCenterY * displacementCenterToCenterY);
	return distanceSquaredCenterToCenter < (sumOfRadii * sumOfRadii);
}


//-----------------------------------------------------------------------------------------------
inline bool DoDiscsOverlap2D( const Disc2D& discA, const Disc2D& discB )
{
	float sumOfRadii = discA.radius + discB.radius;
	float displacementCenterToCenterX = discB.center.x - discA.center.x;
	float displacementCenterToCenterY = discB.center.y - discA.center.y;
	float distanceSquaredCenterToCenter = (displacementCenterToCenterX * displacementCenterToCenterX) + (displacementCenterToCenterY * displacementCenterToCenterY);
	return distanceSquaredCenterToCenter < (sumOfRadii * sumOfRadii);
}


//-----------------------------------------------------------------------------------------------
inline float CalcDistanceSquaredPointToLineSegment2D( const Vector2& point, const LineSegment2D& lineSegment )
{
	return CalcDistanceSquaredPointToLineSegment2D( point, lineSegment.m_startPosition, lineSegment.GetEndPosition() );
}


//-----------------------------------------------------------------------------------------------
inline const Vector2 FindClosestPointOnLineSegment2D( const Vector2& point, const LineSegment2D& lineSegment )
{
	return FindClosestPointOnLineSegment2D( point, lineSegment.m_startPosition, lineSegment.GetEndPosition() );
}


//-----------------------------------------------------------------------------------------------
inline float CalcDistanceSquaredPointToLine2D( const Vector2& point, const LineSegment2D& lineSegmentOnLine )
{
	return CalcDistanceSquaredPointToLine2D( point, lineSegmentOnLine.m_startPosition, lineSegmentOnLine.GetEndPosition() );
}


//-----------------------------------------------------------------------------------------------
inline const Vector2 FindClosestPointOnLine2D( const Vector2& point, const LineSegment2D& lineSegmentOnLine )
{
	return FindClosestPointOnLine2D( point, lineSegmentOnLine.m_startPosition, lineSegmentOnLine.GetEndPosition() );
}



#endif // include_GeometricQueries2D
