using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Ika.Graphics;
using Ika.Components;
using TestBoids.Collisions;

namespace TestBoids.Entities
{
    public class EntityFactory : Microsoft.Xna.Framework.GameComponent
    {
        public float Max_Boid_Speed = 4;

        TimeComponent m_timeService;

        Texture2D[] m_boidTexture;
        Texture2D[] m_texNuage;
        Texture2D[] m_texBallon;
        Texture2D m_level;
        Texture2D m_teamBaloon;
        Texture2D[] m_teamBanner;
        Texture2D m_bird, m_fish, m_cactus, m_fall, m_plane;
        Texture2D m_bulle1;
        Texture2D m_bulle2;

        int[] m_boidTotalFrames;
        int[] m_boidUsedFrames;

        int m_Currentlevel;
        Random r = new Random();

        public EntityFactory(Game game)
            : base(game)
        {
        }

        public override void Initialize()
        {
            base.Initialize();

            m_timeService = (TimeComponent)Game.Services.GetService(typeof(TimeComponent));
            m_boidTotalFrames = new int[6];
            m_boidUsedFrames = new int[6];

            m_boidTotalFrames[1] = 8;
            m_boidUsedFrames[1] = 6;

            m_boidTotalFrames[2] = 2;
            m_boidUsedFrames[2] = 2;

            m_boidTotalFrames[3] = 4;
            m_boidUsedFrames[3] = 4;
     
            m_boidTotalFrames[4] = 4;
            m_boidUsedFrames[4] = 4;

            m_boidTotalFrames[5] = 8;
            m_boidUsedFrames[5] = 6;

            m_Currentlevel = 1;
            ChangeLevel(1);

            m_level = Game.Content.Load<Texture2D>("Sprites/change_bulle");
            m_bird = Game.Content.Load<Texture2D>("Sprites/level_1/obs_a");
            m_fish = Game.Content.Load<Texture2D>("Sprites/level_3/obs_a");
            m_cactus = Game.Content.Load<Texture2D>("Sprites/level_4/obs_a");
            m_fall = Game.Content.Load<Texture2D>("Sprites/level_4/obs_b");
            m_plane = Game.Content.Load<Texture2D>("Sprites/level_5/plane");

            m_texBallon = new Texture2D[5];
            m_texBallon[0] = Game.Content.Load<Texture2D>("Sprites/level_" + 1 + "/obs_a");
            m_texBallon[1] = Game.Content.Load<Texture2D>("Sprites/level_" + 1 + "/obs_b");
            m_texBallon[2] = Game.Content.Load<Texture2D>("Sprites/level_" + 1 + "/obs_c");
            m_texBallon[3] = Game.Content.Load<Texture2D>("Sprites/zep");
            m_texBallon[4] = Game.Content.Load<Texture2D>("Sprites/sprites/baloon_object_a");

            m_texNuage = new Texture2D[3];
            m_texNuage[0] = Game.Content.Load<Texture2D>("Sprites/sprites/plane_object_a");
            m_texNuage[1] = Game.Content.Load<Texture2D>("Sprites/sprites/plane_object_b");
            m_texNuage[2] = Game.Content.Load<Texture2D>("Sprites/sprites/plane_object_c");
            
            m_teamBaloon = Game.Content.Load<Texture2D>("Sprites/team/baloon2_blue");

            m_teamBanner = new Texture2D[4];
            m_teamBanner[0] = Game.Content.Load<Texture2D>("Sprites/team/team1");
            m_teamBanner[1] = Game.Content.Load<Texture2D>("Sprites/team/team2");
            m_teamBanner[2] = Game.Content.Load<Texture2D>("Sprites/team/team3");
            m_teamBanner[3] = Game.Content.Load<Texture2D>("Sprites/team/team4");

            m_bulle1 = Game.Content.Load<Texture2D>("Sprites/bulles_a");
            m_bulle2 = Game.Content.Load<Texture2D>("Sprites/bulles_b");
        }

        public void ChangeLevel(int level)
        {

            m_Currentlevel = level;
            m_boidTexture = new Texture2D[2];
            m_boidTexture[0] = Game.Content.Load<Texture2D>("Sprites/level_"+ level + "/boid_a");
            m_boidTexture[1] = Game.Content.Load<Texture2D>("Sprites/level_" + level + "/boid_b");     
        }

        public Zeppelin CreateBigBaloon(Vector2 position, int nbMine)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_texBallon[3], new Vector2(50, 50), 4, 4, 200);
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 2 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;

            Zeppelin b = new Zeppelin(position, sprite, 2.0f, nbMine);
            b.Collision = new BoxCollision(new Vector2(-48, -32), new Vector2(95, 64), b.Position);

            return b;
        }
        public TeamEntity CreateTeam(Vector2 position, int id)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_teamBaloon, new Vector2(50, 50), 5, 4, 500);
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 2 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;

            TeamEntity b = new TeamEntity(position, sprite, id);
            return b;
        }

        public TeamBanner CreateTeamBanner(Vector2 position, int id)
        {
            StaticSprite sprite = new StaticSprite(m_teamBanner[id], new Vector2(50, 50));

            TeamBanner b = new TeamBanner(position, sprite);
            return b;
        }
        public PlaneEntity CreatePlane(Vector2 position)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_plane, new Vector2(50, 50), 1, 1, 200);
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 2 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;

            PlaneEntity p = new PlaneEntity(position, sprite, 0);
            p.Collision = new BoxCollision(new Vector2(-150, -200), new Vector2(300, 400), p.Position);
            return p;
        }

        public Mine CreateMine(Vector2 position)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_texBallon[4], new Vector2(50, 50), 1, 1, 200);
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 2 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;

            Mine b = new Mine(position, sprite, 2.0f);
            b.Collision = new BoxCollision(new Vector2(-15, -32), new Vector2(30, 64), b.Position);

            return b;
        }

        public Boid CreateBoid(Vector2 position)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_boidTexture[r.Next(2)], new Vector2(50, 50), m_boidTotalFrames[m_Currentlevel], m_boidUsedFrames[m_Currentlevel], 80);

            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * m_boidTotalFrames[m_Currentlevel] * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;
            Boid b = new Boid(position, sprite, Max_Boid_Speed);
            b.Collision = new CircleCollision(new Vector2(), 8, b.Position);
            return b;
        }

        public void UpdateBoid(Boid b)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_boidTexture[r.Next(2)], new Vector2(50, 50), m_boidTotalFrames[m_Currentlevel], m_boidUsedFrames[m_Currentlevel], 80);
            b.Sprite = sprite;
        }

        public LevelEntity CreateLevel(Vector2 position, int level)
        {
            StaticSprite sprite = new StaticSprite(m_level, new Vector2(133, 600));
            LevelEntity l = new LevelEntity(position, sprite, level);
            l.Collision = new BoxCollision(new Vector2(0,-300), new Vector2(133, 600), position);
            return l;
        }

        public BlockEntity CreateCactus(Vector2 position)
        {
            StaticSprite sprite = new StaticSprite(m_cactus, new Vector2(50, 50));            
            BlockEntity b = new BlockEntity(position, sprite, 0);
            b.Collision = new BoxCollision(new Vector2(-15, -15), new Vector2(30, 30), b.Position);
            return b;
        }

        public BlockEntity CreateFall(Vector2 position)
        {
            StaticSprite sprite = new StaticSprite(m_fall, new Vector2(50, 50));
            BlockEntity b = new BlockEntity(position, sprite, 0);
            b.Collision = new BoxCollision(new Vector2(-15, -15), new Vector2(30, 30), b.Position);
            return b;
        }

        public EvilFish CreateEvilFish(Vector2 position)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_fish, new Vector2(50, 50), 2, 2, 100);
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 2 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;
            EvilFish b = new EvilFish(position, sprite, 1.0f);
            b.Collision = new BoxCollision(new Vector2(-60, -30), new Vector2(120, 30), b.Position);
            return b;
        }

        public IntroEntity CreateIntroBoid(Vector2 position, Vector2 destination, float maxSpeed)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_boidTexture[0], new Vector2(50, 50), 8, 6, 80);

            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 8 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;
            return new IntroEntity(position, sprite, maxSpeed, destination);
        }

        public BackgroundEntity CreateCloud(Vector2 position)
        {
            StaticSprite sprite = new StaticSprite(m_texNuage[r.Next(3)], new Vector2(50, 50));           
            return new BackgroundEntity(position, sprite);
        }

        public BlockEntity CreateEvilBird(Vector2 position)
        {
            AnimatedSprite sprite = new AnimatedSprite(m_bird, new Vector2(50, 50), 16, 10, 90);
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 8 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;

            BlockEntity b = new EvilBird(position, sprite, 0);
            b.Collision = new BoxCollision(new Vector2(-sprite.Size.X / 2, -sprite.Size.Y / 2), sprite.Size, position);
            return b;
        }

        public BulleEntity CreateBulle(Vector2 position)
        {
            AnimatedSprite sprite;
            Random r = new Random();
            if (r.Next(0, 2) > 10)
            {
                sprite = new AnimatedSprite(m_bulle1, new Vector2(50, 50), 4, 4, 150);
            }
            else
            {
                sprite = new AnimatedSprite(m_bulle1, new Vector2(50, 50), 8, 6, 160);
            }
            sprite.AddTime(new TimeSpan(0, 0, 0, 0, (int)(r.NextDouble() * 2 * sprite.FrameTime)));
            m_timeService.TimeElapsedEvent += sprite.AddTime;

            BulleEntity b = new BulleEntity(position, sprite, 1);
            return b;
        }
    }
}
