using System;
using Turbo.Plugins.Default;  
using System.Linq;    
using System.Collections.Generic;
using SharpDX;
using SharpDX.Direct2D1;
 
namespace Turbo.Plugins.User
{        
    public class SpiritBarrageAndCoe : BasePlugin, IInGameTopPainter, ICustomizer
    {      
        private Dictionary<HeroClass,List<int>> HeroLIndex { get; set; }
           
        private float SizeIconWidth  { get; set; }
        private float SizeIconHeight  { get; set; }
       
        private IFont FontWhite { get; set; }
        private IFont FontGray { get; set; }
        private IFont FontGreen { get; set; }
        private IFont FontRed { get; set; }
        private IFont FontYellow { get; set; }
        private IFont FontOrange { get; set; }
        private IFont FontBlue { get; set; }
        private IFont FontDefault { get; set; } = null;
       
        private IFont FontStacks { get; set; }
        private IFont FontTimeLeft { get; set; }
        private IFont FontStacksRed { get; set; }      
       
        private ITexture TextureFrame { get; set; } = null;
        private int[] IndexToBonus { get; set; }
        private int contador { get; set; } = 0;
 
        private IBrush TimeLeftClockBrush { get; set; }    
        private IBrush BrushBlack { get; set; }
        private IBrush BrushGreen { get; set; }
        private IBrush BrushRed { get; set; }
        private IBrush BrushYellow { get; set; }
        private IBrush BrushOrange { get; set; }
        private IBrush BrushBlue { get; set; }
        private IBrush BrushDefault { get; set; }
 
        public float OffsetX  { get; set; }
        public float OffsetY  { get; set; }    
        public float SizeMultiplier  { get; set; }
        public List<int> Lindex { get; set; } =  new List<int> {3,6,7,2};
       // 1 = Arcane, 2 = Cold, 3 = Fire, 4 = Holy, 5 = Lightning, 6 = Physical, 7 = Poison
        public bool ShowCoe { get; set; }
        public bool ShowGlobes { get; set; }
        public bool OnlyGR { get; set; }
        public SharpDX.DirectWrite.TextLayout layout { get; set; } = null; 
           
        public SpiritBarrageAndCoe()
        {
            Enabled = true;    
        }
       
        public override void Load(IController hud)
        {
            base.Load(hud);
            Order = 30001;
           
            OffsetX = 0.10f;        // To set the x coordinate of the icon 05 048 
            OffsetY = 0.95f;        // To set the y coordinate of the icon 07 077      
            SizeMultiplier = 1.0f;  // Size multiplier for icons
            ShowCoe = false;         // Show COE status for WD
            ShowGlobes = true;      // Health Globes Counter (floor)
            OnlyGR = false;         // Show  in GR only
           
           
            TextureFrame = Hud.Texture.BuffFrameTexture;
            TimeLeftClockBrush = Hud.Render.CreateBrush(220, 0, 0, 0, 0);  
            IndexToBonus = new int[8] { 7, 5, 3, 1, 6, 2, 0, 4 };
        }
 
        public void Customize()
        {
            FontWhite = Hud.Render.CreateFont("tahoma", 8f * SizeMultiplier, 255, 255, 255, 255, true, false, 255, 0, 0, 0, true);
            FontGray = Hud.Render.CreateFont("tahoma", 6f * SizeMultiplier, 235, 235, 235, 235, true, false, 255, 0, 0, 0, true);
            FontGreen = Hud.Render.CreateFont("tahoma", 10f * SizeMultiplier, 255, 0, 255, 0, true, false, 255, 0, 0, 0, true);        
            FontRed = Hud.Render.CreateFont("tahoma", 10f * SizeMultiplier, 255, 255, 0, 0, true, false, 255, 0, 0, 0, true);
            FontYellow = Hud.Render.CreateFont("tahoma", 10f * SizeMultiplier, 255, 255, 255, 0, true, false, 255, 0, 0, 0, true);
            FontOrange = Hud.Render.CreateFont("tahoma", 10f * SizeMultiplier, 255, 255, 150, 0, true, false, 255, 0, 0, 0, true);
            FontBlue = Hud.Render.CreateFont("tahoma", 5f * SizeMultiplier, 255, 50, 150, 250, true, false, 255, 0, 0, 0, true);
 
            BrushBlack = Hud.Render.CreateBrush(255, 80, 80, 80, 0);
            BrushGreen = Hud.Render.CreateBrush(255, 0, 255 , 0, 0);
            BrushRed = Hud.Render.CreateBrush(255, 255, 50 , 50, 0);
            BrushYellow = Hud.Render.CreateBrush(255, 255, 255 , 0, 0);
            BrushOrange = Hud.Render.CreateBrush(255, 255, 185 , 0, 0);
            BrushBlue = Hud.Render.CreateBrush(255, 50, 150 , 250, 0);
           
            SizeIconWidth = TextureFrame.Width  * 0.55f * SizeMultiplier;
            SizeIconHeight = TextureFrame.Height * 0.55f * SizeMultiplier;
 
            FontStacks = Hud.Render.CreateFont("tahoma", 9f * SizeMultiplier, 255, 255, 225, 0, true, false, 160, 0, 0, 0, true);
            FontTimeLeft = Hud.Render.CreateFont("tahoma", 6f * SizeMultiplier, 255, 0, 255, 0, true, false, 255, 0, 0, 0, true);              
            FontStacksRed = Hud.Render.CreateFont("tahoma", 9f * SizeMultiplier, 255, 255, 0, 0, true, false, 160, 0, 0, 0, true);                 
        }
       
        private void DrawTimeLeftClock(RectangleF rect, double elapsed, double timeLeft)   // plugins\default\Bufflists\ConventionOfElementsBuffListPlugin.cs
        {
            if ((timeLeft > 0) && (elapsed >= 0) && (TimeLeftClockBrush != null))
            {
                var endAngle = Convert.ToInt32(360.0d / (timeLeft + elapsed) * elapsed);
                var startAngle = 0;
                TimeLeftClockBrush.Opacity = 1 - (float)(0.7f / (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 (var 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);
                }
            }
        }
 
        public void DrawIcon(float x, float y, float width, float height, uint idtexture, int stacks, double timeleft, double elapsed)
        {
            Hud.Texture.GetTexture(idtexture).Draw(x, y, width, height, 1f);
            TextureFrame.Draw(x, y, width, height, 1f);
            if (timeleft > 0)
            {
                DrawTimeLeftClock(new RectangleF(x, y , width, height), elapsed , timeleft);
                layout = FontTimeLeft.GetTextLayout(timeleft.ToString( (timeleft < 1)? "F1" : "F0") );
                FontTimeLeft.DrawText(layout, x + ((width - (float)Math.Ceiling(layout.Metrics.Width))/5.0f), y + ((height - (float)Math.Ceiling(layout.Metrics.Height))/10.0f));          
            }
            layout = FontStacks.GetTextLayout( stacks.ToString() );
            (stacks == 0?FontStacksRed:FontStacks).DrawText(layout, x + width - (float)Math.Ceiling(layout.Metrics.Width) - 2, y + height - (float)Math.Ceiling(layout.Metrics.Height) - 1 );
        }
        public void DrawIconNoBuff(float x, float y, float width, float height, uint idtexture)
        {
            Hud.Texture.GetTexture(idtexture).Draw(x, y, width, height, 1f);
            Hud.Texture.DebuffFrameTexture.Draw(x, y, width, height, 1f);
        }
       
        public void PaintTopInGame(ClipState clipState)
        {
            if (clipState != ClipState.BeforeClip) return;
            if (!Hud.Game.IsInGame) return;
            if(OnlyGR && !Hud.Game.Me.InGreaterRift) return;
   
            var players = Hud.Game.Players.Where(p => p.HasValidActor && p.Powers.UsedSkills.Any(s => s.SnoPower.Sno == 108506 /* && s.Rune == 4 */ )).OrderBy(p => p.PortraitIndex);
            if (players.Count() == 0) return;
 
            var y =  Hud.Window.Size.Height * OffsetY ;
 
            foreach(var player in players)
            {  
                var x =  Hud.Window.Size.Width * OffsetX;
           
              /*  if (player.Powers.GetBuff(67616) != null) // Soul Harvest
                {
                    DrawIcon(x,y,SizeIconWidth,SizeIconHeight,2196086897,player.Powers.GetBuff(67616).IconCounts[0],player.Powers.GetBuff(67616).TimeLeftSeconds[0], player.Powers.GetBuff(67616).TimeLeftSeconds[0] );
                }
                else DrawIconNoBuff(x,y,SizeIconWidth,SizeIconHeight,2196086897);
                x += SizeIconWidth; */ 
               
                if (player.Powers.GetBuff(108506) != null) // Spirit Barrage
                {
                    var n = Hud.Game.Actors.Where(a => a.SnoActor.Sno == ActorSnoEnum._wd_spiritbarragerune_aoe_ghostmodel && (a.SummonerAcdDynamicId == player.SummonerId)).Count();
                    DrawIcon(x,y,SizeIconWidth,SizeIconHeight,1117784160,n,player.Powers.GetBuff(108506).TimeLeftSeconds[3] - 10 , player.Powers.GetBuff(108506).TimeElapsedSeconds[3]);
                }
                else DrawIconNoBuff(x,y,SizeIconWidth,SizeIconHeight,1117784160);
                x +=  SizeIconWidth;   
                   
                  if (player.Powers.GetBuff(208594) != null) // Gruesome Feast
                {              
                    DrawIcon(x,y,SizeIconWidth,SizeIconHeight,1591242582,player.Powers.GetBuff(208594).IconCounts[1],player.Powers.GetBuff(208594).TimeLeftSeconds[1], player.Powers.GetBuff(208594).TimeLeftSeconds[1] ); 
                }
                else DrawIconNoBuff(x,y,SizeIconWidth,SizeIconHeight,1591242582);
                x +=  SizeIconWidth;       
 
             /*   if (ShowGlobes)
                {
                    var n = Hud.Game.Actors.Where(a => a.SnoActor.Kind == ActorKind.HealthGlobe).Count();
                    if (n > 0)
                    {
                        layout = FontWhite.GetTextLayout(n.ToString());
                        BrushRed.DrawEllipse(x + SizeIconWidth / 2 , y + SizeIconHeight / 2 , layout.Metrics.Width + 1, layout.Metrics.Width + 1);
                        FontWhite.DrawText(layout,x + (SizeIconWidth - layout.Metrics.Width) / 2 , y + (SizeIconHeight - layout.Metrics.Height) / 2 );
                    }                                              
                } */
               
                x =  Hud.Window.Size.Width * OffsetX;   y =  y + SizeIconHeight + 2;
               
                if (ShowCoe && (player.Powers.GetBuff(430674) != null) )
                {              
                    var buff = player.Powers.GetBuff(430674);
                    var j = Lindex.Count;   var activo = -1; var best = -1;  double MaxBonus = -1;  bool unico = false;
                    for(var k = j - 1; k > -1 ; k--)
                    {
                        var index = Lindex[k];
                        if (buff.IconCounts[index] > 0) {   activo = index;  }
                       
                        var bonus = player.Offense.ElementalDamageBonus[IndexToBonus[index]];
                        if (bonus > MaxBonus)
                        {
                            MaxBonus = bonus;
                            best = index;
                            unico = true;
                        }  
                        else if (bonus == MaxBonus) unico = false;             
                    }              
                    if ((activo != -1) && (best != -1) )
                    {                      
                        for (var l = 0; l < j; l++)
                        {
                            if (Lindex[j - 1] != best)
                            {
                                Lindex.Insert(0,Lindex[j - 1]);
                                Lindex.RemoveAt(j);
                            }
                            else  {   break;  }
                        }
                       
                        foreach(var index in Lindex)
                        {              
                            Hud.Texture.GetTexture(buff.SnoPower.Icons[index].TextureId).Draw(x, y, SizeIconWidth, SizeIconHeight, 1f);
                            TextureFrame.Draw(x, y, SizeIconWidth, SizeIconHeight, 1f);
 
                            DrawTimeLeftClock(new RectangleF(x, y , SizeIconWidth, SizeIconHeight), buff.TimeElapsedSeconds[index], buff.TimeLeftSeconds[index]);              
                           
                            double s = 0;                      
                            if (unico)
                            {
                                if (index == activo)
                                {
                                    s = buff.TimeLeftSeconds[index];
                                    if (index == best) { FontDefault = FontGreen; BrushDefault = BrushGreen; }
                                    else { FontDefault = FontGray; }
                                }
                                else
                                {          
                                    if (index == best)
                                    {
                                        s = (j - Lindex.IndexOf(activo) - 1) * 4 - buff.TimeElapsedSeconds[activo] ;           
                                        if (  s >  ((j - 1) * 2) ) { FontDefault = FontOrange;  BrushDefault = BrushOrange; }
                                        else { FontDefault = FontYellow; BrushDefault = BrushYellow; }
                                    }
                                }
                            }
                            else
                            {
                                if (player.Offense.ElementalDamageBonus[IndexToBonus[index]] == player.Offense.HighestElementalDamageBonus)
                                {
                                    layout = FontBlue.GetTextLayout( (player.Offense.HighestElementalDamageBonus * 100).ToString() );
                                    FontBlue.DrawText(layout, x + SizeIconWidth - (float)Math.Ceiling(layout.Metrics.Width) - 3, y + SizeIconHeight - (float)Math.Ceiling(layout.Metrics.Height) - 2);
                                }
                                s = buff.TimeLeftSeconds[index];
                                BrushDefault = BrushBlue;   FontDefault = FontWhite;
                            }
 
                            if (s > 0)
                            {
                                layout = FontDefault.GetTextLayout(s.ToString( (s < 1)? "F1" : "F0") );
                                FontDefault.DrawText(layout, x + ((SizeIconWidth - (float)Math.Ceiling(layout.Metrics.Width))/2.0f), y + ((SizeIconHeight - (float)Math.Ceiling(layout.Metrics.Height))/2.0f));
                            }  
                            x += SizeIconWidth;                    
                        }
                        BrushBlack.DrawRectangle(x , y - 2, - SizeIconWidth * j , 2);
                        BrushDefault.DrawRectangle(x  , y - 2, (float) ( (SizeIconWidth * ( (j - Lindex.IndexOf(activo)) * 4 - buff.TimeElapsedSeconds[activo] )) / -4) , 2);
                        y =  y + SizeIconHeight;
                    }
                }
                y =  y + SizeIconHeight / 2;
            }
        }
    }
}