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

namespace TestBoids.Graphic
{
    class BirdsRenderer : BasicRenderer
    {
        Sprite m_birdSprite;
        SpriteBatch spriteBatch;
        SpriteFont m_font;

        SkyEffect m_skyEffect;

        TimeComponent m_time;

        Vector2 m_cameraPosition = Vector2.Zero;
        public Vector2 CameraPosition
        {
            get { return m_cameraPosition; }
            set { m_cameraPosition = value; }
        }

        /// <summary>
        /// Create a renderer
        /// </summary>
        /// <param name="game">The XNA game object</param>
        public BirdsRenderer(Game game)
            : base(game)
        {
        }

        /// <summary>
        /// Initialize the renderer
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            m_time = new TimeComponent(Game);
            Game.Components.Add(m_time);

            spriteBatch = new SpriteBatch(Game.GraphicsDevice);

            m_skyEffect = new SkyEffect(Game.Content.Load<Effect>("Shaders/VerticalGradient"));

            Texture2D birdTex, birdTex2;
            birdTex = Game.Content.Load<Texture2D>("Sprites/Piaf");
            //birdTex2 = Game.Content.Load<Texture2D>("Sprites/bird_alt1");

            m_birdSprite = new StaticSprite(birdTex, new Vector2(50, 50));
            AnimatedSprite anim = new AnimatedSprite(birdTex, new Vector2(50, 50), 8, 6, 80);
            m_time.TimeElapsedEvent += anim.AddTime;

            m_birdSprite = anim;
            m_font = Game.Content.Load<SpriteFont>("fpsFont");

            Camera = m_cameraHUD;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            Game.GraphicsDevice.Clear(Color.CornflowerBlue);
        }

        public Vector2 WorldToScreen(Vector2 world)
        {
            return world - CameraPosition;
        }

        public Vector2 ScreenToWorld(Vector2 screen)
        {
            return screen + CameraPosition;
        }

        public void DrawSprite(Sprite sprite, Vector2 pos)
        {
            DrawSprite(sprite, pos, Color.White);
        }

        public void DrawSprite(Sprite sprite, Vector2 pos, Color color)
        {
            if (sprite == null)
                return;
            pos = WorldToScreen(pos);
            Rectangle textureSource = new Rectangle((int)sprite.TextureSourceOrigin.X, (int)sprite.TextureSourceOrigin.Y, (int)sprite.TextureSourceEnd.X - (int)sprite.TextureSourceOrigin.X, (int)sprite.TextureSourceEnd.Y - (int)sprite.TextureSourceOrigin.Y);
            spriteBatch.Begin();
            spriteBatch.Draw(sprite.Texture, pos - new Vector2(textureSource.Width / 2, textureSource.Height / 2), textureSource, color);
            spriteBatch.End();
        }

        public void DrawText(string text, Vector2 pos, Color color)
        {
            spriteBatch.Begin();
            spriteBatch.DrawString(m_font, text, pos, color);
            spriteBatch.End();
        }

        public void DrawSky(Color top, Color bottom, Vector2 center, Vector2 size)
        {
            m_skyEffect.TopColor = top;
            m_skyEffect.BottomColor = bottom;

            DrawEffect(m_skyEffect.Effect, new Rectangle(0, 0, (int)size.X, (int)size.Y), center, size);
            //DrawFullScreen(m_skyEffect.Effect);
        }

        public void DrawLeaderBird(Entity e)
        {
            DrawSprite(e.Sprite, e.Position, Color.OrangeRed);
        }

        public void DrawEntity(Entity e)
        {
            DrawSprite(e.Sprite, e.Position);
        }

        public void DrawEntity(Entity e, Color color)
        {
            DrawSprite(e.Sprite, e.Position, color);
        }

        public void DrawLine(Vector2 v1, Vector2 v2)
        {
            v1 = WorldToScreen(v1);
            v2 = WorldToScreen(v2);
            float distance = (float)Math.Abs(Vector2.Distance(v2, v1));
            Vector3 center = new Vector3((v1 + v2) * 0.5f, 0.0f);
            float angle = (float)Math.Atan2(v2.Y - v1.Y, v2.X - v1.X);

            Matrix World = Matrix.Identity;
            World *= Matrix.CreateScale(0.5f * distance);
            World *= Matrix.CreateRotationZ(angle);
            World *= Matrix.CreateTranslation(center);

            DrawMesh(m_lineMesh, World, m_uniformEffect.Effect, false);
        }

        public void DrawRectangle(Vector2 pos, Vector2 size)
        {
            DrawLine(pos, pos + new Vector2(size.X, 0));
            DrawLine(pos + new Vector2(size.X, 0), pos + size);
            DrawLine(pos + size, pos + new Vector2(0, size.Y));
            DrawLine(pos + new Vector2(0, size.Y), pos);

        }

        public void DrawCircle(Vector2 center, float radius)
        {
            center = WorldToScreen(center);
            Matrix World = Matrix.Identity;
            World *= Matrix.CreateScale(radius);
            World *= Matrix.CreateTranslation(new Vector3(center, 0.0f));

            DrawMesh(m_circleMesh, World, m_uniformEffect.Effect, false);
        }
    }
}
