//---------------------------------------------------------------------------------------------------------------------------------------------------
// 
//     Copyright (C)2007 DarkWynter Studios.  All rights reserved.
// 
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Engine
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;
    using System.Threading;
    using System.Net;
    
    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;
    using System.Xml;
    using System.Windows.Forms;
    using Audio;
    using Init;
    using Menus;
    using Globals;
    using Utilities;
    using Controllers;
    using ObjectLib;
    using GameObjects;
    using Physics;
    using DarkWynter.Stream;
    using DarkWynter.Engine.UserInterface;
    
    #endregion
    using Nuclex;
    // Once we mix XNA with the System.Windows.Forms namespace, some ambiguities will
    // arise. The following lines create some shortcuts so the can conveniently address
    // the classes we actually want to use.
    using XnaColor = Microsoft.Xna.Framework.Graphics.Color;
    using XnaRectangle = Microsoft.Xna.Framework.Rectangle;
    using DarkWynter.Engine.EventControl;
    /// 
    /// Base class for creating a game using the DarkWynter Engine.
    /// DarkWynterEngine extends object modification to the user through XML.
    /// DakrWynterEngine extends functionality to the user through overridable objects.
    /// 
    public class DarkWynterEngine : Nuclex.GameControl
    {
        #region Properties
        /// 
        /// Main User's Heads Up Display
        /// 
        public static HeadsUpDisplay HUD;
        /// 
        /// Manage scoring, respawn, and gameover
        /// 
        private GameLogicController gameRules;
        /// 
        /// Game Controller
        /// 
        public static List gameControllers;
        /// 
        /// Menu Controller
        /// 
        public static List menuControllers;
        /// 
        /// List of user-defined game objects
        /// 
        protected List gameObjectTypes;
        /// 
        /// A scenegraph/collections class, contains all GameObject instants
        /// 
        public static ObjectLibrary objectLibrary;
        /// 
        /// Handles collision detection.
        /// 
        protected Collision collision;
        /// 
        ///  Renders the scene once for each viewport.
        /// 
        protected Renderer renderer;
        /// 
        /// Menu System Componenets
        /// 
        protected MenuSystem menuSystem;
        /// 
        ///  Interface to GPU Uniform variables
        /// 
        private ShaderParameters shaderParameters;
        /// 
        ///  FPS - Frames Per Second
        /// 
        public FPSCounter fps;
        ///// 
        //// Controller
        //// 
        //public static Controller playerController;
        
        //// 
        //// Controller for the MenuSystem
        //// 
        //public static Controller menuController;
        /// 
        ///  Screen Saver Shader
        /// 
        private ScreenSaver screenSaver;
        /// 
        /// Terrain Mod Singleton
        /// 
        public static MajikWand majikWand = new MajikWand();
        /// 
        /// Supplied from upper layer components that require notification whenever a new Level is loaded.
        /// 
        /// Controller boolean event arguments
        public delegate void OnLevelChange(EventArgs args);
        public static event OnLevelChange onLevelChange;
        /// 
        /// Supplied from upper layer components that require notification whenever a new Level is loaded.
        /// 
        /// Controller boolean event arguments
        public delegate void OnSurveyPretest(object sender, EventArgs args);
        public static event OnSurveyPretest onSurveyPretest;
        public static bool launchPreTest = false;
        /// 
        /// Supplied from upper layer components that require notification whenever a new Level is loaded.
        /// 
        /// Controller boolean event arguments
        public delegate void OnSurveyPosttest(object sender, EventArgs args);
        public static event OnSurveyPosttest onSurveyPosttest;
        public static bool launchPostTest = false;
        #endregion
        #region Methods
        // --------------- Constructor -----------------
        /// 
        /// Main Engine Class.
        /// Check for Hardware Capabilities.
        /// Create GraphicsDeviceManager and ContentManager.
        /// 
        public DarkWynterEngine():base()
        {
            // Draw is called as many times as the hardware can handle.
            // If(IsFixedTimeStep), then Update is called 30x per second.
            // If(!IsFixedTimeStep), then Update is called as many times as the hardware can handle.
            // The differrence affects both controller inputs and physics responses in the Virtual Environment.
            this.IsFixedTimeStep = true;
            // Set up Global Graphics Device and Content Loader
            Statics_Stream.RenderSettings.graphics = this.graphics;
            Statics_Engine.SystemSettings.content = new ContentManager(Services);
            Statics_Stream.RenderSettings.graphics.SynchronizeWithVerticalRetrace = false;
            // Check all available adapters on the system
            for (int i = 0; i < GraphicsAdapter.Adapters.Count; i++)
            {
                // Get the capabilities of the hardware device
                GraphicsDeviceCapabilities caps = GraphicsAdapter.Adapters[i].GetCapabilities(DeviceType.Hardware);
                if (caps.MaxPixelShaderProfile < ShaderProfile.PS_3_0)
                {
                    System.Diagnostics.Debug.WriteLine("This adapter does not support Shader Model 3.0.");
                    Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.NOT_SUPPORTED;
                }
                else
                {
                    //Yay! They can play
                    Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.CREDIT_SCREEN;
                }
            }
            // Initialize Control Docking
            this.Dock = DockStyle.Fill;
            this.Focus();
            // Set up  Mouse to Activate and Deactivate, using Left and Right mouse clicks respectively.
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown);
            // Drag/Drop Level Creation
            this.AllowDrop = true; 
            this.DragEnter += new DragEventHandler(terrain_DragEnter);
            this.DragDrop += new DragEventHandler(terrain_DragDrop);
        }
        // ----------------- Load ----------------------
        /// 
        /// Set Up Display Window.
        /// Create Logging, XML, GameFlow, Renderer, SpriteBatch, 
        /// FontWriter, MenuSystem, Audio, ShaderParameters, ChatClient, 
        /// Frames Per Second Counter, and Screensaver
        /// 
        protected virtual void Initialize(GameObjectTypes userDefinedTypes)
        {
            try
            {
                // Load System XML Settings
                XML.LoadUserPreferences();
                DarkWynterEngine.Load_LevelIndex();
                DarkWynterEngine.Load_EventIndex();
                XML.LoadQuestInfo();
                // Load GameObjectTypes - Xml/GameObject Equivalency List
                XML.gameObjectTypes = new List();
                XML.gameObjectTypes.Add(new GameObjectTypes());
                XML.gameObjectTypes.Add(userDefinedTypes);
                
                if (!XML.contentInstalled)
                {
                    this.SuspendLayout();
                    Label installContentLabel = new Label();
                    installContentLabel.AutoSize = true;
                    installContentLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.00F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    installContentLabel.Location = new System.Drawing.Point(10, 10);
                    installContentLabel.Text = "Content Project could not be found... ";
                    installContentLabel.ForeColor = System.Drawing.Color.Silver;
                    Label installContentLabel2 = new Label();
                    installContentLabel2.AutoSize = true;
                    installContentLabel2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.00F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    installContentLabel2.Location = new System.Drawing.Point(10, 50);
                    installContentLabel2.Text = "Please select \"Download Package\" below, to install content from web.";
                    installContentLabel2.ForeColor = System.Drawing.Color.Silver;
                    Panel panel = new Panel();
                    panel.SuspendLayout();
                    panel.Dock = DockStyle.Fill;
                    panel.Controls.Add(installContentLabel);
                    panel.Controls.Add(installContentLabel2);
                    panel.ResumeLayout(false);
                    panel.PerformLayout();
                    this.Controls.Clear();
                    this.Controls.Add(panel);
                    this.ResumeLayout(false);
                    this.PerformLayout();
                }
                // Menu System 
                menuSystem = new MenuSystem();
                XML.LoadAssembly("DWGame.dll");
                objectLibrary = new ObjectLibrary();
                collision = new Collision();
                // Set up display
                renderer = new Renderer(Statics_Engine.SystemSettings.content);
                UpdateRendererSettings();
                // Set up the renderer draw delegates
                renderer.drawObjectLibrary = new Renderer.DrawObjectLibrary(objectLibrary.Draw);
                renderer.drawSprites = new Renderer.DrawSprites(objectLibrary.Draw_Billboards);
                renderer.drawHUD = new Renderer.DrawHUD(objectLibrary.PostDraw_HUD);
                renderer.drawObjectOverhead = new Renderer.DrawObjectOverhead(objectLibrary.DrawOverhead);
                //PUT AN IMPORTANT METHOD CALL HERE
                // Set up Gpu Shader Handles
                shaderParameters = new ShaderParameters(Statics_Engine.SystemSettings.content);
                // Init the audio engine
                Audio.Audio.Initialize();
                Audio.Audio.PlayLevelSong("Theme4");
                // ScreenSaver for menuSystem
                screenSaver = new ScreenSaver();
                Statics_Engine.SystemSettings.screenSaverTimer = Stopwatch.StartNew();
                // Load the Font class
                Statics_Stream.Fonts.Arial = Statics_Engine.SystemSettings.content.Load("Content/_fonts/Arial");
                Statics_Stream.Fonts.ComicSans = Statics_Engine.SystemSettings.content.Load("Content/_fonts/ComicSansMS");
                Statics_Stream.Fonts.ComicSansSmall = Statics_Engine.SystemSettings.content.Load("Content/_fonts/ComicSansSmall");
                // Start Logging
                Logging.setStart(System.DateTime.Now);
                Logging.G2LLogList.Add(System.DateTime.Now.ToString());
                // Create new FPS class
                fps = new FPSCounter();
               // DarkWynterEngine.Deactivate();
                // Set up the Game Rules
                gameRules = new GameLogicController();
                // Controller Setup 
                gameControllers = new List();
                menuControllers = new List();
                ControllerManager.CheckForControllers(objectLibrary);
                base.Initialize();
            }
            // Catch all loading exceptions and print message to user.
            catch (Exception e)
            {
                Label installContentLabel2 = new Label();
                installContentLabel2.AutoSize = true;
                installContentLabel2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.00F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                installContentLabel2.Location = new System.Drawing.Point(10, 50);
                installContentLabel2.Text = "Error Initializing, Prob Due to Content. \n" + e.Message;
                installContentLabel2.ForeColor = System.Drawing.Color.Silver;
                Panel panel = new Panel();
                panel.SuspendLayout();
                panel.Dock = DockStyle.Fill;
                panel.Controls.Add(installContentLabel2);
                panel.ResumeLayout(false);
                panel.PerformLayout();
                this.Controls.Clear();
                this.Controls.Add(panel);
                this.ResumeLayout(false);
                this.PerformLayout();
            }
        }
        /// 
        /// Loads availible Levels from _Levels.xml and stores them in the LevelInfo list. 
        /// 
        public static void Load_LevelIndex()
        {
            string LevelXMLFile = "_xml/LevelEdit/_Levels.xml";
            Statics_Engine.levelInfo = new List();
            try
            {
                // Load physics, music, and fog
                XmlDocument reader = new XmlDocument();
                reader.Load(LevelXMLFile);
                XmlNodeList allNodes = reader.ChildNodes;
                foreach (XmlNode levelNode in allNodes)
                {
                    if (levelNode.Name == "levels")
                    {
                        XmlNodeList levelNodes = levelNode.ChildNodes;
                        foreach (XmlNode node in levelNodes)
                        {
                            if (node.Name == "level")
                            {
                                Statics_Engine.LevelInfo level = new Statics_Engine.LevelInfo();
                                level.name = node.Attributes["name"].Value;
                                level.filepath = node.Attributes["xmlFile"].Value;
                                level.description = node.Attributes["description"].Value;
                                level.cameraModeEnum_XML = (DarkWynter.Stream.Camera.CameraMode)Enum.Parse(typeof(DarkWynter.Stream.Camera.CameraMode), node.Attributes["CameraModeEnum"].Value, true);
                                Statics_Engine.levelInfo.Add(level);
                            }
                        }
                    }
                }
            }
            catch
            {
                XML.contentInstalled = false;
                System.Diagnostics.Debug.WriteLine("Error reading xml");
                //throw new Exception("Error reading XML");
            }
        }
        public static void Load_EventIndex()
        {
            string EventsXMLFile = "_xml/QuestSettings/_Levels.xml";
            Statics_Engine.eventsInfo = new List();
            try
            {
                // Load physics, music, and fog
                XmlDocument reader = new XmlDocument();
                reader.Load(EventsXMLFile);
                XmlNodeList allNodes = reader.ChildNodes;
                foreach (XmlNode eventsNode in allNodes)
                {
                    if (eventsNode.Name == "levels")
                    {
                        XmlNodeList levelNodes = eventsNode.ChildNodes;
                        foreach (XmlNode node in levelNodes)
                        {
                            if (node.Name == "events")
                            {
                                Statics_Engine.EventsInfo eventsInfo = new Statics_Engine.EventsInfo();
                                eventsInfo.name = node.Attributes["name"].Value;
                                eventsInfo.filepath = node.Attributes["xmlFile"].Value;
                                eventsInfo.description = node.Attributes["description"].Value;
                                Statics_Engine.eventsInfo.Add(eventsInfo);
                            }
                        }
                    }
                }
            }
            catch
            {
                XML.contentInstalled = false;
                System.Diagnostics.Debug.WriteLine("Error reading xml");
                //throw new Exception("Error reading XML");
            }
        }
        /// 
        /// 
        /// 
        public static void Save_LevelIndex()
        {
            // Output xml level index to file
        }
        /// 
        /// 
        /// 
        public static void Load_Level(string LevelXml_FilePath, string ScriptXml_FilePath)
        {
            // Reset load level flag
            Statics_Engine.GameSettings.LoadLevel = false;
            if (HUD == null)
            {
                HUD = new HeadsUpDisplay();
            }
            // Call Load Sequence
            objectLibrary.LoadLevel(LevelXml_FilePath);
            GameEventHandler.LoadEventsXml(ScriptXml_FilePath);
            // XML.LoadPlayerIndex();
            //Statics_Engine.LevelSettings.ViewportSize = new Vector2(
            //    Statics_Stream.RenderSettings.cameraList[0].viewport.Width, 
            //    Statics_Stream.RenderSettings.cameraList[0].viewport.Height);
            Statics_Stream.RenderSettings.cameraList[0].mode = Stream.Camera.CameraMode.FirstPerson;
            Statics_Stream.RenderSettings.cameraList[0].fixedPosition = new Microsoft.Xna.Framework.Vector3(8000, 6000, 8000);
            Statics_Stream.RenderSettings.cameraList[0].mode = Statics_Engine.levelInfo[Statics_Engine.levelIndex].cameraModeEnum_XML;
            
            // If we only have one player, add a terrain camera for the mini map
            if (Statics_Stream.RenderSettings.cameraList.Count == 1)
            {
                Camera HUDCamera = new Camera();
                Statics_Stream.RenderSettings.cameraList.Add(HUDCamera);
                HUDCamera.mode = Camera.CameraMode.FixedPosition;
                HUDCamera.lookAtPosition = Vector3.Zero;
                HUDCamera.cameraPosition = new Vector3(0, 5000, 0);
                //position
                HUDCamera.viewport.X = 100;
                HUDCamera.viewport.Y = 100;
                //size
                HUDCamera.viewport.Width = 50;
                HUDCamera.viewport.Height = 50;
            }
            // Switch into Game Mode processing
            Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.GAME_MODE;
            // Call Level-Loaded Callback delegate to notify upper layers of change.
            onLevelChange(new EventArgs());
        }
        // ---------------  Update ---------------------
        /// 
        /// Update MenuSystemGame, Audio, FPS.
        /// Check For Level Loading Request.
        /// Check For Exit.
        /// 
        /// XNA GameTime
        protected override void Update(GameTime gameTime)
        {
            // Set current change in time
            Statics_Engine.SystemSettings.dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
            // Update renderer settings if changed
            UpdateRendererSettings();
            Statics_Engine.GameSettings.viewport = Statics_Stream.RenderSettings.cameraList[0].viewport;
          //  GameEventHandler.CurrentGameConditions._triggerCoins = 1;
            // If requested via flag
            if (Statics_Engine.GameSettings.LoadLevel)
            {
                // Load new Level
                Load_Level(
                    Statics_Engine.levelInfo[Statics_Engine.levelIndex].filepath,
                    Statics_Engine.eventsInfo[Statics_Engine.levelIndex].filepath
                );
            }
            // If Window is active...
            if (Statics_Engine.SystemSettings.WINDOW_IN_FOCUS)
            {
                // Update all Engine Controllers
                UpdateControllers();
            }
            // If compiler disabled
            if (Statics_Engine.SystemSettings.enableCompilerConsole == false)
            {
                // If in 3D GameMode
                if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
                {
                    // Update ObjectLibrary    
                    objectLibrary.Update(ref objectLibrary, collision);
                    // Update TerrainMod Caps
                    majikWand.Update(objectLibrary);
                }
                else
                {
                    if (Statics_Engine.SystemSettings.WINDOW_IN_FOCUS)
                    {
                        // Update menu system
                        menuSystem.Update(objectLibrary);
                    }
                }
            }
            // Update Frame Rate Counter
            if (Statics_Engine.SystemSettings.enableFPSDisplay)
            { fps.Update(); }
            // Crank the audio engine
            Audio.Audio.Update();
            // Crank the video engine
            //video.Update();
            if (launchPreTest)
            {
                if (DarkWynterEngine.onSurveyPretest != null)
                {
                    DarkWynterEngine.onSurveyPretest(this, new EventArgs());
                    launchPreTest = false;
                }
            }
            if (launchPostTest)
            {
                Logging.writeG2LLog(
                   DarkWynter.Engine.Globals.Statics_Engine.PlayerSettings.studentIDNumber + "-G2Llog.txt",
                   DarkWynter.Engine.Utilities.Logging.G2LLogList
                   );
                Logging.writeG2LLog(
                    DarkWynter.Engine.Globals.Statics_Engine.PlayerSettings.studentIDNumber + "-G2LPositionalLog.txt",
                    DarkWynter.Engine.Utilities.Logging.G2LPositionalLog
                    );
                if (DarkWynterEngine.onSurveyPosttest != null)
                {
                    DarkWynterEngine.onSurveyPosttest(this, new EventArgs());
                    launchPostTest = false;
                }
            }
            // Call XNA Update
            base.Update(gameTime);
        }
        private void UpdateRendererSettings()
        {
            // Update renderer settings if changed
            if (Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Height != Statics_Stream.RenderSettings.GAME_WINDOW_HEIGHT ||
                Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Width != Statics_Stream.RenderSettings.GAME_WINDOW_WIDTH)
            {
                renderer.AutoDetectResolution();
                renderer.AutoDetectWindowAndDefaultViewport(/*Window*/);
                Renderer.ResetViewports(Statics_Engine.SystemSettings.TOTAL_PLAYERS);
            }
        }
        private void UpdateControllers()
        {
            // Update Game Mode Controllers
            if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
            {
                // Update Controllers
                foreach (GameController gameController in gameControllers)
                {
                    // Check that the human is alive and hence active in the game
                    if (objectLibrary.humans[gameController.playerNumber].IsAlive())
                    {
                        gameController.Update(ref objectLibrary, ref menuSystem);
                    }
                }
                // Update GameRules
                gameRules.Update(ref objectLibrary);
            }
            // Update Menu Mode Controllers
            else
            {
                // Update all menu controllers
                foreach (MenuController menuController in menuControllers)
                {
                    menuController.Update(ref objectLibrary, ref menuSystem);
                }
            }
        }
        // ----------------- Draw ----------------------
        /// 
        /// Draw Game or MenuSystem Screen
        /// 
        /// XNA GameTime
        protected override void Draw(GameTime gameTime)
        {
            // Clear the device
            Statics_Engine.SystemSettings.elementalGameTime = gameTime;
            // If in Game Mode (or paused) call game draw function
            if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE || Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_PAUSE)
            {
                             
                renderer.Draw(Statics_Engine.SystemSettings.TOTAL_PLAYERS);
                //renderer.DrawOverhead(Statics_Stream.RenderSettings.cameraList[1]);
            }
            if (Statics_Engine.SystemSettings.gameState != Enums_Engine.EngineState.GAME_MODE)
            {
                menuSystem.Draw(renderer.spriteBatch, screenSaver);
            }
            fps.Draw(renderer.spriteBatch);
            // Call XNA Draw
            base.Draw(gameTime);
        }
        // ---------------- Exit -----------------------
        /// 
        /// Check to see if user has requested to exit the application.
        /// 
        protected virtual void CheckExit()
        {
            XML.SaveUserPreferences();
            //Logging.genReport(System.DateTime.Now);
            //Logging.saveLog(System.DateTime.Now);
            Statics_Engine.SystemSettings.enableFPSDisplay = false;
           
            
            //chatClient.CloseConnection();
            this.Exit();
        }
        /// 
        /// Unload resources loaded using the content manager
        /// 
        protected override void UnloadContent()
        {
            base.UnloadContent();
            Statics_Engine.SystemSettings.content.Unload();
            Statics_Engine.SystemSettings.content.Dispose();
        }
        #endregion
        #region Events
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            //if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
            {
                if (HUD != null)
                {
                        //// Resize based on percentage of FULL screen viewport size
                    HUD.Resize(new Vector2(this.Size.Width, this.Size.Height));
                }
            }
        }
        /// 
        /// Copy the new image
        /// 
        /// 
        /// 
        void terrain_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Bitmap))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        /// 
        /// Create the new bitmap onto the terrain and add the csobject to the list
        /// 
        /// 
        /// 
        void terrain_DragDrop(object sender, DragEventArgs e)
        {
            //objectLibrary.humans[0].holdingObject = ObjectLibrary.soloObjects[3];
            objectLibrary.humans[0].holdingObject.mass.scale = new Vector3(100);
            //// Create the object and attach to Player
            //if (tempObj != null)
            //{
            //    //if (tempObj is Waypoint)
            //    //{
            //    //}
            //    //if (tempObj is Actor)
            //    //{
            //    //}
            //    //if (tempObj is Prop)
            //    //{
            //    //}
            //}
        }
        /// 
        /// Override XNA function
        /// Activate Mouse when window gains focus.
        /// 
        /// 
        /// 
        protected override void OnActivated(object sender, EventArgs args)
        {
            //base.OnActivated(sender, args);
            Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = true;
            
        }
        /// 
        /// Override XNA function.
        /// Deactivate Mouse when window looses focus.
        /// 
        /// 
        /// 
        protected override void OnDeactivated(object sender, EventArgs args)
        {
            //base.OnDeactivated(sender, args);
            Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = false;
        }
        /// 
        /// Toggle game controllers on/off
        /// 
        public static void Activate()
        {
            Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = true;
        }
        /// 
        /// Deactivate Mouse, Controls, and most of the Update Loop.
        /// 
        public static void Deactivate()
        {
            Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = false;
        }
        /// 
        /// Activates Mouse, Controller, and unpauses Game when Left-Clicked.
        /// Deactivates Mouse, Controller and pauses Game when Right-Clicked.
        /// 
        /// 
        /// 
        protected void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                DarkWynterEngine.Activate();
            }
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                DarkWynterEngine.Deactivate();
            }
        }
        /// 
        /// Initiate exit procedure
        /// 
        public static void DoExit(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("Would you like to close the application?", "Allow Close?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                   == DialogResult.No)
            {
                e.Cancel = true;
            }
            else if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
            {
                Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.FINALIZE_G2LSTUFF;
            }
            else if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.FINALIZE_G2LSTUFF)
            {
                Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.GAME_OVER;
            }
            else if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_OVER)
            {
                Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.EXIT;
            }
            
        }
        #endregion
    }
}