using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Blindfold.Managers;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;

namespace Blindfold.Objects
{
    public class Player : Obj
    {
        private Vector3 position;
        private Vector3 look;

        private float soundtimer;
        private bool leftFoot;

        private float speed;
        private int sprint;
        private bool sprinted;

        private SoundEffectInstance breath;

        #region PROPERTIES
        public Vector3 POSITION
        {
            get
            {
                return position;
            }
        }
        public Vector3 LOOK
        {
            get
            {
                return look;
            }
            set
            {
                look = value;
            }
        }
        public float SPEED
        {
            get
            {
                return speed;
            }
        }
        #endregion

        public Player(Vector3 pos)
            : base()
        {
            position = pos;
            look = new Vector3(0, 1, 0);
            soundtimer = 500.0f;
            sprint = 10000;
            breath = ObjManager.GAME.SOUNDMANAGER.getEffectInstance("breath1");
        }

        public override void Update(GameTime gameTime)
        {
            Vector2 walkdir = -ObjManager.GAME.INPUTMANAGER.getLeftDir(0);

            //TODO Walk to waypoint instead of walking away from Player
            if (!walkdir.Equals(Vector2.Zero))
            {
                float velocity = 0.01f;
                if (walkdir.Y < 0)
                {
                    velocity = 0.006f;
                }
                if (walkdir.Y > 0 && (ObjManager.GAME.INPUTMANAGER.buttonDown(Buttons.RightShoulder, 0) || ObjManager.GAME.INPUTMANAGER.buttonDown(Buttons.RightTrigger, 0)))
                {
                    if (sprint > 0 && !sprinted)
                    {
                        sprint -= gameTime.ElapsedGameTime.Milliseconds;
                        velocity = 0.02f;
                    }
                }
                else if(sprint < 10000)
                {
                    sprint += gameTime.ElapsedGameTime.Milliseconds;
                }
                if (sprint <= 10 && !sprinted)
                {
                    sprinted = true;
                    breath.Stop();
                    breath = ObjManager.GAME.SOUNDMANAGER.getEffectInstance("breath2");
                    breath.Play();
                }
                else if (sprint > 5000 && sprinted)
                {
                    sprinted = false;
                    breath.Stop();
                }

                float actualDir = (float)(Math.Atan2(look.X, look.Y) + Math.Atan2(-walkdir.X, walkdir.Y));

                walkdir = new Vector2((float)Math.Cos(actualDir), (float)Math.Sin(actualDir));


                ObjManager.GAME.INPUTMANAGER.vibrateGamepad(0, 0);
                // Collision Detection
                Vector3 predictedPosition = position + ((new Vector3(walkdir.X, 0, 0)) * velocity * gameTime.ElapsedGameTime.Milliseconds);
                List<Obj> list = ObjManager.GAME.OBJECTMANAGER.objectsOfType(typeof(Wall));
                bool collided = false;
                foreach(Wall w in list)
                {
                    if ((new Rectangle((int)predictedPosition.X, (int)predictedPosition.Y, 16, 16).Intersects(new Rectangle((int)w.POSITION.X, (int)w.POSITION.Y, 16, 16))))
                    {
                        collided = true;
                        break;
                    }
                }
                if (!collided)
                {
                    position = predictedPosition;
                }
                else
                {
                    ObjManager.GAME.INPUTMANAGER.vibrateGamepad(0,0.5f);
                }
                predictedPosition = position + ((new Vector3(0, walkdir.Y, 0)) * velocity * gameTime.ElapsedGameTime.Milliseconds);
                foreach (Wall w in list)
                {
                    if ((new Rectangle((int)predictedPosition.X, (int)predictedPosition.Y, 16, 16).Intersects(new Rectangle((int)w.POSITION.X, (int)w.POSITION.Y, 16, 16))))
                    {
                        collided = true;
                        break;
                    }
                }
                if (!collided)
                {
                    position = predictedPosition;
                }
                else
                {
                    ObjManager.GAME.INPUTMANAGER.vibrateGamepad(0, 0.5f);
                }

                speed = 0.0f;
                speed = Math.Max(Math.Abs(walkdir.X), Math.Abs(walkdir.Y));
                speed *= gameTime.ElapsedGameTime.Milliseconds;
                soundtimer -= speed * (velocity * 100);
            }

            if (soundtimer <= 0)
            {
                soundtimer = 500.0f;
                SoundEffectInstance sei;
                if (leftFoot)
                {
                    sei = ObjManager.GAME.SOUNDMANAGER.getEffectInstance("step_l");
                }
                else
                {
                    sei = ObjManager.GAME.SOUNDMANAGER.getEffectInstance("step_r");
                }
                sei.Volume = 0.02f;
                sei.Play();
                leftFoot = !leftFoot;
            }

            Vector2 lookDir = ObjManager.GAME.INPUTMANAGER.getRightDir(0);

            look = Vector3.Transform(look, Matrix.CreateRotationZ((float)(gameTime.ElapsedGameTime.TotalMilliseconds * (-.001 * lookDir.X))));

            base.Update(gameTime);
        }

        public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch sb)
        {
            sb.Draw(ObjManager.GAME.OBJTEX, new Rectangle(312, 232, 16, 16), Color.White);
            base.Draw(sb);
        }
    }
}
