/*
	--------------------------------------------------------------
	KF_DialogueSpot_SE
	--------------------------------------------------------------

    

	Author :  			PooSH
	Original Author:	Alex Quick

	--------------------------------------------------------------
*/

class KF_DialogueSpot_SE	extends KF_DialogueSpot
placeable;

/**
	ERequiredEventType - determines what to do on RequiredEvent triggered:
	RET_Trigger		Act the same as original KF_DialogueSpot - start dialogue from triggered index
	RET_Enable		Just enables triggered index (doesn't show dialogue). 
	RET_Disable		Disables triggered index (doesn't show dialogue)
	RET_Toggle		Toggles between enabled and disabled
	
	In all cases except RET_Trigger, bLooping shows if dialogue is initially DISABLED 
*/
enum ERequiredEventType
{
	RET_Trigger,
	RET_Enable,
	RET_Disable,
	RET_Toggle
};
var(KF_DialogueSpot) const ERequiredEventType RequiredEventType;

var(KF_DialogueSpot) float DisplayTimePerWord;
var(KF_DialogueSpot) float DisplayTimePerChar;
var(KF_DialogueSpot) float MinDisplayTime;
var(KF_DialogueSpot) float MaxDisplayTime;



function PostBeginPlay()
{
	local int i;
	local Dialogue_EventListener		NewListener;

    /* No KFO Gametype, no Initialization */
	if(KFStoryGameinfo(Level.Game) == none)
	{
        return;
	}

	// Spawn Event listeners for Dialogue entries which require them.
	for(i = 0 ; i < Dialogues.length ; i ++)
	{
		NewListener = Spawn(class'Dialogue_EventListener_SE',self,Dialogues[i].Events.RequiredEvent);
		NewListener.AssociatedIndex = i ;
		Dialogues[i].EventListener = NewListener;
		if ( RequiredEventType != RET_Trigger && Dialogues[i].Events.RequiredEvent != '' )
			Dialogues[i].bWasTriggered = Dialogues[i].bLooping;
	}
}

// C&P to set bLooping as default bWasTriggered state  -- PooSH
function Reset()
{
	local int i, SavedIdx;
	local array<byte>	SavedTriggerStates;

	Super.Reset();

	/* Partial reset using saved positions*/

	bTraversing = false;

	if(!bFinished)
	{
		SavedIdx = KFStoryGameInfo(Level.Game).CurrentCheckPoint.GetSavedDialogueIndexFor(self,SavedTriggerStates) ;
		CurrentMsgIdx =  SavedIdx;

		if(bDebugDialogue)
		{
			log("----- DIALOGUE DEBUG ------   Resetting "@self@". Dialogue will play back from Index : "@SavedIdx, 'Story_Debug');
		}

		for(i = 0 ; i < Dialogues.length ; i ++)
		{
			Dialogues[i].bWasTriggered = bool(SavedTriggerStates[i]);
		}
	}
	else	/* Full reset from the start. */
	{
 		for(i = 0 ; i < Dialogues.length ; i ++)
		{
			if ( RequiredEventType != RET_Trigger && Dialogues[i].Events.RequiredEvent != '' )
				Dialogues[i].bWasTriggered = Dialogues[i].bLooping;
			else
				Dialogues[i].bWasTriggered = false;
		}

		CurrentMsgIdx = 0;
		bFinished = false;
	}
}

function		int			GetNextDlgRequiredEventIdx(int 	TestIndex)
{
	if ( RequiredEventType == RET_Trigger )
		return super.GetNextDlgRequiredEventIdx(TestIndex);
	
	return -1; // for other event types - event is not required, it just enables/disables that dialogue
}

function int GetRandomEnabledDialogueIndex()
{
	local array<int> AvaliableIndicies;
	local int i;
	
	for ( i=0; i<Dialogues.length; ++i ) {
		if ( !Dialogues[i].bWasTriggered )
			AvaliableIndicies[AvaliableIndicies.Length] = i;
	}
	
	if ( AvaliableIndicies.length == 0 )
		return -1;
	if ( AvaliableIndicies.length == 1)
		return 0;
	return AvaliableIndicies[RandRange(0,AvaliableIndicies.length)];
}

function TraverseDialogue()
{
	local float DisplayDur;
	
	if ( RequiredEventType == RET_Trigger ) {
		super.TraverseDialogue();
		return;
	}

	/* Hit the end. early out */
	if( bTraversing || bFinished )
		return;

	if(bRandomize) {
		CurrentMsgIdx = GetRandomEnabledDialogueIndex();
		if ( CurrentMsgIdx == -1 ) {
			OnDialogueCompleted();
			return;
		}
	}
	else if ( CurrentMsgIdx >= Dialogues.length ) {
		return;
	}

	while ( CurrentMsgIdx < Dialogues.length && Dialogues[CurrentMsgIdx].bWasTriggered )
		CurrentMsgIdx++;
		
	if ( CurrentMsgIdx >= Dialogues.length ) {
		OnDialogueCompleted();
		return;
	}


	if(bDebugDialogue)
	{
		log("----- DIALOGUE DEBUG ------  Showing Dialogue at index .. "@CurrentMsgIdx, 'Story_Debug');
	}
	ShowDialogue(CurrentMsgIdx);
	
	if( !bRandomize ) {
		if(CurrentMsgIdx + 1 < Dialogues.length )
		{
			bTraversing = true;

			DisplayDur = GetCurrentDisplayDur();
			if(DisplayDur > 0)
			{
				SetTimer(DisplayDur,false);
			}
			else
			{
				Timer();
			}
		}
		else
		{
			/* we're finished. Reset the actor */
			OnDialogueCompleted();
		}
	}
}

function Timer()
{
	if ( RequiredEventType == RET_Trigger ) {
		super.Timer();
		return;
	}
	
	if(bTraversing)	{
		bTraversing = false;
		CurrentMsgIdx++ ;
		TraverseDialogue();
	}
}

/* Helper function - calculates the amount of time a string should
be displayed for based on its word length  */

function float CalcDisplayTime(string InString)
{
    local array<string> Words;

	if ( DisplayTimePerWord > 0 )
		Split(InString," ",Words);
	
	return FClamp(Words.length * DisplayTimePerWord + Len(InString)*DisplayTimePerChar, MinDisplayTime, MaxDisplayTime);
}

defaultproperties
{
     DisplayTimePerWord=0.300000
     MinDisplayTime=3.000000
     MaxDisplayTime=60.000000
}
