using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

    float laneSize = 32.0f;
    public int lane = 0;
    Vector3 targetPos;
    Manager manager;
    GameObject[] lanes;
    public bool alive = true;
    AudioSource deathSnd;
    int deathTime = 0;
    Vector3 playerStartPosition;
    public int framesSinceRespawn = 4000;
    public int lives = 4;
    bool permadeath = false;
    GameObject lifeText;
    Vector3 normalScale;
    float pitchSpeedup = -1.0f;
    AudioSource musicrev;
    AudioSource musicbg;
    public bool started = false;
	// Use this for initialization
    public Vector3 PosXLane(int lane)
    {
        return new Vector3(-32.0f, 0.1f, (float)lane * laneSize - laneSize);
    }

    void Start () {
        lanes = GameObject.FindGameObjectsWithTag("wavelane");
        deathSnd = GameObject.Find("DeathSnd").GetComponent<AudioSource>();
        playerStartPosition = PosXLane(1);
        manager = GameObject.Find("Manager").GetComponent<Manager>();
        lifeText = GameObject.Find("LifeText");
        normalScale = transform.localScale;
        musicrev = GameObject.Find("Musicrev").GetComponent<AudioSource>();
        musicbg = GameObject.Find("MusicBG").GetComponent<AudioSource>();

	}

    void FullRestart()
    {
        foreach (GameObject g in lanes)
        {
            MeshWave mw = g.GetComponent<MeshWave>();
            mw.GetComponent<AudioSource>().Play();
            mw.GetComponent<AudioSource>().pitch = manager.speed;
            mw.GetComponent<AudioSource>().time = 0.0f;
        }
        musicrev.time = 0.0f;
        musicrev.pitch = manager.speed;
        if (!musicrev.isPlaying) musicrev.Play();

        musicbg.time = 0.0f;
        musicbg.pitch = manager.speed;
        if (!musicbg.isPlaying) musicbg.Play();

        lives = 4;
        transform.position = playerStartPosition;
        targetPos = this.transform.position;
        alive = true;
        framesSinceRespawn = 1000;
        permadeath = false;
        lane = 0;
        started = true;
    }

    void WIN()
    {
        manager.speed += 0.2f;
        GameObject.Find("DemoText").GetComponent<WinText>().Show();

        foreach (GameObject g in lanes)
        {
            MeshWave mw = g.GetComponent<MeshWave>();
            mw.GetComponent<AudioSource>().Play();
            mw.GetComponent<AudioSource>().pitch = manager.speed;
            mw.GetComponent<AudioSource>().time = 0.0f;
        }
        GameObject.Find("Musicrev").GetComponent<AudioSource>().time = 0.0f;
        GameObject.Find("Musicrev").GetComponent<AudioSource>().pitch = manager.speed;
        if (!musicrev.isPlaying) musicrev.Play();

        GameObject.Find("MusicBG").GetComponent<AudioSource>().time = 0.0f;
        GameObject.Find("MusicBG").GetComponent<AudioSource>().pitch = manager.speed;
        if (!musicbg.isPlaying) musicbg.Play();

        lives = 4;
        transform.position = playerStartPosition;
        targetPos = this.transform.position;
        alive = true;
        framesSinceRespawn = 1000;
        permadeath = false;
        lane = 0;
        started = true;
    }
	
	// Update is called once per frame
	void Update () {


        if (!started) GetComponent<MeshRenderer>().enabled = false; 
        else
            GetComponent<MeshRenderer>().enabled = true;

        if (lanes == null || lanes.Length == 0)
        {
            lanes = GameObject.FindGameObjectsWithTag("wavelane");
        }

        string lifetext = "";
        GameObject dtext = GameObject.Find("DeathText");

        dtext.GetComponent<DeathText>().visible = false;

        if (permadeath || !started)
        {
            lives = 0;

            dtext.GetComponent<DeathText>().visible = true;
            if (Input.GetKeyDown(KeyCode.Space))
            {
                FullRestart();
                GameObject.Find("Start").GetComponent<AudioSource>().Play();
            }
        }

        if(lives == 1) lifetext= "I";
        if(lives == 2) lifetext= "II";
        if(lives == 3) lifetext= "III";
        if(lives == 4) lifetext = "IV";

        lifeText.GetComponent<TextMesh>().text = "" + lifetext;

        if (!started) return;


        if (alive)
        {

            //reached the end
            if (lanes[0].GetComponent<AudioSource>().time > 132.0f)
            {
                WIN();
            }

            if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.RightArrow))
            {
                lane += 1;
                if (lane > manager.nLanes-1) lane = manager.nLanes-1;
            }

            if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.LeftArrow))
            {
                lane -= 1;
                if (lane < 0) lane = 0;
            }

            this.transform.position = Vector3.Lerp(transform.position, PosXLane(lane) + new Vector3(0.0f,8.0f,0.0f), 0.3f);

            transform.localScale = normalScale;
            if (framesSinceRespawn < 120.0f)
            {
                float flash = Time.time % 0.25f;
                bool flashstate = flash > 0.125f;
                if (flashstate) transform.localScale = new Vector3(0.0f, 0.0f, 0.0f);
            }
            
            foreach (GameObject g in lanes)
            {
                if (g != null)
                {
                    MeshWave mw = g.GetComponent<MeshWave>();
                    if (mw.meshId == lane + 1)
                    {
                        if (mw.RMS > 0.01f && framesSinceRespawn>120.0f)
                        {
                            alive = false;
                            deathSnd.Play();

                            //spawn explosion 
                            for (int i = 0; i < 64; i++)
                            {
                                Vector3 rpos = new Vector3(Random.value - 0.5f, Random.value - 0.5f, Random.value - 0.5f) * 16.0f;
                                GameObject shardlet = GameObject.Instantiate(Resources.Load("Shardlet"), transform.position + rpos, Quaternion.identity) as GameObject;
                                shardlet.GetComponent<Rigidbody>().AddExplosionForce(1000.0f, this.transform.position, 100.0f);
                            }
                            this.transform.position = new Vector3(10000.0f, 10000.0f, 10000.0f);

                            lives--;
                            if (lives < 0)
                            {
                                permadeath = true;
                                GameObject.Find("Reverse").GetComponent<AudioSource>().Play();
                            }

                            targetPos = this.transform.position;
                            deathTime = 0;
                            pitchSpeedup = -0.33f;

                            foreach (GameObject gg in lanes)
                            {
                                MeshWave mwg = gg.GetComponent<MeshWave>();
                                mwg.GetComponent<AudioSource>().pitch = pitchSpeedup;
                                if (!mwg.GetComponent<AudioSource>().isPlaying) mwg.GetComponent<AudioSource>().Play();
                            }
                            GameObject.Find("Musicrev").GetComponent<AudioSource>().pitch = pitchSpeedup;
                            GameObject.Find("MusicBG").GetComponent<AudioSource>().pitch = pitchSpeedup;
                            if (!musicrev.isPlaying) musicrev.Play();
                            if (!musicbg.isPlaying) musicbg.Play();

                        }
                    }
                }
            }

            framesSinceRespawn++;
        }
        else
        {
            //speed up cool reverse sfx
            pitchSpeedup *= 1.05f;
            pitchSpeedup = Mathf.Clamp(pitchSpeedup, -4.0f, 4.0f);
            foreach (GameObject gg in lanes)
            {
                MeshWave mwg = gg.GetComponent<MeshWave>();
                mwg.GetComponent<AudioSource>().pitch = pitchSpeedup;
            }
            GameObject.Find("Musicrev").GetComponent<AudioSource>().pitch = pitchSpeedup;
            GameObject.Find("MusicBG").GetComponent<AudioSource>().pitch = pitchSpeedup;
            if (!musicrev.isPlaying) musicrev.Play();
            if (!musicbg.isPlaying) musicbg.Play();

            //countdown to starting again
            if (deathTime > 60 && !permadeath)
            {
                transform.position = playerStartPosition;
                targetPos = this.transform.position;
                alive = true;
                framesSinceRespawn = 0;

                //rewind music
                float newTime = 0.0f;
                if (lanes[0].GetComponent<AudioSource>().time > 17.0f)
                    newTime = 17.0f;

                if (lanes[0].GetComponent<AudioSource>().time > 33.0f)
                    newTime = 33.0f;

                foreach (GameObject gg in lanes)
                {
                    MeshWave mwg = gg.GetComponent<MeshWave>();
                    mwg.GetComponent<AudioSource>().pitch = manager.speed;
                    if (!mwg.GetComponent<AudioSource>().isPlaying) mwg.GetComponent<AudioSource>().Play();

                }
                GameObject.Find("Musicrev").GetComponent<AudioSource>().pitch = manager.speed;
                GameObject.Find("MusicBG").GetComponent<AudioSource>().pitch = manager.speed;
                if (!musicrev.isPlaying) musicrev.Play();
                if (!musicbg.isPlaying) musicbg.Play();
            }

            //make music play in reverse while dead

            deathTime += 1;
        }

	}
}
