class InspectItemInspectionEvent extends Event
{
	var owner : weak< GameObject >;
}

class LootItemInspectionEvent extends Event
{
	var owner : weak< GameObject >;
}

import enum questObjectInspectEventType
{
	Undefined,
	Started,
	Finished,
}

importonly abstract class IInspectListener extends IScriptable
{
}

importonly class ObjectInspectListener extends IInspectListener
{
	public import function OnInspect( type : questObjectInspectEventType );
}

importonly class InspectListenerEvent extends Event
{
	import var listener : ObjectInspectListener;
	import var register : Bool;
}

class SetInspectStateEvent extends Event
{
	var state : questObjectInspectEventType;
}

class InspectableObjectComponentPS extends GameComponentPS
{
	private persistent var m_isStarted : Bool;
	private persistent var m_isFinished : Bool;
	private var m_listeners : array< ObjectInspectListener >;

	public const function IsState( state : questObjectInspectEventType ) : Bool
	{
		if( state == questObjectInspectEventType.Started && m_isStarted )
		{
			return true;
		}
		if( state == questObjectInspectEventType.Finished && m_isFinished )
		{
			return true;
		}
		return false;
	}

	public function OnRegisterListener( evt : InspectListenerEvent ) : EntityNotificationType
	{
		if( evt.register )
		{
			m_listeners.PushBack( evt.listener );
		}
		else
		{
			m_listeners.Remove( evt.listener );
		}
		return EntityNotificationType.DoNotNotifyEntity;
	}

	public function OnSetState( evt : SetInspectStateEvent ) : EntityNotificationType
	{
		if( evt.state == questObjectInspectEventType.Started )
		{
			SetStarted();
		}
		else if( evt.state == questObjectInspectEventType.Finished )
		{
			SetFinished();
		}
		return EntityNotificationType.DoNotNotifyEntity;
	}

	public function SetStarted()
	{
		m_isStarted = true;
		NotifyListeners( questObjectInspectEventType.Started );
	}

	public function SetFinished()
	{
		m_isFinished = true;
		NotifyListeners( questObjectInspectEventType.Finished );
	}

	private function NotifyListeners( state : questObjectInspectEventType )
	{
		var i : Int32;
		for( i = 0; i < m_listeners.Size(); i += 1 )
		{
			m_listeners[ i ].OnInspect( state );
		}
	}

}

class InspectableObjectComponent extends ScriptableComponent
{
	instanceeditable var m_factToAdd : CName;
	instanceeditable var m_itemID : String;
	hint m_itemID = "Item from this definition will be given to player when he decides to loot inspectable object";
	instanceeditable var m_offset : Float;
	default m_offset = 0.5f;
	instanceeditable var m_adsOffset : Float;
	default m_adsOffset = 0.25f;
	instanceeditable var m_timeToScan : Float;
	default m_timeToScan = 2.f;
	private var m_slot : String;
	default m_slot = "AttachmentSlots.Inspect";

	protected const override function GetPS() : InspectableObjectComponentPS
	{
		return ( ( InspectableObjectComponentPS )( GetBasePS() ) );
	}

	private function InspectObject( activator : GameObject )
	{
		var evt : InspectionTriggerEvent;
		evt = new InspectionTriggerEvent;
		evt.inspectedObjID = GetOwner().GetEntityID();
		evt.item = m_itemID;
		evt.offset = m_offset;
		evt.adsOffset = m_adsOffset;
		evt.timeToScan = m_timeToScan;
		activator.QueueEvent( evt );
		SetInspectableObjectState( false );
		SetFactValue( GetOwner().GetGame(), m_factToAdd, 1 );
		GetPS().SetStarted();
	}

	protected event OnInspectEvent( evt : ObjectInspectEvent )
	{
		SetInspectableObjectState( evt.showItem );
	}

	private function GiveInspectableItem( activator : GameObject )
	{
		var inspectEvt : ObjectInspectEvent;
		var transSystem : TransactionSystem;
		transSystem = GameInstance.GetTransactionSystem( GetOwner().GetGame() );
		transSystem.GiveItem( activator, ItemID.FromTDBID( TDBID.Create( m_itemID ) ), 1 );
		inspectEvt = new ObjectInspectEvent;
		inspectEvt.showItem = false;
		GetOwner().QueueEvent( inspectEvt );
		GetPS().SetFinished();
	}

	protected event OnInspectItem( evt : InspectItemInspectionEvent )
	{
		InspectObject( evt.owner );
	}

	protected event OnLootItem( evt : InspectItemInspectionEvent )
	{
		GiveInspectableItem( evt.owner );
	}

	private function SetInspectableObjectState( b : Bool )
	{
		var owner : InspectDummy;
		var state : InteractionSetEnableEvent;
		owner = ( ( InspectDummy )( GetOwner() ) );
		state = new InteractionSetEnableEvent;
		state.enable = b;
		owner.QueueEvent( state );
		owner.m_mesh.Toggle( b );
	}

}

