// Fill out your copyright notice in the Description page of Project Settings.


#include "AC_PlayerDialogueInterpreter.h"

#include "EndlessVendetta/EndlessVendettaCharacter.h"


// Sets default values for this component's properties
UAC_PlayerDialogueInterpreter::UAC_PlayerDialogueInterpreter()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = false;

	// ...
}


// Called when the game starts
void UAC_PlayerDialogueInterpreter::BeginPlay()
{
	Super::BeginPlay();

	// ...
}

FDialogueCharacter* UAC_PlayerDialogueInterpreter::GetCharacterSpeakingFromEnum(ECharacterSpeaking CharacterSpeakingEnum) const
{
	switch (CharacterSpeakingEnum)
	{
	case ECharacterSpeaking::Character1:
		return &CurrentDialogueTree->Character1;
	case ECharacterSpeaking::Character2:
		return &CurrentDialogueTree->Character2;
	case ECharacterSpeaking::Character3:
		return &CurrentDialogueTree->Character3;
	case ECharacterSpeaking::Character4:
		return &CurrentDialogueTree->Character4;
	}
	return nullptr;
}

// Called every frame
void UAC_PlayerDialogueInterpreter::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// ...
}

void UAC_PlayerDialogueInterpreter::StartDialogue(UDialogueTree* DialogueTree)
{
	CurrentDialogueTree = DialogueTree;
	CurrentTextNode = Cast<UDialogueTextNode>(DialogueTree->RootNodes[0]->ChildrenNodes[0]);
	if (!IsValid(CurrentTextNode)) return;
	CurrentCharacterSpeaking = *GetCharacterSpeakingFromEnum(CurrentTextNode->DialogueCharacterSpeaking);
	OnStartDialogue.Broadcast(CurrentTextNode);

	if (APlayerController* PlayerController = GetWorld()->GetFirstPlayerController())
	{
		FInputModeUIOnly InputModeData;
		InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
		PlayerController->SetInputMode(InputModeData);
		PlayerController->bShowMouseCursor = true;
	}
}

void UAC_PlayerDialogueInterpreter::NextDialogue()
{
	if (!IsValid(CurrentTextNode)) return;
	if (IsValid(CurrentChoiceNode)) return;
	if (CurrentTextNode->ChildrenNodes.Num() == 0)
	{
		EndDialogue();
		return;
	}
	if (Cast<UDialogueChoiceNode>(CurrentTextNode->ChildrenNodes[0]))
	{
		CurrentChoiceNode = Cast<UDialogueChoiceNode>(CurrentTextNode->ChildrenNodes[0]);
		OnChoiceDialogue.Broadcast(CurrentChoiceNode);
		CurrentTextNode = nullptr;
	}
	else
	{
		CurrentTextNode = Cast<UDialogueTextNode>(CurrentTextNode->ChildrenNodes[0]);
		CurrentCharacterSpeaking = *GetCharacterSpeakingFromEnum(CurrentTextNode->DialogueCharacterSpeaking);
		OnNextDialogue.Broadcast(CurrentTextNode);
		CurrentChoiceNode = nullptr;
	}
}

void UAC_PlayerDialogueInterpreter::MakeChoiceDialogue(const int Choice)
{
	if (!IsValid(CurrentChoiceNode)) return;
	if (Cast<UDialogueChoiceNode>(CurrentChoiceNode->ChildrenNodes[Choice]))
	{
		CurrentChoiceNode = Cast<UDialogueChoiceNode>(CurrentChoiceNode->ChildrenNodes[Choice]);
		OnChoiceDialogue.Broadcast(CurrentChoiceNode);
		CurrentTextNode = nullptr;
	}
	else
	{
		CurrentTextNode = Cast<UDialogueTextNode>(CurrentChoiceNode->ChildrenNodes[Choice]);
		CurrentCharacterSpeaking = *GetCharacterSpeakingFromEnum(CurrentTextNode->DialogueCharacterSpeaking);
		OnNextDialogue.Broadcast(CurrentTextNode);
		CurrentChoiceNode = nullptr;
	}
}

void UAC_PlayerDialogueInterpreter::EndDialogue()
{
	CurrentChoiceNode = nullptr;
	CurrentTextNode = nullptr;
	CurrentCharacterSpeaking = FDialogueCharacter();
	OnEndDialogue.Broadcast();

	if (APlayerController* PlayerController = GetWorld()->GetFirstPlayerController())
	{
		const FInputModeGameOnly InputModeData;
		PlayerController->SetInputMode(InputModeData);
		PlayerController->bShowMouseCursor = false;
	}
}
