context: using System;
  using System.Collections.Generic;
  using System.Diagnostics.Eventing.Reader;
  using System.Drawing.Printing;
  using System.Linq;
  using LeagueSharp;
  using LeagueSharp.Common;
  using LeagueSharp.Common.Data;
  using ItemData = LeagueSharp.Common.Data.ItemData;
  using Color = System.Drawing.Color;
  using SharpDX;
  
  using EloBuddy; 
   using LeagueSharp.Common; 
   namespace JustOlaf___Reborn
  {
      internal class OlafAxe
      {
          public GameObject Object { get; set; }
          public float NetworkId { get; set; }
          public Vector3 AxePos { get; set; }
          public double ExpireTime { get; set; }
      }
  
      internal class Program
      {
  
          public const string ChampName = "Olaf";
          public const string Menuname = "JustOlaf";
          private static readonly OlafAxe olafAxe = new OlafAxe();
          public static int LastTickTime;
          public static Menu Config;
          public static Orbwalking.Orbwalker Orbwalker;
          private static GameObject _axeObj;
          public static Spell Q, Q2, W, E, R;
          private static SpellSlot _smiteSlot = SpellSlot.Unknown;
          private static Spell _smite;
          //Credits to Kurisu
          private static readonly int[] SmitePurple = { 3713, 3726, 3725, 3726, 3723 };
          private static readonly int[] SmiteGrey = { 3711, 3722, 3721, 3720, 3719 };
          private static readonly int[] SmiteRed = { 3715, 3718, 3717, 3716, 3714 };
          private static readonly int[] SmiteBlue = { 3706, 3710, 3709, 3708, 3707 };
          private static SpellSlot Ignite;
          public static int[] abilitySequence;
          public static int qOff = 0, wOff = 0, eOff = 0, rOff = 0;
          private static readonly AIHeroClient player = ObjectManager.Player;
  
          public static void Main()
          {
              Game_OnGameLoad();
          }
  
          static void Game_OnGameLoad()
          {
              if (player.ChampionName != ChampName)
                  return;
  
              Notifications.AddNotification("JustOlaf Reborn Loaded - [V.1.0.0.0]", 8000);
  
              //Ability Information - Range - Variables.
              Q = new Spell(SpellSlot.Q, 1000);
              Q2 = new Spell(SpellSlot.Q, 550);
              W = new Spell(SpellSlot.W);
              E = new Spell(SpellSlot.E, 325);
              R = new Spell(SpellSlot.R);
  
              Q.SetSkillshot(0.25f, 75f, 1500f, false, SkillshotType.SkillshotLine);
              Q2.SetSkillshot(0.25f, 75f, 1600f, false, SkillshotType.SkillshotLine);
  
              SetSmiteSlot();
              
              abilitySequence = new int[] { 2, 1, 3, 3, 3, 4, 3, 1, 3, 1, 4, 1, 1, 2, 2, 4, 2, 2 };
  
              Config = new Menu(Menuname, Menuname, true);
              Config.AddSubMenu(new Menu("Orbwalking", "Orbwalking"));
  
              var targetSelectorMenu = new Menu("Target Selector", "Target Selector");
              TargetSelector.AddToMenu(targetSelectorMenu);
              Config.AddSubMenu(targetSelectorMenu);
  
              Orbwalker = new Orbwalking.Orbwalker(Config.SubMenu("Orbwalking"));
  
              //Combo
              Config.AddSubMenu(new Menu("Combo", "Combo"));
              Config.SubMenu("Combo").AddItem(new MenuItem("UseQ", "Use Q").SetValue(true));
              Config.SubMenu("Combo").AddItem(new MenuItem("UseW", "Use W").SetValue(true));
              Config.SubMenu("Combo").AddItem(new MenuItem("UseE", "Use E").SetValue(true));
              Config.SubMenu("Combo").AddItem(new MenuItem("UseR", "Use R").SetValue(true));
              Config.SubMenu("Combo").AddItem(new MenuItem("UseS", "Use Smite (Red/Blue)").SetValue(true));
              Config.SubMenu("Combo").AddItem(new MenuItem("Rene", "Min Enemies for R").SetValue(new Slider(2, 1, 5)));
             
              //Harass
              Config.AddSubMenu(new Menu("Harass", "Harass"));
              Config.SubMenu("Harass").AddItem(new MenuItem("hQ", "Use Q").SetValue(true));
              Config.SubMenu("Harass").AddItem(new MenuItem("hQ2","Use Q with short range").SetValue(true));
              Config.SubMenu("Harass").AddItem(new MenuItem("hQA", "Use Auto Q Harass").SetValue(true));
              Config.SubMenu("Harass").AddItem(new MenuItem("hW", "Use W").SetValue(false));
              Config.SubMenu("Harass").AddItem(new MenuItem("hE", "Use E").SetValue(true));
              Config.SubMenu("Harass")
                  .AddItem(new MenuItem("harassmana", "Mana Percentage").SetValue(new Slider(30, 0, 100)));
  
              //Item
              Config.AddSubMenu(new Menu("Item", "Item"));
              Config.SubMenu("Item").AddItem(new MenuItem("useGhostblade", "Use Youmuu's Ghostblade").SetValue(true));
              Config.SubMenu("Item").AddItem(new MenuItem("UseBOTRK", "Use Blade of the Ruined King").SetValue(true));
              Config.SubMenu("Item").AddItem(new MenuItem("eL", "  Enemy HP Percentage").SetValue(new Slider(80, 0, 100)));
              Config.SubMenu("Item").AddItem(new MenuItem("oL", "  Own HP Percentage").SetValue(new Slider(65, 0, 100)));
              Config.SubMenu("Item").AddItem(new MenuItem("UseBilge", "Use Bilgewater Cutlass").SetValue(true));
              Config.SubMenu("Item")
                  .AddItem(new MenuItem("HLe", "  Enemy HP Percentage").SetValue(new Slider(80, 0, 100)));
              Config.SubMenu("Item").AddItem(new MenuItem("UseIgnite", "Use Ignite").SetValue(true));
  
              //Laneclear
              Config.AddSubMenu(new Menu("Clear", "Clear"));
              Config.SubMenu("Clear").AddItem(new MenuItem("laneQ", "Use Q").SetValue(true));
              Config.SubMenu("Clear").AddItem(new MenuItem("fE", "Farm with E ( While pressing last hit )").SetValue(true));
              Config.SubMenu("Clear")
                  .AddItem(new MenuItem("femana", "Health Percentage").SetValue(new Slider(30, 0, 100)));
              Config.SubMenu("Clear").AddItem(new MenuItem("laneE", "Use E").SetValue(true));
              Config.SubMenu("Clear").AddItem(new MenuItem("laneW", "Use W").SetValue(true));
              Config.SubMenu("Clear")
                  .AddItem(new MenuItem("lanemana", "Mana Percentage").SetValue(new Slider(30, 0, 100)));
  
              //Draw
              Config.AddSubMenu(new Menu("Draw", "Draw"));
              Config.SubMenu("Draw").AddItem(new MenuItem("Draw_Disabled", "Disable All Spell Drawings").SetValue(false));
              Config.SubMenu("Draw").AddItem(new MenuItem("Qdraw", "Draw Q Range").SetValue(true));
              Config.SubMenu("Draw").AddItem(new MenuItem("Edraw", "Draw E Range").SetValue(true));
              Config.SubMenu("Draw").AddItem(new MenuItem("Rdraw", "Draw R Range").SetValue(true));
              Config.SubMenu("Draw").AddItem(new MenuItem("combodamage", "Damage on HPBar")).SetValue(true);
  
              //Misc
              Config.AddSubMenu(new Menu("Misc", "Misc"));
              Config.SubMenu("Misc").AddItem(new MenuItem("ksQ", "Killsteal with Q").SetValue(true));
              Config.SubMenu("Misc").AddItem(new MenuItem("ksE", "Killsteal with E").SetValue(true));
              Config.SubMenu("Misc").AddItem(new MenuItem("autolevel", "Auto Level Spells").SetValue(false));
  
              Config.AddToMainMenu();
              Drawing.OnDraw += OnDraw;
              Game.OnUpdate += Game_OnGameUpdate;
              GameObject.OnCreate += GameObject_OnCreate;
              GameObject.OnDelete += GameObject_OnDelete;
              }
  
          public static string Smitetype()
          {
              if (SmiteBlue.Any(id => Items.HasItem(id)))
              {
                  return "s5_summonersmiteplayerganker";
              }
              if (SmiteRed.Any(id => Items.HasItem(id)))
              {
                  return "s5_summonersmiteduel";
              }
              if (SmiteGrey.Any(id => Items.HasItem(id)))
              {
                  return "s5_summonersmitequick";
              }
              if (SmitePurple.Any(id => Items.HasItem(id)))
              {
                  return "itemsmiteaoe";
              }
              return "summonersmite";
          }
          
          private static void combo()
          {
              var enemys = Config.Item("Rene").GetValue<Slider>().Value;
              var target = TargetSelector.GetTarget(Q.Range, TargetSelector.DamageType.Physical);
              if (target == null || !target.IsValidTarget())
                  return;
  
              if (target.IsValidTarget() && Config.Item("UseQ").GetValue<bool>() && Q.IsReady() &&
                 player.Distance(target.ServerPosition) <= Q.Range)
              {
                  PredictionOutput Qpredict = Q.GetPrediction(target);
                  var hithere = Qpredict.CastPosition.Extend(ObjectManager.Player.Position, -100);
                  if (player.Distance(target.ServerPosition) >= 350)
                  {
                      Q.Cast(hithere);
                  }
                  else
                      Q.Cast(Qpredict.CastPosition);
              }
  
              UseSmite(target);
  
              if (target.IsValidTarget() && Config.Item("UseE").GetValue<bool>() && E.IsReady() &&
                  player.Distance(target.ServerPosition) <= E.Range)
              {
                  E.CastOnUnit(target);
              }
  
              if (target.IsValidTarget() && Config.Item("UseW").GetValue<bool>() && W.IsReady() &&
                  player.Distance(target.ServerPosition) <= 225f)
              {
                  W.Cast();
              }
  
              if (R.IsReady() && Config.Item("UseR").GetValue<bool>() && target.IsValidTarget(R.Range))
                  if (Config.Item("Rene").GetValue<Slider>().Value <= enemys)
                      R.Cast();
  
              if (Orbwalker.ActiveMode == Orbwalking.OrbwalkingMode.Combo)
                  items();
          }
  
          private static float GetComboDamage(AIHeroClient Target)
          {
              if (Target != null)
              {
                  float ComboDamage = new float();
  
                  ComboDamage = Q.IsReady() ? Q.GetDamage(Target) : 0;
                  ComboDamage += W.IsReady() ? W.GetDamage(Target) : 0;
                  ComboDamage += E.IsReady() ? E.GetDamage(Target) : 0;
                  ComboDamage += ObjectManager.Player.Spellbook.CanUseSpell(_smiteSlot) == SpellState.Ready ? GetSmiteDmg() : 0;
                  ComboDamage += player.TotalAttackDamage;
                  return ComboDamage;
              }
              return 0;
          }
  
          public static void UseSmite(AIHeroClient target)
          {
              var usesmite = Config.Item("UseS").GetValue<bool>();
              var itemscheck = SmiteBlue.Any(i => Items.HasItem(i)) || SmiteRed.Any(i => Items.HasItem(i));
              if (itemscheck && usesmite &&
                  ObjectManager.Player.Spellbook.CanUseSpell(_smiteSlot) == SpellState.Ready &&
                  target.Distance(player.Position) < _smite.Range)
              {
                  ObjectManager.Player.Spellbook.CastSpell(_smiteSlot, target);
              }
          }
  
          private static void SetSmiteSlot()
          {
              foreach (
                  var spell in
                      ObjectManager.Player.Spellbook.Spells.Where(
                          spell => String.Equals(spell.Name, Smitetype(), StringComparison.CurrentCultureIgnoreCase)))
              {
                  _smiteSlot = spell.Slot;
                  _smite = new Spell(_smiteSlot, 700);
                  return;
              }
          }
  
          private static int GetSmiteDmg()
          {
              int level = player.Level;
              int index = player.Level / 5;
              float[] dmgs = { 370 + 20 * level, 330 + 30 * level, 240 + 40 * level, 100 + 50 * level };
              return (int)dmgs[index];
          }
  
          private static float[] GetLength()
          {
              var Target = TargetSelector.GetTarget(Q.Range, TargetSelector.DamageType.Physical);
              if (Target != null)
              {
                  float[] Length =
                  {
                      GetComboDamage(Target) > Target.Health
                          ? 0
                          : (Target.Health - GetComboDamage(Target))/Target.MaxHealth,
                      Target.Health/Target.MaxHealth
                  };
                  return Length;
              }
              return new float[] { 0, 0 };
          }
  
          private static float IgniteDamage(AIHeroClient target)
          {
              if (Ignite == SpellSlot.Unknown || player.Spellbook.CanUseSpell(Ignite) != SpellState.Ready)
                  return 0f;
              return (float)player.GetSummonerSpellDamage(target, Damage.SummonerSpell.Ignite);
          }
  
          private static void Killsteal()
          {
              if (Config.Item("ksQ").GetValue<bool>() && Q.IsReady())
              {
                  var target =
                      ObjectManager.Get<AIHeroClient>()
                          .FirstOrDefault(
                              enemy =>
                                  enemy.IsValidTarget(Q.Range) && enemy.Health < player.GetSpellDamage(enemy, SpellSlot.Q));
                  if (target.IsValidTarget(Q.Range))
                  {
                      Q.Cast();
                      EloBuddy.Player.IssueOrder(GameObjectOrder.AttackUnit, target);
                  }
              }
  
              if (Config.Item("ksE").GetValue<bool>() && E.IsReady())
              {
                  var target =
                      ObjectManager.Get<AIHeroClient>()
                          .FirstOrDefault(
                              enemy =>
                                  enemy.IsValidTarget(E.Range) && enemy.Health < player.GetSpellDamage(enemy, SpellSlot.E));
                  if (target.IsValidTarget(E.Range))
                  {
                      E.CastOnUnit(target);
                  }
              }
          }
  
          private static void items()
          {
              Ignite = player.GetSpellSlot("summonerdot");
              var target = TargetSelector.GetTarget(Q.Range, TargetSelector.DamageType.Physical);
              if (target == null || !target.IsValidTarget())
                  return;
  
              var botrk = ItemData.Blade_of_the_Ruined_King.GetItem();
              var Ghost = ItemData.Youmuus_Ghostblade.GetItem();
              var cutlass = ItemData.Bilgewater_Cutlass.GetItem();
  
              if (botrk.IsReady() && botrk.IsOwned(player) && botrk.IsInRange(target)
                  && target.HealthPercent <= Config.Item("eL").GetValue<Slider>().Value
                  && Config.Item("UseBOTRK").GetValue<bool>())
  
                  botrk.Cast(target);
  
              if (botrk.IsReady() && botrk.IsOwned(player) && botrk.IsInRange(target)
                  && target.HealthPercent <= Config.Item("oL").GetValue<Slider>().Value
                  && Config.Item("UseBOTRK").GetValue<bool>())
  
                  botrk.Cast(target);
  
              if (cutlass.IsReady() && cutlass.IsOwned(player) && cutlass.IsInRange(target) &&
                  target.HealthPercent <= Config.Item("HLe").GetValue<Slider>().Value
                  && Config.Item("UseBilge").GetValue<bool>())
  
                  cutlass.Cast(target);
  
              if (Ghost.IsReady() && Ghost.IsOwned(player) && target.IsValidTarget(Q.Range)
                  && Config.Item("useGhostblade").GetValue<bool>())
  
                  Ghost.Cast();
  
              if (player.Distance(target.Position) <= 600 && IgniteDamage(target) >= target.Health &&
                  Config.Item("UseIgnite").GetValue<bool>())
                  player.Spellbook.CastSpell(Ignite, target);
          }
  
          private static void Game_OnGameUpdate(EventArgs args)
          {
              if (player.IsDead || MenuGUI.IsChatOpen || player.IsRecalling())
              {
                  return;
              }
  
              if (Config.Item("autolevel").GetValue<bool>()) LevelUpSpells();
  
              switch (Orbwalker.ActiveMode)
              {
                  case Orbwalking.OrbwalkingMode.Combo:
                      combo();
                      break;
                  case Orbwalking.OrbwalkingMode.LastHit:
                      Lasthit();
                      break;
                  case Orbwalking.OrbwalkingMode.Mixed:
                      harass();
                      break;
                  case Orbwalking.OrbwalkingMode.LaneClear:
                      Clear();
                      break;
              }
  
              Killsteal();
              AutoHarass();
          }
  
          private static void Lasthit()
          {
              var femana = Config.Item("femana").GetValue<Slider>().Value;
              var minions = MinionManager.GetMinions(player.ServerPosition, E.Range);
              if (minions.Count <= 0)
                  return;
  
              if (E.IsReady() && Config.Item("fE").GetValue<bool>() && player.HealthPercent >= femana)
              {
                  var etarget =
                      minions.Where(
                          x =>
                              x.Distance(player) < E.Range &&
                              (x.Health < player.GetSpellDamage(x, SpellSlot.E) &&
                               !(x.Health < player.GetAutoAttackDamage(x))))
                          .OrderByDescending(x => x.Health)
                          .FirstOrDefault();
                  if (HealthPrediction.GetHealthPrediction(etarget, (int)0.5) <=
                      player.GetSpellDamage(etarget, SpellSlot.E))
                      E.Cast(etarget);
              }
          }
  
          private static void AutoHarass()
          {
              var target = TargetSelector.GetTarget(Q.Range, TargetSelector.DamageType.Physical);
              var harassmana = Config.Item("harassmana").GetValue<Slider>().Value;
              if (!Q.IsReady() || !Config.Item("hQA").GetValue<bool>() || player.IsRecalling() || target == null || !target.IsValidTarget())
                  return;
  
              if (Q.IsReady() && Config.Item("hQA").GetValue<bool>() && target.IsValidTarget(Q.Range) && player.ManaPercent >= harassmana)
                 {
                      PredictionOutput Qpredict = Q.GetPrediction(target);
                      var hithere = Qpredict.CastPosition.Extend(ObjectManager.Player.Position, -100);
                      if (player.Distance(target.ServerPosition) >= 350)
                      {
                          Q.Cast(hithere);
                      }
                      else
                          Q.Cast(Qpredict.CastPosition);
                  }
          }
  
          //Thanks to LuNi
          private static void LevelUpSpells()
          {
              int qL = player.Spellbook.GetSpell(SpellSlot.Q).Level + qOff;
              int wL = player.Spellbook.GetSpell(SpellSlot.W).Level + wOff;
              int eL = player.Spellbook.GetSpell(SpellSlot.E).Level + eOff;
              int rL = player.Spellbook.GetSpell(SpellSlot.R).Level + rOff;
              if (qL + wL + eL + rL < ObjectManager.Player.Level)
              {
                  int[] level = new int[] { 0, 0, 0, 0 };
                  for (int i = 0; i < ObjectManager.Player.Level; i++)
                  {
                      level[abilitySequence[i] - 1] = level[abilitySequence[i] - 1] + 1;
                  }
                  if (qL < level[0]) ObjectManager.Player.Spellbook.LevelSpell(SpellSlot.Q);
                  if (wL < level[1]) ObjectManager.Player.Spellbook.LevelSpell(SpellSlot.W);
                  if (eL < level[2]) ObjectManager.Player.Spellbook.LevelSpell(SpellSlot.E);
                  if (rL < level[3]) ObjectManager.Player.Spellbook.LevelSpell(SpellSlot.R);
  
              }
          }
  
          private static void harass()
          {
              var target = TargetSelector.GetTarget(E.Range, TargetSelector.DamageType.Physical);
              var harassmana = Config.Item("harassmana").GetValue<Slider>().Value;
              if (target == null || !target.IsValidTarget())
                  return;
  
              if (Config.Item("hQ").GetValue<bool>() && target.IsValidTarget(Q.Range) &&
                 player.ManaPercent >= harassmana)
              {
                  PredictionOutput Qpredict = Q.GetPrediction(target);
                  var hithere = Qpredict.CastPosition.Extend(ObjectManager.Player.Position, -100);
  
gt:                 if (player.Distance(target.ServerPosition) >= 350)