//
// Tools_SurroundPan_Dialog.cpp
//
// Created by Richard Rice - 18/07/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

#include "Sound/Tools_SurroundPan_Dialog.h"

#include "Core/Asura_TextureManagement.h"
#include "Core/Asura_UserInput.h"
#include "Debugging/Asura_Assert.h"
#include "Interface/Asura_Cursor.h"
#include "Interface/Asura_Overlay_System.h"
#include "Rendering/Asura_Text_Output.h"
#include "Rendering/Asura_Render.h"


//constants for the size etc of the various graphics
static const int g_iPanX = 0;
static const int g_iPanY = 0;
static const int g_iPanWidth = 48;
static const int g_iPanHeight = 48;
static const int g_iPanRadius = 15;

static const int g_iBlobX = 57;
static const int g_iBlobY = 0;
static const int g_iBlobWidth = 7;
static const int g_iBlobHeight = 7;

static const float g_fGraphicWidth = 64.0f;
static const float g_fGraphicHeight = 64.0f;

extern unsigned int Asura_OverlayBrightness;

/////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------------**
** Tools_SurroundPan_Dialog **
**--------------------------*/


Tools_SurroundPan_Dialog::Tools_SurroundPan_Dialog(const Asura_Vector_2& xOffset,Asura_SurroundPan* pxPan,bool* pbModified)
:Asura_Dialog("",xOffset)
,m_pxPan(pxPan)
{
	Asura_Assert(pxPan,"");


	//create the only gadget
	Tools_SurroundPan_Gadget* pxGadget = new Tools_SurroundPan_Gadget(xOffset,pxPan,pbModified);
	AddGadget(pxGadget);

	m_xMaxCoord.x = xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = xOffset.y + pxGadget->m_fHeight;
}

void Tools_SurroundPan_Dialog::PerFrameUpdate()
{
	//update help text to contain current pan/fade settings
	char szText[100];
	Asura_PrintfToBfr(szText,"Pan  : %.3f\nFade : %.3f",sizeof(szText),true,m_pxPan->m_fPan,m_pxPan->m_fFade);
	SetHelpText(szText);

	Asura_Dialog::PerFrameUpdate();
}

/////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------------**
** Tools_SurroundPan_Gadget **
**--------------------------*/

int Tools_SurroundPan_Gadget::s_iTextureIndex = ASURA_TEXTURE_NONE;

Tools_SurroundPan_Gadget::Tools_SurroundPan_Gadget(const Asura_Vector_2& xOffset,Asura_SurroundPan* pxPan,bool* pbModified)
:m_pxPan(pxPan)
,m_pbModified(pbModified)
{
	m_xOffset = xOffset;
	m_fWidth = g_iPanWidth/ASURA_TEXT_OUTPUT_FONT_WIDTH;
	m_fHeight = g_iPanHeight/ASURA_TEXT_OUTPUT_FONT_HEIGHT;

	if(s_iTextureIndex == ASURA_TEXTURE_NONE)
	{
		s_iTextureIndex = Asura_Texture_Management::AddTexture("\\Tools\\Pan.dds");
		Asura_Texture_Management::LoadTextures();
	}
}

void Tools_SurroundPan_Gadget::Render(const Asura_Vector_2& xOrigin)
{
	//get top left in screen coords
	float fX = (float)Asura_Maths::FloatToInt_Near((xOrigin.x + m_xOffset.x)*ASURA_TEXT_OUTPUT_FONT_WIDTH);
	float fY = (float)Asura_Maths::FloatToInt_Near((xOrigin.y + m_xOffset.y)*ASURA_TEXT_OUTPUT_FONT_HEIGHT);

	//draw the main pan graphic
	Asura_Render::Overlay.Colour = Asura_OverlayBrightness|0xffffff;
	Asura_Render::Overlay.TextureIndex = s_iTextureIndex;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;

	Asura_Render::Overlay.SetRectUV(g_iPanX/g_fGraphicWidth,
									g_iPanY/g_fGraphicHeight,
									g_iPanWidth/g_fGraphicWidth,
									g_iPanHeight/g_fGraphicHeight);
	Asura_Render::Overlay.SetRectXY(fX-0.5f,
									fY-0.5f,
									(float)g_iPanWidth,
									(float)g_iPanHeight);

	Asura_Render::Overlay.Render();
	Asura_Render::FlushDisplay();

	//Determine the position for the blob
	#if 1
	//get the bottom left of the area covered by the blob
	Asura_Vector_2 xPos(fX,fY);
	xPos.x += g_iPanWidth/2.0f-g_iPanRadius;
	xPos.y += g_iPanHeight/2.0f-g_iPanRadius;
	//and move to the correct point relative to that
	xPos.x += (m_pxPan->m_fPan*g_iPanRadius*2.0f);
	xPos.y += (1.0f-m_pxPan->m_fFade)*g_iPanRadius*2.0f;
	#else
	//get a normalisied direction from the centre
	Asura_Vector_2 xDir(m_pxPan->m_fPan-0.5f,0.5f-m_pxPan->m_fFade);
	if(xDir == Asura_Maths::ZeroVector2)
	{
		xDir.x = 0.0f;
		xDir.y = -1.0f;
	}
	else
	{
		xDir.Normalise();
	}

	//get the centre of the circle
	Asura_Vector_2 xPos(fX,fY);
	xPos.x += g_iPanWidth/2;
	xPos.y += g_iPanHeight/2;
	//and move to the correct point on the circle
	xPos.x += xDir.x*g_iPanRadius;
	xPos.y += xDir.y*g_iPanRadius;
	#endif
	//offset so that the blob's centre is at this position
	xPos.x -= g_iBlobWidth/2;
	xPos.y -= g_iBlobHeight/2;

	//And draw it
	Asura_Render::Overlay.Colour = Asura_OverlayBrightness|0xffffff;
	Asura_Render::Overlay.TextureIndex = s_iTextureIndex;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;

	Asura_Render::Overlay.SetRectUV(g_iBlobX/g_fGraphicWidth,
									g_iBlobY/g_fGraphicHeight,
									g_iBlobWidth/g_fGraphicWidth,
									g_iBlobHeight/g_fGraphicHeight);
	Asura_Render::Overlay.SetRectXY(xPos.x-0.5f,
									xPos.y-0.5f,
									(float)g_iBlobWidth,
									(float)g_iBlobHeight);
	Asura_Render::Overlay.Render();

	Asura_Gadget::Render(xOrigin);
}

void Tools_SurroundPan_Gadget::Update(const Asura_Vector_2& xOrigin)
{
	if( m_bIsMouseOver && m_bIsClickable && Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_MOUSEBUTTON1) )
	{
 		Asura_Overlay_System::TakeFocus(this,OverlayFocusType_Mouse);
        m_bClickedThisFrame = true;
	}
		
 	if (Asura_UserInput::KeyPressed(ASURA_KEYID_MOUSEBUTTON1))
 	{
 		if(m_iFocusFlags)
 		{
			#if 1
			//move the pan to the position clicked on
			Asura_Vector_2 xPos;
			Asura_Cursor::GetScreenCoords(xPos.x,xPos.y);
			
			//get coord relative to corner of box
			xPos.x-=(xOrigin.x + m_xOffset.x);
			xPos.y-=(xOrigin.y + m_xOffset.y);
			
			xPos.x *= ASURA_TEXT_OUTPUT_FONT_WIDTH;
			xPos.y *= ASURA_TEXT_OUTPUT_FONT_HEIGHT;

			//and relative to the corner of the area covered by the blob
			xPos.x -= g_iPanWidth/2.0f-g_iPanRadius;
			xPos.y -= g_iPanHeight/2.0f-g_iPanRadius;

			//scale and clamp to 0-1
			xPos.x /= (float)g_iPanRadius*2.0f;
			xPos.y /= (float)g_iPanRadius*2.0f;

			xPos.x = Asura_Maths::ClampToRange(xPos.x,0.0f,1.0f);
			xPos.y = Asura_Maths::ClampToRange(xPos.y,0.0f,1.0f);
			

			if(Asura_UserInput::KeyPressed(ASURA_KEYID_SHIFT))
			{
				//snap position to edges/middle
				if(xPos.x <0.1f) xPos.x = 0.0f;
				else if(xPos.x>0.4f && xPos.x <0.6f) xPos.x = 0.5f;
				else if(xPos.x>0.9f) xPos.x = 1.0f;

				if(xPos.y <0.1f) xPos.y = 0.0f;
				else if(xPos.y>0.4f && xPos.y <0.6f) xPos.y = 0.5f;
				else if(xPos.y>0.9f) xPos.y = 1.0f;


			}

			m_pxPan->m_fPan = xPos.x;
			m_pxPan->m_fFade = 1.0f-xPos.y;

			if(m_pbModified) *m_pbModified = true;
			#else
			//move the pan to the position clicked on
			Asura_Vector_2 xPos;
			Asura_Cursor::GetScreenCoords(xPos.x,xPos.y);
			
			//get coord relative to centre of box
			xPos.x-=(xOrigin.x + m_xOffset.x);
			xPos.y-=(xOrigin.y + m_xOffset.y);
			
			xPos.x *= ASURA_TEXT_OUTPUT_FONT_WIDTH;
			xPos.y *= ASURA_TEXT_OUTPUT_FONT_HEIGHT;
			
			xPos.x -= g_iPanWidth/2.0f;
			xPos.y -= g_iPanHeight/2.0f;

			if(xPos != Asura_Maths::ZeroVector2)
			{
				xPos.Normalise();
			 	
			 	if(Asura_UserInput::KeyPressed(ASURA_KEYID_SHIFT))
				{
					//snap to nearest compass point
					if(Asura_Maths::Abs(xPos.x)>Asura_Maths::Abs(xPos.y))
					{
						xPos.x = xPos.x>0 ? 1.0f : -1.0f;
						xPos.y = 0.0f;

					}
					else
					{
						xPos.x = 0.0f;
						xPos.y = xPos.y>0 ? 1.0f : -1.0f;
					}
				}
				//convert value on unit circle to a pan/fade value
				m_pxPan->m_fPan = 0.5f+xPos.x/2.0f;
				m_pxPan->m_fFade = 0.5f-xPos.y/2.0f;

				if(m_pbModified) *m_pbModified = true;
			}
			#endif
		}
	}
	else if(m_iFocusFlags)
	{
		Asura_Overlay_System::ReleaseFocus(OverlayFocusType_Mouse);
	}
}

//eof
