using System;
using System.Globalization;
using System.Reflection;
using ECOT.Engine;
using ECOT.Game.States;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Graphics;


#if !XBOX
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;
#endif

namespace ECOT.Game
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game : Microsoft.Xna.Framework.Game
    {
        public string Revision;
        public string Branch;
        public string Version;
        public StorageDevice Device;

        private GameSpeed currentSpeed = GameSpeed.Play;

        public Game()
        {
            // add the Profile Tracking
            this.Components.Add(new GamerServicesComponent(this));
#if !XBOX
            this.engine = new Kernel(this, new Size(VideoSettings.Default.ScreenWidth, VideoSettings.Default.ScreenHeight), VideoSettings.Default.Fullscreen);
#else
            this.engine = new Kernel(this, new Size(1280, 720), true);

            Kernel.Instance.Input.InitControllers();
            Kernel.Instance.Input.OnDisconnection += this.OnDeactivated;
            Kernel.Instance.Input.OnConnection += this.OnActivated;
#endif
            // Récupère la révision en cours
            this.Revision = "$Revision: 17 $";
            this.Revision = this.Revision.Substring(11, 3);
            // Branche de développement
            this.Branch = "(programmez-branch)";
            // Version
            this.Version = "1.0";
            // Assigne le titre de la fenêtre
            this.Window.Title = string.Format("Ecological Tycoon {0} {1} r{2}", this.Branch, this.Version, this.Revision);
        }

        /// <summary>
        /// 
        /// </summary>
        protected override void BeginRun()
        {
            // Initialise le moteur
            this.engine.Initialize("Bootstrap", "ECOT.Game.Text", Assembly.GetExecutingAssembly());

#if XBOX
            Kernel.Instance.OnLocaleChange += this.OnLocaleChangeHandler;
            this.OnLocaleChangeHandler(null);
#endif

            // Crée les états de jeu
            new EcothinkState();
            new GameplayState();

            // Enregistre l'état de jeu par défaut
            this.engine.StateManager.SwitchTo("Ecothink", null);

            if (GameController.Instance != null)
                this.currentSpeed = GameController.Instance.Speed;

            base.BeginRun();
        }

        protected override void OnActivated(object sender, EventArgs args)
        {
            base.OnActivated(sender, args);

            if (GameController.Instance != null)
            {
                GameController.Instance.Speed = this.currentSpeed;
            }
        }
        protected override void OnDeactivated(object sender, EventArgs args)
        {
            base.OnDeactivated(sender, args);

            if (GameController.Instance != null)
            {
                this.currentSpeed = GameController.Instance.Speed;
                GameController.Instance.Speed = GameSpeed.Pause;
            }
        }

        protected override void OnExiting(object sender, EventArgs args)
        {
            // Stoppe tous les threads
            Kernel.Instance.KillAllThreads();
        }

        protected override void Update(GameTime gameTime)
        {
            this.engine.Time = gameTime;
            this.engine.TotalElapsedSeconds += gameTime.ElapsedGameTime.Milliseconds / 1000.0f;

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        protected override void Draw(GameTime gameTime)
        {
            this.engine.Time = gameTime;

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

        /// <summary>
        /// 
        /// </summary>
        public static void Main()
        {
            try
            {
                Game.instance = new Game();
                Game.instance.Run();
            }
            catch (Exception eGame)
            {
                // Récupère d'un éventuelle exception lors de l'arrêt du jeu (ça ne sert pas à grand chose).
                // Mais mieux vaut prévenir que guérir :)
                try
                {
                    // TODO: exit le moteur
                    Game.instance.Exit();
                }
                catch { /* Rien */ }
#if XBOX
                throw eGame;
#else
                {
                    MessageBox.Show(eGame.Message + "\n\n" + eGame.StackTrace, "Error :(", MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                }
#endif
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static Game Instance
        {
            get { return Game.instance; }
        }

        public StorageDevice StorageDevice
        {
            get { return this.Device; }
        }

        /// <summary>
        /// 
        /// </summary>
        private Engine.Kernel engine;

        /// <summary>
        /// 
        /// </summary>
        private static Game instance;
    }
}
