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

namespace DarkWynter.Game.GameObjects
{
    #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;
    using System.Xml;
    using DarkWynter.Engine.Globals;
    using DarkWynter.Engine.Physics;
    using DarkWynter.Engine.ObjectLib;
    using DarkWynter.Engine.GameObjects;
    using DarkWynter.Engine.Init;
    using DarkWynter.Stream;
    using System.Diagnostics;
    #endregion

    /// <summary>
    /// An abstract door with locking mechanics.
    /// </summary>
    public class Bomb : GameObject
    {
        Vector2 blendTexturePos1 = new Vector2(0);
        Vector2 blendTexturePos2 = new Vector2(0);
        Stopwatch stopWatch = new Stopwatch();

        const int TIMER = 1;
        
        /// <summary>
        /// Portal constructor
        /// </summary>
        public Bomb(Load gameObjectLoader)
            : base(gameObjectLoader)
        {
            mass.objectType = Enums_Engine.ObjectType.PORTAL;
            mass.dynamicFrictionCoefficient = 0.0f;
            mass.isMoving = true;
        }

        /// <summary>
        /// Override and supplament base loading in GameObject.
        /// </summary>
        /// <param name="node">XML node containing load data.</param>
        /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param>
        /// <returns>True if it was able to load, else false</returns>
        public override bool Load(ObjectLibrary objectLibrary)
        {
            // Call before user code is executed
            if (!base.Load(objectLibrary))
            {
                return false;
            }

            if (Statics_Engine.LevelSettings.bombCounter == 0)
            {
                draw.textureList[0] = Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/bomb1");
                ShaderSetup();
            }
            else if (Statics_Engine.LevelSettings.bombCounter == 1)
            {
                draw.textureList[0] = Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/bomb3");
                ShaderSetup();
                
            }
            else if (Statics_Engine.LevelSettings.bombCounter == 2)
            {
                draw.textureList[0] = Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/bomb4");
                ShaderSetup();
                
            }
            else 
            {
                draw.textureList[0] = Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/coin");
                ShaderSetup();
                
            }

            Statics_Engine.GameSettings.BombCurrentPosition = mass.currentPosition;
            
            Statics_Engine.LevelSettings.bombCounter++;

            return true;
        }

        private void ShaderSetup()
        {
            draw.textureList[1] = Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/bomb2");
            // Get terrain height at position
            //float yPosition = objectLibrary.terrain.GetTerrainHeight(load.startPosition.X / Statics_Engine.TerrainSettings.terrainScaleFactor,
            //                                                         load.startPosition.Z / Statics_Engine.TerrainSettings.terrainScaleFactor);

            float yPosition = float.Parse(load.node.Attributes["y"].Value) * Statics_Engine.TerrainSettings.terrainScaleFactor;


            // Set position and reference
            Vector3 locpos = new Vector3(load.startPosition.X, yPosition, load.startPosition.Z);
            Vector3 refpos = new Vector3(load.startPosition.X, yPosition, load.startPosition.Z - 1);
            mass.SetPosition(locpos, refpos);


            draw.drawMethod = Enums_Stream.DrawMethod.BasicGameObject_Draw;
            //draw.technique = "ToonShaderMain";

            draw.technique = "FlickerFlame";

            mass.scale = new Vector3(mass.scale.X, 100, mass.scale.Z);
            mass.boundingVolume = new BoundingVolume(new BoundingSphere(mass.currentPosition, 100.0f));

            stopWatch.Start();
            blendTexturePos1 = Vector2.Zero;
            blendTexturePos2 = Vector2.Zero;
            ShaderParameters.DrawFX.blendTexturePosition1.SetValue(blendTexturePos1);
            ShaderParameters.DrawFX.blendTexturePosition2.SetValue(blendTexturePos2);
        }

        /// <summary>
        /// Override and supplement base Update in GameObject.
        /// </summary>
        /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param>
        public override void Update(ref ObjectLibrary objectLibrary)
        {
            // Call before user code is executed
             //base.Update(ref objectLibrary);

             mass.boundingVolume.radius = mass.scale.X / 2;
             mass.boundingVolume.UpdateSphere(mass.currentPosition);   
        }

        /// <summary>
        /// Override and supplement response to colliding GameObjects
        /// </summary>
        /// <param name="collidedObject">Object that hit the Portal.</param>
        /// <param name="resultantForce">Force that Portal was hit wi3.
        /// th.</param>
        /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param>
        /// <returns>True if collidedObject needs to be recycled</returns>
        public override bool ObjectCollisionResponse(GameObject collidedObject, Vector3 resultantForce, ObjectLibrary objectLibrary)
        {

            if (collidedObject.mass.objectType != Enums_Engine.ObjectType.PLAYER)
            {

            }
            if (collidedObject is Human)
            {
                Player player = collidedObject as Player;
                player.SpawnPlayer();
            }


            return false;
        }


        /// <summary>
        /// Overrides and supplements response to this object hitting the ground.
        /// </summary>
        /// <param name="terrain">The terrain object which this Portal hit.</param>
        public override void TerrainCollisionResponse(Terrain terrain)
        {
            base.GetObjectHeight(terrain);

            // Add Gravity if terrain and player are touching
            if (heightDifference < 0.0f)
            {
                mass.AddForce(mass.mass * Statics_Engine.GameSettings.accelDueToGravity);
            }
            else if (heightDifference > 0.0f)
            {
                base.TerrainCollisionResponse(terrain);

                if (mass.totalForce.Y > 0.0f)
                {
                    mass.totalForce.Y = 0.0f;
                }

                if (mass.velocity.Y > 0.0f)
                {
                    mass.velocity.Y = 0.0f;
                }

                if (heightDifference < 0.0f)
                {
                    mass.AddForce(mass.mass * Statics_Engine.GameSettings.accelDueToGravity);
                }
                else if (heightDifference > 0.0f)
                {
                    if (mass.totalForce.Y > 0.0f) { mass.totalForce.Y = 0.0f; }
                    if (mass.velocity.Y > 0.0f) { mass.velocity.Y = 0.0f; }

                    // Ground pushing up to negate gravity
                    mass.AddForce(new Vector3(0.0f, heightDifference * terrain.propSurfaceTension, 0.0f) -
                                  (new Vector3(0.0f, mass.totalForce.Y, 0.0f) +
                                  new Vector3(0.0f, mass.velocity.Y * mass.mass / Statics_Engine.SystemSettings.dt, 0.0f)));
                }
            }
        }


        /// <summary>
        /// Override draw for portal
        /// </summary>
        public override Draw Draw()
        {
            // When position reaches one, reset to zero
            if (blendTexturePos1.X > 1.0f || blendTexturePos1.Y > 1.0f)
            {
                blendTexturePos1 = Vector2.Zero;
                blendTexturePos2 = Vector2.Zero;
            }

            // Update position based on timer
            if (stopWatch.ElapsedMilliseconds > TIMER)
            {
                blendTexturePos1.X += .001f;
                blendTexturePos1.Y += .001f;
                blendTexturePos2.X += .001f;
                blendTexturePos2.Y += .001f;

                stopWatch.Reset();
                stopWatch.Start();
            }

            // Blend the textures
            ShaderParameters.DrawFX.blendTexturePosition1.SetValue(blendTexturePos1);
            ShaderParameters.DrawFX.blendTexturePosition2.SetValue(blendTexturePos2);


                // Calculate ObjectSpace(Rotation) and WorldSpace(Translation) Transformation Matrix
                draw.matrix = draw.initialTransform * Matrix.CreateScale(mass.scale) *
                              Matrix.CreateFromQuaternion(mass.currentRotation) *
                              Matrix.CreateTranslation(mass.currentPosition);
    
            return draw;
        }

        /// <summary>
        /// Override and supplement base Billboard drawing specific to this Portal.
        /// </summary>
        /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param>
        /// <param name="gameObjectBillboards">Dynamic list of billboards to be drawn this frame.</param>
        public override void Draw_Billboards(ObjectLibrary objectLibrary, BillboardList gameObjectBillboards)
        {

        }
    }
}