using ActionGame.GameArtifacts.Models.Characters;
using ActionGame.GameArtifacts.Models.Game;
using ActionGame.GameArtifacts.Operators.Characters;
using ActionGame.GameResources.Models;
using ActionGame.RawResources.Manager;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;


namespace ActionGame.GameArtifacts.Models.WeaponSprites
{
    public class Claw : IWeaponSprite
    {
        public WorldPosition WorldPosition { get; set; }
        public MovementPhysics MovementPhysics { get; set; }
        public Boolean IsExpired { get; set; }

        private IRawContentManager rawContentManager;
        private GameData gameData;
        private IBattleObject caster;
        private Int32 attack;

        private IList<Texture2D> textures;
        private Int32 frame;
        private TimeSpan lastFrameUpdateTime;
        private Boolean hasDamaged;

        private TimeSpan creationTime;
        public readonly Int32 SIZE = 32;


        public Claw(IRawContentManager rawContentManager, GameData gameData, IBattleObject caster, WorldPosition worldPosition, Int32 attack)
        {
            IsExpired = false;
            this.rawContentManager = rawContentManager;
            this.gameData = gameData;

            this.caster = caster;
            this.WorldPosition = worldPosition.Copy();
            this.MovementPhysics = new MovementPhysics();

            this.textures = new List<Texture2D>();
            this.textures.Add(rawContentManager.TextureRepository.GetContent(@"textures\items\claw-1"));
            this.textures.Add(rawContentManager.TextureRepository.GetContent(@"textures\items\claw-2"));
            this.textures.Add(rawContentManager.TextureRepository.GetContent(@"textures\items\claw-3"));
            this.textures.Add(rawContentManager.TextureRepository.GetContent(@"textures\items\claw-4"));
            this.textures.Add(rawContentManager.TextureRepository.GetContent(@"textures\items\claw-5"));

            this.attack = attack;
            frame = 0;
            hasDamaged = false;
        }


        public Rectangle GetCurrentCollisionArea()
        {
            Rectangle rect = GetCollisionAreaAtPosition(this.WorldPosition.PositionX, this.WorldPosition.PositionY);

            return rect;
        }


        public Rectangle GetCollisionAreaAtPosition(int x, int y)
        {
            Rectangle rect = new Rectangle(x, y - SIZE, SIZE, SIZE);

            return rect;
        }


        public Rectangle GetDrawArea()
        {
            return GetCurrentCollisionArea();
        }


        public void Update(GameTime gameTime)
        {
            if (creationTime == default(TimeSpan)) creationTime = gameTime.TotalGameTime;
            if (lastFrameUpdateTime == default(TimeSpan)) lastFrameUpdateTime = gameTime.TotalGameTime;

            //frame update
            if ((gameTime.TotalGameTime - lastFrameUpdateTime).TotalSeconds >= 0.1)
            {
                lastFrameUpdateTime = gameTime.TotalGameTime;

                frame++;
                if (frame >= this.textures.Count) frame = 0;
            }

            if (hasDamaged == false)
            {
                DetectHitAndDoDamage();
            }

            //expire
            if ((gameTime.TotalGameTime - creationTime).TotalSeconds >= 0.5)
            {
                IsExpired = true;
            }
        }


        private void DetectHitAndDoDamage()
        {
            IList<IBattleObject> objectsInRange = gameData.GameState.GetBattleObjectsInArea(GetCurrentCollisionArea());

            foreach (IBattleObject target in objectsInRange)
            {
                if (target != caster)
                {
                    Damager damager = new Damager();

                    Int32 damageDone = damager.Do(this.attack, target);

                    if (damageDone != 0)
                    {
                        DamageSprite damageSprite = new DamageSprite(rawContentManager, target, damageDone, target.WorldPosition);
                        gameData.GameState.ActiveDisplaySprites.Add(damageSprite);
                    }

                    hasDamaged = true;
                }
            }
        }


        public void Draw(SpriteBatch spriteBatch)
        {
            Rectangle rect = this.GetDrawArea();

            spriteBatch.Draw(this.textures[frame], rect, Color.White);
        }


    }
}
