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


#include "CameraPawn.h"

#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "InputActionValue.h"

void ACameraPawn::CameraZoom(const FInputActionValue& Value)
{
	auto f = Value.Get<float>();
	SpringArmComponent->TargetArmLength += f * ZoomSpeed;
	SpringArmComponent->TargetArmLength = FMath::Clamp(SpringArmComponent->TargetArmLength, MinArmLength, MaxArmLength);
}

void ACameraPawn::CameraRotate(const FInputActionValue& Value)
{
	auto f = Value.Get<float>();
	FRotator r = FRotator(0.0f, -f * RotateSpeed, 0.0f);
	AddActorWorldRotation(r);

	// 同时旋转控制器
	auto c = Cast<APlayerController>(FollowTarget->GetController());
	if (c)
	{
		c->SetControlRotation(GetActorRotation());
	}
}

void ACameraPawn::CameraMove(const FInputActionValue& Value)
{
	auto f2d = Value.Get<FVector2D>();
	auto r = GetActorRightVector();
	auto f = r.Cross(FVector::UpVector);
	f.Normalize();
	auto l = GetRootComponent()->GetRelativeLocation() + f * f2d.X * MoveSpeed + r * f2d.Y * MoveSpeed;
	l.X = FMath::Clamp(l.X, -CameraMoveClamp, CameraMoveClamp);
	l.Y = FMath::Clamp(l.Y, -CameraMoveClamp, CameraMoveClamp);
	SetActorRelativeLocation(l);
}

void ACameraPawn::CameraReset(const FInputActionValue& Value)
{
	SpringArmComponent->TargetArmLength = InitialArmLength;
	SetActorRotation(InitialRotation);
	SetActorRelativeLocation(FVector::ZeroVector);

	// 同时旋转控制器
	auto c = Cast<APlayerController>(FollowTarget->GetController());
	if (c)
	{
		c->SetControlRotation(GetActorRotation());
	}
}

// Sets default values
ACameraPawn::ACameraPawn()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	// 初始化 SpringArmComponent 和 CameraComponent
	SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComponent"));
	SpringArmComponent->SetupAttachment(RootComponent);
	SpringArmComponent->TargetArmLength = InitialArmLength;
	SpringArmComponent->bUsePawnControlRotation = true;// TODO: 何意味？
	CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
	CameraComponent->SetupAttachment(SpringArmComponent, USpringArmComponent::SocketName);
	
	// 设置弹簧臂碰撞属性
	SpringArmComponent->bDoCollisionTest = false;
}

// Called when the game starts or when spawned
void ACameraPawn::BeginPlay()
{
	Super::BeginPlay();
	
	if (FollowTarget)
	{
		// 切换到当前摄像头
		auto c = Cast<APlayerController>(FollowTarget->GetController());
		if (c)
		{
			c->SetViewTarget(this);
		}

		// 附加到父物体
		this->AttachToActor(FollowTarget, FAttachmentTransformRules::KeepWorldTransform);
		this->GetRootComponent()->SetAbsolute(false, true, true);
	}

	// 设置自身旋转
	SetActorRotation(InitialRotation);
}

// Called every frame
void ACameraPawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ACameraPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

