using SharpDX;
using SharpDX.DirectInput;
using System;
using System.Linq;
using System.Globalization;
using System.Collections.Generic;
using Turbo.Plugins.Default;
 
namespace Turbo.Plugins.User
{
    public class DAV_PartyCDPlugin : BasePlugin, IInGameTopPainter {
        public float xPos { get; set; }
        public float yPos { get; set; }
        public float iconSize { get; set; }
        public IFont ClassFont { get; set; }
        public Dictionary<HeroClass, string> _classShortName;
        public DAV_SkillPainter SkillPainter { get; set; }
        public List<uint> WatchedSnos;
 
        private Dictionary<HeroClass, Tuple<uint,ITexture>> classCheatDeath;
 
        public DAV_PartyCDPlugin() {
            Enabled = true;
        }
 
        public override void Load(IController hud) {
            base.Load(hud);
 
            xPos = Hud.Window.Size.Width * 0.650f; //0.625f;
            yPos = Hud.Window.Size.Height * 0.005f;
            iconSize = Hud.Window.Size.Height / 27;
 
            ClassFont = Hud.Render.CreateFont("arial", 7, 255, 255, 255, 255, true, false, 255, 0, 0, 0, true);
            SkillPainter = new DAV_SkillPainter(Hud);
 
            _classShortName = new Dictionary<HeroClass, string> {
                {HeroClass.Barbarian, "\n(Barb)"},
                {HeroClass.Monk, "\n(Monk)"},
                {HeroClass.Necromancer, "\n(Necro)"},
                {HeroClass.Wizard, "\n(Wiz)"},
                {HeroClass.WitchDoctor, "\n(WD)"},
                {HeroClass.Crusader, "\n(Sader)"},
                {HeroClass.DemonHunter, "\n(DH)"}
            };
 
            classCheatDeath = new Dictionary<HeroClass, Tuple<uint, ITexture>> {
                {HeroClass.Barbarian, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.Barbarian_Passive_NervesOfSteel.Sno, Hud.Texture.GetTexture(3216866912))},
                {HeroClass.Monk, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.Monk_Passive_NearDeathExperience.Sno, Hud.Texture.GetTexture(2406461858))},
                {HeroClass.Necromancer, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.Necromancer_Passive_FinalService.Sno, Hud.Texture.GetTexture(725994273))},
                {HeroClass.Wizard, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.Wizard_Passive_UnstableAnomaly.Sno, Hud.Texture.GetTexture(4122255698))},
                {HeroClass.WitchDoctor, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.WitchDoctor_Passive_SpiritVessel.Sno, Hud.Texture.GetTexture(4048913488))},
                {HeroClass.Crusader, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.Crusader_Passive_Indestructible.Sno, Hud.Texture.GetTexture(1659761171))},
                {HeroClass.DemonHunter, new Tuple<uint, ITexture>(Hud.Sno.SnoPowers.DemonHunter_Passive_Awareness.Sno, Hud.Texture.GetTexture(542514827))}
            };
 
            WatchedSnos = new List<uint> {
                //--- Crusader
                Hud.Sno.SnoPowers.Crusader_AkaratsChampion.Sno,
 
                //--- Necromancer
                //Hud.Sno.SnoPowers.Necromancer_Simulacrum.Sno,
                Hud.Sno.SnoPowers.Necromancer_LandOfTheDead.Sno,
				//Hud.Sno.SnoPowers.Necromancer_SkeletalMage.Sno,
				//Hud.Sno.SnoPowers.Necromancer_BoneArmor.Sno,
				
 
                //--- Barb
              // Hud.Sno.SnoPowers.Barbarian_GroundStomp.Sno,
              // Hud.Sno.SnoPowers.Barbarian_IgnorePain.Sno,
              // Hud.Sno.SnoPowers.Barbarian_WrathOfTheBerserker.Sno,
              // Hud.Sno.SnoPowers.Barbarian_WarCry.Sno,
			   
 
                //--- Monk
              // Hud.Sno.SnoPowers.Monk_InnerSanctuary.Sno,
              // Hud.Sno.SnoPowers.Monk_Epiphany.Sno,
                 Hud.Sno.SnoPowers.Monk_Serenity.Sno,
 
                //--- Witch Doctor
              // Hud.Sno.SnoPowers.WitchDoctor_SpiritWalk.Sno,
                Hud.Sno.SnoPowers.WitchDoctor_BigBadVoodoo.Sno,
 
                //--- Demon Hunter
            //   Hud.Sno.SnoPowers.DemonHunter_Companion.Sno,
 
                //--- Wizard
            //    Hud.Sno.SnoPowers.Wizard_Archon.Sno,
            };
        }
 
        public void PaintTopInGame(ClipState clipState) {
            if (clipState != ClipState.BeforeClip) return;
 
            var xref = xPos;
            foreach (var player in Hud.Game.Players.OrderBy(p => p.HeroClassDefinition.HeroClass)) {
                var foundCarrySkill = false;
                var flagIsFirstIterator = true;
                var yref = yPos;
 
                foreach (var skill in player.Powers.UsedSkills.OrderBy(p => p.SnoPower.Sno)) {
                    if (skill == null || !WatchedSnos.Contains(skill.SnoPower.Sno)) continue;
 
                    foundCarrySkill = true;
                    if (flagIsFirstIterator) {
                        var layout = ClassFont.GetTextLayout(player.BattleTagAbovePortrait + _classShortName[player.HeroClassDefinition.HeroClass]);
                        ClassFont.DrawText(layout, xref, yref);
                        flagIsFirstIterator = false;
                        yref += layout.Metrics.Height + 2f;
                    }
 
                    var rect = new SharpDX.RectangleF(xref, yref, iconSize, iconSize);
                    SkillPainter.Paint(skill, rect);
 
                    yref += iconSize + 2f;
                }
 
                var CheatDeathBuff = player.Powers.GetBuff(classCheatDeath[player.HeroClassDefinition.HeroClass].Item1);
                if (CheatDeathBuff?.TimeLeftSeconds[1] > 0.0) {
                    if (flagIsFirstIterator) {
                        var layout = ClassFont.GetTextLayout(player.BattleTagAbovePortrait + _classShortName[player.HeroClassDefinition.HeroClass]);
                        ClassFont.DrawText(layout, xref, yref);
                        foundCarrySkill = true;
                        yref += layout.Metrics.Height + 2f;
                    }
                    classCheatDeath[player.HeroClassDefinition.HeroClass].Item2?.Draw(xref, yref, iconSize, iconSize);
 
                    var layout2 = ClassFont.GetTextLayout(CheatDeathBuff.TimeLeftSeconds[1].ToString("0"));
                    ClassFont.DrawText(layout2, xref + (iconSize - layout2.Metrics.Width) / 2, yref + (iconSize - layout2.Metrics.Height) / 2);
                }
 
                if (foundCarrySkill)
                    xref += iconSize * 2.5f;
            }
        }
    }
 
    public class DAV_SkillPainter {
        public IController Hud { get; set; }
        public IFont CDFont { get; set; }
        public IFont BuffFont { get; set; }
 
        public DAV_SkillPainter(IController hud) {
            Hud = hud;
            CDFont = Hud.Render.CreateFont("arial", 9, 255, 255, 255, 255, true, false, 255, 0, 0, 0, true);
            BuffFont = Hud.Render.CreateFont("arial", 9, 255, 51, 255, 51, true, false, 255, 0, 0, 0, true);
        }
 
        public void Paint(IPlayerSkill skill, RectangleF rect) {
            if (skill == null) return;
 
            var texture = Hud.Texture.GetTexture(skill.SnoPower.NormalIconTextureId);
            texture?.Draw(rect.X, rect.Y, rect.Width, rect.Height);
 
            if (skill.BuffIsActive) {
                var ActiveTime = 0.0d;
                for (var i = 4; i >= 0; i--) // for (var i = 4; i >= 0; i--)
				{
                    ActiveTime= skill.Buff.TimeLeftSeconds[i];
                    if (ActiveTime > 0) {
                        BuffFont.DrawText(ActiveTime.ToString(ActiveTime > 3.0f ? "F0" : "F1"), rect.X + 2, rect.Y + 2);
                        break;
                    }
                }
            }
 
            var remainingSeconds = (skill.CooldownFinishTick - Hud.Game.CurrentGameTick) / 60.0d;
            if (skill?.SnoPower.Sno == Hud.Sno.SnoPowers.Wizard_Archon.Sno && skill.BuffIsActive) {
                var ActiveTime = skill.Buff.TimeLeftSeconds[2];
 
                if (ActiveTime > 0)
                    remainingSeconds = skill.CalculateCooldown(skill.Rune == 3.0 ? 100 : 120) - 20 + ActiveTime;
            }
 
            if (remainingSeconds <= 0) return;
 
            var textLayout = CDFont.GetTextLayout(remainingSeconds.ToString(remainingSeconds > 3.0f ? "F0" : "F1"));
            CDFont.DrawText(textLayout, rect.Right - textLayout.Metrics.Width - 2, rect.Bottom - textLayout.Metrics.Height - 2);
        }
    }
}