using UnityEngine;
using System.Collections;
using Framework.Entities;
using Framework.ActorComponents;
using Project.World;
using Framework.Utility;
using Project.Sound;
using Project.Constructs;

namespace Project.Player
{
    public class PlayerInput : CoreBehaviour
    {
        public class FreezeInputAction : CoreAction { }
        public class UnfreezeInputAction : CoreAction { }
        public class LevelChangeAction : CoreAction { }
        public class PlayerHurtAction : CoreAction { }

        public float moveSpeed = 2f;
        public float humRange = 10f;
        public float humSpeed = 2f;
        public AudioClip humClip;
        public int selectedMelody;
        public float melodySpeed = 3f;
        public PowerMelody freezeMelody;
        private Vector3 moveVector;
        private CharacterController controller;
        private UnityTimer humTimer;
        private Melody[] melodies;
        private UnityTimer melodyTimer;
        private bool freeze;
        private Animator animator;

        // Use this for initialization
        protected override void InnerAwake()
        {
            AddGlobalActionHandler<FreezeInputAction>(this, (FreezeInputAction action) => { this.freeze = true; });
            AddGlobalActionHandler<UnfreezeInputAction>(this, (UnfreezeInputAction action) => { this.freeze = false; });

            this.controller = GetComponent<CharacterController>();
            this.humTimer = new UnityTimer(this.humSpeed, true);
            this.animator = this.transform.FindChild("Visual").GetComponent<Animator>();

            if (this.freezeMelody == null)
            {
                this.freezeMelody = new PowerMelody(null, 6f, 5f);
            }

            // Set up melodies 
            this.melodies = new Melody[] 
            {
                this.freezeMelody
            };
            this.selectedMelody = 0;
            this.melodyTimer = new UnityTimer(this.melodySpeed, true);
        }

        // Update is called once per frame
        protected override void InnerUpdate() 
        {
            if (!this.freeze)
            {
                Time.timeScale = 1f;
                Time.fixedDeltaTime = 0.02f;
                // hum
                if (Input.GetButton("Fire2") && this.humTimer.IsComplete())
                {
                    //Loadable.LoadFromPosition(this.transform.position);
                    Announce(new AudioVisualDirector.SoundAction(this.humClip, this.transform.position, this.humRange));
                    this.humTimer.Reset();
                }
                if (Input.GetButton("Fire1") && this.melodyTimer.IsComplete())
                {
                    this.melodies[this.selectedMelody].Sing(this.transform);
                    //Loadable.LoadFromPosition(this.transform.position);
                    Announce(new AudioVisualDirector.SoundAction(this.melodies[this.selectedMelody].clip, this.transform.position, this.melodies[this.selectedMelody].range));
                    this.melodyTimer.Reset();
                }

                if (!this.humTimer.IsComplete())
                {
                    this.humTimer.Advance();
                }
                if (!this.melodyTimer.IsComplete())
                {
                    this.melodyTimer.Advance();
                }
                moveVector = ((Vector3.forward * Input.GetAxis("Vertical")) + (Vector3.left * -Input.GetAxis("Horizontal"))) * Time.deltaTime * moveSpeed;
                //Debug.Log(moveVector);
            }
            else
            {
                Time.timeScale = 0.01f;
                Time.fixedDeltaTime = 0.01f * 0.02f;
                moveVector = Vector3.zero;
            }
            Interact(new PlayerMover.MoveAction(moveVector));
	    }

        protected void OnCollisionEnter(Collision collision)
        {
            GameObject other = collision.collider.gameObject;
            if (other.GetComponent<DoorBehaviour>() != null)
            {
                Announce(new LevelChangeAction());
                Application.LoadLevel(Application.loadedLevel + 1);
            }
        }
    }
}