using UnityEngine;
using System.Collections;
using UnityEngine.Rendering;

public class Player : Inputable {
    Camera cam;
    Rigidbody2D body;
	private float shootCD = 0.0f;

    private int playerID;

    [SerializeField]
    GameObject crownPrefab;
    
	[SerializeField]
	GameObject projectile;
    [SerializeField]
	float jumpForce;
    [SerializeField]
	bool jumping;
    [SerializeField]
	float moveForce;
    [SerializeField]
	float shootForce;
    [SerializeField]
	float rubberBand;
    [SerializeField]
	private Color[] playerColors;

    private Color myColor;
    [SerializeField]
	float score;
    GameObject crown;
    private float speed;

    private float aniJumpTimer;
    private float aniShootTimer;

    AudioSource aud;

    Animator ani;
    void Awake()
    {
        //InputManager.AttachPlayer(this, 0);
    }

    // Use this for initialization
    void Start () {
        FindObjectOfType<Camera>().GetComponent<CameraScript>().RegisterToCamera(this);
        cam = FindObjectOfType<Camera>();
        ani = GetComponent<Animator>();
        aud = GetComponent<AudioSource>();
        body = this.GetComponent<Rigidbody2D>();
        score = 0.0f;

        jumping = false;
        //ChangePlayerColor(0);

        aniJumpTimer = 0.0f;
        aniShootTimer = 0.0f;
    }

    public void Initialize(int playerNum)
    {
        crown = Instantiate(crownPrefab);
        ChangePlayerColor(playerNum);
        Debug.Log("Crown SetActive");
        crown.SetActive(false);

        playerID = playerNum;

        FindObjectOfType<ScoreManager>().Subscribe(this, playerID);
    }

    

    void ChangePlayerColor(int color)
    {
        myColor = playerColors[color];
        GetComponent<SpriteRenderer>().color = myColor;
        crown.GetComponent<CrownScript>().SetColor(myColor);
    }

	public Color GetPlayerColor()
	{
		return myColor;
	}

	// Update is called once per frame
	void Update () {
        //if (cam.WorldToViewportPoint(this.transform.position).y < 0)
        //{
        //    StartCoroutine(RubberBand());
        //}

        shootCD += -1.0f * Time.deltaTime;

        if(Mathf.Abs(body.velocity.magnitude) < 0.01f)
        {
            ani.SetBool("isMoving", false);
        }

        speed = body.velocity.x;
        ani.SetFloat("playerSpeed", speed);

        if(ani.GetBool("isJumping") == true)
        {
            aniJumpTimer += 1.0f * Time.deltaTime;
            if(aniJumpTimer > .5f)
            {
                ani.SetBool("isJumping", false);
                aniJumpTimer = 0.0f;
            }
        }

        if (ani.GetBool("isShooting") == true)
        {
            aniShootTimer += 1.0f * Time.deltaTime;
            if (aniShootTimer > .5f)
            {
                ani.SetBool("isShooting", false);
                aniShootTimer = 0.0f;
            }
        }

        crown.transform.position = Vector3.Lerp(crown.transform.position, new Vector3(transform.position.x, transform.position.y + 0.4f, transform.position.z),Time.deltaTime * 12.5f);
    }

    private IEnumerator RubberBand()
    {
        yield return new WaitForSeconds(.22f);
        body.velocity = Vector2.zero;

        yield return new WaitForSeconds(1.0f);
        body.AddForce(new Vector2(0, rubberBand));
    }


    public override void ThumbstickLeft(float vert, float horiz)
    {
        body.AddForce(new Vector2(horiz, 0) * moveForce);
        ani.SetBool("isMoving", true);
    }

    public override void ThumbstickRight(float vert, float horiz)
    {
        ShootProjectile(vert,horiz);
    }

    private void ShootProjectile(float vert, float horiz)
    {
        if (shootCD < 0)
        {
            ani.SetBool("isShooting", true);
            shootCD = 0.5f;
            GameObject spawnedProj = (GameObject)Instantiate(projectile, (Vector2)this.transform.position + new Vector2(horiz,vert) * .2f, this.transform.rotation);
			transform.up = new Vector3(horiz * 0.2f, vert * 0.2f);
            spawnedProj.GetComponent<Projectile>().SetPlayer(this.gameObject);
            spawnedProj.GetComponent<SpriteRenderer>().color = myColor;
            spawnedProj.GetComponent<Rigidbody2D>().AddForce(new Vector2(horiz, vert) * shootForce);
            spawnedProj.GetComponent<Projectile>().SetExplosionColor(myColor);
        }
        //ani.SetBool("isShooting", false);
    }

	/*
    public override void TriggerRight()
    {
        Debug.Log("Player TriggerRight");
        if (!jumping)
        {
            Debug.Log("Activate Jump");
            body.AddForce(new Vector2(0, jumpForce));
            jumping = true;
        }
    }
	//*/

	public override void BumperLeft()
	{
		Debug.Log("Player BumperLeft");
		if (!jumping)
		{
			Debug.Log("Activate Jump");
			body.AddForce(new Vector2(0, jumpForce));
			jumping = true;
            ani.SetBool("isJumping", true);
            if (!aud.isPlaying)
            {
                aud.Play();
            }
        }
        
	}

	public override void BumperRight()
	{
		Debug.Log("Player BumperRight");
		if (!jumping)
		{
			Debug.Log("Activate Jump");
			body.AddForce(new Vector2(0, jumpForce));
			jumping = true;
			ani.SetBool("isJumping", true);
		}

	}

	public override void ButtonLeft()
	{
		Debug.Log("Player ButtonLeft");
		if (!jumping)
		{
			Debug.Log("Activate Jump");
			body.AddForce(new Vector2(0, jumpForce));
			jumping = true;
			ani.SetBool("isJumping", true);
		}
	}

	public override void ButtonRight()
	{
		Debug.Log("Player ButtonRight");
		if (!jumping)
		{
			Debug.Log("Activate Jump");
			body.AddForce(new Vector2(0, jumpForce));
			jumping = true;
			ani.SetBool("isJumping", true);
		}
	}

	public override void ButtonDown()
	{
		Debug.Log("Player ButtonDown");
		if (!jumping)
		{
			Debug.Log("Activate Jump");
			body.AddForce(new Vector2(0, jumpForce));
			jumping = true;
			ani.SetBool("isJumping", true);
		}
	}

	public override void ButtonUp()
	{
		Debug.Log("Player ButtonUp");
		if (!jumping)
		{
			Debug.Log("Activate Jump");
			body.AddForce(new Vector2(0, jumpForce));
			jumping = true;
			ani.SetBool("isJumping", true);
		}
	}

	void OnCollisionStay2D(Collision2D other)
    {
        if(other.gameObject.tag == "Ground" || other.gameObject.tag == "Player")
        {
            if (Mathf.Abs(body.velocity.y) < 0.1f)
            {
                jumping = false;
            }
        }
    }

	public void AddScore(float val)
	{
		score += val;
	}

    public float GetScore()
    {
        return score;
    }

    public void ActivateCrown()
    {
        Debug.Log("ActivateCrown");
        crown.SetActive(true);
    }
    public void DeactivateCrown()
    {
        Debug.Log("DeactivateCrown");
        crown.SetActive(false);
    }

}
