using System;
using Icarus.Graphics.Animation;

namespace Icarus.Logic.Physics
{
	/// <summary>
	/// Summary description for PhysicsGNURobot.
	/// </summary>
	public class PhysicsGNURobot : PhysicsPlayer
	{

        private ChildObject coFlameLeft;
        private ChildObject coFlameRight;

		public PhysicsGNURobot()
		{
            //Default health
            this.GameStats.Health = 25;

			this.CollisionBox = new CollisionBoxEnemyDefault();
            this.CollisionBox.BoundingBox.X = 0;
            this.CollisionBox.BoundingBox.Y = 0;
            this.CollisionBox.BoundingBox.Width = 80;
            this.CollisionBox.BoundingBox.Height = 160;
            this.CollisionBox.BoundingBoxWidth = 80;
            this.CollisionBox.BoundingBoxHeight = 160;
            this.CBXoffset = 40;
            this.CBYoffset = 155;
            ((CollisionBoxEnemyDefault)this.CollisionBox).Damage = 2;

            this.ActionState = (int)PhysicsSettings.enumPlayerActionStates.StandingLeft;
            this.po_gravity = PhysicsSettings.Instance.sv_mercGravity;
            this.SetAnimation(@"\GNU_bot\idle_left\frames\GNU_bot_left_idle.png", Icarus.Graphics.Animation.AnimationType.LoopForever, 1);

            coFlameLeft = new ChildObject();
            coFlameLeft.Parent = this;
            coFlameLeft.AnchorPoint = new Icarus.Logic.Physics.Point(10, 0, 0);
            coFlameLeft.CollisionBox = new CollisionBoxEnemyDefault();
            ((CollisionBoxEnemyDefault)coFlameLeft.CollisionBox).ThrowDirection = (int)PhysicsSettings.enumDirection.Left;
            ((CollisionBoxEnemyDefault)coFlameLeft.CollisionBox).Damage = 5;
            coFlameLeft.CollisionBox.BoundingBox.X = 0;
            coFlameLeft.CollisionBox.BoundingBox.Y = 0;
            coFlameLeft.CollisionBox.BoundingBox.Width = 250;
            coFlameLeft.CollisionBox.BoundingBox.Height = 50;
            coFlameLeft.CollisionBox.BoundingBoxWidth = 250;
            coFlameLeft.CollisionBox.BoundingBoxHeight = 50;
            coFlameLeft.CBXoffset = 300;
            coFlameLeft.CBYoffset = 115;
            coFlameLeft.SetAnimation(@"\GNU_bot\attack_left\frames\GNU_bot_attack_left.png", Icarus.Graphics.Animation.AnimationType.LoopForever, 1);

            coFlameRight = new ChildObject();
            coFlameRight.Parent = this;
            coFlameRight.AnchorPoint = new Icarus.Logic.Physics.Point(-10, 0, 0);
            coFlameRight.CollisionBox = new CollisionBoxEnemyDefault();
            ((CollisionBoxEnemyDefault)coFlameRight.CollisionBox).ThrowDirection = (int)PhysicsSettings.enumDirection.Right;
            ((CollisionBoxEnemyDefault)coFlameRight.CollisionBox).Damage = 10;
            coFlameRight.CollisionBox.BoundingBox.X = 0;
            coFlameRight.CollisionBox.BoundingBox.Y = 0;
            coFlameRight.CollisionBox.BoundingBox.Width = 250;
            coFlameRight.CollisionBox.BoundingBox.Height = 50;
            coFlameRight.CollisionBox.BoundingBoxWidth = 250;
            coFlameRight.CollisionBox.BoundingBoxHeight = 50;
            coFlameRight.CBXoffset = -40;
            coFlameRight.CBYoffset = 115;
            coFlameRight.SetAnimation(@"\GNU_bot\attack_right\frames\GNU_bot_attack_right.png", Icarus.Graphics.Animation.AnimationType.LoopForever, 1);



		}


        // <summary>
        /// Starts the player walking left and puts him in the correct
        /// action state
        /// </summary>
        public override void walkLeft()
        {
            //Check to see if walking left is valid at this moment
            if(this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.StandingLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.StandingRight
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingRight
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingUpSlopeLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingDownSlopeLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingUpSlopeRight
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingDownSlopeRight)
            {
                //Don't stop walking
                this.StopWalking = false;

                //Set action state
                this.LastActionState = this.ActionState;
                this.ActionState = (int)PhysicsSettings.enumPlayerActionStates.WalkingLeft;
                //Set velocity
                this.Velocity.i = -PhysicsSettings.Instance.WalkVelocity/2f;
            }
        }

        /// <summary>
        /// Starts the player walking right and puts him in the correct
        /// action states
        /// </summary>
        public override void walkRight()
        {
            //Check to see if walking left is valid at this moment
            if(this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.StandingLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.StandingRight
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingRight
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingUpSlopeLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingDownSlopeLeft
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingUpSlopeRight
                || this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingDownSlopeRight)
            {
                //Don't stop walking
                this.StopWalking = false;

                //Set action state
                this.LastActionState = this.ActionState;
                this.ActionState = (int)PhysicsSettings.enumPlayerActionStates.WalkingRight;
                //Set velocity
                this.Velocity.i = PhysicsSettings.Instance.WalkVelocity/2f;
            }
        }

        /// <summary>
        /// Causes this GNU bot to do a flame attack
        /// </summary>
        public void attack()
        {
            //Attack left
            if(this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.StandingLeft ||
                this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingLeft ||
                this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingUpSlopeLeft ||
                this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingDownSlopeLeft)
            {
                this.LastActionState = this.ActionState;
                //Using whipleft for attact left
                this.ActionState = (int)PhysicsSettings.enumPlayerActionStates.WhippingLeft;
            }
            //Attack right
            else if(this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.StandingRight ||
                this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingRight ||
                this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingUpSlopeRight ||
                this.ActionState == (int)PhysicsSettings.enumPlayerActionStates.WalkingDownSlopeRight)
            {
                this.LastActionState = this.ActionState;
                //Using whipleft for attact left
                this.ActionState = (int)PhysicsSettings.enumPlayerActionStates.WhippingRight;
            }
        }

        /// <summary>
        /// Performs specific updates on teh GNU bot. Including changing of animations
        /// and changing attack parameters
        /// </summary>
        public override int specificUpdates()
        {

            if(!this.Vulnerable)
            {
                this.InvulnerableIterationCount++;
                if(this.InvulnerableIterationCount > this.InvulnerableIterationLimit)
                {
                    this.Vulnerable = true;
                    this.InvulnerableIterationCount = 0;
                }
            }

            //check to see if we are dead
            if(this.GameStats.Health <= 0)
            {
                this.DeathIterationCount++;


                this.CollisionBox.Damage = 0;
                if(this.DeathIterationCount < this.DeathIterationLimit)
                {
                    //we are dead, stop all actions and flicker
                    this.stopAll();
                    if((this.DeathIterationCount/5)%2 == 0)//Swap animation every other frame
                    {
                        this.SetAnimation(@"\null\null_fset.png", Icarus.Graphics.Animation.AnimationType.LoopOnce, 1);
                    }
                    else if(this.ActionState == (int)Physics.PhysicsSettings.enumPlayerActionStates.StandingLeft)
                    {
                        this.SetAnimation(@"\GNU_bot\idle_left\frames\GNU_bot_left_idle.png", AnimationType.LoopOnce, 1);
                    }
                    else
                    {
                        this.SetAnimation(@"\GNU_bot\idle_right\frames\GNU_bot_idle_right.png", AnimationType.LoopForever, 1);
                    }
                }
                else
                {
                    //return remove
                    return (int)PhysicsSettings.enumActions.Remove;
                }

            }

            if(this.LastActionState != this.ActionState)
            {
                if (this.LastActionState == (int)PhysicsSettings.enumPlayerActionStates.WhippingLeft &&
                    this.ActionState != (int)PhysicsSettings.enumPlayerActionStates.WhippingRight)
                {
                    this.RemoveChildObject(coFlameLeft);
                } 
                else if (this.LastActionState == (int)PhysicsSettings.enumPlayerActionStates.WhippingRight &&
                    this.ActionState != (int)PhysicsSettings.enumPlayerActionStates.WhippingLeft)
                {
                    this.RemoveChildObject(coFlameRight);
                }

                switch (this.ActionState)
                {
                        //TODO: Have the animations stored in the level or player type. ie: don't manually set
                    case (int)Physics.PhysicsSettings.enumPlayerActionStates.StandingLeft:
                        //Set standing animation
                        this.SetAnimation(@"\GNU_bot\idle_left\frames\GNU_bot_left_idle.png", AnimationType.LoopForever, 1);
                        break;
                    case (int)Physics.PhysicsSettings.enumPlayerActionStates.StandingRight:
                        //set standing animation
                        this.SetAnimation(@"\GNU_bot\idle_right\frames\GNU_bot_idle_right.png", AnimationType.LoopForever, 1);
                        break;
                    case (int)Physics.PhysicsSettings.enumPlayerActionStates.WalkingLeft:
                        //Set walking left animation
                        this.SetAnimation(@"\GNU_bot\idle_left\frames\GNU_bot_left_idle.png", AnimationType.LoopForever, 1);
                        break;
                    case (int)Physics.PhysicsSettings.enumPlayerActionStates.WalkingRight:
                        //Set walking right animation
                        this.SetAnimation(@"\GNU_bot\idle_right\frames\GNU_bot_idle_right.png", AnimationType.LoopForever, 1);
                        break;
                    //Using whip state for the GNU attack state
                    case (int)Physics.PhysicsSettings.enumPlayerActionStates.WhippingLeft:
                        this.SetAnimation(@"\GNU_bot\idle_left\frames\GNU_bot_left_idle.png", AnimationType.LoopForever, 1);
                        this.AddChildObject(coFlameLeft);
                        break;
                    case (int)Physics.PhysicsSettings.enumPlayerActionStates.WhippingRight:
                        this.SetAnimation(@"\GNU_bot\idle_right\frames\GNU_bot_idle_right.png", AnimationType.LoopForever, 1);
                        this.AddChildObject(coFlameRight);
                        break;

                }
                this.LastActionState = this.ActionState;
            }
            return (int)PhysicsSettings.enumActions.DoNothing;
        }


	}
}
