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

#include "SelectableActorBase.h"
#include "UObject/ConstructorHelpers.h"
#include "Runtime/Engine/Classes/Engine/StaticMesh.h"
#include "Kismet/GameplayStatics.h"
#include "Blueprint/UserWidget.h"
#include "Runtime/Engine/Classes/Materials/MaterialInstanceDynamic.h"

#include "OptiXVRPawn.h"

ASelectableActorBase::ASelectableActorBase(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{

	UE_LOG(LogTemp, Display, TEXT("OptiX ASelectableActorBase Constructor Start"));

	SetMobility(EComponentMobility::Movable);

	GetStaticMeshComponent()->SetGenerateOverlapEvents(true);
	GetStaticMeshComponent()->CastShadow = 0;

	UE_LOG(LogTemp, Display, TEXT("OptiX ASelectableActorBase Constructor Component Setup Start"));


	Gizmo = CreateDefaultSubobject<USceneComponent>(TEXT("Gizmo"));
	Gizmo->SetupAttachment(GetStaticMeshComponent());
	Gizmo->SetHiddenInGame(true);

	SupportWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("SupportWidget"));
	SupportWidget->SetupAttachment(Gizmo);
	static ConstructorHelpers::FClassFinder<UUserWidget> SupportWidgetClass(TEXT("/OptiX/UI/SupportSwapWidget2"));
	SupportWidget->SetWidgetClass(SupportWidgetClass.Class);
	SupportWidget->SetAbsolute(false, true, false);
	SupportWidget->SetWorldScale3D(FVector(0.05, 0.05, 0.05));
	SupportWidget->SetDrawSize(FVector2D(800, 2300));
	SupportWidget->SetGenerateOverlapEvents(false);
	SupportWidget->SetHiddenInGame(true);
	SupportWidget->SetTwoSided(true);

	UE_LOG(LogTemp, Display, TEXT("OptiX ASelectableActorBase Constructor 1/4"));


	TranslationSupport = CreateDefaultSubobject<USceneComponent>(TEXT("TranslationSupport"));
	TranslationSupport->SetupAttachment(Gizmo);

	TranslateX = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TranslateX"));
	TranslateX->SetupAttachment(TranslationSupport);
	static ConstructorHelpers::FObjectFinder<UStaticMesh> TranslateXMesh(TEXT("StaticMesh'/OptiX/UI/Translator/Arrowbody.Arrowbody'"));
	TranslateX->SetStaticMesh(TranslateXMesh.Object);
	TranslateX->SetAbsolute(false, true, false);
	TranslateX->SetWorldScale3D(FVector(0.8f, 0.8f, 0.8f));
	TranslateX->SetGenerateOverlapEvents(false);
	TranslateX->SetHiddenInGame(true);

	TranslateX->CastShadow = 0;
	TranslateX->bVisibleInReflectionCaptures = false;
	TranslateX->SetCanEverAffectNavigation(false);

	ArrowX = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ArrowX"));
	ArrowX->SetupAttachment(TranslateX);
	static ConstructorHelpers::FObjectFinder<UStaticMesh> TranslateArrow(TEXT("StaticMesh'/OptiX/UI/Translator/Arrowhead.Arrowhead'"));
	ArrowX->SetStaticMesh(TranslateArrow.Object);
	//ArrowX->SetAbsolute(false, true, false);
	//ArrowX->SetWorldScale3D(FVector(0.8f, 0.8f, 0.8f));
	ArrowX->SetRelativeLocation(FVector(39, 0, 0));
	ArrowX->SetGenerateOverlapEvents(false);
	ArrowX->SetHiddenInGame(true);
	ArrowX->SetAbsolute(false, false, true);

	ArrowX->CastShadow = 0;
	ArrowX->bVisibleInReflectionCaptures = false;
	ArrowX->SetCanEverAffectNavigation(false);

	TranslateWidgetX = CreateDefaultSubobject<UWidgetComponent>(TEXT("TranslateWidgetX"));
	TranslateWidgetX->SetAbsolute(false, true, true);
	TranslateWidgetX->SetupAttachment(ArrowX);
	static ConstructorHelpers::FClassFinder<UUserWidget> PosWidgetClass(TEXT("/OptiX/UI/Translator/PositionCounter"));
	TranslateWidgetX->SetWidgetClass(PosWidgetClass.Class);
	//TranslateWidgetX->SetRelativeLocationAndRotation(FVector(0, 0, 0), FRotator(0, 90, 0));
	//TranslateWidgetX->SetWorldRotation(FRotator());
	TranslateWidgetX->SetRelativeScale3D(FVector(0.05, 0.05, 0.05));
	TranslateWidgetX->SetDrawSize(FVector2D(300, 300));
	TranslateWidgetX->SetHiddenInGame(true);
	TranslateWidgetX->SetGenerateOverlapEvents(false);
	//TranslateWidgetX->SetTwoSided(true);
	// todo

	TranslateY = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TranslateY"));
	TranslateY->SetupAttachment(TranslationSupport);
	TranslateY->SetStaticMesh(TranslateXMesh.Object);
	TranslateY->SetAbsolute(false, true, false);
	TranslateY->SetWorldScale3D(FVector(0.6f, 0.6f, 0.6f));
	TranslateY->SetGenerateOverlapEvents(false);
	TranslateY->SetHiddenInGame(true);
	TranslateY->SetWorldRotation(FRotator(0.f, 90.0f, 0.0f));

	TranslateY->CastShadow = 0;
	TranslateY->bVisibleInReflectionCaptures = false;
	TranslateY->SetCanEverAffectNavigation(false);

	ArrowY = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ArrowY"));
	ArrowY->SetupAttachment(TranslateY);
	ArrowY->SetStaticMesh(TranslateArrow.Object);
	//ArrowY->SetAbsolute(false, true, false);
	ArrowY->SetWorldScale3D(FVector(0.6f, 0.6f, 0.6f));
	ArrowY->SetRelativeLocation(FVector(39, 0, 0));
	ArrowY->SetGenerateOverlapEvents(false);
	ArrowY->SetHiddenInGame(true);
	ArrowY->SetAbsolute(false, false, true);

	ArrowY->CastShadow = 0;
	ArrowY->bVisibleInReflectionCaptures = false;
	ArrowY->SetCanEverAffectNavigation(false);

	TranslateWidgetY = CreateDefaultSubobject<UWidgetComponent>(TEXT("TranslateWidgetY"));	
	TranslateWidgetY->SetAbsolute(false, true, true);
	TranslateWidgetY->SetupAttachment(ArrowY);
	TranslateWidgetY->SetWidgetClass(PosWidgetClass.Class);
	//TranslateWidgetY->SetWorldRotation(FRotator());
	TranslateWidgetY->SetRelativeScale3D(FVector(0.05, 0.05, 0.05));
	TranslateWidgetY->SetDrawSize(FVector2D(300, 300));
	TranslateWidgetY->SetHiddenInGame(true);
	TranslateWidgetY->SetGenerateOverlapEvents(false);
	//TranslateWidgetY->SetTwoSided(true);

	TranslateZ = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TranslateZ"));
	TranslateZ->SetupAttachment(TranslationSupport);
	TranslateZ->SetStaticMesh(TranslateXMesh.Object);
	TranslateZ->SetAbsolute(false, true, false);
	TranslateZ->SetWorldScale3D(FVector(0.6f, 0.6f, 0.6f));
	TranslateZ->SetGenerateOverlapEvents(false);
	TranslateZ->SetHiddenInGame(true);
	TranslateZ->SetWorldRotation(FRotator(90.f, 0.0f, 0.0f));
	TranslateZ->SetCanEverAffectNavigation(false);
	TranslateZ->CastShadow = 0;
	TranslateZ->bVisibleInReflectionCaptures = false;

	ArrowZ = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ArrowZ"));
	ArrowZ->SetupAttachment(TranslateZ);
	ArrowZ->SetStaticMesh(TranslateArrow.Object);
	//ArrowZ->SetAbsolute(false, true, false);
	ArrowZ->SetWorldScale3D(FVector(0.6f, 0.6f, 0.6f));
	ArrowZ->SetRelativeLocation(FVector(39, 0, 0));
	ArrowZ->SetGenerateOverlapEvents(false);
	ArrowZ->SetHiddenInGame(true);
	ArrowZ->SetAbsolute(false, false, true);
	ArrowZ->SetCanEverAffectNavigation(false);
	ArrowZ->CastShadow = 0;
	ArrowZ->bVisibleInReflectionCaptures = false;

	TranslateWidgetZ = CreateDefaultSubobject<UWidgetComponent>(TEXT("TranslateWidgetZ"));
	TranslateWidgetZ->SetAbsolute(false, true, true);
	//TranslateWidgetZ->SetTwoSided(true);

	TranslateWidgetZ->SetupAttachment(ArrowZ);
	TranslateWidgetZ->SetWidgetClass(PosWidgetClass.Class);
	//TranslateWidgetZ->SetWorldRotation(FRotator());
	TranslateWidgetZ->SetRelativeScale3D(FVector(0.05, 0.05, 0.05));
	TranslateWidgetZ->SetDrawSize(FVector2D(300, 300));
	TranslateWidgetZ->SetRelativeLocation(FVector(8, 0, 0));

	TranslateWidgetZ->SetHiddenInGame(true);
	TranslateWidgetZ->SetGenerateOverlapEvents(false);

	UE_LOG(LogTemp, Display, TEXT("OptiX ASelectableActorBase Constructor 2/4"));


	RotationSupport = CreateDefaultSubobject<USceneComponent>(TEXT("RotationSupport"));
	RotationSupport->SetupAttachment(Gizmo);

	ScaleH = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ScaleH"));
	ScaleH->SetupAttachment(RotationSupport);
	static ConstructorHelpers::FObjectFinder<UStaticMesh> ScaleMesh(TEXT("StaticMesh'/OptiX/UI/Rotator/scale1.scale1'"));
	ScaleH->SetStaticMesh(ScaleMesh.Object);
	ScaleH->SetAbsolute(false, true, false);
	ScaleH->SetGenerateOverlapEvents(false);
	ScaleH->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ScaleH->SetHiddenInGame(true);
	ScaleH->SetCanEverAffectNavigation(false);
	ScaleH->CastShadow = 0;
	ScaleH->bVisibleInReflectionCaptures = false;

	ScaleV = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ScaleV"));
	ScaleV->SetupAttachment(RotationSupport);
	ScaleV->SetStaticMesh(ScaleMesh.Object);
	ScaleV->SetWorldRotation(FRotator(90, 0, 0));
	ScaleV->SetAbsolute(false, true, false);
	ScaleV->SetGenerateOverlapEvents(false);
	ScaleV->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ScaleV->SetHiddenInGame(true);
	ScaleV->SetCanEverAffectNavigation(false);
	ScaleV->CastShadow = 0;
	ScaleV->bVisibleInReflectionCaptures = false;

	SupportH = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SupportH"));
	SupportH->SetupAttachment(RotationSupport);
	static ConstructorHelpers::FObjectFinder<UStaticMesh> SupportMesh(TEXT("StaticMesh'/OptiX/UI/Rotator/Cylinder_2.Cylinder_2'"));
	SupportH->SetStaticMesh(SupportMesh.Object);
	SupportH->SetWorldRotation(FRotator(-90, 0, 0));
	SupportH->SetWorldScale3D(FVector(0.6, 0.6, 0.3));
	SupportH->SetGenerateOverlapEvents(false);
	SupportH->SetHiddenInGame(true);
	//SupportH->SetWorldLocation(FVector(25, 0, 0));
	SupportH->SetCanEverAffectNavigation(false);
	SupportH->CastShadow = 0;
	SupportH->bVisibleInReflectionCaptures = false;

	SupportSphereH = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SupportSphereH"));
	SupportSphereH->SetupAttachment(SupportH);
	static ConstructorHelpers::FObjectFinder<UStaticMesh> SupportSphereMesh(TEXT("StaticMesh'/OptiX/UI/Rotator/SelectorSphere.SelectorSphere'"));
	SupportSphereH->SetStaticMesh(SupportSphereMesh.Object);
	SupportSphereH->SetAbsolute(false, false, true);
	SupportSphereH->SetWorldScale3D(FVector(0.03, 0.03, 0.03));
	SupportSphereH->SetGenerateOverlapEvents(false);
	SupportSphereH->SetHiddenInGame(true);
	SupportSphereH->SetRelativeLocation(FVector(0, 0, 100));
	SupportSphereH->SetCanEverAffectNavigation(false);
	SupportSphereH->CastShadow = 0;
	SupportSphereH->bVisibleInReflectionCaptures = false;

	DegreeWidgetH = CreateDefaultSubobject<UWidgetComponent>(TEXT("DegreeWidgetH"));
	DegreeWidgetH->SetupAttachment(SupportSphereH);
	static ConstructorHelpers::FClassFinder<UUserWidget> DegreeWidgetClass(TEXT("/OptiX/UI/Rotator/DegreeCounter"));
	DegreeWidgetH->SetWidgetClass(DegreeWidgetClass.Class);
	DegreeWidgetH->SetRelativeLocationAndRotation(FVector(0, 0, -40), FRotator(0, 90, -90));
	//DegreeWidgetH->SetRelativeScale3D(FVector(2.0, 2.0, 0.08));
	DegreeWidgetH->SetDrawSize(FVector2D(200, 300));
	DegreeWidgetH->SetHiddenInGame(true);
	DegreeWidgetH->SetGenerateOverlapEvents(false);
	//DegreeWidgetH->SetTwoSided(true);

	SupportV = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SupportV"));
	SupportV->SetupAttachment(RotationSupport);
	SupportV->SetStaticMesh(SupportMesh.Object);
	SupportV->SetWorldRotation(FRotator(0.0f, 0.0f, 90.0f));
	SupportV->SetWorldScale3D(FVector(0.6, 0.6, 0.3));
	SupportV->SetGenerateOverlapEvents(false);
	SupportV->SetHiddenInGame(true);
	//SupportV->SetWorldLocation(FVector(0, 25, 0));
	SupportV->SetCanEverAffectNavigation(false);
	SupportV->CastShadow = 0;
	SupportV->bVisibleInReflectionCaptures = false;

	SupportSphereV = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SupportSphereV"));
	SupportSphereV->SetupAttachment(SupportV);
	//static ConstructorHelpers::FObjectFinder<UStaticMesh> SupportSphereMesh(TEXT("StaticMesh'/OptiX/UI/Rotator/Sphere_2.Sphere_2'"));
	SupportSphereV->SetStaticMesh(SupportSphereMesh.Object);
	SupportSphereV->SetAbsolute(false, false, true);
	SupportSphereV->SetWorldScale3D(FVector(0.03, 0.03, 0.03));
	SupportSphereV->SetGenerateOverlapEvents(false);
	SupportSphereV->SetHiddenInGame(true);
	SupportSphereV->SetRelativeLocation(FVector(0, 0, 100));
	SupportSphereV->SetCanEverAffectNavigation(false);
	SupportSphereV->CastShadow = 0;
	SupportSphereV->bVisibleInReflectionCaptures = false;

	DegreeWidgetV = CreateDefaultSubobject<UWidgetComponent>(TEXT("DegreeWidgetV"));
	DegreeWidgetV->SetupAttachment(SupportSphereV);
	DegreeWidgetV->SetWidgetClass(DegreeWidgetClass.Class);
	DegreeWidgetV->SetRelativeLocationAndRotation(FVector(0, 0, 40), FRotator(0, 0, -90));
	//DegreeWidgetV->SetRelativeScale3D(FVector(2.0, 2.0, 0.08));
	DegreeWidgetV->SetDrawSize(FVector2D(200, 300));
	DegreeWidgetV->SetHiddenInGame(true);
	DegreeWidgetV->SetGenerateOverlapEvents(false);
	//DegreeWidgetV->SetTwoSided(true);

	UE_LOG(LogTemp, Display, TEXT("OptiX ASelectableActorBase Constructor 3/4"));
	   	 

	// Rods	   	 

	static ConstructorHelpers::FObjectFinder<UMaterial> MetalMaterial(TEXT("Material'/OptiX/Laser/MetalSilver.MetalSilver'"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereMesh(TEXT("StaticMesh'/Engine/BasicShapes/Sphere.Sphere'"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> Cylinder2(TEXT("StaticMesh'/OptiX/UI/Rotator/Cylinder_2.Cylinder_2'"));

	Socket = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SocketNew"));
	Socket->SetAbsolute(false, false, true);

	Socket->SetupAttachment(GetStaticMeshComponent());
	Socket->SetStaticMesh(SphereMesh.Object);
	Socket->SetGenerateOverlapEvents(false);
	Socket->SetMaterial(0, MetalMaterial.Object);
	Socket->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	Socket->SetWorldScale3D(FVector(0.03, 0.03, 0.03));
	//Socket->SetRelativeLocation(FVector(0, 0, 0));
	Socket->SetCanEverAffectNavigation(false);
	Socket->CastShadow = 0;
	Socket->bVisibleInReflectionCaptures = false;

	ConnectorV = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ConnectorVNew"));
	ConnectorV->SetAbsolute(false, true, true);

	ConnectorV->SetupAttachment(Socket);
	ConnectorV->SetStaticMesh(Cylinder2.Object);
	ConnectorV->SetWorldScale3D(FVector(0.5, 0.5, -1));
	ConnectorV->SetGenerateOverlapEvents(false);
	ConnectorV->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ConnectorV->SetMaterial(0, MetalMaterial.Object);
	ConnectorV->SetMaterial(1, MetalMaterial.Object);
	ConnectorV->SetCanEverAffectNavigation(false);
	ConnectorV->CastShadow = 0;
	ConnectorV->bVisibleInReflectionCaptures = false;

	Sphere = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SphereNew"));
	Sphere->SetAbsolute(false, false, true);

	Sphere->SetupAttachment(ConnectorV);
	Sphere->SetStaticMesh(SphereMesh.Object);
	Sphere->SetGenerateOverlapEvents(false);
	Sphere->SetMaterial(0, MetalMaterial.Object);
	Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	Sphere->SetWorldScale3D(FVector(0.03, 0.03, 0.03));
	Sphere->SetRelativeLocation(FVector(0, 0, 100));
	Sphere->SetCanEverAffectNavigation(false);
	Sphere->CastShadow = 0;
	Sphere->bVisibleInReflectionCaptures = false;

	ConnectorH = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ConnectorHNew"));
	ConnectorH->SetAbsolute(false, true, true);
	ConnectorH->SetupAttachment(ConnectorV);
	ConnectorH->SetStaticMesh(Cylinder2.Object);
	ConnectorH->SetGenerateOverlapEvents(false);	
	ConnectorH->SetRelativeLocation(FVector(0, 0, 100));
	ConnectorH->SetWorldScale3D(FVector(0.5, 0.5, 1.0));
	ConnectorH->SetMaterial(0, MetalMaterial.Object);
	ConnectorH->SetMaterial(1, MetalMaterial.Object);
	ConnectorH->SetGenerateOverlapEvents(false);
	ConnectorH->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ConnectorH->SetCanEverAffectNavigation(false);
	ConnectorH->CastShadow = 0;
	ConnectorH->bVisibleInReflectionCaptures = false;

	UE_LOG(LogTemp, Display, TEXT("OptiX ASelectableActorBase Constructor End 4/4"));


}

void ASelectableActorBase::BeginPlay()
{
	Super::BeginPlay();

	ArrowX->CreateAndSetMaterialInstanceDynamicFromMaterial(0, ArrowX->GetMaterial(0));
	ArrowX->CreateAndSetMaterialInstanceDynamicFromMaterial(1, ArrowX->GetMaterial(1));
	ArrowY->CreateAndSetMaterialInstanceDynamicFromMaterial(0, ArrowY->GetMaterial(0));
	ArrowY->CreateAndSetMaterialInstanceDynamicFromMaterial(1, ArrowY->GetMaterial(1));
	ArrowZ->CreateAndSetMaterialInstanceDynamicFromMaterial(0, ArrowZ->GetMaterial(0));
	ArrowZ->CreateAndSetMaterialInstanceDynamicFromMaterial(1, ArrowZ->GetMaterial(1));

	SupportSphereH->CreateAndSetMaterialInstanceDynamicFromMaterial(0, SupportSphereH->GetMaterial(0));
	SupportSphereV->CreateAndSetMaterialInstanceDynamicFromMaterial(0, SupportSphereV->GetMaterial(0));


	SupportSphereH->OnComponentBeginOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapBegin);
	SupportSphereH->OnComponentEndOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapEnd);

	SupportSphereV->OnComponentBeginOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapBegin);
	SupportSphereV->OnComponentEndOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapEnd);

	ArrowX->OnComponentBeginOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapBegin);
	ArrowX->OnComponentEndOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapEnd);

	ArrowY->OnComponentBeginOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapBegin);
	ArrowY->OnComponentEndOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapEnd);

	ArrowZ->OnComponentBeginOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapBegin);
	ArrowZ->OnComponentEndOverlap.AddDynamic(this, &ASelectableActorBase::OnOverlapEnd);
}

void ASelectableActorBase::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	

	FVector PlayerLocation = UGameplayStatics::GetPlayerPawn(GetWorld(), 0)->GetActorLocation();
	{
		FVector Diff = PlayerLocation - DegreeWidgetV->GetComponentTransform().GetLocation();
		FVector Projected = FVector::VectorPlaneProject(Diff, FVector(0, 0, 1));
		DegreeWidgetV->SetWorldRotation(FRotationMatrix::MakeFromXZ(Projected, FVector(0, 0, 1)).Rotator());
	}
	{
		FVector Diff = PlayerLocation - DegreeWidgetH->GetComponentTransform().GetLocation();
		FVector Projected = FVector::VectorPlaneProject(Diff, FVector(0, 0, 1));
		DegreeWidgetH->SetWorldRotation(FRotationMatrix::MakeFromXZ(Projected, FVector(0, 0, 1)).Rotator());
	}
	{
		FVector Diff = PlayerLocation - SupportWidget->GetComponentTransform().GetLocation();
		FVector Projected = FVector::VectorPlaneProject(Diff, FVector(0, 0, 1));
		SupportWidget->SetWorldRotation(FRotationMatrix::MakeFromXZ(Projected, FVector(0, 0, 1)).Rotator());
	}
	{
		FVector Diff = PlayerLocation - TranslateWidgetX->GetComponentTransform().GetLocation();
		FVector Projected = FVector::VectorPlaneProject(Diff, FVector(0, 0, 1));
		TranslateWidgetX->SetWorldRotation(FRotationMatrix::MakeFromXZ(Projected, FVector(0, 0, 1)).Rotator());
	} 
	{
		FVector Diff = PlayerLocation - TranslateWidgetY->GetComponentTransform().GetLocation();
		FVector Projected = FVector::VectorPlaneProject(Diff, FVector(0, 0, 1));
		TranslateWidgetY->SetWorldRotation(FRotationMatrix::MakeFromXZ(Projected, FVector(0, 0, 1)).Rotator());
	}
	{
		FVector Diff = PlayerLocation - TranslateWidgetZ->GetComponentTransform().GetLocation();
		FVector Projected = FVector::VectorPlaneProject(Diff, FVector(0, 0, 1));
		TranslateWidgetZ->SetWorldRotation(FRotationMatrix::MakeFromXZ(Projected, FVector(0, 0, 1)).Rotator());
	}

}

void ASelectableActorBase::SetScaleV(FRotator Rot)
{
	ScaleV->SetWorldRotation(Rot);
}

void ASelectableActorBase::SetScaleH(FRotator Rot)
{
	ScaleH->SetWorldRotation(Rot);
}

void ASelectableActorBase::EnableTranslation()
{
	TranslationSupport->SetHiddenInGame(false, true);
	RotationSupport->SetHiddenInGame(true, true);

	SupportSphereV->SetGenerateOverlapEvents(false);
	SupportSphereH->SetGenerateOverlapEvents(false);
	ArrowX->SetGenerateOverlapEvents(true);
	ArrowY->SetGenerateOverlapEvents(true);
	ArrowZ->SetGenerateOverlapEvents(true);

	AOptiXVRPawn* OptiXVRPawn = Cast<AOptiXVRPawn>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
	if (OptiXVRPawn)
	{
		OptiXVRPawn->UIEventTranslation();
	}

}

void ASelectableActorBase::EnableRotation()
{
	TranslationSupport->SetHiddenInGame(true, true);
	RotationSupport->SetHiddenInGame(false, true);

	SupportSphereV->SetGenerateOverlapEvents(true);
	SupportSphereH->SetGenerateOverlapEvents(true);
	ArrowX->SetGenerateOverlapEvents(false);
	ArrowY->SetGenerateOverlapEvents(false);
	ArrowZ->SetGenerateOverlapEvents(false);

	AOptiXVRPawn* OptiXVRPawn = Cast<AOptiXVRPawn>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
	if (OptiXVRPawn)
	{
		OptiXVRPawn->UIEventRotation();
	}
}

void ASelectableActorBase::DeselectActor()
{
	AOptiXVRPawn* OptiXVRPawn = Cast<AOptiXVRPawn>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
	if (OptiXVRPawn)
	{
		OptiXVRPawn->UIEventDeselect();
	}
	Deselect();
}

void ASelectableActorBase::DeleteActor()
{
	AOptiXVRPawn* OptiXVRPawn = Cast<AOptiXVRPawn>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
	if (OptiXVRPawn)
	{
		OptiXVRPawn->UIEventDelete();
	}
	Destroy();
}


void ASelectableActorBase::SetRodPosition(FVector TablePosition)
{
	FVector TableZero = TablePosition + FVector(0, 0, 95); // Table Height	

	// Far away from the table or below table, make it go straight down
	if ( (Socket->GetComponentLocation().Z <= TableZero.Z) || (Socket->GetComponentLocation() - TableZero).Size() > 200) 
	{
		ConnectorH->SetWorldScale3D(FVector(0, 0, 0));
		ConnectorV->SetWorldScale3D(FVector(1, 1, -10));
		return;
	}


	float ScaleFactorV = FMath::Abs(ConnectorV->GetComponentLocation().Z - TableZero.Z) / 100.0f;
	ConnectorV->SetWorldScale3D(FVector(1, 1, -ScaleFactorV));

	FVector DistanceToSphere = TableZero - Sphere->GetComponentLocation();
	float ScaleFactorH = DistanceToSphere.Size() / 100.0f;
	ConnectorH->SetWorldScale3D(FVector(1, 1, ScaleFactorH));

	ConnectorH->SetWorldRotation(FRotationMatrix::MakeFromZ(DistanceToSphere).Rotator());

}

// TODO Material highlighting - swap material slots?
void ASelectableActorBase::OnOverlapBegin(UPrimitiveComponent * OverlapComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	//int32 N = OverlapComponent->GetNumMaterials();
	//for (int32 i = 0; i < N; i++)
	//{
	//	Cast<UMaterialInstanceDynamic>(OverlapComponent->GetMaterial(i))->SetVectorParameterValue("Color", FLinearColor(0.5, 0.5, 0.8));
	//}
}

void ASelectableActorBase::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	//int32 N = OverlappedComp->GetNumMaterials();
	//for (int32 i = 0; i < N; i++)
	//{
	//	Cast<UMaterialInstanceDynamic>(OverlappedComp->GetMaterial(i))->SetVectorParameterValue("Color", FLinearColor(0.4, 0.4, 0.4));
	//}
}