#include "hud.h"

#include "Mix/Scene/ICamera.h"

HUD::HUD( void ) :
m_pCamera( NULL )
{
}

HUD::~HUD( void )
{
}

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

	Int32 itemY = 16;

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

	MIX_ADD_REF( pCamera );
	m_pCamera = pCamera;

	const Mix::Point& screenSize = m_pCamera->GetConfig().targetSize;
	const Mix::Scene::ICamera::LUMINOSITY_SETTINGS& lumSettings = pCamera->GetLuminositySettings();
	const Mix::Scene::ICamera::BLOOM_SETTINGS& bloomSettings = pCamera->GetBloomSettings();

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

	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_LumL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_LumL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumL.SetText( L"Luminance:" );
	m_LumL.Initialize( this, HUD::CTRL_LUM_L );

	m_LumToneMappingCB.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumToneMappingCB.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumToneMappingCB.SetText( L"ToneMapping" );
	m_LumToneMappingCB.SetState( MIX_TESTBIT( lumSettings.flags, Mix::Scene::ICamera::LUM_TONE_MAPPING ) == Mix::Scene::ICamera::LUM_TONE_MAPPING );
	m_LumToneMappingCB.Initialize( this, HUD::CTRL_LUM_TONE_MAPPING_CB );
	itemY += HUD::ITEM_Y_STEP;

	m_LumBlueShiftCB.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumBlueShiftCB.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumBlueShiftCB.SetText( L"BlueShift" );
	m_LumBlueShiftCB.SetState( MIX_TESTBIT( lumSettings.flags, Mix::Scene::ICamera::LUM_BLUE_SHIFT ) == Mix::Scene::ICamera::LUM_BLUE_SHIFT );
	m_LumBlueShiftCB.Initialize( this, HUD::CTRL_LUM_BLUE_SHIFT_CB );
	itemY += HUD::ITEM_Y_STEP;

	m_LumWhiteSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumWhiteSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumWhiteSF.SetText( L"White" );
	m_LumWhiteSF.SetRange( 0.001f, 1.0f );
	m_LumWhiteSF.SetStep( 0.001f );
	m_LumWhiteSF.SetValue( lumSettings.white );
	m_LumWhiteSF.Initialize( this, HUD::CTRL_LUM_WHITE_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_LumRodsSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumRodsSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumRodsSF.SetText( L"Rods" );
	m_LumRodsSF.SetRange( 0.0f, 1.0f );
	m_LumRodsSF.SetStep( 0.1f );
	m_LumRodsSF.SetValue( lumSettings.rods );
	m_LumRodsSF.Initialize( this, HUD::CTRL_LUM_RODS_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_LumConesSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumConesSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumConesSF.SetText( L"Cones" );
	m_LumConesSF.SetRange( 0.0f, 1.0f );
	m_LumConesSF.SetStep( 0.1f );
	m_LumConesSF.SetValue( lumSettings.cones );
	m_LumConesSF.Initialize( this, HUD::CTRL_LUM_CONES_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_LumForceAdaptationB.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumForceAdaptationB.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumForceAdaptationB.SetText( L"ForceAdaptation" );
	m_LumForceAdaptationB.Initialize( this, HUD::CTRL_LUM_FORCE_ADAPTATION );
	itemY += HUD::ITEM_Y_STEP;

	m_LumSRAdaptationB.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_LumSRAdaptationB.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_LumSRAdaptationB.SetText( L"SuspendAdaptation" );
	m_LumSRAdaptationB.Initialize( this, HUD::CTRL_LUM_SR_ADAPTATION );
	itemY += HUD::ITEM_YY_STEP;

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

	m_BloomL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_BloomL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BloomL.SetText( L"Bloom:" );
	m_BloomL.Initialize( this, HUD::CTRL_BLOOM_L );

	m_BloomEnabledCB.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BloomEnabledCB.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BloomEnabledCB.SetText( L"Enabled" );
	m_BloomEnabledCB.SetState( m_pCamera->IsBloomEnabled() );
	m_BloomEnabledCB.Initialize( this, HUD::CTRL_BLOOM_ENABLED_CB );
	itemY += HUD::ITEM_Y_STEP;

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

	m_BloomOffsetSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BloomOffsetSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BloomOffsetSF.SetText( L"Offset" );
	m_BloomOffsetSF.SetRange( 0.001f, 4.0f );
	m_BloomOffsetSF.SetStep( 0.001f );
	m_BloomOffsetSF.SetValue( bloomSettings.brightPass.offset );
	m_BloomOffsetSF.Initialize( this, HUD::CTRL_BLOOM_OFFSET_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_BloomThresholdSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BloomThresholdSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BloomThresholdSF.SetText( L"Threshold" );
	m_BloomThresholdSF.SetRange( 0.001f, 4.0f );
	m_BloomThresholdSF.SetStep( 0.001f );
	m_BloomThresholdSF.SetValue( bloomSettings.brightPass.threshold );
	m_BloomThresholdSF.Initialize( this, HUD::CTRL_BLOOM_THRESHOLD_SF );
	itemY += HUD::ITEM_Y_STEP;

	m_BloomScaleSF.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_BloomScaleSF.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_BloomScaleSF.SetText( L"Intensity" );
	m_BloomScaleSF.SetRange( 0.001f, 2.0f );
	m_BloomScaleSF.SetStep( 0.001f );
	m_BloomScaleSF.SetValue( bloomSettings.intensity );
	m_BloomScaleSF.Initialize( this, HUD::CTRL_BLOOM_SCALE_SF );
	itemY += HUD::ITEM_YY_STEP;

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

	m_DofL.SetPosition( Mix::Point( HUD::LABEL_X, itemY ) );
	m_DofL.SetSize( Mix::Point( HUD::LABEL_WIDTH, HUD::ITEM_HEIGHT ) );
	m_DofL.SetText( L"Dof:" );
	m_DofL.Initialize( this, HUD::CTRL_DOF_L );

	m_DofEnabledCB.SetPosition( Mix::Point( HUD::ITEM_X, itemY ) );
	m_DofEnabledCB.SetSize( Mix::Point( HUD::ITEM_WIDTH, HUD::ITEM_HEIGHT ) );
	m_DofEnabledCB.SetText( L"Enabled" );
	m_DofEnabledCB.SetState( m_pCamera->IsDofEnabled() );
	m_DofEnabledCB.Initialize( this, HUD::CTRL_DOF_ENABLED_CB );
	itemY += HUD::ITEM_YY_STEP;
}

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

void HUD::OnButton_Click( Utility::UI::Button* pButton )
{
	switch( pButton->GetID() )
	{
	case HUD::CTRL_LUM_FORCE_ADAPTATION:
		m_pCamera->ForceLuminosityAdaptation();
		break;
	case HUD::CTRL_LUM_SR_ADAPTATION:
		if( m_pCamera->GetLuminosityAdaptationSuspendCount() > 0 )
		{
			m_pCamera->ResumeLuminosityAdaptation();
			pButton->SetText( L"SuspendAdaptation" );
		}
		else
		{
			m_pCamera->SusupendLuminosityAdaptation();
			pButton->SetText( L"ResumeAdaptation" );
		}
		break;
	}
}

void HUD::OnCheckBox_Click( Utility::UI::CheckBox* pCheckBox )
{
	Mix::Scene::ICamera::LUMINOSITY_SETTINGS lumSettings = m_pCamera->GetLuminositySettings();

	switch( pCheckBox->GetID() )
	{
	case HUD::CTRL_LUM_TONE_MAPPING_CB:
		if( pCheckBox->GetState() == True )
		{
			MIX_SETBIT( lumSettings.flags, Mix::Scene::ICamera::LUM_TONE_MAPPING );
		}
		else
		{
			MIX_RESETBIT( lumSettings.flags, Mix::Scene::ICamera::LUM_TONE_MAPPING );
		}
		m_pCamera->SetLuminositySettings( lumSettings );
		break;
	case HUD::CTRL_LUM_BLUE_SHIFT_CB:
		if( pCheckBox->GetState() == True )
		{
			MIX_SETBIT( lumSettings.flags, Mix::Scene::ICamera::LUM_BLUE_SHIFT );
		}
		else
		{
			MIX_RESETBIT( lumSettings.flags, Mix::Scene::ICamera::LUM_BLUE_SHIFT );
		}
		m_pCamera->SetLuminositySettings( lumSettings );
		break;

	case HUD::CTRL_BLOOM_ENABLED_CB:
		m_pCamera->SetBloomEnabled( pCheckBox->GetState() );
		break;

	case HUD::CTRL_DOF_ENABLED_CB:
		m_pCamera->SetDofEnabled( pCheckBox->GetState() );
		break;
	}
}

void HUD::OnSlider_ValueChanged( Utility::UI::SliderF* pSlider )
{
	Mix::Scene::ICamera::LUMINOSITY_SETTINGS lumSettings = m_pCamera->GetLuminositySettings();
	Mix::Scene::ICamera::BLOOM_SETTINGS bloomSettings = m_pCamera->GetBloomSettings();

	switch( pSlider->GetID() )
	{
	case HUD::CTRL_LUM_WHITE_SF:
		lumSettings.white = pSlider->GetValue();
		m_pCamera->SetLuminositySettings( lumSettings );
		break;
	case HUD::CTRL_LUM_RODS_SF:
		lumSettings.rods = pSlider->GetValue();
		m_pCamera->SetLuminositySettings( lumSettings );
		break;
	case HUD::CTRL_LUM_CONES_SF:
		lumSettings.cones = pSlider->GetValue();
		m_pCamera->SetLuminositySettings( lumSettings );
		break;

	case HUD::CTRL_BLOOM_WHITE_SF:
		bloomSettings.brightPass.white = pSlider->GetValue();
		m_pCamera->SetBloomSettings( bloomSettings );
		break;
	case HUD::CTRL_BLOOM_OFFSET_SF:
		bloomSettings.brightPass.offset = pSlider->GetValue();
		m_pCamera->SetBloomSettings( bloomSettings );
		break;
	case HUD::CTRL_BLOOM_THRESHOLD_SF:
		bloomSettings.brightPass.threshold = pSlider->GetValue();
		m_pCamera->SetBloomSettings( bloomSettings );
		break;
	case HUD::CTRL_BLOOM_SCALE_SF:
		bloomSettings.intensity = pSlider->GetValue();
		m_pCamera->SetBloomSettings( bloomSettings );
		break;
	}
}
