context: using System;
  using System.Drawing;
  using System.Linq;
  using LeagueSharp;
  using LeagueSharp.Common;
  using EloBuddy;
  
  namespace SorakaToTheChallenger
  {
      public static class Program
      {
          /// <summary>
          /// The Q Spell
          /// </summary>
          public static Spell Q;
          /// <summary>
          /// The W Spell
          /// </summary>
          public static Spell W;
          /// <summary>
          /// The E Spell
          /// </summary>
          public static Spell E;
          /// <summary>
          /// The R Spell
          /// </summary>
          public static Spell R;
          /// <summary>
          /// The Menu
          /// </summary>
          public static Menu Menu;
          /// <summary>
          /// The Blacklist Menu
          /// </summary>
          public static Menu BlacklistMenu;
          /// <summary>
          /// The Orbwalker
          /// </summary>
          public static Orbwalking.Orbwalker Orbwalker;
          /// <summary>
          /// The Priority Menu
          /// </summary>
          public static Menu PriorityMenu;
  
          /// <summary>
          /// The Load
          /// </summary>
          /// <param name="args">The args</param>
          public static void Load()
          {
              if (ObjectManager.Player.CharData.BaseSkinName != "Soraka") return;
  
              Q = new Spell(SpellSlot.Q, 800, TargetSelector.DamageType.Magical);
              W = new Spell(SpellSlot.W, 550);
              E = new Spell(SpellSlot.E, 900, TargetSelector.DamageType.Magical);
              R = new Spell(SpellSlot.R);
  
              Q.SetSkillshot(0.3f, 160, 1600, false, SkillshotType.SkillshotCircle);
              E.SetSkillshot(0.5f, 70f, 1600, false, SkillshotType.SkillshotCircle);
  
              Menu = new Menu("Soraka To The Challenger", "sttc", true);
              PriorityMenu = Menu.AddSubMenu(new Menu("Heal Priority", "sttc.priority"));
              BlacklistMenu = Menu.AddSubMenu(new Menu("Heal Blacklist", "sttc.blacklist"));
              foreach (var ally in ObjectManager.Get<AIHeroClient>().Where(h => h.IsAlly && !h.IsMe))
              {
                  var championName = ally.CharData.BaseSkinName;
                  BlacklistMenu.AddItem(new MenuItem("dontheal" + championName, championName).SetValue(false));
              }
              var orbwalkerMenu = Menu.AddSubMenu(new Menu("Orbwalker", "sttc.orbwalker"));
              Orbwalker = new Orbwalking.Orbwalker(orbwalkerMenu);
  
  
              Menu.AddItem(
                  new MenuItem("sttc.mode", "Play Mode: ").SetValue(new StringList(new[] { "SMART", "AP-SORAKA", "ONLYHEAL" })));
              Menu.AddItem(new MenuItem("sttc.wmyhp", "Don't heal (W) if I'm below HP%").SetValue(new Slider(20, 1)));
              Menu.AddItem(new MenuItem("sttc.dontwtanks", "Don't heal (W) tanks").SetValue(true));
              Menu.AddItem(new MenuItem("atanktakesxheals", "A TANK takes X Heals (W) to  FULLHP").SetValue(new Slider(15, 5, 30)));
  
              Menu.AddItem(new MenuItem("sttc.ultmyhp", "ULT if I'm below HP%").SetValue(new Slider(20, 1)));
              Menu.AddItem(new MenuItem("sttc.ultallyhp", "ULT if an ally is below HP%").SetValue(new Slider(15)));
              Menu.AddItem(new MenuItem("sttc.blockaa", "Block AutoAttacks?").SetValue(false));
              Menu.AddItem(new MenuItem("sttc.antiks", "Anti-KS").SetValue(true));
              Menu.AddItem(new MenuItem("sttc.drawq", "Draw Q?")
                  .SetValue(new Circle(true, Color.DarkMagenta)));
              Menu.AddItem(new MenuItem("sttc.draww", "Draw W?")
                   .SetValue(new Circle(true, Color.Turquoise)));
              Menu.AddItem(new MenuItem("sttc.drawdebug", "Draw Heal Info?")
                   .SetValue(new Circle(false, Color.White)));
  
              Menu.AddToMainMenu();
              Game.OnUpdate += OnUpdate;
              Interrupter2.OnInterruptableTarget += (sender, eventArgs) =>
              {
                  if (Menu.Item("sttc.mode").GetValue<StringList>().SelectedValue == "ONLYHEAL") return;
                  if (eventArgs.DangerLevel == Interrupter2.DangerLevel.High)
                  {
                      var pos = sender.ServerPosition;
                      if (pos.Distance(ObjectManager.Player.ServerPosition) < 900)
                      {
                          E.Cast(pos);
                      }
                  }
              };
              AntiGapcloser.OnEnemyGapcloser += OnEnemyGapcloser;
              Obj_AI_Base.OnProcessSpellCast += OnProcessSpellCast;
              Obj_AI_Base.OnSpellCast += OnProcessSpellCast;
              GameObject.OnCreate += (sender, eventArgs) =>
              {
                  if (Menu.Item("sttc.mode").GetValue<StringList>().SelectedValue == "ONLYHEAL") return;
                  if (sender.Name.Contains("Draven_Base_Q_reticle_self.troy"))
                  {
                      E.Cast(sender.Position);
                  }
              };
              Drawing.OnDraw += eventArgs =>
              {
                  if (Menu.Item("sttc.drawq").GetValue<Circle>().Active)
                  {
                      Render.Circle.DrawCircle(ObjectManager.Player.Position, 950,
                          Menu.Item("sttc.drawq").GetValue<Circle>().Color,
                          7);
                  }
                  if (Menu.Item("sttc.draww").GetValue<Circle>().Active)
                  {
                      Render.Circle.DrawCircle(ObjectManager.Player.Position, 550, W.IsReady() ?
                          Menu.Item("sttc.draww").GetValue<Circle>().Color : Color.Red,
                          7);
                  }
                  if (Menu.Item("sttc.drawdebug").GetValue<Circle>().Active)
                  {
                      if (ObjectManager.Player.GetSpell(SpellSlot.W).Level > 0)
                      {
                          foreach (var healingCandidate in HeroManager.Allies.Where(
                          a =>
                              !a.IsMe && a.ServerPosition.Distance(ObjectManager.Player.ServerPosition) < 550 &&
                              !BlacklistMenu.Item("dontheal" + a.CharData.BaseSkinName).GetValue<bool>()))
                          {
                              if (healingCandidate != null)
                              {
                                  var wtsPos = Drawing.WorldToScreen(healingCandidate.Position);
                                  Drawing.DrawText(wtsPos.X, wtsPos.Y, Menu.Item("sttc.drawdebug").GetValue<Circle>().Color, "1W Heals " + Math.Round(GetWHealingAmount()).ToString() + "HP");
                              }
                          }
                      }
                  }
              };
          }
  
          /// <summary>
          /// The On Enemy Gapcloser
          /// </summary>
          /// <param name="gapcloser">The Gapcloser</param>
          private static void OnEnemyGapcloser(ActiveGapcloser gapcloser)
          {
              if (Menu.Item("sttc.mode").GetValue<StringList>().SelectedValue == "ONLYHEAL") return;
              if (gapcloser.Sender.IsMelee && HeroManager.Allies.Any(a => a.Distance(gapcloser.End) < 200) && ObjectManager.Player.ServerPosition.Distance(gapcloser.Sender.ServerPosition) < 900)
              {
                  E.Cast(gapcloser.End);
              }
          }
  
          /// <summary>
          /// The On Process Spell Cast
          /// </summary>
          /// <param name="sender">The Sender</param>
          /// <param name="args">The Args</param>
          private static void OnProcessSpellCast(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args)
          {
              if (Menu.Item("sttc.mode").GetValue<StringList>().SelectedValue == "ONLYHEAL") return;
              if (sender.Type != GameObjectType.AIHeroClient) return;
              var target = sender as AIHeroClient;
              var pos = sender.ServerPosition;
              if (sender.CharData.BaseSkinName == "Yasuo")
              {
                  if (target.GetSpellSlot(args.SData.Name) == SpellSlot.R &&
                      ObjectManager.Player.ServerPosition.Distance(pos) < 900)
                  {
                      E.Cast(target.ServerPosition);
                  }
              }
              if (sender.CharData.BaseSkinName == "Vi")
              {
                  if (target.GetSpellSlot(args.SData.Name) == SpellSlot.R &&
                      ObjectManager.Player.ServerPosition.Distance(pos) < 900)
                  {
                      E.Cast(target.ServerPosition);
                  }
              }
          }
  
          /// <summary>
          /// The OnUpdate
          /// </summary>
          /// <param name="args">The Args</param>
          public static void OnUpdate(EventArgs args)
          {
              WLogic();
              RLogic();
              QLogic();
              ELogic();
              Orbwalker.SetAttack(!Menu.Item("sttc.blockaa").GetValue<bool>());
          }
  
          /// <summary>
          /// The Q Logic
          /// </summary>
          public static void QLogic()
          {
              if (!Q.IsReady() || (ObjectManager.Player.Mana < 3 * GetWManaCost() && CanW())) return;
              var shouldntKS = Menu.Item("sttc.antiks").GetValue<bool>();
              switch (Menu.Item("sttc.mode").GetValue<StringList>().SelectedValue)
              {
                  case "SMART":
                      if (ObjectManager.Player.MaxHealth - ObjectManager.Player.Health > GetQHealingAmount())
                      {
                          foreach (var hero in ObjectManager.Get<AIHeroClient>().Where(h => h.IsValidTarget(925)))
                          {
                              if (shouldntKS && Q.GetDamage(hero) > hero.Health)
                              {
                                  return;
                              }
                              Q.CastIfHitchanceEquals(hero, HitChance.VeryHigh);
                          }
                      }
                      break;
                  case "AP-SORAKA":
                      foreach (var hero in ObjectManager.Get<AIHeroClient>().Where(h => h.IsValidTarget(925)))
                      {
                          if (shouldntKS && Q.GetDamage(hero) > hero.Health)
                          {
                              return;
                          }
                          Q.CastIfHitchanceEquals(hero, HitChance.VeryHigh);
                      }
                      break;
                  case "ONLYHEAL":
                      break;
              }
          }
  
          /// <summary>
          /// The W Logic
          /// </summary>
          /// 
  
          public  static void WLogic()
          {
              if (!W.IsReady() || !CanW()) return;
              var ally =
                  HeroManager.Allies.Where(
                      a =>
                          !a.IsMe && a.ServerPosition.Distance(ObjectManager.Player.ServerPosition) < 550 &&
                          a.MaxHealth - a.Health > GetWHealingAmount())
                      .OrderByDescending(TargetSelector.GetPriority)
                      .ThenBy(ally1 => ally1.Health).FirstOrDefault();
              {
  
gt:                 if (ally == null || ally.IsDead || ally.IsZombie)