context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using LeagueSharp;
  using LeagueSharp.Common;
  using SharpDX;
  using SebbyLib;
  
  using EloBuddy; 
  using LeagueSharp.Common; 
  namespace OneKeyToWin_AIO_Sebby.Champions
  {
      class Jinx : Base
      {
          public double lag = 0, WCastTime = 0, QCastTime = 0, DragonTime = 0, grabTime = 0;
          public float DragonDmg = 0;
  
          public Jinx()
          {
              Q = new Spell(SpellSlot.Q);
              W = new Spell(SpellSlot.W, 1500f);
              E = new Spell(SpellSlot.E, 920f);
              R = new Spell(SpellSlot.R, 3000f);
  
              W.SetSkillshot(0.6f, 60f, 3300f, true, SkillshotType.SkillshotLine);
              E.SetSkillshot(1f, 50f, 1750f, false, SkillshotType.SkillshotCircle);
              R.SetSkillshot(0.7f, 140f, 1500f, false, SkillshotType.SkillshotLine);
  
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("noti", "Show notification", true).SetValue(false));
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("semi", "Semi-manual R target", true).SetValue(false));
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("qRange", "Q range", true).SetValue(false));
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("wRange", "W range", true).SetValue(false));
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("eRange", "E range", true).SetValue(false));
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("rRange", "R range", true).SetValue(false));
              Config.SubMenu(Player.ChampionName).SubMenu("Draw").AddItem(new MenuItem("onlyRdy", "Draw only ready spells", true).SetValue(true));
  
              Config.SubMenu(Player.ChampionName).SubMenu("Q Config").AddItem(new MenuItem("autoQ", "Auto Q", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("Q Config").AddItem(new MenuItem("Qharras", "Harass Q", true).SetValue(true));
  
              Config.SubMenu(Player.ChampionName).SubMenu("W Config").AddItem(new MenuItem("autoW", "Auto W", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("W Config").AddItem(new MenuItem("Wharras", "Harass W", true).SetValue(true));
  
              Config.SubMenu(Player.ChampionName).SubMenu("E Config").AddItem(new MenuItem("autoE", "Auto E on CC", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("E Config").AddItem(new MenuItem("comboE", "Auto E in Combo BETA", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("E Config").AddItem(new MenuItem("AGC", "AntiGapcloserE", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("E Config").AddItem(new MenuItem("opsE", "OnProcessSpellCastE", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("E Config").AddItem(new MenuItem("telE", "Auto E teleport", true).SetValue(true));
  
              Config.SubMenu(Player.ChampionName).SubMenu("R Config").AddItem(new MenuItem("autoR", "Auto R", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("R Config").SubMenu("R Jungle stealer").AddItem(new MenuItem("Rjungle", "R Jungle stealer", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("R Config").SubMenu("R Jungle stealer").AddItem(new MenuItem("Rdragon", "Dragon", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("R Config").SubMenu("R Jungle stealer").AddItem(new MenuItem("Rbaron", "Baron", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("R Config").AddItem(new MenuItem("useR", "OneKeyToCast R", true).SetValue(new KeyBind("T".ToCharArray()[0], KeyBindType.Press))); //32 == space
              Config.SubMenu(Player.ChampionName).SubMenu("R Config").AddItem(new MenuItem("Rturrent", "Don't R under turret", true).SetValue(true));
  
              Config.SubMenu(Player.ChampionName).SubMenu("Farm").AddItem(new MenuItem("farmQout", "Q farm out range AA", true).SetValue(true));
              Config.SubMenu(Player.ChampionName).SubMenu("Farm").AddItem(new MenuItem("farmQ", "Q LaneClear Q", true).SetValue(true));
  
              Game.OnUpdate += Game_OnUpdate;
              Orbwalking.BeforeAttack += BeforeAttack;
              Obj_AI_Base.OnProcessSpellCast += Obj_AI_Base_OnProcessSpellCast;
              AntiGapcloser.OnEnemyGapcloser += AntiGapcloser_OnEnemyGapcloser;
              Drawing.OnDraw += Drawing_OnDraw;
          }
  
          private void BeforeAttack(Orbwalking.BeforeAttackEventArgs args)
          {
              if (!Q.IsReady() || !Config.Item("autoQ", true).GetValue<bool>() || !FishBoneActive)
                  return;
  
              var t = args.Target as AIHeroClient;
  
              if (t != null)
              {
                  var realDistance = GetRealDistance(t) - 50;
                  if (Program.Combo && (realDistance < GetRealPowPowRange(t) || (Player.Mana < RMANA + 20 && Player.GetAutoAttackDamage(t) * 3 < t.Health)))
                      Q.Cast();
                  else if (Program.Harass && Config.Item("Qharras", true).GetValue<bool>() && (realDistance > bonusRange() || realDistance < GetRealPowPowRange(t) || Player.Mana < RMANA + EMANA + WMANA + WMANA))
                      Q.Cast();
              }
  
              var minion = args.Target as Obj_AI_Minion;
              if (Program.Farm && minion != null)
              {
                  var realDistance = GetRealDistance(minion);
  
                  if(realDistance < GetRealPowPowRange(minion) || Player.ManaPercent < Config.Item("Mana", true).GetValue<Slider>().Value)
                  {
                      Q.Cast();
                      return;
                  }
                  else if(HeroManager.Enemies.Any( tar => tar.IsValidTarget(1000) && args.Target.Position.Distance(Prediction.GetPrediction(tar,0.25f).CastPosition) < 200))
                  {
                      Q.Cast();
                      return;
                  }
              }
  
          }
  
          private void AntiGapcloser_OnEnemyGapcloser(ActiveGapcloser gapcloser)
          {
              if (Config.Item("AGC", true).GetValue<bool>() && E.IsReady() && Player.Mana > RMANA + EMANA)
              {
                  var Target = gapcloser.Sender;
                  if (Target.IsValidTarget(E.Range))
                      E.Cast(gapcloser.End);
              }
          }
  
          private void Obj_AI_Base_OnProcessSpellCast(Obj_AI_Base unit, GameObjectProcessSpellCastEventArgs args)
          {
              if (unit.IsMinion)
                  return;
  
              if (unit.IsMe)
              {
                  if (args.SData.Name == "JinxWMissile")
                      WCastTime = Game.Time;
              }
              if (E.IsReady())
              {
                  if (unit.IsEnemy && Config.Item("opsE", true).GetValue<bool>() &&  unit.IsValidTarget(E.Range) && ShouldUseE(args.SData.Name))
                  {
                      E.Cast(unit.ServerPosition, true);
                  }
                  if (unit.IsAlly && args.SData.Name == "RocketGrab" && Player.Distance(unit.Position) < E.Range)
                  {
                      grabTime = Game.Time;
                  }
              }
  
          }
  
          private void Game_OnUpdate(EventArgs args)
          {
              if (R.IsReady())
              {
                  if (Config.Item("useR", true).GetValue<KeyBind>().Active)
                  {
                      var t = TargetSelector.GetTarget(R.Range, TargetSelector.DamageType.Physical);
                      if (t.IsValidTarget())
                          R.Cast(t);
                  }
                  if (Config.Item("Rjungle", true).GetValue<bool>())
                  {
                      KsJungle();
                  }
              }
  
              if (Program.LagFree(0))
              {
                  SetMana();
              }
  
              if (E.IsReady())
                  LogicE();
  
              if (Program.LagFree(2) && Q.IsReady() && Config.Item("autoQ", true).GetValue<bool>())
                  LogicQ();
  
              if (Program.LagFree(3) && W.IsReady() && !ObjectManager.Player.Spellbook.IsAutoAttacking && Config.Item("autoW", true).GetValue<bool>())
                  LogicW();
  
              if (Program.LagFree(4) && R.IsReady())
                  LogicR();
          }
  
          private void LogicQ()
          {
              if (Program.Farm && !FishBoneActive && !ObjectManager.Player.Spellbook.IsAutoAttacking && Orbwalker.GetTarget() == null && Orbwalking.CanAttack() && Config.Item("farmQout", true).GetValue<bool>() && Player.Mana > RMANA + WMANA + EMANA + 10)
              {
                  foreach (var minion in Cache.GetMinions(Player.Position, bonusRange() + 30).Where(
                  minion => !Orbwalking.InAutoAttackRange(minion) && GetRealPowPowRange(minion) < GetRealDistance(minion) && bonusRange() < GetRealDistance(minion)))
                  {
                      var hpPred = SebbyLib.HealthPrediction.GetHealthPrediction(minion, 400, 70);
                      if (hpPred < Player.GetAutoAttackDamage(minion) * 1.1 && hpPred > 5)
                      {
                          Orbwalker.ForceTarget(minion);
                          Q.Cast();
                          return;
                      }
                  }
              }
  
              var t = TargetSelector.GetTarget(bonusRange() + 60, TargetSelector.DamageType.Physical);
              if (t.IsValidTarget())
              {
                  if (!FishBoneActive && (!Orbwalking.InAutoAttackRange(t) || t.CountEnemiesInRange(250) > 2) && Orbwalker.GetTarget() == null)
                  {
                      var distance = GetRealDistance(t);
                      if (Program.Combo && (Player.Mana > RMANA + WMANA + 10 || Player.GetAutoAttackDamage(t) * 3 > t.Health))
                          Q.Cast();
                      else if (Program.Harass && !ObjectManager.Player.Spellbook.IsAutoAttacking && Orbwalking.CanAttack() && Config.Item("Qharras", true).GetValue<bool>() && !ObjectManager.Player.UnderTurret(true) && Player.Mana > RMANA + WMANA + EMANA + 20 && distance < bonusRange() + t.BoundingRadius + Player.BoundingRadius)
                          Q.Cast();
                  }
              }
              else if (!FishBoneActive && Program.Combo && Player.Mana > RMANA + WMANA + 20 && Player.CountEnemiesInRange(2000) > 0)
                  Q.Cast();
              else if (FishBoneActive && Program.Combo && Player.Mana < RMANA + WMANA + 20)
                  Q.Cast();
              else if (FishBoneActive && Program.Combo && Player.CountEnemiesInRange(2000) == 0)
                  Q.Cast();
              else if (FishBoneActive && Program.Farm )
              {
                  Q.Cast();
              }
          }
  
          private void LogicW()
          {
              var t = TargetSelector.GetTarget(W.Range, TargetSelector.DamageType.Physical);
              if (t.IsValidTarget())
              {
   
                  foreach (var enemy in HeroManager.Enemies.Where(enemy => enemy.IsValidTarget(W.Range) && enemy.Distance(Player) > bonusRange()))
                  {
                      var comboDmg = OktwCommon.GetKsDamage(enemy, W);
                      if (R.IsReady() && Player.Mana > RMANA + WMANA + 20)
                      {
                          comboDmg += R.GetDamage(enemy, 1);
                      }
                      if (comboDmg > enemy.Health && OktwCommon.ValidUlt(enemy))
                      {
                          Program.CastSpell(W, enemy);
                          return;
                      }
                  }
  
                  if (Player.CountEnemiesInRange(bonusRange()) == 0)
                  {
                      if (Program.Combo && Player.Mana > RMANA + WMANA + 10)
                      {
                          foreach (var enemy in HeroManager.Enemies.Where(enemy => enemy.IsValidTarget(W.Range) && GetRealDistance(enemy) > bonusRange() ).OrderBy(enemy => enemy.Health))
                              Program.CastSpell(W, enemy);
                      }
                      else if (Program.Harass && Player.Mana > RMANA + EMANA + WMANA + WMANA + 40 && OktwCommon.CanHarras() && Config.Item("Wharras", true).GetValue<bool>())
                      {
                          foreach (var enemy in HeroManager.Enemies.Where(enemy => enemy.IsValidTarget(W.Range) && Config.Item("Harass" + enemy.ChampionName).GetValue<bool>()))
                              Program.CastSpell(W, enemy);
                      }
                  }
                  if (!Program.None && Player.Mana > RMANA + WMANA && Player.CountEnemiesInRange(GetRealPowPowRange(t)) == 0)
                  {
                      foreach (var enemy in HeroManager.Enemies.Where(enemy => enemy.IsValidTarget(W.Range) && !OktwCommon.CanMove(enemy)))
                          W.Cast(enemy, true);
                  }
              }
          }
  
          private void LogicE()
          {
              if (Player.Mana > RMANA + EMANA && Config.Item("autoE", true).GetValue<bool>() && Game.Time - grabTime > 1)
              {
                  foreach (var enemy in HeroManager.Enemies.Where(enemy => enemy.IsValidTarget(E.Range + 50) && !OktwCommon.CanMove(enemy)))
                  {
                      E.Cast(enemy);
                      return;
                  }
                  if (!Program.LagFree(1))
                      return;
  
                  if (Config.Item("telE", true).GetValue<bool>())
                  {
                      var trapPos = OktwCommon.GetTrapPos(E.Range);
                      if(!trapPos.IsZero)
                          E.Cast(trapPos);
                  }
  
                  if (Program.Combo && Player.IsMoving && Config.Item("comboE", true).GetValue<bool>() && Player.Mana > RMANA + EMANA + WMANA)
                  {
                      var t = TargetSelector.GetTarget(E.Range, TargetSelector.DamageType.Physical);
                      if (t.IsValidTarget(E.Range) && E.GetPrediction(t).CastPosition.Distance(t.Position) > 250 )
                      {
                          E.CastIfWillHit(t, 2);
                          if (t.HasBuffOfType(BuffType.Slow))
                          {
                              Program.CastSpell(E, t);
                          }
                          if (OktwCommon.IsMovingInSameDirection(Player, t))
                              Program.CastSpell(E, t);
                      }
                  }
              }
          }
  
          private void LogicR()
          {
              if (Player.UnderTurret(true) && Config.Item("Rturrent", true).GetValue<bool>())
                  return;
              if (Game.Time - WCastTime > 0.9 && Config.Item("autoR", true).GetValue<bool>())
              {
                  foreach (var target in HeroManager.Enemies.Where(target => target.IsValidTarget(R.Range) && OktwCommon.ValidUlt(target)))
                  {
                      var predictedHealth = target.Health - OktwCommon.GetIncomingDamage(target);
                      var Rdmg = R.GetDamage(target, 1);
  
                      if (Rdmg > predictedHealth && !OktwCommon.IsSpellHeroCollision(target, R) && GetRealDistance(target) > bonusRange() + 200)
                      {
                          if ( GetRealDistance(target) > bonusRange() + 300 + target.BoundingRadius && target.CountAlliesInRange(500) == 0 && Player.CountEnemiesInRange(400) == 0)
                          {
                              Program.CastSpell(R, target);
                          }
  
gt:                         else if (target.CountEnemiesInRange(200) > 2)