using System;
using System.Collections.Generic;
using System.Text;
using HumanLikeBattleRobots.Graphic;

namespace HumanLikeBattleRobots.Logic
{
    abstract class Robot: ICollidable
    {
        protected List<List<Sprite>> sprites = new List<List<Sprite>>();
        protected Sprite shadow;

        protected Vec2f position = new Vec2f(400, 400);
        protected float speedDirection = 0;
        protected float rotationDirection = 0;
        protected float towerAngle = 0;
        protected float timer = 0;

        //части робота
        protected Legs legs;
        protected Tower tower;
        protected Sprite body;

        //настраиваемые параметры
        protected float health = 10;
        protected float forwardSpeed = 160;
        protected float backwardSpeed = 120;
        protected float forwardAngularVelocity = 1;
        protected float backwardAngularVelocity = 1;
        protected float size = 45;

        public float TowerAngle { get { return towerAngle; } set { towerAngle = value; } }
        public Vec2f Position { get { return position; } set { position = value; } }
        public Vec2f Normal { get { return legs.Normal; } }
        public bool IsAlive { get { if (health > 0) return true; else return false; } }
        public float Health { get { return health; } set { health = value; } }

        public Robot(): this(new Vec2f(400,400))
        { }

        public Robot(Vec2f position)
        {
            this.position = position;

            for (int i = 0; i < 3; i++)
                sprites.Add(new List<Sprite>());

            SetParams();
        }

        protected abstract void SetParams();

        public virtual void Proceed(double delta)
        {
            float speed = Math.Sign(speedDirection) * 
                (Math.Sign(speedDirection) < 0 ? forwardSpeed : backwardSpeed);

            float angularVelocity = Math.Sign(rotationDirection) * 
                (Math.Sign(speedDirection) < 0 ? forwardAngularVelocity : backwardAngularVelocity);
            
            if (speed != 0)
                timer += (float)delta;
            if (timer > 2 * Math.PI)
                timer -= 2 * (float)Math.PI;

            legs.Move(speed);

            legs.Rotate(angularVelocity);
            legs.Proceed(delta);

            position = legs.AxisCenter;
            position = position + GameManager.CheckCollision(this);
            legs.AxisCenter = position;

            if (tower != null)
            {
                tower.Position = legs.AxisCenter;
                tower.Normal = tower.Normal.Rotate(legs.RotationAngle);
                tower.Position = tower.Position + tower.Normal * (float)Math.Abs(Math.Sin(timer * 4)) * 10;
                tower.Proceed(delta);
                body.Angle = legs.AxisAngle();
            }
            // картинка
            body.Position = this.position;

            shadow.Position = this.position;
        }

        //только при наведении
        public void RotateTower(Vec2f aimPosition)
        {
            tower.Rotate(aimPosition);
        }

        public void Fire(Vec2f aimPosition, bool left)
        {
            tower.Fire(aimPosition, left);
        }

        public void Draw(int stage)
        {
            if (stage == 0)
            {
                shadow.Draw();
                return;
            }

            foreach (Sprite sprite in sprites[stage - 1])
                sprite.Draw();
        }

        Vec2f ICollidable.Position
        {
            get { return this.position; }
        }

        float ICollidable.Radius
        {
            get { return this.size; }
        }

        float ICollidable.HitRadius
        {
            get { return this.size - 10; }
        }

        void ICollidable.GetDamage(float damage)
        {
            health -= damage/10;
            if (health < 0)
                health = 0;
        }
    }
}
