#include "hud.h"

#include "Mix/Graphics/ITexture.h"
#include "Mix/Scene/ICamera.h"

HUD::HUD( void ) :
m_pCamera( NULL ),
m_pBrustTex( NULL ),
m_pDirtTex( NULL )
{
}

HUD::~HUD( void )
{
}

void HUD::Initialize( Mix::Scene::ICamera* pCamera )
{
	MIX_ASSERT( pCamera != NULL );

	const Mix::Point& screenSize = pCamera->GetConfig().targetSize;
	const Mix::Scene::ICamera::LENS_FLARE_SETTINGS& lfSettings = pCamera->GetLensFlareSettings();
	const Mix::Scene::BRIGHT_PASS& brightPass = lfSettings.brightPass;
	Int32 itemY = 16;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ADD_REF( pCamera );
	m_pCamera = pCamera;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	SetHUDEnabled( True );
	SetPosition( Mix::Point( screenSize.x - HUD::DLG_WIDTH, screenSize.y - HUD::DLG_HEIGHT ) );
	SetSize( Mix::Point( HUD::DLG_WIDTH, HUD::DLG_HEIGHT ) );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_BPL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_BPL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BPL.SetText( L"BrightPass:" );
	m_BPL.Initialize( this, HUD::CTRL_BP_L );

	m_BPWhiteSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BPWhiteSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BPWhiteSF.SetText( L"White" );
	m_BPWhiteSF.SetRange( 0.0f, 10.0f );
	m_BPWhiteSF.SetStep( 0.001f );
	m_BPWhiteSF.SetValue( brightPass.white );
	m_BPWhiteSF.Initialize( this, HUD::CTRL_BP_WHITE_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_BPThresholdSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BPThresholdSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BPThresholdSF.SetText( L"Threshold" );
	m_BPThresholdSF.SetRange( 0.0f, 10.0f );
	m_BPThresholdSF.SetStep( 0.001f );
	m_BPThresholdSF.SetValue( brightPass.threshold );
	m_BPThresholdSF.Initialize( this, HUD::CTRL_BP_THRESHOLD_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_BPOffsetSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BPOffsetSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BPOffsetSF.SetText( L"Offset" );
	m_BPOffsetSF.SetRange( 0.0f, 10.0f );
	m_BPOffsetSF.SetStep( 0.001f );
	m_BPOffsetSF.SetValue( brightPass.offset );
	m_BPOffsetSF.Initialize( this, HUD::CTRL_BP_OFFSET_SF );
	itemY += HUD::ITEM_YY_STEP;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_GhostL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_GhostL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_GhostL.SetText( L"Ghost:" );
	m_GhostL.Initialize( this, HUD::CTRL_GHOST_L );

	m_GhostNumSI.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_GhostNumSI.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_GhostNumSI.SetText( L"Num" );
	m_GhostNumSI.SetRange( 1, 32 );
	m_GhostNumSI.SetStep( 1 );
	m_GhostNumSI.SetValue( lfSettings.ghostNum );
	m_GhostNumSI.Initialize( this, HUD::CTRL_GHOST_NUM_SI );
	itemY += HUD::ITEM_Y_STEP;

	m_GhostWeightSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_GhostWeightSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_GhostWeightSF.SetText( L"Weight" );
	m_GhostWeightSF.SetRange( 1.0f, 10.0f );
	m_GhostWeightSF.SetStep( 0.001f );
	m_GhostWeightSF.SetValue( lfSettings.ghostWeight );
	m_GhostWeightSF.Initialize( this, HUD::CTRL_GHOST_WEIGHT_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_GhostDispersalSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_GhostDispersalSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_GhostDispersalSF.SetText( L"Dispersal" );
	m_GhostDispersalSF.SetRange( 0.0f, 1.0f );
	m_GhostDispersalSF.SetStep( 0.001f );
	m_GhostDispersalSF.SetValue( lfSettings.ghostDispersal );
	m_GhostDispersalSF.Initialize( this, HUD::CTRL_GHOST_DISPERSAL_SF );
	itemY += HUD::ITEM_YY_STEP;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_HaloL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_HaloL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_HaloL.SetText( L"Halo:" );
	m_HaloL.Initialize( this, HUD::CTRL_HALO_L );

	m_HaloWeightSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_HaloWeightSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_HaloWeightSF.SetText( L"Weight" );
	m_HaloWeightSF.SetRange( 1.0f, 10.0f );
	m_HaloWeightSF.SetStep( 0.001f );
	m_HaloWeightSF.SetValue( lfSettings.haloWeight );
	m_HaloWeightSF.Initialize( this, HUD::CTRL_HALO_WEIGHT_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_HaloWidthSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_HaloWidthSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_HaloWidthSF.SetText( L"Width" );
	m_HaloWidthSF.SetRange( 0.0f, 0.5f );
	m_HaloWidthSF.SetStep( 0.001f );
	m_HaloWidthSF.SetValue( lfSettings.haloWidth );
	m_HaloWidthSF.Initialize( this, HUD::CTRL_HALO_WIDTH_SF );
	itemY += HUD::ITEM_YY_STEP;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_BrustL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_BrustL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BrustL.SetText( L"Brust:" );
	m_BrustL.SetState( True );
	m_BrustL.Initialize( this, HUD::CTRL_BRUST_L );

	m_BrustSharpnessSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BrustSharpnessSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BrustSharpnessSF.SetText( L"Sharpness" );
	m_BrustSharpnessSF.SetRange( 1.0f, 10.0f );
	m_BrustSharpnessSF.SetStep( 0.001f );
	m_BrustSharpnessSF.SetValue( lfSettings.brustSharpness );
	m_BrustSharpnessSF.Initialize( this, HUD::CTRL_BRUST_SHARPNESS_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_BrustIntensitySF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BrustIntensitySF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BrustIntensitySF.SetText( L"Intensity" );
	m_BrustIntensitySF.SetRange( 0.0f, 10.0f );
	m_BrustIntensitySF.SetStep( 0.001f );
	m_BrustIntensitySF.SetValue( lfSettings.brustIntensity );
	m_BrustIntensitySF.Initialize( this, HUD::CTRL_BRUST_INTENSITY_SF );
	itemY += HUD::ITEM_YY_STEP;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_DirtL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_DirtL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_DirtL.SetText( L"Dirt:" );
	m_DirtL.SetState( True );
	m_DirtL.Initialize( this, HUD::CTRL_DIRT_L );

	m_DirtSharpnessSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_DirtSharpnessSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_DirtSharpnessSF.SetText( L"Sharpness" );
	m_DirtSharpnessSF.SetRange( 1.0f, 10.0f );
	m_DirtSharpnessSF.SetStep( 0.001f );
	m_DirtSharpnessSF.SetValue( lfSettings.dirtSharpness );
	m_DirtSharpnessSF.Initialize( this, HUD::CTRL_DIRT_SHARPNESS_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_DirtIntensitySF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_DirtIntensitySF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_DirtIntensitySF.SetText( L"Intensity" );
	m_DirtIntensitySF.SetRange( 0.0f, 10.0f );
	m_DirtIntensitySF.SetStep( 0.001f );
	m_DirtIntensitySF.SetValue( lfSettings.dirtIntensity );
	m_DirtIntensitySF.Initialize( this, HUD::CTRL_DIRT_INTENSITY_SF );
	itemY += HUD::ITEM_YY_STEP;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_MiscL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_MiscL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_MiscL.SetText( L"Misc:" );
	m_MiscL.Initialize( this, HUD::CTRL_HALO_L );

	m_DistortionSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_DistortionSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_DistortionSF.SetText( L"Distortion" );
	m_DistortionSF.SetRange( 0.0f, 10.0f );
	m_DistortionSF.SetStep( 0.001f );
	m_DistortionSF.SetValue( lfSettings.distortion );
	m_DistortionSF.Initialize( this, HUD::CTRL_DISTORTION_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_BlurSI.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BlurSI.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BlurSI.SetText( L"Blur" );
	m_BlurSI.SetRange( 0, 60 );
	m_BlurSI.SetStep( 1 );
	m_BlurSI.SetValue( lfSettings.blur.GetIntValue() );
	m_BlurSI.Initialize( this, HUD::CTRL_BLUR_SI );
	itemY += HUD::ITEM_Y_STEP;

	m_IntensitySF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_IntensitySF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_IntensitySF.SetText( L"Intensity" );
	m_IntensitySF.SetRange( 0.0f, 10.0f );
	m_IntensitySF.SetStep( 0.001f );
	m_IntensitySF.SetValue( lfSettings.intensity );
	m_IntensitySF.Initialize( this, HUD::CTRL_INTENSITY_SF );
	itemY += HUD::ITEM_Y_STEP;
}

void HUD::OnDispose( void )
{
	MIX_RELEASE( m_pDirtTex );
	MIX_RELEASE( m_pBrustTex );
	MIX_RELEASE( m_pCamera );
}

void HUD::OnCheckBox_Click( Utility::UI::CheckBox* pCheckBox )
{
	switch( pCheckBox->GetID() )
	{
	case HUD::CTRL_BRUST_L:
		if( m_pBrustTex != NULL )
		{
			m_pCamera->SetLensFlareTexture( Mix::Scene::ICamera::LFT_BRUST, m_pBrustTex );
			MIX_RELEASE( m_pBrustTex );
		}
		else
		{
			m_pCamera->GetLensFlareTexture( Mix::Scene::ICamera::LFT_BRUST, &m_pBrustTex );
			m_pCamera->SetLensFlareTexture( Mix::Scene::ICamera::LFT_BRUST, NULL );
		}
		break;

	case HUD::CTRL_DIRT_L:
		if( m_pDirtTex != NULL )
		{
			m_pCamera->SetLensFlareTexture( Mix::Scene::ICamera::LFT_DIRT, m_pDirtTex );
			MIX_RELEASE( m_pDirtTex );
		}
		else
		{
			m_pCamera->GetLensFlareTexture( Mix::Scene::ICamera::LFT_DIRT, &m_pDirtTex );
			m_pCamera->SetLensFlareTexture( Mix::Scene::ICamera::LFT_DIRT, NULL );
		}
		break;
	}
}

void HUD::OnSlider_ValueChanged( Utility::UI::SliderI* pSlider )
{
	Mix::Scene::ICamera::LENS_FLARE_SETTINGS lfSettings = m_pCamera->GetLensFlareSettings();
	Int32 valueI;

	switch( pSlider->GetID() )
	{
	case HUD::CTRL_GHOST_NUM_SI:
		lfSettings.ghostNum = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;

	case HUD::CTRL_BLUR_SI:
		valueI = pSlider->GetValue();
		if( valueI > 0 )
		{
			lfSettings.blur = Mix::Scene::BLUR::GAUSSIAN_EX( 4 + valueI );
		}
		else
		{
			lfSettings.blur = Mix::Scene::BLUR::NONE();
		}
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	}
}

void HUD::OnSlider_ValueChanged( Utility::UI::SliderF* pSlider )
{
	Mix::Scene::ICamera::LENS_FLARE_SETTINGS lfSettings = m_pCamera->GetLensFlareSettings();

	switch( pSlider->GetID() )
	{
	case HUD::CTRL_BP_WHITE_SF:
		lfSettings.brightPass.white = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_BP_THRESHOLD_SF:
		lfSettings.brightPass.threshold = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_BP_OFFSET_SF:
		lfSettings.brightPass.offset = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;

	case HUD::CTRL_GHOST_WEIGHT_SF:
		lfSettings.ghostWeight = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_GHOST_DISPERSAL_SF:
		lfSettings.ghostDispersal = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;

	case HUD::CTRL_HALO_WEIGHT_SF:
		lfSettings.haloWeight = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_HALO_WIDTH_SF:
		lfSettings.haloWidth = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;

	case HUD::CTRL_BRUST_SHARPNESS_SF:
		lfSettings.brustSharpness = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_BRUST_INTENSITY_SF:
		lfSettings.brustIntensity = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;

	case HUD::CTRL_DIRT_SHARPNESS_SF:
		lfSettings.dirtSharpness = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_DIRT_INTENSITY_SF:
		lfSettings.dirtIntensity = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;

	case HUD::CTRL_DISTORTION_SF:
		lfSettings.distortion = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	case HUD::CTRL_INTENSITY_SF:
		lfSettings.intensity = pSlider->GetValue();
		m_pCamera->SetLensFlareSettings( lfSettings );
		break;
	}
}
