#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

namespace Sounds
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;

        AudioEngine audio;
        WaveBank wavebank;
        SoundBank soundbank;

        Cue titleCue;
        Cue zapCue;
        Cue wailCue;
        Cue dyingCue;

        GamePadState _curState;
        GamePadState _lastState;

        float volume = 1.0f;
        AudioCategory category;

        AudioEmitter emitter;
        AudioListener listener;
        Vector3 position;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);

            audio = new AudioEngine("Content/Chapter5sounds.xgs");
            wavebank = new WaveBank(audio, "Content/Wave Bank.xwb");
            soundbank = new SoundBank(audio, "Content/Sound Bank.xsb");

            category = audio.GetCategory("Default");

            emitter = new AudioEmitter();
            listener = new AudioListener();
            
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            titleCue = soundbank.GetCue("title");
            zapCue = soundbank.GetCue("zap");
            wailCue = soundbank.GetCue("wail");
            dyingCue = soundbank.GetCue("dying");

            zapCue.Apply3D(listener, emitter);
        }

        protected override void Update(GameTime gameTime)
        {
            _curState = GamePad.GetState(PlayerIndex.One);

            // Allows the game to exit
            if (_curState.Buttons.Back == ButtonState.Pressed)
                this.Exit();

            position = new Vector3(_curState.ThumbSticks.Left.X, 0.0f, _curState.ThumbSticks.Left.Y);

            emitter.Position = position;


            if (_curState.Buttons.A == ButtonState.Pressed && _lastState.Buttons.A==ButtonState.Released)
            {
                if (!titleCue.IsPlaying)
                {
                    titleCue = soundbank.GetCue("title");
                    titleCue.Play();
                }
                else if (titleCue.IsPaused)
                    titleCue.Resume();
                else if (titleCue.IsPlaying)
                    titleCue.Pause();

            }
            
            if (_curState.Buttons.B == ButtonState.Pressed)
            {
                if (!zapCue.IsPlaying)
                {
                    zapCue = soundbank.GetCue("zap");
                    zapCue.Apply3D(listener, emitter);
                    zapCue.Play();
                }
            }
            
            if (_curState.Buttons.X == ButtonState.Pressed)
            {
                if (!wailCue.IsPlaying)
                {
                    wailCue = soundbank.GetCue("wail");
                    wailCue.Play();
                }
            }
            
            if (_curState.Buttons.Y == ButtonState.Pressed)
            {
                if (!dyingCue.IsPlaying)
                {
                    dyingCue = soundbank.GetCue("dying");
                    dyingCue.Play();
                }
            }

            if (_curState.DPad.Up == ButtonState.Pressed)
            {
                volume = MathHelper.Clamp(volume + 0.01f, 0.0f, 5.0f);
            }

            if (_curState.DPad.Down == ButtonState.Pressed)
            {
                volume = MathHelper.Clamp(volume - 0.01f, 0.0f, 5.0f);
            }

            category.SetVolume(volume);

            _lastState = _curState;

            base.Update(gameTime);
        }


        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}
