void AMyCharacter::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	// Get mouse position
	APlayerController* pc = Cast<APlayerController>(GetController());

	float mouseX = 0.f;
	float mouseY = 0.f;

	FVector mousePos = FVector::ZeroVector;

	if (pc->GetMousePosition(mouseX, mouseY))
	{
		mousePos = FVector(mouseX, mouseY, 0.0f);
		// UE_LOG(LogTemp, Warning, TEXT("Mouse X %f: MouseY %f"), mouseX, mouseY);
	}

	// Calculate look at direction
	const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY());

	FVector middleOfScreen = FVector(ViewportSize.X / 2, ViewportSize.Y / 2, 0.0f);

	FVector directionToMouse = mousePos - middleOfScreen;

	FRotator UpperBodyRot = directionToMouse.Rotation();

	UpperBodyRot.Roll = -90.0f;
	UpperBodyRot.Pitch = 0.0f;
	UpperBodyRot.Yaw = UpperBodyRot.Yaw + 90.0f;

	UpperBodyFB->SetWorldRotation(UpperBodyRot);

	// Determine Heading of lower Body
	FVector upperBodyVec = UpperBodyRot.Vector();
	upperBodyVec.Normalize();

	FVector vel = GetVelocity();
	vel.Z = 0.0f; // Ignore the movement in the vertical direction like when he is falling.

	// Calculate Movement Vector
	if (!vel.Equals(FVector::ZeroVector))
	{
		MovementDirectionVec = vel;
	}

	MovementDirectionVec.Normalize();

	// Calculate Angle
	float dotProduct = FVector::DotProduct(upperBodyVec, MovementDirectionVec);
	float magnitudes = upperBodyVec.Size() * MovementDirectionVec.Size();

	float AimAtAngle = FMath::RadiansToDegrees(acosf(dotProduct / magnitudes));

	FVector sideVector = UpperBodyRot.Vector().RotateAngleAxis(90.0f, FVector(0, 0, 1));

	// Greater than 0 is left, Less than zero is right
	float sideDirection = FVector::DotProduct(sideVector, MovementDirectionVec);

	// He is looking left
	if (sideDirection < 0 && AimAtAngle > StrafingStartAngle && AimAtAngle < StrafingEndAngle)
	{
		CurMovementAction = EMovementActions::STRAFING_LEFT;
	}

	// He is looking right
	if (sideDirection > 0 && AimAtAngle > StrafingStartAngle && AimAtAngle < StrafingEndAngle)
	{
		CurMovementAction = EMovementActions::STRAFING_RIGHT;
	}

	// Is he moving forward in relation to where he is facing
	if (AimAtAngle < StrafingStartAngle)
	{
		CurMovementAction = EMovementActions::MOVING_FORWARDS;
	}

	// Is he moving backward in relation to where he is facing
	if (AimAtAngle > StrafingEndAngle)
	{
		CurMovementAction = EMovementActions::MOVING_BACKWARDS;
	}

	// Debug
	// Draw Vectors for debugging
	// UE_LOG(LogTemp, Warning, TEXT("Angle %f"), AimAtAngle);

	DrawDebugLine(GetWorld(), UpperBodyFB->GetComponentLocation(), UpperBodyFB->GetComponentLocation() + (upperBodyVec * 500), FColor::Red, false, -1, 0, 12.333);
	DrawDebugLine(GetWorld(), UpperBodyFB->GetComponentLocation(), UpperBodyFB->GetComponentLocation() + (sideVector * 500), FColor::Green, false, -1, 0, 12.333);
	DrawDebugLine(GetWorld(), GetActorLocation(), GetActorLocation() + (MovementDirectionVec * 500), FColor::Yellow, false, -1, 0, 12.333);

	// Movement
	// UE_LOG(LogTemp, Warning, TEXT("Moving Forward %d, Strafing Left %d, Moving Backward %d, Strafing Right %d"), bIsMovingForwards, bIsStrafingLeft, bIsMovingBackwards, bIsStrafingRight);
	// UE_LOG(LogTemp, Warning, TEXT("Dot Product: %f"), dotProduct);
	// UE_LOG(LogTemp, Warning, TEXT("Side Direction: %f"), sideDirection);
	UE_LOG(LogTemp, Warning, TEXT("MovementDirectionVec: X = %f, Y = %f, Z = %f"), MovementDirectionVec.X, MovementDirectionVec.Y, MovementDirectionVec.Z);

	switch (CurMovementAction)
	{
	case EMovementActions::STRAFING_LEFT:
		UE_LOG(LogTemp, Warning, TEXT("STRAFING_LEFT"));
		break;
	case EMovementActions::STRAFING_RIGHT:
		UE_LOG(LogTemp, Warning, TEXT("STRAFING_RIGHT"));
		break;
	case EMovementActions::MOVING_FORWARDS:
		UE_LOG(LogTemp, Warning, TEXT("MOVING_FORWARDS"));
		break;
	case EMovementActions::MOVING_BACKWARDS:
		UE_LOG(LogTemp, Warning, TEXT("MOVING_BACKWARDS"));
		break;
	}
}
FVector2D AGameplayPawn::GetMouseWorldPosition()
{
	UWorld* TestWorld = GetWorld();
	if (TestWorld)
	{
		APlayerController* PlayerController = TestWorld->GetFirstPlayerController();
		FVector2D MousePos = FVector2D(0, 0);
		FVector WorldPos = FVector(MousePos.X, MousePos.Y, 0);
		FVector Dir = FVector(0, 0, 0);
		if (PlayerController != nullptr)
		{
			PlayerController->GetMousePosition(MousePos.X, MousePos.Y);
			PlayerController->DeprojectMousePositionToWorld(WorldPos, Dir);
		}
		return FVector2D((int)(WorldPos.X/SCALE_FACTOR), (int)(WorldPos.Y/SCALE_FACTOR));
	}
	return FVector2D::ZeroVector;
}