context: using System;
  using System.Data;
  using System.Linq;
  using System.Windows.Forms;
  using Ninject;
  using Realm.DAL;
  using Realm.DAL.Common;
  using Realm.DAL.Enumerations;
  using Realm.DAL.Models;
  using Realm.Edit.Extensions;
  using Realm.Library.Common;
  using Realm.Library.Controls.DataGridViewControls;
  
  namespace Realm.Edit.EditorControls
  {
      public partial class AbilityControl : BaseEditorControl
      {
          private int _tagSetId;
  
          public AbilityControl()
          {
              InitializeComponent();
              InitControls();
              Id = 0;
              Initializing = false;
          }
  
          public AbilityControl(int classId)
              : base(SystemTypes.Ability, classId)
          {
              InitializeComponent();
              InitControls();
              Id = 0;
              Initializing = false;
          }
  
          public override void InitTooltipsImpl()
          {
              base.InitTooltipsImpl();
  
              txtSystemName.SetTooltip("SystemName field is the internal name for the object.", false);
              txtDisplayName.SetTooltip("DisplayName field is the public name of the object.", false);
              txtDisplayDescription.SetTooltip("Description field is the public description of the object.", false);
          }
  
          private void InitControls()
          {
              cboOffensiveStat.Fill<Statistic>();
              cboDefensiveStat.Fill<Statistic>();
              lstAbilityTags.Fill("AbilityTags");
  
              InitAbilityEffectsGrid();
              InitAbilityPrerequisitesGrid();
          }
  
          private void InitAbilityEffectsGrid()
          {
              DataGridViewColumn column;
  
              {
                  column = gridEffects.CreateDataGridControls<DataGridViewColumn, DataGridViewTypedLinkCell>("Effect",
                      "Effect", 100);
                  if (column.CellTemplate is DataGridViewTypedLinkCell)
                      ((DataGridViewTypedLinkCell) column.CellTemplate).SystemType = SystemTypes.Effect;
              }
  
              {
                  column =
                      gridEffects.CreateDataGridControls<DataGridViewComboBoxColumn, DataGridViewComboBoxCell>(
                          "TargetClassType", "Target Class Type", 25);
                  if (column.CellTemplate is DataGridViewComboBoxCell)
                      ((DataGridViewComboBoxCell) column.CellTemplate).Fill<TargetClassTypes>();
  
                  DataGridViewComboBoxColumn comboColumn = (DataGridViewComboBoxColumn) column;
                  comboColumn.ValueMember = "Value";
                  comboColumn.DisplayMember = "Name";
              }
          }
  
          private void InitAbilityPrerequisitesGrid()
          {
              DataGridViewColumn column;
  
              gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewNumericTextCell>(
                  "MinLevel", "Min Level", 50);
  
              {
                  column = gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewTypedLinkCell>(
                      "Race", "Race", 100);
                  if (column.CellTemplate is DataGridViewTypedLinkCell)
                      ((DataGridViewTypedLinkCell)column.CellTemplate).SystemType = SystemTypes.Race;
              }
  
              {
                  column = gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewTypedLinkCell>(
                      "Faction", "Faction", 100);
                  if (column.CellTemplate is DataGridViewTypedLinkCell)
                      ((DataGridViewTypedLinkCell)column.CellTemplate).SystemType = SystemTypes.Faction;
              }
  
              gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewNumericTextCell>(
                  "FactionLevel", "Min Faction", 50);
  
              {
                  column = gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewComboBoxCell>(
                      "Statistic", "Statistic", 100);
                  if (column.CellTemplate is DataGridViewComboBoxCell)
                      ((DataGridViewComboBoxCell)column.CellTemplate).Fill<Statistic>();
              }
  
              gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewNumericTextCell>(
                 "StatisticValue", "Min Statistic", 50);
  
              {
                  column = gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewTypedLinkCell>(
                      "Skill", "Skill", 100);
                  if (column.CellTemplate is DataGridViewTypedLinkCell)
                      ((DataGridViewTypedLinkCell) column.CellTemplate).SystemType = SystemTypes.Skill;
              }
  
              gridPrerequisites.CreateDataGridControls<DataGridViewColumn, DataGridViewNumericTextCell>(
                 "SkillValue", "Min Skill", 50);
          }
  
          // TODO: AbilityReagantMap (Item)
          // TODO: AbilityGuildMap (Flags?)
  
          public override void InitNewImpl()
          {
              cboOffensiveStat.Fill<Statistic>();
              cboDefensiveStat.Fill<Statistic>();
          }
  
          public override void MakeCopyImpl()
          {
              txtSystemName.Text = ControlName;
              Id = 0;
          }
  
          public override void InitContentImpl(int id)
          {
              IRealmDbContext dbContext = Program.NinjectKernel.Get<IRealmDbContext>();
              var obj = (Ability)dbContext.GetPrimitive(SystemTypes.Ability, id);
  
              txtSystemName.Text = obj.SystemName;
              txtDisplayName.Text = obj.DisplayName;
              txtDisplayDescription.Text = obj.DisplayDescription;
              numRechargeRate.Value = (decimal) obj.RechargeRate;
              numericUpDownPreDelay.Value = (decimal) obj.PreDelay;
              numericUpDownPostDelay.Value = (decimal) obj.PostDelay;
              numStaminaCost.Value = obj.StaminaCost;
              numManaCost.Value = obj.ManaCost;
  
              cboOffensiveStat.Fill<Statistic>((int)obj.OffensiveStat);
              cboDefensiveStat.Fill<Statistic>((int)obj.DefensiveStat);
  
              if (obj.Terrain != null)
                  linkTerrain.Setup(SystemTypes.Terrain, obj.Terrain.Id);
              if (obj.InterruptionResistSkill != null)
                  linkInterruptResist.Setup(SystemTypes.Skill, obj.InterruptionResistSkill.Id);
              if (obj.InterruptionEffect != null)
                  linkInterruptEffect.Setup(SystemTypes.Effect, obj.InterruptionEffect.Id);
  
              PopulateCheckboxes(dbContext, obj);
  
              _tagSetId = obj.TagSet?.Id ?? 0;
              if (_tagSetId > 0)
                  lstAbilityTags.Fill("AbilityTags", _tagSetId);
              else 
                  lstAbilityTags.Fill("AbilityTags");
  
              // TODO: Populate AbilityEffects
              // TODO: Populate AbilityPrerequisites
              // TODO: Populate AbilityReagants
              // TODO: Populate AbilityGuild
  
              ControlName = txtSystemName.Text;
          }
  
          private void PopulateCheckboxes(IRealmDbContext dbContext, Ability obj)
          {
              chkNotInterruptible.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits,
                  "NotInterruptible");
              chkAutoAttack.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits, "AutoAttack");
              chkWeaponRequired.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits,
                  "WeaponRequired");
              chkImplementRequired.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits,
                  "ImplementRequired");
              chkVerbalRequired.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits, "VerbalRequired");
              chkPassive.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits, "Passive");
              chkTerrainRequired.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits,
                  "TerrainRequired");
              chkNoCombatUse.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits, "NoCombatUse");
              chkSightRequired.Checked = dbContext.DoesPrimitiveHaveBit(BitTypes.AbilityBits, obj.Bits, "SightRequired");
          }
  
          public override bool SaveImpl()
          {
              try
              {
                  IRealmDbContext dbContext = Program.NinjectKernel.Get<IRealmDbContext>();
                  var ability = (Ability)(Id == 0 ? new Ability() : dbContext.GetPrimitive(SystemTypes.Ability, Id));
  
                  if (Id == 0)
                  {
                      ability.SystemClass = dbContext.SystemClasses.FirstOrDefault(x => x.Id == ClassId);
                      dbContext.Abilities.Add(ability);
                  }
  
                  ability.SystemName = txtSystemName.Text;
                  ability.DisplayName = txtDisplayName.Text;
                  ability.DisplayDescription = txtDisplayDescription.Text;
  
                  ability.RechargeRate = (float)numRechargeRate.Value;
  
gt:                 ability.StaminaCost = (int)numStaminaCost.Value;