// ExtendedOculusPlugin (Original by Zy)
// Ground Decorators & Timers for Oculus Ring circles.
// In Party GR, shows the closest Oculus to the Trashkiller/Bosskiller and if he's inside Oculus.
// In Solo GR & Outside GR, shows additional decorator when you're standing inside Oculus.
 
using System.Linq;
using Turbo.Plugins.Default;
 
namespace Turbo.Plugins.User
{
    public class ExtendedOculusPlugin : BasePlugin, ICustomizer, IInGameWorldPainter
    {
    public WorldDecoratorCollection InsideMarkerDecorator { get; set; }
    public WorldDecoratorCollection OculusDecorator { get; set; }
    public WorldDecoratorCollection CloseOculusDecorator { get; set; }
    public WorldDecoratorCollection InsideOculusDecorator { get; set; }
 
    public float CircleRadius { get; set; }
    public float InsideRadius { get; set; }
    public bool EnableDpsMarker { get; set; }
    public bool EnableInsideMarker { get; set; }
 
        public ExtendedOculusPlugin()
        {
            Enabled = true;
        EnableDpsMarker = true; // Closest & Inside Decorators for Meta DPS in Party GR
        EnableInsideMarker = true;  // Additional Circle Decorator when you are in it
        }
 
        public void Customize()
        {
    // Disable Default OculusPlugin
    Hud.GetPlugin<OculusPlugin>().Enabled = false;
        }
 
        public override void Load(IController hud)
        {
        base.Load(hud);
 
        CircleRadius = 10.0f; // Change the radius of the circle decorator
        InsideRadius = 10.0f; // Change the radius of the additional "inside marker"
 
        InsideMarkerDecorator = new WorldDecoratorCollection(
                new GroundCircleDecorator(Hud)
                {
                    Brush = Hud.Render.CreateBrush(255, 0, 130, 0, -2, SharpDX.Direct2D1.DashStyle.Dash),
                    Radius = InsideRadius,
                }
                );
 
            OculusDecorator = new WorldDecoratorCollection(
                new GroundCircleDecorator(Hud)
                {
                    Brush = Hud.Render.CreateBrush(255, 255, 255, 0, 2),
                    Radius = CircleRadius,
                },
                new GroundLabelDecorator(Hud)
                {
                    CountDownFrom = 7,
                    TextFont = Hud.Render.CreateFont("tahoma", 11, 255, 96, 255, 96, true, false, 128, 0, 0, 0, true),
                },
                new GroundTimerDecorator(Hud)
                {
                    CountDownFrom = 7,
                    BackgroundBrushEmpty = Hud.Render.CreateBrush(128, 0, 0, 0, 0),
                    BackgroundBrushFill = Hud.Render.CreateBrush(200, 0, 192, 0, 0),
                    Radius = 30,
                }
                );
 
            CloseOculusDecorator = new WorldDecoratorCollection(
                new GroundCircleDecorator(Hud)
                {
                    Brush = Hud.Render.CreateBrush(255, 0, 100, 200, -2),
                    Radius = CircleRadius,
                },
                new GroundLabelDecorator(Hud)
                {
                    CountDownFrom = 7,
                    TextFont = Hud.Render.CreateFont("tahoma", 11, 255, 96, 255, 96, true, false, 128, 0, 0, 0, true),
                },
                new GroundTimerDecorator(Hud)
                {
                    CountDownFrom = 7,
                    BackgroundBrushEmpty = Hud.Render.CreateBrush(128, 0, 0, 0, 0),
                    BackgroundBrushFill = Hud.Render.CreateBrush(200, 0, 192, 0, 0),
                    Radius = 30,
                }
                );
 
            InsideOculusDecorator = new WorldDecoratorCollection(
                new GroundCircleDecorator(Hud)
                {
                    Brush = Hud.Render.CreateBrush(255, 220, 0, 0, -2),
                    Radius = CircleRadius,
                },
                new GroundLabelDecorator(Hud)
                {
                    CountDownFrom = 7,
                    TextFont = Hud.Render.CreateFont("tahoma", 11, 255, 96, 255, 96, true, false, 128, 0, 0, 0, true),
                },
                new GroundTimerDecorator(Hud)
                {
                    CountDownFrom = 7,
                    BackgroundBrushEmpty = Hud.Render.CreateBrush(128, 0, 0, 0, 0),
                    BackgroundBrushFill = Hud.Render.CreateBrush(200, 0, 192, 0, 0),
                    Radius = 30,
                }
                );
 
        }
 
        public void PaintWorld(WorldLayer layer)
        {
            if (Hud.Game.IsInTown) return;
 
            bool BossAlive = (Hud.Game.AliveMonsters.Count(m => m.SnoMonster.Priority == MonsterPriority.boss) > 0);
 
            IWorldCoordinate DpsPosition = Hud.Game.Players.First().FloorCoordinate;
            int DpsIngame = 0;
 
            foreach (var player in Hud.Game.Players)
            {
 
    if (DpsIngame == 0) {
 
        if (!BossAlive) {
                if (player.Offense.AreaDamageBonus >= 110)
                {
                    DpsPosition = player.FloorCoordinate;
                    DpsIngame++;
                }
                if (player.Powers.BuffIsActive(Hud.Sno.SnoPowers.TheBarber.Sno) && player.Offense.AreaDamageBonus < 110)
                {
                    DpsPosition = player.FloorCoordinate;
                    DpsIngame++;
                }
                }
 
        if (BossAlive) {
                if (player.Powers.BuffIsActive(Hud.Sno.SnoPowers.BaneOfTheStrickenPrimary.Sno))
                {
                    DpsPosition = player.FloorCoordinate;
                    DpsIngame++;
                }
                }
 
        }
    }
 
            float mindist = float.MaxValue;
        bool Inside = false;
 
            var actors = Hud.Game.Actors.Where(x => x.SnoActor.Sno == ActorSnoEnum._generic_proxy && x.GetAttributeValueAsInt(Hud.Sno.Attributes.Power_Buff_1_Visual_Effect_None, Hud.Sno.SnoPowers.OculusRing.Sno) == 1).OrderBy(d => d.CentralXyDistanceToMe);
 
        if (EnableInsideMarker && Hud.Game.Me.Powers.BuffIsActive(402461, 2)) { Inside = true; }
 
            if (actors.Count() > 0) // Null check
            {
                var closest = actors.First();
 
 
                foreach (var actor in actors)
                {
                    float dist = actor.FloorCoordinate.XYDistanceTo(DpsPosition);
                    if (dist < mindist) { closest = actor; mindist = dist; }
                }
 
 
                foreach (var actor in actors)
                {
 
 
        // In Party GR : Draw DPS closest and DPS inside decorators if there is a DPS identified.
 
                    if (Hud.Game.SpecialArea == SpecialArea.GreaterRift && EnableDpsMarker && Hud.Game.NumberOfPlayersInGame > 1)
                    {
            if (DpsIngame == 1) {
                        if (actor == closest)
                        {
                            if (mindist <= 13.3f)
                            { InsideOculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null); }
                            if (mindist > 13.3f && actors.Count() > 0)
                            { CloseOculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null); }
                        }
                        else
                        {
                OculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null);
            }
            }
 
            else
            {
            OculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null);
            if (Inside) { InsideMarkerDecorator.Paint(layer, actor, actor.FloorCoordinate, null); Inside = false; }
            }
 
                    }
 
        // In Party GR : Draw base decorators if EnableDpsMarker option disabled.
 
                    if (Hud.Game.SpecialArea == SpecialArea.GreaterRift && !EnableDpsMarker && Hud.Game.NumberOfPlayersInGame > 1)
                    {
            OculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null);
            if (Inside) { InsideMarkerDecorator.Paint(layer, actor, actor.FloorCoordinate, null); Inside = false; }
            }
 
        // In Solo GR : Draw base decorators.
 
                    if (Hud.Game.SpecialArea == SpecialArea.GreaterRift && Hud.Game.NumberOfPlayersInGame == 1)
                    {
            OculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null);
            if (Inside) { InsideMarkerDecorator.Paint(layer, actor, actor.FloorCoordinate, null); Inside = false; }
            }
 
        // Outside GR : Draw base decorators.
 
                    if (Hud.Game.SpecialArea != SpecialArea.GreaterRift)
                    {
            OculusDecorator.Paint(layer, actor, actor.FloorCoordinate, null);
            if (Inside) { InsideMarkerDecorator.Paint(layer, actor, actor.FloorCoordinate, null); Inside = false; }
            }
 
                }
            }
        }
    }
}