using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using FredriksdalAssault2.GameDebugTools;

namespace FredriksdalAssault2
{
    /// <summary>
    /// This is the main type for this game
    /// </summary>
    public class GameAssault : Microsoft.Xna.Framework.Game
    {
        #region Variables

        // Variables declared by Microsoft
        GraphicsDeviceManager graphics;

        // Network (screenManager is a game component)
        ScreenManager screenManager;
        static readonly string[] preloadAssets = { "Menus/gradient", "Menus/ammo", "Menus/chat_ready", "Menus/chat_able", 
                                                     "Menus/chat_talking", "Menus/chat_mute", };

        // Debug system
        //public static DebugSystem debugSystem;

        #endregion

        #region Properties

        #endregion

        #region Constructors

        /// <summary>
        /// Create a new game.
        /// </summary>
        public GameAssault()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Debug system.
            //IsFixedTimeStep = false;
            //graphics.SynchronizeWithVerticalRetrace = false;

            // Set the resolution
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;

//#if (!XBOX)
//            // Get the windows game into fullscreen mode.
//            graphics.ToggleFullScreen();
//#endif

            // Set the window title
            Window.Title = "Fredriksdal Assault";

            // Create components.
            screenManager = new ScreenManager(this);

            Components.Add(screenManager);
            Components.Add(new MessageDisplayComponent(this));
            Components.Add(new GamerServicesComponent(this));

            // Activate the first screens.
            screenManager.AddScreen(new BackgroundScreen(), null);
            screenManager.AddScreen(new MainMenuScreen(), null);

            // Listen for invite notification events.
            NetworkSession.InviteAccepted += (sender, e)
                => NetworkSessionComponent.InviteAccepted(screenManager, e);

            // To test the trial mode behavior while developing your game,
            // uncomment this line:
            //Guide.SimulateTrialMode = true;

        }

        #endregion

        #region Initialization

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content. Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            //debugSystem = DebugSystem.Initialize(this, "Fonts/gamefont");

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Load assets, images, for network.
            foreach (string asset in preloadAssets)
            {
                Content.Load<object>(asset);
            }

            //debugSystem.FpsCounter.Visible = true;
            //debugSystem.TimeRuler.Visible = true;
            //debugSystem.TimeRuler.ShowLog = true;
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // Unload any non SEE GameplayScreen.
            Content.Unload();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // tell the TimeRuler that we're starting a new frame. you always want
            // to call this at the start of Update
            //debugSystem.TimeRuler.StartFrame();
            //debugSystem.TimeRuler.BeginMark("Update", Color.Blue);

            // Allows the game to exit
            //if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            //    this.Exit();

            base.Update(gameTime);

            // Stop measuring time for "Update".
            //debugSystem.TimeRuler.EndMark("Update");
        }

        /// <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)
        {
            // Start measuring time for "Draw".
            //debugSystem.TimeRuler.BeginMark("Draw", Color.Yellow);

            graphics.GraphicsDevice.Clear(Color.Black);

            // The real drawing happens inside the screen manager component.
            base.Draw(gameTime);

            // Stop measuring time for "Draw".
            //debugSystem.TimeRuler.EndMark("Draw");

        }

        #endregion

    } // End of class

} // End of namespace
