using System;
using System.Collections.Generic;
using Coroutine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extended.Tiled;
using MLEM.Startup;
using MLEM.Textures;
using MonoGame.Extended;
using RectangleF = MLEM.Misc.RectangleF;

namespace GreatSpringGameJam {
    public class WaterDrop : Entity {

        private static readonly SoundEffect PlantGrowSound = MlemGame.LoadContent<SoundEffect>("Sounds/PlantGrow");
        private readonly bool growsPlants;
        private Vector2 velocity;
        private TimeSpan timeToLive;
        private bool onGround;

        public WaterDrop(Map map, Vector2 position, Vector2 velocity) : base(map, position) {
            this.velocity = velocity;
            this.timeToLive = TimeSpan.FromSeconds(0.5F);
            this.growsPlants = Random.NextSingle() <= 0.25F;
        }

        public override void Update(GameTime time) {
            base.Update(time);

            this.Position += this.velocity;
            this.Collide(() => new RectangleF(this.Position - new Vector2(1 / 16F), new Vector2(2 / 16F)), ref this.velocity, ref this.onGround);
            if (this.onGround)
                this.velocity = Vector2.Zero;
            this.velocity.Y += 0.008F;

            this.timeToLive -= time.ElapsedGameTime;
            if (this.timeToLive <= TimeSpan.Zero) {
                this.Map.RemoveEntity(this);

                // growing plants
                if (!this.growsPlants)
                    return;
                var (x, y) = this.Position.ToPoint();
                var tile = this.Map.GetTile("Ground", x, y);
                if (tile.IsBlank)
                    return;
                var tileset = this.Map.GetTileset(tile);
                var tilesetTile = this.Map.GetTilesetTile(tile, tileset);
                var grown = tilesetTile.Properties.GetInt("GrownVersion");
                if (grown == 0)
                    return;
                var grownTile = tileset.GetTilesetTile(grown);
                this.Map.SetTile("Ground", x, y, tileset, grownTile);
                PlantGrowSound.Play();

                // vines
                if (grownTile.Properties.GetBool("Vine")) {
                    IEnumerable<Wait> GrowVines() {
                        while (y-- > 0) {
                            yield return new Wait(0.2F);
                            if (this.Map.GetTile("Ground", x, y).GlobalIdentifier != 0)
                                break;
                            this.Map.SetTile("Ground", x, y, tileset, grownTile);
                        }
                    }

                    CoroutineHandler.Start(GrowVines());
                }
                // forget me not
                if (grownTile.Properties.GetBool("ForgetMeNot")) {
                    this.Map.ForgetMeNotTime = TimeSpan.FromSeconds(10);
                    Map.ForgetMeNotPlatformSound.Play();
                }
            }
        }

        public override void Draw(GameTime time, SpriteBatch batch) {
            base.Draw(time, batch);
            var tex = StuffTexture[3, 0];
            batch.Draw(tex, this.Position * this.Map.TileSize - tex.Size.ToVector2() / 2, Color.White);
        }

    }
}