context: #region License
  
  /*
   Copyright 2014 - 2015 Nikita Bernthaler
   MDrawing.cs is part of SFXAltar.
  
   SFXAltar 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.
  
   SFXAltar 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 SFXAltar. If not, see <http://www.gnu.org/licenses/>.
  */
  
  #endregion License
  
  #region
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using LeagueSharp;
  using SFXAltar.Library.Logger;
  using SharpDX.Direct3D9;
  
  #endregion
  
  namespace SFXAltar.Classes
  {
      internal class MDrawing
      {
          private static readonly Dictionary<int, Font> Fonts = new Dictionary<int, Font>();
          private static readonly HashSet<Line> Lines = new HashSet<Line>();
          private static Sprite _sprite;
          private static bool _unloaded;
  
          static MDrawing()
          {
              try
              {
                  Drawing.OnPreReset += OnDrawingPreReset;
                  Drawing.OnPostReset += OnDrawingPostReset;
                  Global.SFX.OnUnload += OnUnload;
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
          }
  
          private static void OnUnload(object sender, UnloadEventArgs unloadEventArgs)
          {
              try
              {
                  _unloaded = true;
  
                  if (_sprite != null && !_sprite.IsDisposed)
                  {
                      _sprite.Dispose();
                  }
  
                  foreach (var font in Fonts.Where(font => font.Value != null && !font.Value.IsDisposed))
                  {
                      font.Value.Dispose();
                  }
  
                  foreach (var line in Lines.Where(line => line != null && !line.IsDisposed))
                  {
                      line.Dispose();
                  }
  
                  Drawing.OnPreReset -= OnDrawingPreReset;
                  Drawing.OnPostReset -= OnDrawingPostReset;
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
          }
  
          private static void OnDrawingPostReset(EventArgs args)
          {
              try
              {
                  if (_unloaded)
                  {
                      return;
                  }
  
                  if (_sprite != null && !_sprite.IsDisposed)
                  {
                      _sprite.OnResetDevice();
                  }
  
                  foreach (var font in Fonts.Where(font => font.Value != null && !font.Value.IsDisposed))
                  {
                      font.Value.OnResetDevice();
                  }
  
                  foreach (var line in Lines.Where(line => line != null && !line.IsDisposed))
                  {
                      line.OnResetDevice();
                  }
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
          }
  
          private static void OnDrawingPreReset(EventArgs args)
          {
              try
              {
                  if (_unloaded)
                  {
                      return;
                  }
  
                  if (_sprite != null && !_sprite.IsDisposed)
                  {
                      _sprite.OnLostDevice();
                  }
  
                  foreach (var font in Fonts.Where(font => font.Value != null && !font.Value.IsDisposed))
                  {
                      font.Value.OnLostDevice();
                  }
  
                  foreach (var line in Lines.Where(line => line != null && !line.IsDisposed))
                  {
                      line.OnLostDevice();
                  }
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
          }
  
          public static Font GetFont(int fontSize)
          {
              Font font = null;
              try
              {
                  if (!Fonts.TryGetValue(fontSize, out font))
                  {
                      font = new Font(
                          Drawing.Direct3DDevice,
                          new FontDescription
                          {
                              FaceName = Global.DefaultFont,
                              Height = fontSize,
                              OutputPrecision = FontPrecision.Default,
                              Quality = FontQuality.Default
                          });
                      Fonts[fontSize] = font;
                  }
                  else
                  {
                      if (!_unloaded && (font == null || font.IsDisposed))
                      {
                          Fonts.Remove(fontSize);
                          GetFont(fontSize);
                      }
                  }
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
              return font;
          }
  
          public static Line GetLine(int width = -1)
          {
              Line line = null;
              try
              {
                  line = new Line(Drawing.Direct3DDevice);
                  if (width >= 0)
                  {
                      line.Width = width;
                  }
                  Lines.Add(line);
              }
              catch (Exception ex)
              {
                  Global.Logger.AddItem(new LogItem(ex));
              }
              return line;
          }
  
          public static Sprite GetSprite()
          {
              try
              {
                  if (!_unloaded && (_sprite == null || _sprite.IsDisposed))
                  {
  
gt:                     _sprite = new Sprite(Drawing.Direct3DDevice);