using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using SharpDX;
using SharpDX.Direct2D1;
 
using Turbo.Plugins.Default;
   
namespace Turbo.Plugins.User
{
    public class NecSkeletalMagePlugin : BasePlugin, IInGameTopPainter
    {
        public bool ShowStacks { get; set; }
        public bool ShowTimeLeftNumbers { get; set; }
        public bool ShowTimeLeftClock { get; set; }
       
        public SkillPainter SkillPainter { get; set; }
        public IFont TimeLeftFont { get; set; }
        public IFont StackFont { get; set; }
        public IBrush TimeLeftClockBrush { get; set; }
       
        public float SkillRatio { get; set; }
       
        public NecSkeletalMagePlugin()
        {
            Enabled = true;
           
            ShowStacks = true;
            ShowTimeLeftNumbers = true;
            ShowTimeLeftClock = true;
        }
 
        public override void Load(IController hud)
        {
            base.Load(hud);
           
            //similar to bufflist
            SkillPainter = new SkillPainter(Hud, true)
            {
                TextureOpacity = 1.0f,
                EnableSkillDpsBar = false,
                EnableDetailedDpsHint = false,
            };
           
            TimeLeftFont = Hud.Render.CreateFont("tahoma", 7, 255, 255, 255, 255, false, false, 255, 0, 0, 0, true);
            StackFont = Hud.Render.CreateFont("tahoma", 6, 255, 255, 240, 0, false, false, 255, 0, 0, 0, true);
            TimeLeftClockBrush = Hud.Render.CreateBrush(220, 0, 0, 0, 0);
            SkillRatio = 0.65f;
        }
       
        public void PaintTopInGame(ClipState clipState)
        {
            if (clipState != ClipState.BeforeClip) return;
               
            var players = Hud.Game.Players;
            foreach(var p in players)
            {
                if (p.IsMe) continue;
                if (!p.HasValidActor) continue;
               
                if (p.HeroClassDefinition.HeroClass == HeroClass.Necromancer)
                {
                    DrawBuffPortrait(p);
                }
            }
        }
       
        private void DrawBuffPortrait(IPlayer player)
        {
            var portraitRect = player.PortraitUiElement.Rectangle;
           
            var XPos = portraitRect.Right;
            var YPos = portraitRect.Top;
            var size = Hud.Window.Size.Width * 0.025f * SkillRatio;
            YPos += portraitRect.Height * 0.28f;
            if (Hud.Game.Me.HeroClassDefinition.HeroClass == HeroClass.Barbarian)
            {
                //not me NEC, barb mit pain, -> wegen skill leiste
                XPos += portraitRect.Height * 0.21f;
            }
           
            // ISnoPower Necromancer_SkeletalMage { get; } // 462089
            var _skMage = player.Powers.GetBuff(Hud.Sno.SnoPowers.Necromancer_SkeletalMage.Sno);
            if (_skMage != null)
            {
                //don't draw, if no mages
                if (_skMage.IconCounts[6] == 0) return;
               
                //draw icon
                // ISnoPower Necromancer_SkeletalMage { get; } // 462089
                var skill = player.Powers.UsedSkills.FirstOrDefault(_sk => _sk.SnoPower.Sno == Hud.Sno.SnoPowers.Necromancer_SkeletalMage.Sno);
                var rect = new RectangleF(XPos, YPos, size, size);
                SkillPainter.Paint(skill, rect);
               
                //draw TimeLeftClock
                if (ShowTimeLeftClock)
                {
                    double _maxlifeTime = 6d;
                    // ISnoPower Necromancer_Passive_ExtendedServitude { get; } // 464994
                    var _PassiveBuff_ExctendedServitude = player.Powers.GetBuff(Hud.Sno.SnoPowers.Necromancer_Passive_ExtendedServitude.Sno);
                    if (_PassiveBuff_ExctendedServitude != null && _PassiveBuff_ExctendedServitude.Active)
                        _maxlifeTime *= 1.25d;
                    // ISnoPower CircleOfNailujsEvol { get; } // 475247 - P6_ItemPassive_Unique_Ring_043
                    var _ItemBuff_CircleOfNailujsEvol = player.Powers.GetBuff(Hud.Sno.SnoPowers.CircleOfNailujsEvol.Sno);
                    if (_ItemBuff_CircleOfNailujsEvol != null && _ItemBuff_CircleOfNailujsEvol.Active)
                        _maxlifeTime += 4d;
                    DrawTimeLeftClock(rect, _maxlifeTime - _skMage.TimeLeftSeconds[6], _skMage.TimeLeftSeconds[6]);
                }
               
                //draw TimeLeftNumbers
                if (ShowTimeLeftNumbers)
                    DrawTimeLeftNumbers(rect, _skMage.TimeLeftSeconds[6]);
               
                //draw Stacks
                if (ShowStacks)
                    DrawStacks(rect, _skMage.IconCounts[6]);
            }
           
        }
       
        private void DrawTimeLeftClock(RectangleF rect, double elapsed, double timeLeft)
        {
            if ((timeLeft > 0) && (elapsed >= 0) && (TimeLeftClockBrush != null))
            {
                var endAngle = Convert.ToInt32((360.0d / (timeLeft + elapsed)) * elapsed);
                var startAngle = 0;
                TimeLeftClockBrush.Opacity = 1 - (float)(0.3f / (timeLeft + elapsed) * elapsed);
                var rad = rect.Width * 0.45f;
                using (var pg = Hud.Render.CreateGeometry())
                {
                    using (var gs = pg.Open())
                    {
                        gs.BeginFigure(rect.Center, FigureBegin.Filled);
                        for (int angle = startAngle; angle <= endAngle; angle++)
                        {
                            var mx = rad * (float)Math.Cos((angle - 90) * Math.PI / 180.0f);
                            var my = rad * (float)Math.Sin((angle - 90) * Math.PI / 180.0f);
                            var vec = new Vector2(rect.Center.X + mx, rect.Center.Y + my);
                            gs.AddLine(vec);
                        }
                        gs.EndFigure(FigureEnd.Closed);
                        gs.Close();
                    }
                    TimeLeftClockBrush.DrawGeometry(pg);
                }
            }
        }
 
        private void DrawTimeLeftNumbers(RectangleF rect, double TimeLeft)
        {
            if (TimeLeft == 0) return;
 
            var text = "";
            if (TimeLeft > 1.0f)
            {
                var mins = Convert.ToInt32(Math.Floor(TimeLeft / 60.0d));
                var secs = Math.Floor(TimeLeft - mins * 60.0d);
                if (TimeLeft >= 60)
                {
                    text = mins.ToString("F0", CultureInfo.InvariantCulture) + ":" + (secs < 10 ? "0" : "") + secs.ToString("F0", CultureInfo.InvariantCulture);
                }
                else text = TimeLeft.ToString("F0", CultureInfo.InvariantCulture);
            }
            else text = TimeLeft.ToString("F1", CultureInfo.InvariantCulture);
 
            var layout = TimeLeftFont.GetTextLayout(text);
            TimeLeftFont.DrawText(layout, rect.X + (rect.Width - (float)Math.Ceiling(layout.Metrics.Width)) / 2.0f, rect.Y + (rect.Height - layout.Metrics.Height) / 2);
        }
 
        private void DrawStacks(RectangleF rect, int stacks)
        {
            var layout = StackFont.GetTextLayout(stacks.ToString());
            StackFont.DrawText(layout, rect.Right - (rect.Width / 8.0f) - (float)Math.Ceiling(layout.Metrics.Width), rect.Bottom - layout.Metrics.Height - (rect.Width / 15.0f));
        }
    }
}