/// <summary>
 /// Updates the component.
 /// </summary>
 /// <param name="packet">The packet of input data.</param>
 /// <param name="deltatime">The time that has passed since last update.</param>
 public virtual void Update(InputPacket packet, float deltatime)
 {
     if (!Initialized)
     {
         Initialize();
     }
 }
        public override void Update(InputPacket packet, float deltatime)
        {
            base.Update(packet, deltatime);

            if (Target == null)
            {
                return;
            }

            if (Target.Map == Owner.Map)
            {
                LastKnownPosition = Target.Position;
            }
        }
        /// <summary>
        /// Updates the component.
        /// </summary>
        /// <param name="packet">The packet of input data.</param>
        /// <param name="deltatime">The time that has passed since last update.</param>
        public override void Update(InputPacket packet, float deltatime)
        {
            base.Update(packet, deltatime);

            if (packet.Check == PressState.Pressed)
            {
                //First we'll get where the reticle is.
                Vector position = Owner.Hitbox.Center;
                Vector direction = Vector.Zero;

                switch (Owner.Facing)
                {
                    case (FacingState.North):
                        direction.Y--;
                        break;
                    case (FacingState.Northeast):
                        direction.X++;
                        direction.Y--;
                        break;
                    case (FacingState.East):
                        direction.X++;
                        break;
                    case (FacingState.Southeast):
                        direction.X++;
                        direction.Y++;
                        break;
                    case (FacingState.South):
                        direction.Y++;
                        break;
                    case (FacingState.Southwest):
                        direction.X--;
                        direction.Y++;
                        break;
                    case (FacingState.West):
                        direction.X--;
                        break;
                    case (FacingState.Northwest):
                        direction.X--;
                        direction.Y--;
                        break;
                }

                direction.Normalize();

                position += direction * StartDistance;

                for (float i = StartDistance; i < MaxDistance; i += IterationRate)
                {
                    //First we'll check entities.
                    //This needs more optimizations. It's rudimentary for now.
                    Rectangle hitbox = new Rectangle((int)position.X, (int)position.Y, 1, 1);

                    foreach (var entity in Owner.Map.Entities.GetEntityList())
                    {
                        if (entity.Hitbox.Intersects(hitbox))
                        {
                            if (entity.OnChecked(Owner))
                            {
                                //We're done if we find something.
                                return;
                            }
                        }
                    }

                    //Then we'll check tiles.
                    Vector tileposition = new Vector((int)position.X / (int)Owner.Map.TileSize.X, (int)position.Y / (int)Owner.Map.TileSize.Y);
                    Tile tile = Owner.Map.GetTile(tileposition, Owner.Map.CollisionLayer);

                    if (tile != null)
                    {
                        if (tile.HandleCheckEffects(tileposition, Owner))
                        {
                            //We're done if we find something.
                            return;
                        }
                    }

                    position += direction * IterationRate;
                }
            }
        }
        /// <summary>
        /// Updates the component.
        /// </summary>
        /// <param name="packet">The packet of input data.</param>
        /// <param name="deltatime">The time that has passed since last update.</param>
        public override void Update(InputPacket packet, float deltatime)
        {
            if (Owner.TagExists("nomove"))
            {
                return;
            }

            //First we'll get how fast we should go and tell what state we're in...
            float speed = 0;

            if (packet.Run == PressState.Down)
            {
                speed = RunSpeed;
                Owner.MovingState = MovingState.Running;
            }
            else
            {
                speed = WalkSpeed;
                Owner.MovingState = MovingState.Walking;
            }

            //And multiply it by deltatime.
            speed *= deltatime;

            //Now we'll find what direction we're going...
            Vector direction = Vector.Zero;

            if (packet.Up == PressState.Down)
            {
                direction.Y--;
            }

            if (packet.Down == PressState.Down)
            {
                direction.Y++;
            }

            if (packet.Left == PressState.Down)
            {
                direction.X--;
            }

            if (packet.Right == PressState.Down)
            {
                direction.X++;
            }

            //Check if you're actually moving...
            if (!direction.Equals(Vector.Zero))
            {
                //First we'll report to the entity what direction we're moving
                switch (Owner.FacingStyle)
                {
                    case FacingStyle.Static:
                        //We don't do anything for static!
                        break;
                    case FacingStyle.FourWay:
                        if (direction.X < 0) //W
                        {
                            Owner.Facing = FacingState.West;
                        }
                        else if (direction.X > 0) //E
                        {
                            Owner.Facing = FacingState.East;
                        }

                        if (direction.Y < 0) //N
                        {
                            Owner.Facing = FacingState.North;
                        }
                        else if (direction.Y > 0) //S
                        {
                            Owner.Facing = FacingState.South;
                        }

                        break;
                    case FacingStyle.EightWay:
                        if (direction.Y.Equals(-1) && direction.X.Equals(0)) //N
                        {
                            Owner.Facing = FacingState.North;
                            break;
                        }

                        if (direction.Y.Equals(-1) && direction.X.Equals(-1)) //NW
                        {
                            Owner.Facing = FacingState.Northwest;
                            break;
                        }

                        if (direction.Y.Equals(-1) && direction.X.Equals(1)) //NE
                        {
                            Owner.Facing = FacingState.Northeast;
                            break;
                        }

                        if (direction.Y.Equals(0) && direction.X.Equals(-1)) //W
                        {
                            Owner.Facing = FacingState.West;
                            break;
                        }

                        if (direction.Y.Equals(0) && direction.X.Equals(1)) //E
                        {
                            Owner.Facing = FacingState.East;
                            break;
                        }

                        if (direction.Y.Equals(1) && direction.X.Equals(0)) //S
                        {
                            Owner.Facing = FacingState.South;
                            break;
                        }

                        if (direction.Y.Equals(1) && direction.X.Equals(-1)) //SW
                        {
                            Owner.Facing = FacingState.Southwest;
                            break;
                        }

                        if (direction.Y.Equals(1) && direction.X.Equals(1)) //SE
                        {
                            Owner.Facing = FacingState.Southeast;
                            break;
                        }

                        //If it got to here, then it must not have changed direction.
                        break;
                }

                //Normalize it so that diagonals aren't faster.
                direction.Normalize();

                //Rudimentary movement for now. We'll replace this with proper collision checking later.
                Owner.Velocity += direction*speed;
            }
            else
            {
                //If you aren't moving, you're standing!
                Owner.MovingState = MovingState.Standing;
            }
        }
        /// <summary>
        /// Updates entity using an update packet.
        /// </summary>
        /// <param name="packet">The packet of input data.</param>
        /// <param name="deltatime">The time that has passed since last update.</param>
        public virtual void Update(InputPacket packet, float deltatime)
        {
            //Update animation.
            if (CurrentAnimation == null)
            {
                HandleDerivedAnimation();
            }

            CurrentAnimation.Update(deltatime);

            //Add new components and logics.
            foreach (var component in ComponentsToAdd)
            {
                AddComponent(component.Key, component.Value);
            }

            foreach (var logic in LogicsToAdd)
            {
                AddLogic(logic.Key, logic.Value);
            }

            //Handle logic.
            if (packet != null)
            {
                foreach (var component in Components)
                {
                    component.Value.Update(packet, deltatime);
                }

                foreach (var logic in Logics)
                {
                    logic.Value.Update(packet, deltatime);
                }

                HandleVelocity();

                if (!IsAnimationOverridden)
                {
                    HandleDerivedAnimation();
                }
            }

            //Prune dead components.
            List<string> componentstodelete = new List<string>();
            List<string> logicstodelete = new List<string>();

            foreach (var component in Components)
            {
                if (component.Value.Dead)
                {
                    componentstodelete.Add(component.Key);
                }
            }

            foreach (var logic in Logics)
            {
                if (logic.Value.Dead)
                {
                    logicstodelete.Add(logic.Key);
                }
            }

            foreach (var component in componentstodelete)
            {
                Components.Remove(component);
            }

            foreach (var logic in logicstodelete)
            {
                Logics.Remove(logic);
            }

            //Update the hitbox position.
            UpdateHitbox();
            CheckFloorEffects();
        }
        /// <summary>
        /// Gets the AI input packet based on AI components.
        /// </summary>
        /// <returns></returns>
        public virtual InputPacket GetAIPacket()
        {
            InputPacket packet = new InputPacket();

            foreach (var logic in Logics)
            {
                logic.Value.GetInput(packet);
            }

            return packet;
        }
 /// <summary>
 /// Modifies the packet to determine its input.
 /// </summary>
 /// <param name="packet">The packet.</param>
 public virtual void GetInput(InputPacket packet)
 {
 }
        /// <summary>
        /// Starts the entity's move cycle.
        /// </summary>
        /// <param name="packet">The packet.</param>
        private void StartMove(InputPacket packet)
        {
            //First we'll get how fast we should go and tell what state we're in...
            float speed = 0;

            if (packet.Run == PressState.Down)
            {
                speed = RunSpeed;
                Owner.MovingState = MovingState.Running;
            }
            else
            {
                speed = WalkSpeed;
                Owner.MovingState = MovingState.Walking;
            }

            //Now we'll find what direction we're going...
            Vector direction = Vector.Zero;

            if (packet.Up == PressState.Down)
            {
                direction = new Vector(0,-1);
            }

            if (packet.Down == PressState.Down)
            {
                direction = new Vector(0, 1);
            }

            if (packet.Left == PressState.Down)
            {
                direction = new Vector(-1,0);
            }

            if (packet.Right == PressState.Down)
            {
                direction = new Vector(1,0);
            }

            //Check if you're actually moving...
            if (!direction.Equals(Vector.Zero))
            {
                //First we'll report to the entity what direction we're moving
                switch (Owner.FacingStyle)
                {
                    case FacingStyle.Static:
                        //We don't do anything for static!
                        break;
                    case FacingStyle.FourWay:
                        if (direction.X < 0) //W
                        {
                            Owner.Facing = FacingState.West;
                        }
                        else if (direction.X > 0) //E
                        {
                            Owner.Facing = FacingState.East;
                        }

                        if (direction.Y < 0) //N
                        {
                            Owner.Facing = FacingState.North;
                        }
                        else if (direction.Y > 0) //S
                        {
                            Owner.Facing = FacingState.South;
                        }

                        break;
                    case FacingStyle.EightWay:
                        if (direction.Y.Equals(-1) && direction.X.Equals(0)) //N
                        {
                            Owner.Facing = FacingState.North;
                            break;
                        }

                        if (direction.Y.Equals(-1) && direction.X.Equals(-1)) //NW
                        {
                            Owner.Facing = FacingState.Northwest;
                            break;
                        }

                        if (direction.Y.Equals(-1) && direction.X.Equals(1)) //NE
                        {
                            Owner.Facing = FacingState.Northeast;
                            break;
                        }

                        if (direction.Y.Equals(0) && direction.X.Equals(-1)) //W
                        {
                            Owner.Facing = FacingState.West;
                            break;
                        }

                        if (direction.Y.Equals(0) && direction.X.Equals(1)) //E
                        {
                            Owner.Facing = FacingState.East;
                            break;
                        }

                        if (direction.Y.Equals(1) && direction.X.Equals(0)) //S
                        {
                            Owner.Facing = FacingState.South;
                            break;
                        }

                        if (direction.Y.Equals(1) && direction.X.Equals(-1)) //SW
                        {
                            Owner.Facing = FacingState.Southwest;
                            break;
                        }

                        if (direction.Y.Equals(1) && direction.X.Equals(1)) //SE
                        {
                            Owner.Facing = FacingState.Southeast;
                            break;
                        }

                        //If it got to here, then it must not have changed direction.
                        break;
                }

                //Normalize it so that diagonals aren't faster.
                direction.Normalize();

                //Set the course of action.
                Direction = direction;
                Speed = speed;
                Moving = true;

                Target = Owner.Position / GridSize;
                Target += Direction;
                Target *= GridSize;
            }
            else
            {
                //If you aren't moving, you're standing!
                Owner.MovingState = MovingState.Standing;
            }
        }
        /// <summary>
        /// Updates the component.
        /// </summary>
        /// <param name="packet">The packet of input data.</param>
        /// <param name="deltatime">The time that has passed since last update.</param>
        public override void Update(InputPacket packet, float deltatime)
        {
            if (Owner.TagExists("nomove"))
            {
                Moving = false;
                Direction = Vector.Zero;
                Speed = 0f;
                Target = Vector.Zero;
                return;
            }

            if (!Moving)
            {
                StartMove(packet);
            }

            Owner.Velocity += Direction * Speed * deltatime;

            CheckStop();
        }
        /// <summary>
        /// Modifies the packet to determine its input.
        /// </summary>
        /// <param name="packet">The packet to modify.</param>
        public override void GetInput(InputPacket packet)
        {
            if (Target == null)
            {
                return;
            }

            Vector diff = Vector.Zero;

            if (Target.Map == Owner.Map)
            {
                diff = LastKnownPosition - Owner.Position;
            }
            else
            {
                float length = float.MaxValue;

                foreach (var door in Owner.Map.Doors)
                {
                    Vector doordiff = door.Hitbox.Center - Owner.Position;
                    float doorlength = doordiff.Length();

                    if (doorlength < length)
                    {
                        diff= doordiff;
                        length = doorlength;
                    }
                }
            }

            if (diff.Length() > Distance || Target.Map != Owner.Map)
            {
                //Check for Down.
                if (diff.Y > 0)
                {
                    if (Math.Abs(diff.Y) > Safezone.Y || Target.Map != Owner.Map)
                    {
                        packet.Down = PressState.Down;
                    }
                }

                //Check for Up.
                if (diff.Y < 0)
                {
                    if (Math.Abs(diff.Y) > Safezone.Y || Target.Map != Owner.Map)
                    {
                        packet.Up = PressState.Down;
                    }
                }

                //Check for Right.
                if (diff.X > 0)
                {
                    if (Math.Abs(diff.X) > Safezone.X || Target.Map != Owner.Map)
                    {
                        packet.Right = PressState.Down;
                    }
                }

                //Check for Left.
                if (diff.X < 0)
                {
                    if (Math.Abs(diff.X) > Safezone.X || Target.Map != Owner.Map)
                    {
                        packet.Left = PressState.Down;
                    }
                }
            }
            

            //Check if you should run.
            if (diff.Length() > RunDistance || Target.Map != Owner.Map)
            {
                packet.Run = PressState.Down;
            }
        }