using System;
using System.Collections.Generic;
using System.Linq;
using MLEM.Extensions;
using MLEM.Textures;

namespace TouchyTickets {
    public class Upgrade {

        public static readonly Dictionary<string, Upgrade> Upgrades = new Dictionary<string, Upgrade>();
        public static readonly Upgrade[] MapSize = RegisterTiers("MapSize", 5, 1, 1, Ui.Texture[0, 3]);
        public static readonly Upgrade[] TapIncrease = RegisterTiers("TapIncrease", 3, 1, 0.5F, Ui.Texture[6, 3]);
        public static readonly Upgrade FerrisWheelModifier = Register(new Upgrade("FerrisWheelModifier", 1, Ui.Texture[2, 3]));
        public static readonly Upgrade NatureModifier = Register(new Upgrade("NatureModifier", 1, Ui.Texture[8, 3]));
        public static readonly Upgrade FoodCourtModifier = Register(new Upgrade("FoodCourtModifier", 2, Ui.Texture[1, 3]));
        public static readonly Upgrade RollerCoasterModifier = Register(new Upgrade("RollerCoasterModifier", 2, Ui.Texture[3, 3]));
        public static readonly Upgrade ManualRideModifier = Register(new Upgrade("ManualRideModifier", 2, Ui.Texture[4, 3]));
        public static readonly Upgrade SpiralSlideModifier = Register(new Upgrade("SpiralSlideModifier", 2, Ui.Texture[5, 3]));
        public static readonly Upgrade HauntedHouseModifier = Register(new Upgrade("HauntedHouseModifier", 2, Ui.Texture[7, 3]));

        public readonly string Name;
        public readonly int Price;
        public readonly TextureRegion Texture;
        public readonly Upgrade[] Dependencies;

        public Upgrade(string name, int price, TextureRegion texture, params Upgrade[] dependencies) {
            this.Name = name;
            this.Price = price;
            this.Texture = texture;
            this.Dependencies = dependencies;
        }

        private static Upgrade[] RegisterTiers(string name, int amount, int startPrice, float priceIncrease, TextureRegion texture) {
            var ret = new Upgrade[amount];
            for (var i = 0; i < amount; i++) {
                // every tier except first depends on last tier
                var deps = i == 0 ? Array.Empty<Upgrade>() : new[] {ret[i - 1]};
                var price = (startPrice * (1 + i * priceIncrease)).Floor();
                Register(ret[i] = new Upgrade(name + (i + 1), price, texture, deps));
            }
            return ret;
        }

        public void OnApplied() {
            // map size upgrades
            if (MapSize.Contains(this)) {
                var oldMap = GameImpl.Instance.Map;
                GameImpl.Instance.Map = oldMap.Copy(oldMap.Width + 10, oldMap.Height + 10);
            }
        }

        private static Upgrade Register(Upgrade upgrade) {
            Upgrades.Add(upgrade.Name, upgrade);
            return upgrade;
        }

        public bool IsActive() {
            return GameImpl.Instance.AppliedUpgrades.Contains(this);
        }

    }
}