using UnityEngine;
using System.Collections;

public class Mg_Camera : Singleton <Mg_Camera>
{
    #region Manager references
    Mg_Player mgPlayer;
    #endregion

    Player _player;
    Transform _target;
    Vector3 _velocity;
    float _distance;
    float _distVelocity;

    public Camera mainCamera;
    Transform cameraT;
    Transform cameraTrollyT;

    void Start()
    {
        mgPlayer = Mg_Player.Instance;

        mainCamera.transparencySortMode = TransparencySortMode.Orthographic;
        cameraT = mainCamera.transform;
        cameraTrollyT = mainCamera.transform.parent;
    }

    public void setCameraProjectionToOrtho()
    {
        mainCamera.orthographic = true;
        mainCamera.orthographicSize = (2000f / Screen.width) * 10f;

        float a = 8.782925364f;
        float b = -36.24407498f;
        float c = 48.45106148f;
        float width = Screen.width;
        float height = Screen.height;
        float t;
        t = width / height;
        float answer;
        answer = Mathf.Round(10 * (a * Mathf.Pow(t, 2) + b * t + c)) / 10;
        mainCamera.camera.orthographicSize = answer;
    }

    public void setCameraProjectionToPerspective()
    {
        mainCamera.orthographic = false;
    }

    public void StartFollowingPlayer()
    {
        _player = mgPlayer._player;
        _target = _player.transform;
    }

    public void StopFollowingPlayer()
    {
        _target = this.transform;
        _player = null;
    }

    public void HardSetPosition(Vector2 pos)
    {
        _target = null;
        cameraTrollyT.position = ((Vector3)pos) + Vector3.forward * -20f;
    }

    public void GoToTarget(Transform t)
    {
        _target = t;
        _player = null;
        cameraTrollyT.position = t.position + Vector3.forward * -20f;
    }

    public void SetTarget(Transform t)
    {
        _target = t;
        _player = null;
    }

    public IEnumerator MoveTo_R(Vector3 target, float duration)
    {
        Vector3 pos = cameraTrollyT.position;
        float t = duration;
        float frac = 0f;
        _target = null;
        while (t > 0f)
        {
            frac = 1f - (t / duration);
            cameraTrollyT.position = Vector3.Lerp(pos, target, frac);
            t -= Time.deltaTime;
            yield return null;
        }
        cameraTrollyT.position = target;
    }
    public IEnumerator MoveToFollow_R(Transform trans, float targetHeight, float duration)
    {
        Vector3 target = new Vector3(trans.position.x, trans.position.y, targetHeight);
        yield return StartCoroutine(MoveTo_R(target, duration));
        _target = trans;
    }

    float _shakeForce;
    float _shakeDuration;
    bool _shaking;
    public void Shake(float duration, float strength)
    {
        _shakeDuration = duration;
        _shakeForce = strength;
        if (!_shaking)
        {
            StartCoroutine(Shake_R());
        }
    }
    IEnumerator Shake_R()
    {
        float depth = cameraT.localPosition.z;
        _shaking = true;
        while (_shakeDuration > 0f)
        {
            cameraT.localPosition = new Vector3(Random.insideUnitCircle.x * _shakeForce, Random.insideUnitCircle.y * _shakeForce, depth);
            yield return new WaitForSeconds(0);
            _shakeDuration -= Time.deltaTime + 0.1f;
        }
        cameraT.localPosition = new Vector3(0, 0, depth);
        _shaking = false;
    }

    public bool IsTargetVisible(GameObject go)
    {
        if (go.renderer == null) return false;

        return (go.renderer.IsVisibleFrom(mainCamera));
    }

    void LateUpdate()
    {
        if (_target != null)
        {
            if (_player != null)
                cameraTrollyT.position = Vector3.SmoothDamp(cameraTrollyT.position, _target.position + _target.up * 1 - Vector3.forward * (1 + 20f), ref _velocity, 0.75f);
            else
                cameraTrollyT.position = Vector3.SmoothDamp(cameraTrollyT.position, _target.position + new Vector3(0, 0, -20f), ref _velocity, 0.75f);
        }
    }
}
