context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using LeagueSharp;
  using LeagueSharp.Common;
  using Color = System.Drawing.Color;
  using UnderratedAIO.Helpers;
  using Environment = UnderratedAIO.Helpers.Environment;
  
  
  using EloBuddy; 
   using LeagueSharp.Common; 
   namespace UnderratedAIO.Champions
  {
      internal class Poppy
      {
          public static Menu config;
          public static Orbwalking.Orbwalker orbwalker;
          public static readonly AIHeroClient player = ObjectManager.Player;
          public static Spell Q, W, E, R;
          public static double[] eSecond = new double[5] { 75, 125, 175, 225, 275 };
          public static List<string> NotDash = new List<string>() { "Udyr", "Malphite", };
          public static AutoLeveler autoLeveler;
  
          public Poppy()
          {
              Initpoppy();
              InitMenu();
              //Chat.Print("<font color='#9933FF'>Soresu </font><font color='#FFFFFF'>- Poppy</font>");
              Game.OnUpdate += Game_OnGameUpdate;
              Drawing.OnDraw += Game_OnDraw;
              AntiGapcloser.OnEnemyGapcloser += OnEnemyGapcloser;
              Interrupter2.OnInterruptableTarget += OnInterruptableTarget;
              Jungle.setSmiteSlot();
              HpBarDamageIndicator.DamageToUnit = ComboDamage;
          }
  
          private void OnInterruptableTarget(AIHeroClient sender, Interrupter2.InterruptableTargetEventArgs args)
          {
              if (config.Item("useEint", true).GetValue<bool>() && E.IsReady() && E.CanCast(sender))
              {
                  E.CastOnUnit(sender);
              }
          }
  
  
          private static void Game_OnGameUpdate(EventArgs args)
          {
              if (FpsBalancer.CheckCounter())
              {
                  return;
              }
              AIHeroClient targetf = DrawHelper.GetBetterTarget(1000, TargetSelector.DamageType.Magical);
              if (config.Item("useeflashforced", true).GetValue<KeyBind>().Active)
              {
                  if (targetf == null)
                  {
                      EloBuddy.Player.IssueOrder(GameObjectOrder.MoveTo, Game.CursorPos);
                  }
                  else
                  {
                      var bestpos = CombatHelper.bestVectorToPoppyFlash2(targetf);
                      bool hasFlash = player.Spellbook.CanUseSpell(player.GetSpellSlot("SummonerFlash")) ==
                                      SpellState.Ready;
                      if (E.IsReady() && hasFlash && !CheckWalls(player, targetf) && bestpos.IsValid())
                      {
                          player.Spellbook.CastSpell(player.GetSpellSlot("SummonerFlash"), bestpos);
                          EloBuddy.Player.IssueOrder(GameObjectOrder.MoveTo, Game.CursorPos);
                      }
                      else if (!hasFlash)
                      {
                          Combo();
                          Orbwalking.Orbwalk(targetf, Game.CursorPos, 90, 90);
                      }
                  }
              }
              switch (orbwalker.ActiveMode)
              {
                  case Orbwalking.OrbwalkingMode.Combo:
                      Combo();
                      KsPassive();
                      break;
                  case Orbwalking.OrbwalkingMode.Mixed:
                      Harass();
                      KsPassive();
                      break;
                  case Orbwalking.OrbwalkingMode.LaneClear:
                      Clear();
                      KsPassive();
                      break;
                  case Orbwalking.OrbwalkingMode.LastHit:
                      KsPassive();
                      break;
                  default:
                      break;
              }
              if (!player.IsDead)
              {
                  foreach (var dashingEnemy in
                      HeroManager.Enemies.Where(
                          e =>
                              e.IsValidTarget() && e.Distance(player) < 1600 &&
                              config.Item("useAutoW" + e.BaseSkinName, true).GetValue<Slider>().Value > 0)
                          .OrderByDescending(e => config.Item("useAutoW" + e.BaseSkinName, true).GetValue<Slider>().Value)
                          .ThenBy(e => e.Distance(player)))
                  {
                      var nextpos = Prediction.GetPrediction(dashingEnemy, 0.1f).UnitPosition;
                      if (dashingEnemy.IsDashing() && !dashingEnemy.HasBuffOfType(BuffType.SpellShield) &&
                          !dashingEnemy.HasBuff("poppyepushenemy") && dashingEnemy.Distance(player) <= W.Range &&
                          (nextpos.Distance(player.Position) > W.Range || (player.Distance(dashingEnemy) < W.Range - 100)) &&
                          dashingEnemy.IsTargetable && !NotDash.Contains(dashingEnemy.ChampionName))
                      {
                          W.Cast();
                      }
                      if (
                          CombatHelper.DashDatas.Any(
                              d => d.ChampionName == dashingEnemy.ChampionName && d.IsReady(dashingEnemy)))
                      {
                          break;
                      }
                  }
              }
          }
  
          private static void KsPassive()
          {
              var target =
                  HeroManager.Enemies.Where(
                      e =>
                          e.IsInAttackRange() &&
                          HealthPrediction.GetHealthPrediction(e, 500) < player.GetAutoAttackDamage(e, true) &&
                          e.IsValidTarget()).OrderByDescending(e => TargetSelector.GetPriority(e)).FirstOrDefault();
              if (target != null)
              {
                  orbwalker.ForceTarget(target);
              }
          }
  
          private static void Combo()
          {
              AIHeroClient target = DrawHelper.GetBetterTarget(1000, TargetSelector.DamageType.Magical);
              if (target == null)
              {
                  return;
              }
              var cmbdmg = ComboDamage(target);
              if (config.Item("useItems").GetValue<bool>())
              {
                  ItemHandler.UseItems(target, config, ComboDamage(target));
              }
              bool hasFlash = player.Spellbook.CanUseSpell(player.GetSpellSlot("SummonerFlash")) == SpellState.Ready;
              if (config.Item("usee", true).GetValue<bool>() && E.IsReady())
              {
                  if (config.Item("useewall", true).GetValue<bool>())
                  {
                      var bestpos = CombatHelper.bestVectorToPoppyFlash2(target);
                      float damage =
                          (float)
                              (ComboDamage(target) +
                               Damage.CalcDamage(
                                   player, target, Damage.DamageType.Magical,
                                   (eSecond[E.Level - 1] + 0.8f * player.FlatMagicDamageMod)) +
                               (player.GetAutoAttackDamage(target) * 4));
                      float damageno = (float) (ComboDamage(target) + (player.GetAutoAttackDamage(target) * 4));
                      if (config.Item("useeflash", true).GetValue<bool>() && hasFlash && !CheckWalls(player, target) &&
                          damage > target.Health && target.Health > damageno &&
                          CombatHelper.bestVectorToPoppyFlash(target).IsValid())
                      {
                          player.Spellbook.CastSpell(player.GetSpellSlot("SummonerFlash"), bestpos);
                          LeagueSharp.Common.Utility.DelayAction.Add(100, () => E.CastOnUnit(target));
                      }
                      if (E.CanCast(target) &&
                          (CheckWalls(player, target) ||
                           target.Health < E.GetDamage(target) + player.GetAutoAttackDamage(target, true)))
                      {
                          E.CastOnUnit(target);
                      }
                      if (E.CanCast(target) && Q.IsReady() && Q.Instance.SData.Mana + E.Instance.SData.Mana > player.Mana &&
                          target.Health <
                          E.GetDamage(target) + Q.GetDamage(target) + player.GetAutoAttackDamage(target, true))
                      {
                          E.CastOnUnit(target);
                      }
                  }
                  else
                  {
                      if (E.CanCast(target))
                      {
                          E.CastOnUnit(target);
                      }
                  }
              }
              if (config.Item("useq", true).GetValue<bool>() && Q.IsReady() && Q.CanCast(target) &&
                  Orbwalking.CanMove(100) && target.Distance(player) < Q.Range &&
                  (player.Distance(target) > Orbwalking.GetRealAutoAttackRange(target) || !Orbwalking.CanAttack()))
              {
                  Q.CastIfHitchanceEquals(target, HitChance.High);
              }
  
              bool hasIgnite = player.Spellbook.CanUseSpell(player.GetSpellSlot("SummonerDot")) == SpellState.Ready &&
                               config.Item("useIgnite").GetValue<bool>();
              var ignitedmg = hasIgnite ? (float) player.GetSummonerSpellDamage(target, Damage.SummonerSpell.Ignite) : 0f;
              if (ignitedmg > target.Health && hasIgnite && !E.CanCast(target) && !Q.CanCast(target) &&
                  (player.Distance(target) > Q.Range || player.HealthPercent < 30))
              {
                  player.Spellbook.CastSpell(player.GetSpellSlot("SummonerDot"), target);
              }
              if (config.Item("userindanger", true).GetValue<bool>() && R.IsReady() &&
                  ((player.CountEnemiesInRange(800) >= 2 &&
                    player.CountEnemiesInRange(800) > player.CountAlliesInRange(1500) + 1 && player.HealthPercent < 60) ||
                   (player.Health < target.Health && player.HealthPercent < 40 &&
                    player.CountAlliesInRange(1000) + 1 < player.CountEnemiesInRange(1000))))
              {
                  var targ =
                      HeroManager.Enemies.Where(
                          e =>
                              e.IsValidTarget() && R.CanCast(e) &&
                              (player.HealthPercent < 60 || e.CountEnemiesInRange(300) > 2) &&
                              HeroManager.Enemies.Count(h => h.Distance(e) < 400 && e.HealthPercent < 35) == 0 &&
                              R.GetPrediction(e).CastPosition.Distance(player.Position) < R.ChargedMaxRange)
                          .OrderByDescending(e => R.GetPrediction(e).CastPosition.CountEnemiesInRange(400))
                          .ThenByDescending(e => e.Distance(target))
                          .FirstOrDefault();
                  if (R.Range > 1300 && targ == null)
                  {
                      targ =
                          HeroManager.Enemies.Where(
                              e =>
                                  e.IsValidTarget() && R.CanCast(e) &&
                                  R.GetPrediction(e).CastPosition.Distance(player.Position) < R.ChargedMaxRange)
                              .OrderByDescending(e => R.GetPrediction(e).CastPosition.CountEnemiesInRange(400))
                              .ThenByDescending(e => e.Distance(target))
                              .FirstOrDefault();
                  }
                  if (!R.IsCharging && targ != null)
                  {
                      R.StartCharging();
                  }
                  if (R.IsCharging && targ != null && R.CanCast(targ) && R.Range > 1000 && R.Range > targ.Distance(player))
                  {
                      R.CastIfHitchanceEquals(targ, HitChance.Medium);
                  }
                  if (R.IsCharging && targ != null && R.Range < 1000)
                  {
                      return;
                  }
              }
              if (config.Item("user", true).GetValue<bool>() && R.IsReady() && player.Distance(target) < 1400 &&
                  !target.UnderTurret(true))
              {
                  var cond = ((Rdmg(target) < target.Health && ignitedmg + Rdmg(target) > target.Health &&
                               player.Distance(target) < 600) ||
                              (target.Distance(player) > E.Range && Rdmg(target) > target.Health &&
                               target.Distance(player) < 1100));
                  if (!R.IsCharging && cond && !Q.IsReady() && player.HealthPercent < 40)
                  {
                      R.StartCharging();
                      if (hasIgnite && cmbdmg > target.Health && cmbdmg - Rdmg(target) < target.Health)
                      {
                          if (!target.HasBuff("summonerdot"))
                          {
                              player.Spellbook.CastSpell(player.GetSpellSlot("SummonerDot"), target);
                          }
                      }
                  }
                  if (R.IsCharging && R.CanCast(target) && R.Range > target.Distance(player) && cond)
                  {
                      R.CastIfHitchanceEquals(target, HitChance.High);
                  }
              }
          }
  
          private static void Clear()
          {
              var mob = Jungle.GetNearest(player.Position);
              float perc = config.Item("minmana", true).GetValue<Slider>().Value / 100f;
              if (player.Mana < player.MaxMana * perc)
              {
                  return;
              }
              if (config.Item("useeLC", true).GetValue<bool>() && E.CanCast(mob) && CheckWalls(player, mob))
              {
                  E.CastOnUnit(mob);
              }
              MinionManager.FarmLocation bestPositionQ =
                  Q.GetLineFarmLocation(MinionManager.GetMinions(Q.Range, MinionTypes.All, MinionTeam.NotAlly));
              if (bestPositionQ.MinionsHit >= config.Item("qMinHit", true).GetValue<Slider>().Value &&
                  config.Item("useqLC", true).GetValue<bool>())
              {
                  Q.Cast(bestPositionQ.Position);
              }
          }
  
          private static void Harass()
          {
              AIHeroClient target = DrawHelper.GetBetterTarget(Q.Range, TargetSelector.DamageType.Magical);
              float perc = config.Item("minmanaH", true).GetValue<Slider>().Value / 100f;
              if (player.Mana < player.MaxMana * perc || target == null)
              {
                  return;
              }
              if (config.Item("useqH", true).GetValue<bool>() && Q.IsReady() && Q.CanCast(target) &&
                  Orbwalking.CanMove(100) && target.Distance(player) < Q.Range &&
                  (player.Distance(target) > Orbwalking.GetRealAutoAttackRange(target) || !Orbwalking.CanAttack()))
              {
                  Q.CastIfHitchanceEquals(target, HitChance.High);
              }
          }
  
          private static void Game_OnDraw(EventArgs args)
          {
              DrawHelper.DrawCircle(config.Item("drawqq", true).GetValue<Circle>(), Q.Range);
              DrawHelper.DrawCircle(config.Item("drawww", true).GetValue<Circle>(), W.Range);
              DrawHelper.DrawCircle(config.Item("drawee", true).GetValue<Circle>(), E.Range);
              DrawHelper.DrawCircle(config.Item("drawrr", true).GetValue<Circle>(), R.Range);
              HpBarDamageIndicator.Enabled = config.Item("drawcombo").GetValue<bool>();
          }
  
          private static void OnEnemyGapcloser(ActiveGapcloser gapcloser)
          {
              if (config.Item("useEgap", true).GetValue<bool>() && E.IsReady() && E.CanCast(gapcloser.Sender) &&
                  CheckWalls(player, gapcloser.Sender))
              {
                  E.CastOnUnit(gapcloser.Sender);
              }
          }
  
          public static bool CheckWalls(Obj_AI_Base player, Obj_AI_Base enemy)
          {
              var distance = player.Position.Distance(enemy.Position);
              for (int i = 1; i < 6; i++)
              {
                  if (player.Position.Extend(enemy.Position, distance + 60 * i).IsWall())
                  {
                      return true;
                  }
              }
              return false;
          }
  
          public static float ComboDamage(AIHeroClient hero)
          {
              double damage = 0;
              if (Q.IsReady())
              {
                  damage += Damage.GetSpellDamage(player, hero, SpellSlot.Q);
              }
              if (E.IsReady())
              {
                  damage += (float) Damage.GetSpellDamage(player, hero, SpellSlot.E);
              }
              if ((Items.HasItem(ItemHandler.Bft.Id) && Items.CanUseItem(ItemHandler.Bft.Id)) ||
                  (Items.HasItem(ItemHandler.Dfg.Id) && Items.CanUseItem(ItemHandler.Dfg.Id)))
              {
                  damage = (float) (damage * 1.2);
              }
              if (player.Spellbook.CanUseSpell(player.GetSpellSlot("summonerdot")) == SpellState.Ready &&
                  player.Distance(hero) < 500)
              {
                  damage += (float) player.GetSummonerSpellDamage(hero, Damage.SummonerSpell.Ignite);
              }
              if (R.IsReady() || R.IsCharging)
              {
                  damage += (float) Rdmg(hero);
              }
              damage += ItemHandler.GetItemsDamage(hero);
              return (float) damage;
          }
  
          public static double Rdmg(Obj_AI_Base target)
          {
              return Damage.CalcDamage(
                  player, target, Damage.DamageType.Physical,
                  (new double[] { 200, 300, 400 }[R.Level - 1] +
                   0.9f * (player.BaseAttackDamage + player.FlatPhysicalDamageMod)));
          }
  
          private static void Initpoppy()
          {
              Q = new Spell(SpellSlot.Q, 400);
              Q.SetSkillshot(0.55f, 90f, float.MaxValue, false, SkillshotType.SkillshotLine);
              W = new Spell(SpellSlot.W, 400);
              E = new Spell(SpellSlot.E, 500);
              R = new Spell(SpellSlot.R);
              R.SetSkillshot(0.5f, 90f, 1400, true, SkillshotType.SkillshotLine);
              R.SetCharged("PoppyR", "PoppyR", 425, 1400, 1.0f);
          }
  
          private static void InitMenu()
          {
              config = new Menu("Poppy", "Poppy", true);
              // Target Selector
  
gt:             Menu menuTS = new Menu("Selector", "tselect");