// Converted from UnityScript to C# at http://www.M2H.nl/files/js_to_c.php - by Mike Hergaarden
// Do test the code! You usually need to change a few small bits.

using UnityEngine;
using System.Collections;
using UnityEngine.Audio;
using UnityEngine.UI;

public class ScriptedScene : MonoBehaviour {

    public static string fraseVisualizzata;
    public static bool talking = false;
    public static AudioMixer mixer;
    private int textSpeed = 70;      //Default: 40
    private static GameObject damageText;
    private AudioClip damage;

    GlobalVariables globalVariables;
    private bool globalVariablesExists = false;

    void Awake() {
        
    }

    void Start() {
        if (GameObject.Find("GlobalVariables") != null) {
            globalVariables = GameObject.Find("GlobalVariables").GetComponent<GlobalVariables>();
            globalVariablesExists = true;
        }
    }

    public static AudioSource PlayClipAtPoint(AudioClip clip, Vector3 pos, bool menuSound = false, float radius = 1.0f) {
        if (mixer == null) {
            mixer = Resources.Load("MasterMixer") as AudioMixer;
        }
        GameObject tempGO = new GameObject("One shot audio");
        tempGO.transform.position = pos;
        AudioSource aSource = tempGO.AddComponent<AudioSource>();
        aSource.clip = clip;
        aSource.minDistance = radius;
        aSource.maxDistance = 300 * radius;
        aSource.spatialBlend = 1;
        if (mixer != null) {
            if (clip.name == "Victory") {
                aSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Music")[0];
            }
            else if (menuSound) {
                aSource.bypassReverbZones = true;
                aSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Menu")[0];
            }
            else {
                aSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Sound")[0];
            }
        }
        aSource.Play();
        Destroy(tempGO, clip.length);
        return aSource;
    }

    public static AudioSource PlayClipAtPoint(AudioClip clip, Transform par, bool menuSound = false, float radius = 1.0f) {
        if (mixer == null) {
            mixer = Resources.Load("MasterMixer") as AudioMixer;
        }
        GameObject tempGO = new GameObject("One shot audio");
        tempGO.transform.parent = par;
        Vector3 pos = par.position;
        tempGO.transform.position = pos;
        AudioSource aSource = tempGO.AddComponent<AudioSource>();
        aSource.clip = clip;
        aSource.minDistance = radius;
        aSource.maxDistance = 300 * radius;
        aSource.spatialBlend = 1;
        if (mixer != null) {
            if (clip.name == "Victory") {
                aSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Music")[0];
            }
            else if (menuSound) {
                aSource.bypassReverbZones = true;
                aSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Menu")[0];
            }
            else {
                aSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Sound")[0];
            }
        }
        aSource.Play();
        Destroy(tempGO, clip.length);
        return aSource;
    }

    public static AudioSource PlayClipAtPoint(AudioClip clip, Transform par, Vector3 pos, bool menuSound = false) {
        AudioSource res = PlayClipAtPoint(clip, par, menuSound);
        res.transform.localPosition = pos;
        return res;
    }

    public static GameObject FindChild(Transform root, string searchName) {
        foreach (Transform child in root) {
            if (child.name.Equals(searchName)) {
                //Debug.Log(searchName+" found! ["+child.name+"]");
                return child.gameObject;
            }
            else {
                GameObject obj = FindChild(child, searchName);
                if (obj != null) {
                    //Debug.Log(searchName+" found! (Inside) ["+child.name+"]");
                    return obj;
                }
            }
        }
        //Debug.Log(searchName+" not found.");
        return null;
    }

    public static float ClampAngle(float angle) {
        float res = angle;
        while (res > 180) {
            res -= 360;
        }
        while (res < -180) {
            res += 360;
        }
        return res;
    }

    public static string ApplySeparators(string input) {
        string output = input;
        int nDigits = 0;
        for (int i = output.Length-1; i >= 0; i--) {
            if (output[i] == '0' || output[i] == '1' || output[i] == '2' || output[i] == '3' || output[i] == '4' || output[i] == '5' || output[i] == '6' || output[i] == '7' || output[i] == '8' || output[i] == '9') {
                nDigits++;
                if (nDigits > 3) {
                    output = output.Substring(0, i+1) + "." + output.Substring(i+1);
                    nDigits = 1;
                }
            }
        }
        return output;
    }

    public static float OrientedAngle(Vector3 point, Transform relative) {
        float dir;
        dir = Vector3.Angle(point - relative.position, relative.forward) * AngleDir(relative.forward, point - relative.position, relative.up);
        return dir;
    }

    public static float AngleDir(Vector3 fwd, Vector3 targetDir, Vector3 up) {
        Vector3 perp = Vector3.Cross(fwd, targetDir);
        float dir = Vector3.Dot(perp, up);

        if (dir > 0f) {
            return 1f;
        }
        else if (dir < 0f) {
            return -1f;
        }
        else {
            return 0f;
        }
    }

    public static void CheckForCanvas() {
        if (UIObjectsContainer.main == null) {
            GameObject canvas = GameObject.Instantiate(Resources.Load<GameObject>("Canvas"));
            canvas.name = "Canvas";
        }
    }

    public static void CheckForGlobalVariables() {
        if (GlobalVariables.main == null) {
            GameObject gvgo = GameObject.Find("GlobalVariables");
            if (gvgo == null) {
                gvgo = (GameObject)GameObject.Instantiate(Resources.Load("StartGlobalVariables"));
                gvgo.name = "GlobalVariables";
                DontDestroyOnLoad(gvgo);
                if (GlobalVariables.main != null) {
                    GlobalVariables gv = GlobalVariables.main;
                }
            }
        }
    }

    public static float SqrDistance(Vector3 first, Vector3 second) {
        return Vector3.SqrMagnitude(first - second);
    }

    public static Vector3 MidPoint(Vector3 first, Vector3 second) {
        return new Vector3((first.x + second.x) * 0.5f, (first.y + second.y) * 0.5f, (first.z + second.z) * 0.5f);
    }

    /// <summary>
    /// get the square distance from a point to a line segment.
    /// </summary>
    /// <param name="lineP1">line segment start point</param>
    /// <param name="lineP2">line segment end point</param>
    /// <param name="point">point to get distance to</param>
    /// <param name="closestPoint">set to either 1, 2, or 4, determining which end the point is closest to (p1, p2, or the middle)</param>
    /// <returns></returns>
    public static float SqrLineDistance(Vector3 lineP1, Vector3 lineP2, Vector3 point, out int closestPoint) {

        Vector3 v = lineP2 - lineP1;
        Vector3 w = point - lineP1;

        float c1 = Vector3.Dot(w, v);

        if (c1 <= 0) //closest point is p1
        {
            closestPoint = 1;
            return SqrDistance(point, lineP1);
        }

        float c2 = Vector3.Dot(v, v);
        if (c2 <= c1) //closest point is p2
        {
            closestPoint = 2;
            return SqrDistance(point, lineP2);
        }


        float b = c1 / c2;

        Vector3 pb = lineP1 + b * v;
        {
            closestPoint = 4;
            return SqrDistance(point, pb);
        }
    }
}