using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraManager : MonoBehaviour
{
    public Transform cockpit;

    Camera myCamera;

    Vector3 currentOrientation;

    Vector3 defaultCockpitPosition;
    Vector3 defaultPosition;

    bool isShaking = false;

    const float maxHorizontalRotation = 5f;
    const float maxVerticalRotation = 4f;
    
    const float maxAngularSpeed = 50f;
    const float maxAngularSpeedThreshold = 5f;

    void Awake()
    {
        myCamera = Camera.main;
        currentOrientation = Vector3.zero;
        defaultCockpitPosition = cockpit.localPosition;
        defaultPosition = transform.localPosition;
    }

    void Start()
    {
        GameEventManager.OnHyperspaceJump += OnJumpStart;
        GameEventManager.OnJumpEnd += OnJumpEnd;
    }
	
	// Update is called once per frame
	void Update ()
    {
        Vector2 normalizedMousePosition = Input.mousePosition;
        normalizedMousePosition -= new Vector2(Screen.width / 2f, Screen.height / 2f);
        normalizedMousePosition.x *= 2f / Screen.width;
        normalizedMousePosition.y *= 2f / Screen.height;
        normalizedMousePosition.x = Mathf.Clamp(normalizedMousePosition.x, -1f, 1f);
        normalizedMousePosition.y = Mathf.Clamp(normalizedMousePosition.y, -1f, 1f);
        normalizedMousePosition.x *= Mathf.Sign(normalizedMousePosition.x) * normalizedMousePosition.x;
        normalizedMousePosition.y *= Mathf.Sign(normalizedMousePosition.y) * normalizedMousePosition.y;
        Vector3 orientationGoal = new Vector3(-normalizedMousePosition.y * maxVerticalRotation, normalizedMousePosition.x * maxHorizontalRotation);
        
        float diff = Mathf.Abs(orientationGoal.x - currentOrientation.x) + Mathf.Abs(orientationGoal.y - currentOrientation.y);
        float speed = maxAngularSpeed;
        if(diff < maxAngularSpeedThreshold)
        {
            float speedMultiplier = (diff / maxAngularSpeedThreshold);
            speedMultiplier = 1f - speedMultiplier;
            speedMultiplier *= speedMultiplier;
            speedMultiplier = 1f - speedMultiplier;
            speed = maxAngularSpeed * speedMultiplier;
        }
        if(diff > 0)
        {
            currentOrientation = Vector3.Lerp(currentOrientation, orientationGoal, Mathf.Clamp01(Time.deltaTime * speed / diff));
            myCamera.transform.rotation = Quaternion.Euler(currentOrientation);
        }

        if(isShaking)
        {
            float shakeAmplitude = StarsManager.Instance.GetShakeAmplitude();
            Vector3 shake = new Vector3(Random.Range(-shakeAmplitude, shakeAmplitude), Random.Range(-shakeAmplitude, shakeAmplitude), Random.Range(-shakeAmplitude, shakeAmplitude)) * 0.5f;
            cockpit.localPosition = defaultCockpitPosition + shake;

            shake = new Vector3(Random.Range(-shakeAmplitude, shakeAmplitude), Random.Range(-shakeAmplitude, shakeAmplitude), Random.Range(-shakeAmplitude, shakeAmplitude)) * 0.01f;
            transform.localPosition = defaultPosition + shake;
        }
	}

    void OnJumpStart()
    {
        isShaking = true;
    }

    void OnJumpEnd()
    {
        isShaking = false;
        cockpit.localPosition = defaultCockpitPosition;
        transform.localPosition = defaultPosition;
    }
}
