context: #region License
  
  /*
   Copyright 2014 - 2015 Nikita Bernthaler
   Cooldown.cs is part of SFXUtility.
  
   SFXUtility is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
  
   SFXUtility is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.
  
   You should have received a copy of the GNU General Public License
   along with SFXUtility. If not, see <http://www.gnu.org/licenses/>.
  */
  
  #endregion License
  
  #region
  
  using System;
  using System.Collections.Generic;
  using System.Drawing;
  using System.Linq;
  using LeagueSharp;
  using LeagueSharp.Common;
  using SFXUtility.Classes;
  using SFXUtility.Data;
  using SFXUtility.Library;
  using SFXUtility.Library.Extensions.NET;
  using SFXUtility.Library.Extensions.SharpDX;
  using SFXUtility.Library.Logger;
  using PortAIO.Properties;
  using SharpDX;
  using SharpDX.Direct3D9;
  using Font = SharpDX.Direct3D9.Font;
  using Rectangle = SharpDX.Rectangle;
  
  #endregion
  
  #pragma warning disable 618
  
  using EloBuddy;
  using EloBuddy.SDK.Events;
  
  namespace SFXUtility.Features.Timers
  {
      internal class Cooldown : Child<Timers>
      {
          private const float TeleportCd = 300f;
          private readonly Dictionary<int, List<SpellDataInst>> _spellDatas = new Dictionary<int, List<SpellDataInst>>();
          private readonly SpellSlot[] _spellSlots = { SpellSlot.Q, SpellSlot.W, SpellSlot.E, SpellSlot.R };
  
          private readonly Dictionary<int, List<SpellDataInst>> _summonerDatas =
              new Dictionary<int, List<SpellDataInst>>();
  
          private readonly SpellSlot[] _summonerSlots = { SpellSlot.Summoner1, SpellSlot.Summoner2 };
          private readonly Dictionary<string, Texture> _summonerTextures = new Dictionary<string, Texture>();
          private readonly Dictionary<int, float> _teleports = new Dictionary<int, float>();
          private List<AIHeroClient> _heroes = new List<AIHeroClient>();
          private Texture _hudSelfTexture;
          private Texture _hudTexture;
          private Line _line;
          private Sprite _sprite;
          private Font _text;
  
          public Cooldown(Timers parent) : base(parent)
          {
              OnLoad();
          }
  
          public override string Name
          {
              get { return "Cooldown"; }
          }
  
          protected override void OnEnable()
          {
              Drawing.OnEndScene += OnDrawingEndScene;
              Obj_AI_Base.OnSpellCast += OnObjAiBaseProcessSpellCast;
              Teleport.OnTeleport += OnObjAiBaseTeleport;
  
              base.OnEnable();
          }
  
          protected override void OnDisable()
          {
              Drawing.OnEndScene -= OnDrawingEndScene;
              Obj_AI_Base.OnSpellCast -= OnObjAiBaseProcessSpellCast;
              Teleport.OnTeleport -= OnObjAiBaseTeleport;
  
              base.OnDisable();
          }
  
          private void OnObjAiBaseProcessSpellCast(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args)
          {
              try
              {
                  var hero = sender as AIHeroClient;
                  if (hero != null)
                  {
                      var data = hero.IsAlly
                          ? _manualAllySpells.FirstOrDefault(
                              m => m.Spell.Equals(args.SData.Name, StringComparison.OrdinalIgnoreCase))
                          : _manualEnemySpells.FirstOrDefault(
                              m => m.Spell.Equals(args.SData.Name, StringComparison.OrdinalIgnoreCase));
                      if (data != null && data.CooldownExpires - Game.Time < 0.5)
                      {
                          var spell = hero.GetSpell(data.Slot);
                          if (spell != null)
                          {
                              var cooldown = data.Cooldowns[spell.Level - 1];
                              var cdr = hero.PercentCooldownMod * -1 * 100;
                              data.Cooldown = cooldown - cooldown / 100 * (cdr > 40 ? 40 : cdr) + data.Additional;
                              data.CooldownExpires = Game.Time + data.Cooldown;
                          }
                      }
                  }
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
          }
  
          protected sealed override void OnLoad()
          {
              try
              {
                  Menu = new Menu(Name, Name);
                  var drawingMenu = new Menu("Drawing", Name + "Drawing");
                  drawingMenu.AddItem(
                      new MenuItem(drawingMenu.Name + "TimeFormat", "Time Format").SetValue(
                          new StringList(new[] { "mm:ss", "ss" })));
                  drawingMenu.AddItem(
                      new MenuItem(drawingMenu.Name + "FontSize", "Font Size").SetValue(new Slider(13, 3, 30)));
                  drawingMenu.AddItem(new MenuItem(drawingMenu.Name + "Enemy", "Enemy").SetValue(false));
                  drawingMenu.AddItem(new MenuItem(drawingMenu.Name + "Ally", "Ally").SetValue(false));
                  drawingMenu.AddItem(new MenuItem(drawingMenu.Name + "Self", "Self").SetValue(false));
  
                  Menu.AddSubMenu(drawingMenu);
  
                  Menu.AddItem(new MenuItem(Name + "Enabled", "Enabled").SetValue(false));
  
                  Menu.Item(Name + "DrawingEnemy").ValueChanged += delegate(object o, OnValueChangeEventArgs args)
                  {
                      if (_heroes == null)
                      {
                          return;
                      }
                      var ally = Menu.Item(Name + "DrawingAlly").GetValue<bool>();
                      var enemy = args.GetNewValue<bool>();
                      _heroes = ally && enemy
                          ? GameObjects.Heroes.ToList()
                          : (ally ? GameObjects.AllyHeroes : (enemy ? GameObjects.EnemyHeroes : new List<AIHeroClient>()))
                              .ToList();
                      if (Menu.Item(Name + "DrawingSelf").GetValue<bool>())
                      {
                          if (_heroes.All(h => h.NetworkId != ObjectManager.Player.NetworkId))
                          {
                              _heroes.Add(ObjectManager.Player);
                          }
                      }
                      else
                      {
                          _heroes.RemoveAll(h => h.NetworkId == ObjectManager.Player.NetworkId);
                      }
                  };
  
                  Menu.Item(Name + "DrawingAlly").ValueChanged += delegate(object o, OnValueChangeEventArgs args)
                  {
                      if (_heroes == null)
                      {
                          return;
                      }
                      var ally = args.GetNewValue<bool>();
                      var enemy = Menu.Item(Name + "DrawingEnemy").GetValue<bool>();
                      _heroes = ally && enemy
                          ? GameObjects.Heroes.ToList()
                          : (ally ? GameObjects.AllyHeroes : (enemy ? GameObjects.EnemyHeroes : new List<AIHeroClient>()))
                              .ToList();
                      if (Menu.Item(Name + "DrawingSelf").GetValue<bool>() &&
                          _heroes.All(h => h.NetworkId != ObjectManager.Player.NetworkId))
                      {
                          _heroes.Add(ObjectManager.Player);
                      }
                      if (Menu.Item(Name + "DrawingSelf").GetValue<bool>())
                      {
                          if (_heroes.All(h => h.NetworkId != ObjectManager.Player.NetworkId))
                          {
                              _heroes.Add(ObjectManager.Player);
                          }
                      }
                      else
                      {
                          _heroes.RemoveAll(h => h.NetworkId == ObjectManager.Player.NetworkId);
                      }
                  };
  
                  Menu.Item(Name + "DrawingSelf").ValueChanged += delegate(object o, OnValueChangeEventArgs args)
                  {
                      if (_heroes == null)
                      {
                          return;
                      }
                      var ally = Menu.Item(Name + "DrawingAlly").GetValue<bool>();
  
gt:                     var enemy = Menu.Item(Name + "DrawingEnemy").GetValue<bool>();