/* 
 * 
 * Confidential Information of Telekinesys Research Limited (t/a Havok).  Not for disclosure or distribution without Havok's
 * prior written consent.This software contains code, techniques and know-how which is confidential and proprietary to Havok.
 * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2008 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
 * 
 */
#ifndef HK_DEMOCOMMON_DRAWUTILS_H
#define HK_DEMOCOMMON_DRAWUTILS_H

#include <Common/Visualize/hkDebugDisplay.h>

struct hkDrawBase
{
	typedef int ColorARGB;
	static void drawLine(hkVector4Parameter a, hkVector4Parameter b, ColorARGB color);
	static void wireTriangle(hkVector4Parameter a, hkVector4Parameter b, hkVector4Parameter c, ColorARGB color);
	static void fillTriangle(hkVector4Parameter a, hkVector4Parameter b, hkVector4Parameter c, ColorARGB color);
	static void fillRectangle(hkVector4Parameter center, hkVector4Parameter x, hkVector4Parameter y, ColorARGB color);
	static void wireRectangle(hkVector4Parameter center, hkVector4Parameter x, hkVector4Parameter y, ColorARGB color);

	static hkQuadReal s_x2d;
	static hkQuadReal s_y2d;
	static hkQuadReal s_n2d;
};

struct hkDrawRectangle : public hkDrawBase
{ 
	hkDrawRectangle()
	{
		m_center.setZero4();
		m_x = s_x2d;
		m_y = s_y2d;
	}

	hkDrawRectangle& fillColor( ColorARGB c )
	{
		fillRectangle(m_center, m_x, m_y, c);
		return *this;
	}
	hkDrawRectangle& wireFrame( ColorARGB c )
	{
		wireRectangle(m_center, m_x, m_y, c);
		return *this;
	}

	hkDrawRectangle& center( hkVector4Parameter p )
	{
		m_center = p;
		return *this;
	}
	hkDrawRectangle& axes( hkVector4Parameter x, hkVector4Parameter y )
	{
		m_y = x;
		m_x = y;
		return *this;
	}
	hkDrawRectangle& expand( hkReal e )
	{
		hkReal lx = m_x.fastNormalizeWithLength3();
		m_x.mul4( lx + e );
		hkReal ly = m_y.fastNormalizeWithLength3();
		m_y.mul4( ly + e );
		return *this;
	}
	hkDrawRectangle& sideLengths( hkReal s0, hkReal s1 )
	{
		m_x.fastNormalize3(); m_x.mul4( s0 );
		m_y.fastNormalize3(); m_y.mul4( s1 );
		return *this;
	}
	hkDrawRectangle& thickLine3d( hkVector4Parameter v0, hkVector4Parameter v1, hkVector4Parameter n, hkReal w)
	{
		hkVector4 x; x.setSub4(v1,v0); x.mul4(0.5f);
		hkVector4 c; c.setAdd4(v0,x);
		hkVector4 y; y.setCross( n, x );
		y.fastNormalize3(); y.mul4(w);

		m_center = c;
		m_x = x;
		m_y = y;
		return *this;
	}
	hkDrawRectangle& thickLine2d( hkVector4Parameter v0, hkVector4Parameter v1, hkReal w)
	{
		hkVector4 n = s_n2d;
		return thickLine3d(v0, v1, n, w);
	}
	
	hkVector4 m_center;
	hkVector4 m_y;
	hkVector4 m_x;
};

struct hkDrawLine : public hkDrawBase
{
	hkDrawLine& ray( hkVector4Parameter o, hkVector4Parameter d, ColorARGB c )
	{
		hkVector4 p; p.setAdd4( o, d );
		drawLine( o, p, c);
		return *this;
	}
	hkDrawLine& ray( hkVector4Parameter o, hkVector4Parameter d, hkReal t, ColorARGB c )
	{
		hkVector4 p; p.setAddMul4( o, d, t );
		drawLine( o, p, c);
		return *this;
	}
	hkDrawLine& points( hkVector4Parameter a, hkVector4Parameter b, ColorARGB c )
	{
		drawLine( a, b, c);
		return *this;
	}
	hkDrawLine& points( hkVector4Parameter a, hkVector4Parameter b, hkReal t, ColorARGB c )
	{
		hkVector4 p; p.setInterpolate4(a,b,t);
		drawLine( a, p, c);
		return *this;
	}
	hkDrawLine& thickLine2d( hkVector4Parameter a, hkVector4Parameter b, hkReal w, ColorARGB c )
	{
		hkDrawRectangle().thickLine2d(a,b,w).fillColor(c);
		return *this;
	}
	hkDrawLine& linestrip( const hkVector4* p, int np, ColorARGB c )
	{
		for (int i = 0; i < np - 1; ++i)
		{
			drawLine( p[i], p[i+1], c );
		}
		return *this;
	}
};

struct hkDrawTriangle : public hkDrawBase
{
	hkDrawTriangle& points( const hkVector4* p )
	{
		m_a = p[0];
		m_b = p[1];
		m_c = p[2];
		return *this;
	}

	hkDrawTriangle& points( hkVector4Parameter p0, hkVector4Parameter p1, hkVector4Parameter p2 )
	{
		m_a = p0;
		m_b = p1;
		m_c = p2;
		return *this;
	}
	hkDrawTriangle& fillColor( ColorARGB c )
	{
		fillTriangle(m_a, m_b, m_c, c);
		return *this;
	}
	hkDrawTriangle& wireFrame( ColorARGB c )
	{
		wireTriangle(m_a, m_b, m_c, c);
		return *this;

	}
	hkDrawTriangle& expand( hkReal r )
	{
		hkVector4 c; c.setAdd4( m_a, m_b ); c.add4(m_c); c.mul4(1.0f/3.0f);
		hkVector4 da; da.setSub4( m_a, c ); da.fastNormalize3(); m_a.addMul4( r, da );
		hkVector4 db; db.setSub4( m_b, c ); db.fastNormalize3(); m_b.addMul4( r, db );
		hkVector4 dc; dc.setSub4( m_c, c ); dc.fastNormalize3(); m_c.addMul4( r, dc );
		return *this;
	}


	hkVector4 m_a;
	hkVector4 m_b;
	hkVector4 m_c;
};


#endif //HK_DEMOCOMMON_DRAWUTILS_H

/*
* Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20080529)
*
* Confidential Information of Havok.  (C) Copyright 1999-2008 
* Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
* Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
* rights, and intellectual property rights in the Havok software remain in
* Havok and/or its suppliers.
*
* Use of this software for evaluation purposes is subject to and indicates 
* acceptance of the End User licence Agreement for this product. A copy of 
* the license is included with this software and is also available at
* www.havok.com/tryhavok
*
*/
