import class PhotomodeLightInitializedEvent extends Event
{
	import var light : weak< Entity >;
}

import class PhotomodeCameraSwitchedEvent extends Event
{
	import var camera : weak< Entity >;
}

import class PhotomodeSetActiveLightEvent extends Event
{
	private import var isLightTabActive : Bool;
	private import var isCurrentLightEnabled : Bool;
	private import var lightIndex : Int32;

	public const function GetIndex() : Int32
	{
		if( !( isLightTabActive ) || !( isCurrentLightEnabled ) )
		{
			return -1;
		}
		return lightIndex;
	}

}

import class PhotomodeLightIndicatorController extends inkLogicController
{
	editable var m_indicatorRef : inkWidgetRef;
	editable var m_indicatorIconRef : inkWidgetRef;
	editable var m_indicatorNumRef : inkTextRef;
	editable var m_correctionAngle : Float;
	var m_activeIndex : Int32;
	var m_currentCamera : weak< Entity >;
	var m_maxSize : Vector2;

	public import function GetProjection( index : Int32 ) : weak< inkScreenProjection >;
	public import function ClearProjections();

	protected event OnInitialize()
	{
		m_maxSize = GetRootWidget().GetSize();
		inkWidgetRef.SetVisible( m_indicatorRef, false );
	}

	protected event OnUninitialize()
	{
		ClearProjections();
	}

	protected event OnSetActiveCamera( evt : PhotomodeCameraSwitchedEvent )
	{
		m_currentCamera = evt.camera;
	}

	protected event OnActiveIndexChanged( evt : PhotomodeSetActiveLightEvent )
	{
		var projection : weak< inkScreenProjection >;
		if( !( inkWidgetRef.IsValid( m_indicatorRef ) ) )
		{
			return false;
		}
		projection = GetCurrentProjection();
		if( projection != NULL )
		{
			projection.UnregisterListener( this, 'OnUpdateProjection' );
		}
		m_activeIndex = evt.GetIndex();
		inkTextRef.SetText( m_indicatorNumRef, IntToString( m_activeIndex + 1 ) );
		projection = GetCurrentProjection();
		if( projection != NULL )
		{
			projection.RegisterListener( this, 'OnUpdateProjection' );
			OnUpdateProjection( projection );
		}
		else
		{
			inkWidgetRef.SetVisible( m_indicatorRef, false );
		}
	}

	protected event OnUpdateProjection( projection : inkScreenProjection )
	{
		var angle : Float;
		var position : Vector2;
		var direction : Vector2;
		var halfSize : Vector2;
		if( !( m_currentCamera ) || projection.IsInScreen() )
		{
			inkWidgetRef.SetVisible( m_indicatorRef, false );
			return false;
		}
		inkWidgetRef.SetVisible( m_indicatorRef, true );
		halfSize = Vector2( m_maxSize.X / 4.0, m_maxSize.Y / 4.0 );
		position = projection.uvPosition;
		position.X = ClampF( position.X, -1.0, 1.0 );
		position.Y = ClampF( position.Y, -1.0, 1.0 );
		if( position.X == 1.0 )
		{
			inkWidgetRef.SetAnchor( m_indicatorRef, inkEAnchor.CenterRight );
			position.Y = halfSize.Y * position.Y;
			inkWidgetRef.SetMargin( m_indicatorRef, 0.0, -( position.Y ), 0.0, position.Y );
		}
		else if( position.X == -1.0 )
		{
			inkWidgetRef.SetAnchor( m_indicatorRef, inkEAnchor.CenterLeft );
			position.Y = halfSize.Y * position.Y;
			inkWidgetRef.SetMargin( m_indicatorRef, 0.0, -( position.Y ), 0.0, position.Y );
		}
		else if( position.Y == 1.0 )
		{
			inkWidgetRef.SetAnchor( m_indicatorRef, inkEAnchor.TopCenter );
			position.X = halfSize.X * position.X;
			inkWidgetRef.SetMargin( m_indicatorRef, position.X, 0.0, -( position.X ), 0.0 );
		}
		else if( position.Y == -1.0 )
		{
			inkWidgetRef.SetAnchor( m_indicatorRef, inkEAnchor.BottomCenter );
			position.X = halfSize.X * position.X;
			inkWidgetRef.SetMargin( m_indicatorRef, position.X, 0.0, -( position.X ), 0.0 );
		}
		direction = Vector2.Normalize( projection.uvPosition );
		angle = Rad2Deg( AcosF( -( direction.X ) ) );
		angle = ( ( ( direction.Y < 0.0 ) ) ? ( -( angle ) ) : ( angle ) ) + m_correctionAngle;
		inkWidgetRef.SetRotation( m_indicatorRef, angle );
		inkWidgetRef.SetRotation( m_indicatorIconRef, -( angle ) );
	}

	private function GetCurrentProjection() : weak< inkScreenProjection >
	{
		return GetProjection( m_activeIndex );
	}

}

