//---------------------------------------------------------------------------------------------------------------------------------------------------
// <copyright file="ElementalGame.cs" company="DarkWynter Studios">
//     Copyright (C)2007 DarkWynter Studios.  All rights reserved.
// </copyright>
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------

namespace DarkWynter.Game
{
    #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;
    #endregion

    using DarkWynter.Engine;
    using DarkWynter.Engine.Globals;
    using DarkWynter.Engine.Menus;
    using DarkWynter.Engine.Utilities;

    using RuleBook;                 // GameRules (move to engine)
    using Menus;
    
    using GameObjects;              // User Defined Types 
    //using Networking;

    //using WindowsGame2;
    using CSTextEditor;
    using System.Windows.Forms;
    using System.Collections;
    using DarkWynter.Stream;

    /// <summary>
    /// 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.
    /// </summary>
    public class DarkWynterGame : DarkWynterEngine
    {
        #region Properties

        /// <summary>
        /// Manage scoring, respawn, and gameover
        /// </summary>
        private GameRules gameRules;
        /// <summary>
        /// Game Controller
        /// </summary>
        public static GameController gameController;
        /// <summary>
        /// Menu Controller
        /// </summary>
        public MenuController menuController;

        //-- COMPILER
        Panel drawSurface;
        MainForm compilerForm;
        Form gameForm;

        ///// <summary>
        ///// Simple Network Client 
        ///// </summary>
        //private Client chatClient;

        #endregion

        #region Methods

        // --------------- Constructor -----------------
        /// <summary>
        /// Main Engine Class.
        /// Check for Hardware Capabilities.
        /// Create GraphicsDeviceManager and ContentManager.
        /// </summary>
        public DarkWynterGame():base()
        {

            //-- COMPILER
            drawSurface = new Panel();

            gameForm = Form.FromHandle(this.Window.Handle).FindForm();
            //gameForm.IsMdiContainer = true;

            compilerForm = new MainForm();
            //compilerForm.MdiParent = gameForm;

            Statics_Stream.RenderSettings.graphics.PreparingDeviceSettings += OnPreparingDeviceSettings;
            

        }
        /// <summary>
        /// Set Form Draw Surface to Window Handle
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs args)
        {
            args.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = drawSurface.Handle;
        }

        // ----------------- Load ----------------------
        /// <summary>
        /// Set Up Display Window.
        /// Create Logging, XML, GameFlow, Renderer, SpriteBatch, 
        /// FontWriter, MenuSystem, Audio, ShaderParameters, ChatClient, 
        /// Frames Per Second Counter, and Screensaver
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize(new UserDefinedTypes());

            // Menu System 
            menuSystem = new GameMenuSystem();

            // Set up the Game Rules
            gameRules = new GameRules();

            gameController = new GameController(0);
            menuController = new MenuController(0);            

            //-- COMPILER
            drawSurface.Width = Statics_Stream.RenderSettings.clientWidth;
            drawSurface.Height = Statics_Stream.RenderSettings.clientHeight;
            drawSurface.Dock = DockStyle.Top;

            //compilerForm.StartPosition = FormStartPosition.Manual;
            //compilerForm.Location= new System.Drawing.Point(0, 650);
            //compilerForm.Width = Statics_Stream.RenderSettings.clientWidth;
            //compilerForm.Height = Statics_Stream.RenderSettings.clientHeight - 650;
            compilerForm.Dock = DockStyle.Bottom;
            compilerForm.MinimizeBox = false;
            compilerForm.MaximizeBox = false;
            compilerForm.TopLevel = false;
            compilerForm.FormBorderStyle = FormBorderStyle.None;
            compilerForm.Show();


            //compilerForm.BackColor = System.Drawing.Color.Black;
            //compilerForm.TransparencyKey = System.Drawing.Color.Black;

            //this.Window.AllowUserResizing = true;
            gameForm.Text = "DarkWynterEngine Demo from www.darkwynter.com";
            gameForm.MinimizeBox = true;
            gameForm.MaximizeBox = true;
            gameForm.FormBorderStyle = FormBorderStyle.Fixed3D;            

            gameForm.Controls.Add(drawSurface);
            gameForm.Controls.Add(compilerForm);
            this.IsMouseVisible = false;
            //-- COMPILER

            //chatClient = new Client();
            //chatClient.OpenConnection("amanda", 7777);
        }

        // ---------------  Update ---------------------
        /// <summary>
        /// Update MenuSystemGame, Audio, FPS.
        /// Check For Level Loading Request.
        /// Check For Exit.
        /// </summary>
        /// <param name="gameTime">XNA GameTime</param>
        protected override void Update(GameTime gameTime)
        {

            // Update current section of Game Pipeline
            if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE && Statics_Engine.SystemSettings.enableCompilerConsole == false)
            {
                // Update GameRules
                gameRules.Update(ref objectLibrary);
                gameController.Update(ref objectLibrary, ref menuSystem);
            }

            if (Statics_Engine.SystemSettings.gameState != Enums_Engine.EngineState.GAME_MODE && Statics_Engine.SystemSettings.enableCompilerConsole == false)
            {
                menuController.Update(ref objectLibrary, ref menuSystem);
            }

            // Compiler 
            if (Statics_Engine.SystemSettings.enableCompilerConsole)
            {
                drawSurface.Height = Statics_Stream.RenderSettings.clientHeight / 2;
                compilerForm.Height = Statics_Stream.RenderSettings.clientHeight / 2;
                compilerForm.Show();
                Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = false;
            }
            else
            {
                drawSurface.Height = Statics_Stream.RenderSettings.clientHeight;
                compilerForm.Hide();
                Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = true;
            }

            // Check for user exit request
            CheckExit();

            //chatClient.Write("Client 1 chat message");
            //string s = chatClient.Read();

            base.Update(gameTime);


        }

        // ----------------- Draw ----------------------
        /// <summary>
        /// Draw Game or MenuSystem Screen
        /// </summary>
        /// <param name="gameTime">XNA GameTime</param>
        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);


            renderer.DisableSpriteBatches();
        }

        // ---------------- Exit -----------------------
        /// <summary>
        /// Reset the Graphics Device Settings after using SpriteBatch.
        /// Use this function if you are experiencing weird effects after using SpriteBatch.
        /// </summary>
        /// <summary>
        /// Check to see if user has requested to exit the application.
        /// </summary>
        protected override void CheckExit()
        {
            if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.EXIT)
            {
                Controller.StopRumble(objectLibrary);
                base.CheckExit();
            }
        }

        #endregion

        #region Utilities

        /// <summary>
        /// Clean up all files before exiting.
        /// </summary>
        protected override void UnloadContent()
        {
            base.UnloadContent();

        }
        /// <summary>
        /// Override XNA function.
        /// Deactivate Mouse when window looses focus.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected override void OnDeactivated(object sender, EventArgs args)
        {
            // Set flag to disable controllers when window looses focus
            base.OnDeactivated(sender, args);
        }
        /// <summary>
        /// Override XNA function
        /// Activate Mouse when window gains focus.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected override void OnActivated(object sender, EventArgs args)
        {
            // Set flag to enable controllers when window gains focus
            base.OnActivated(sender, args);
        }


        #endregion
    }
}