using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Hover
{
    class Level
    {
        List<Star> stars = new List<Star>();

        public static Level S;
        float surfaceHeight = 172;
        Rectangle[] bgRecs = new Rectangle[]
        {
            new Rectangle(192, 128, 64, 64),
            new Rectangle(128, 128, 64, 64),
            new Rectangle(64, 128, 64, 64),
            new Rectangle(0, 128, 64, 64),
        };
        public List<Row> Rows = new List<Row>();
        public Random Rnd;
        public Perlin Perlin;

        public const int startingRow = 4;
        public const int startingRowTraps = 9;
        public float ScoreStart;

        public int artifactsSpawned = 0;

        public float PerlinCutoff(int height)
        {
            return 0.1f - Math.Min(0.4f, height * 0.001f);
        }
        public float SpikeFloorChance(int height)
        {
            return Math.Max(0.1f, 0.3f - height * 0.001f);
        }
        public float BombChance(int height)
        {
            return 0.97f + Math.Min(0.02f, height * 0.001f);
        }
        public float SpikeCeelingChance(int height)
        {
            return 0.4f - height * 0.0005f;
        }
        public float StalagniteChance(int height)
        {
            return 0.3f - height * 0.0005f;
        }
        public float SpawnFuel(int height)
        {
            return 0.98f;
        }

        public Level(int seed)
        {
            S = this;
            Rnd = new Random(seed);
            Perlin = new Perlin(seed);

            Row.CurrentRowNum = startingRow;

            var row = new Row(this);
            for (int i = 0; i < row.Blocks.Length; i++)
                row.Greens[i] = true;
            row.Initialize();

            row = new Row(this);
            for (int i = 0; i < 16; i++)
                if (i != 5)
                    new Block(row, BlockType.Block, i);
            row.Greens[5] = true;
            row.Initialize();

            ScoreStart = Rows[1].PosY;

            for (int i = 0; i < 400; i++)
                stars.Add(new Star());

            //for (int i = 0; i < 300; i++)
            //{
            //    row = new Row(this);
            //    row.RandomBlocks();
            //    row.Initialize();
            //}
        }

        public void Update()
        {
            //if (Player.S.Position.Y > 10000)
            //    Player.S.Position = new Vector2(0, 0);
            foreach (var item in Rows)
                item.Update();
            foreach (var item in stars)
                item.Update();

            // Add rows while going down
            while (Row.CurrentRowNum < (Engine.CamPos.Y + Engine.GameRes.Y + 120) / Engine.TileSize)
            {
                var row = new Row(this);
                row.RandomBlocks();
                row.Initialize();
            }

            // Remove rows which are high up
            if (Rows.Count > 40)
                Rows.RemoveAt(0);

            Ward.Watch("Row.CurrentRownum", Row.CurrentRowNum);
            Ward.Watch("Rows.Count", Rows.Count);
        }

        public void Draw(SpriteBatch sb)
        {
            const int size = 64;

            foreach (var item in stars)
                item.Draw(sb);

            float camTop = Engine.CamPos.Y - (Engine.CamPos.Y % 64);
            for (int x = 0; x < Engine.GameRes.X / size; x++)
                for (int y = -2; y < Engine.GameRes.Y / size + 1; y++)
                {
                    var pos = new Vector2(size * x, camTop + size * y);
                    if (pos.Y > surfaceHeight)
                    {
                        int a = Math.Abs((int)((pos.X + pos.Y) * 1.55342f % bgRecs.Length));
                        sb.Draw(Engine.Spritesheet, new Vector2(size * x,
                            camTop + size * y), bgRecs[a], Color.White);
                    }
                }

            foreach (var item in Rows)
                item.Draw(sb);
        }

        public void Collide(Player player, ref Vector2 Velocity)
        {
            foreach (var item in Rows)
                item.Collide(player, ref Velocity);
        }
    }
}
