using ActionGame.GameResources.Models;
using ActionGame.RawResources.Models;
using GameMaker.Logic;
using GameMaker.Models;
using GameMaker.UI;
using NAudio.Vorbis;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Windows.Forms;


namespace GameMaker
{
    public partial class MainForm : Form
    {
        private Session Session { get; set; }
        private WaveOutEvent audioOutput;
        private Boolean isGoodToClose;

        public MainForm()
        {
            InitializeComponent();

            isGoodToClose = false;
        }

        #region Form & UI
        private void MainForm_Load(object sender, EventArgs e)
        {
            CloseDirectory();

#if DEBUG
            OpenDirectory(Application.StartupPath.Replace("\\GameMaker\\bin\\Debug", ""));
#endif
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.No) return;

            isGoodToClose = true;
            this.Close();
        }

        private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("Are you sure you want to open a new session?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.No) return;

            FolderBrowserDialog.SelectedPath = Application.StartupPath;
            DialogResult result = FolderBrowserDialog.ShowDialog();

            if (result == DialogResult.OK)
            {
                String folder = FolderBrowserDialog.SelectedPath;
                OpenDirectory(folder);
            }
        }

        private void SaveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("Are you sure you want to save the session?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if(dialogResult == DialogResult.No) return;

            if(this.Session == null)
            {
                MessageBox.Show("No session to save");
            }

            SessionSaver saver = new SessionSaver();
            Exception status = saver.Save(this.Session);

            if(status == null)
            {
                MessageBox.Show("Session saved!");
            }
            else
            {
                MessageBox.Show("Save Error:\n" + status.Message);
            }
        }

        private void CloseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("Are you sure you want to close the session?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.No) return;

            CloseDirectory();
        }
        
        private void SetAppState(Boolean state)
        {
            Tabs.Visible = state;

            saveToolStripMenuItem.Enabled = state;
            closeToolStripMenuItem.Enabled = state;
            TexturesDataGridView.Enabled = state;
            FontsDataGridView.Enabled = state;
            SongsDataGridView.Enabled = state;
            SoundEffectsDataGridView.Enabled = state;
            CharacterSetDataGridView.Enabled = state;
            TileSetDataGridView.Enabled = state;
            TileSetAnimationsDataGridView.Enabled = state;
            WorldDataGridView.Enabled = state;
            EnemiesDataGridView.Enabled = state;
            ItemsDataGridView.Enabled = state;

            if (this.Session != null)
            {
                TexturesDataGridView.DataSource = this.Session.Textures;
                TexturesDataGridView.Refresh();
                SongsDataGridView.DataSource = this.Session.Songs;
                SongsDataGridView.Refresh();
                SoundEffectsDataGridView.DataSource = this.Session.SoundEffects;
                SoundEffectsDataGridView.Refresh();
                FontsDataGridView.DataSource = this.Session.Fonts;
                FontsDataGridView.Refresh();
                CharacterSetDataGridView.DataSource = this.Session.CharacterSets;
                CharacterSetDataGridView.Refresh();
                TileSetDataGridView.DataSource = this.Session.GetListOfTexturesUsedByTileSets();
                TileSetDataGridView.Refresh();
                TileSetAnimationsDataGridView.DataSource = this.Session.GetListOfTexturesUsedByTileSets();
                TileSetAnimationsDataGridView.Refresh();
                WorldDataGridView.DataSource = this.Session.Worlds;
                WorldDataGridView.Refresh();
                EnemiesDataGridView.AutoGenerateColumns = false;
                EnemiesDataGridView.DataSource = this.Session.Enemies;
                EnemiesDataGridView.Refresh();
                ItemsDataGridView.AutoGenerateColumns = false;
                ItemsDataGridView.DataSource = this.Session.Items;
                ItemsDataGridView.Refresh();

                PlayerHealthText.DataBindings.Add("Text", this.Session.Player, "Health");
                PlayerAttackText.DataBindings.Add("Text", this.Session.Player, "Attack");
                PlayerDefenceText.DataBindings.Add("Text", this.Session.Player, "Defence");
                PlayerStartLocationText.Text = this.Session.Player.StartPosition.ToString();
                PlayerCharacterSetText.Text = this.Session.Player.CharacterSetKey.ToString();

                EnemiesAttackTypeCombo.DataSource = Enum.GetValues(typeof(AttackTypes));
                EnemiesMovementTypeCombo.DataSource = Enum.GetValues(typeof(MovementTypes));
                ItemsItemTypeCombo.DataSource = Enum.GetValues(typeof(ItemDefinition.ItemType));
            }
        }

        private void CloseDirectory()
        {
            SetAppState(false);

            this.Session = null;
        }

        private void OpenDirectory(String folder)
        {
            SessionLoader loader = new SessionLoader();
            this.Session = loader.Load(folder);

            SetAppState(true);
        }
        #endregion

        #region Raw Resources
        private void TexturesDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            String value = TexturesDataGridView.Rows[e.RowIndex].Cells[TexturesDataGridView.Columns["FilePath"].Index].Value.ToString();

            TexturesImage.ImageLocation = RawResourceHelper.GetFilePathForTexture(this.Session.WorkingDirectory, value);
            TexturesImage.SizeMode = PictureBoxSizeMode.Zoom;
        }


        private void SongsDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            
        }


        private void SoundEffectsDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            
        }


        private void SoundEffectsPlay_Click(object sender, EventArgs e)
        {
            if ((audioOutput != null) && (audioOutput?.PlaybackState != PlaybackState.Stopped))
            {
                audioOutput.Stop();
            }
            else if (SoundEffectsDataGridView.CurrentRow != null)
            {
                String value = SoundEffectsDataGridView.CurrentRow.Cells[SoundEffectsDataGridView.Columns["FilePath"].Index].Value.ToString();

                audioOutput?.Stop();
                if (audioOutput == null) audioOutput = new WaveOutEvent();

                VorbisWaveReader audioFile = new VorbisWaveReader(RawResourceHelper.GetFilePathForSoundEffect(this.Session.WorkingDirectory, value));
                audioOutput.Init(audioFile);
                audioOutput.Play();
            }
        }


        private void SongsPlay_Click(object sender, EventArgs e)
        {
            if ((audioOutput != null) && (audioOutput.PlaybackState != PlaybackState.Stopped))
            {
                audioOutput.Stop();
            }
            else if(SongsDataGridView.CurrentRow != null)
            {
                String value = SongsDataGridView.CurrentRow.Cells[SongsDataGridView.Columns["FilePath"].Index].Value.ToString();

                audioOutput?.Stop();
                if (audioOutput == null) audioOutput = new WaveOutEvent();

                AudioFileReader audioFile = new AudioFileReader(RawResourceHelper.GetFilePathForSong(this.Session.WorkingDirectory, value));
                audioOutput.Init(audioFile);
                audioOutput.Play();
            }
        }
        #endregion

        #region Game Resources
        private void CharacterSetDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            String value = CharacterSetDataGridView.Rows[e.RowIndex].Cells[CharacterSetDataGridView.Columns["TextureKey"].Index].Value.ToString();
            Int32 textureKey = Int32.Parse(value);

            foreach(RawResource resource in Session.Textures)
            {
                if(resource.Key == textureKey)
                {
                    CharacterSetImage.ImageLocation = RawResourceHelper.GetFilePathForTexture(this.Session.WorkingDirectory, resource.FilePath);
                    CharacterSetImage.SizeMode = PictureBoxSizeMode.Zoom;
                    return;
                }
            }

            CharacterSetImage.ImageLocation = "";
        }

        private void CharacterSetDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            CharacterSetDataGridView.Columns["Key"].ReadOnly = true;
            CharacterSetDataGridView.Columns["TextureKey"].ReadOnly = true;
            CharacterSetDataGridView.Columns["Comment"].ReadOnly = false;
        }

        private void TileSetDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            String value = TileSetDataGridView.Rows[e.RowIndex].Cells[TileSetDataGridView.Columns["Key"].Index].Value.ToString();

            TileSetEdit.Session = this.Session;
            TileSetEdit.TextureKey = Int32.Parse(value);
            TileSetEdit.Refresh();
        }

        private void WorldDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            Int32 key = Int32.Parse(WorldDataGridView.Rows[e.RowIndex].Cells[WorldDataGridView.Columns["Key"].Index].Value.ToString());

            WorldDefinition worldToView = null;
            foreach (WorldDefinition world in this.Session.Worlds)
            {
                if (world.Key == key) worldToView = world;
            }

            WorldPreview.AllowClicks = false;
            WorldPreview.World = worldToView;
            WorldPreview.Refresh();
        }

        private void WorldDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            WorldDataGridView.Columns["Cells"].Visible = false;

            WorldDataGridView.Columns["Key"].ReadOnly = true;
            WorldDataGridView.Columns["Name"].ReadOnly = false;
            WorldDataGridView.Columns["Filename"].ReadOnly = true;
        }

        private void WorldDeleteButton_Click(object sender, EventArgs e)
        {
            if(WorldDataGridView.SelectedRows.Count == 0)
            {
                MessageBox.Show("Select a world");
                return;
            }

            Int32 key = Int32.Parse( WorldDataGridView.SelectedRows[0].Cells["Key"].Value.ToString());

            WorldDefinition worldToRemove = null;
            foreach(WorldDefinition world in this.Session.Worlds)
            {
                if (world.Key == key) worldToRemove = world;
            }

            this.Session.Worlds.Remove(worldToRemove);
            WorldDataGridView.DataSource = null;
            WorldDataGridView.DataSource = this.Session.Worlds;
        }

        private void WorldAddButton_Click(object sender, EventArgs e)
        {
            WorldDefinition world = new WorldDefinition();
            Int32 newKey = this.Session.GetMaxWorldKey();
            world.Key = newKey + 1;
            world.Filename = world.GetFileName();

            this.Session.Worlds.Add(world);
            WorldDataGridView.DataSource = null;
            WorldDataGridView.DataSource = this.Session.Worlds;
        }

        private void WorldEditButton_Click(object sender, EventArgs e)
        {
            if (WorldDataGridView.CurrentRow == null)
            {
                MessageBox.Show("Select a world");
                return;
            }

            Int32 key = Int32.Parse(WorldDataGridView.CurrentRow.Cells["Key"].Value.ToString());

            WorldDefinition worldToEdit = null;
            foreach (WorldDefinition world in this.Session.Worlds)
            {
                if (world.Key == key) worldToEdit = world;
            }

            if(worldToEdit == null)
            {
                MessageBox.Show("Error");
                return;
            }

            WorldForm form = new WorldForm(this.Session, worldToEdit);
            form.WindowState = FormWindowState.Maximized;
            form.Show();
        }

        private void PlayerCharactetSetSelectButton_Click(object sender, EventArgs e)
        {
            CharacterSetSelectDialog dialog = new CharacterSetSelectDialog(this.Session);
            dialog.CharacterSetKey = this.Session.Player.CharacterSetKey;

            DialogResult result = dialog.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                this.Session.Player.CharacterSetKey = dialog.CharacterSetKey;
                PlayerCharacterSetText.Text = dialog.CharacterSetKey.ToString();
            }
        }

        private void PlayerStartLocationSelectButton_Click(object sender, EventArgs e)
        {
            WorldPositionSelectDialog dialog = new WorldPositionSelectDialog(this.Session);
            dialog.WorldPosition = this.Session.Player.StartPosition.Copy();

            DialogResult result = dialog.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                this.Session.Player.StartPosition = dialog.WorldPosition;
                this.PlayerStartLocationText.Text = dialog.WorldPosition.ToString();
            }
        }

        #endregion

        #region Tileset Animations
        private void TileSetAnimationsDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            String value = TileSetAnimationsDataGridView.Rows[e.RowIndex].Cells[TileSetAnimationsDataGridView.Columns["Key"].Index].Value.ToString();

            TileSetAnimationsSelectPanel.Session = this.Session;
            TileSetAnimationsSelectPanel.TextureKey = Int32.Parse(value);
            TileSetAnimationsSelectPanel.SelectedTileSet = null;
            TileSetAnimationsSelectPanel.Refresh();

            TileSetAnimationsSelectPanel2.Session = this.Session;
            TileSetAnimationsSelectPanel2.TextureKey = Int32.Parse(value);
            TileSetAnimationsSelectPanel2.SelectedTileSet = null;
            TileSetAnimationsSelectPanel2.Refresh();

            TileSetAnimationsSelectPanel3.Session = this.Session;
            TileSetAnimationsSelectPanel3.TextureKey = Int32.Parse(value);
            TileSetAnimationsSelectPanel3.SelectedTileSet = null;
            TileSetAnimationsSelectPanel3.Refresh();

            TileSetAnimationsSelectPanel4.Session = this.Session;
            TileSetAnimationsSelectPanel4.TextureKey = Int32.Parse(value);
            TileSetAnimationsSelectPanel4.SelectedTileSet = null;
            TileSetAnimationsSelectPanel4.Refresh();

            TileSetAnimationsSelectPanel5.Session = this.Session;
            TileSetAnimationsSelectPanel5.TextureKey = Int32.Parse(value);
            TileSetAnimationsSelectPanel5.SelectedTileSet = null;
            TileSetAnimationsSelectPanel5.Refresh();
        }


        private void TileSetAnimationsSelectPanel_MouseClick(object sender, MouseEventArgs e)
        {
            TileSetDefinition selectedTile = TileSetAnimationsSelectPanel.SelectedTileSet;

            //reset
            TileSetAnimationsSelectPanel2.SelectedTileSet = null;
            TileSetAnimationsSelectPanel3.SelectedTileSet = null;
            TileSetAnimationsSelectPanel4.SelectedTileSet = null;
            TileSetAnimationsSelectPanel5.SelectedTileSet = null;

            if (selectedTile != null)
            {
                //set selections
                if (selectedTile.AnimationSequence.Count >= 2)
                {
                    TileSetAnimationsSelectPanel2.SelectedTileSet = Session.GetTileSet(selectedTile.AnimationSequence[1]);
                }

                if (selectedTile.AnimationSequence.Count >= 3)
                {
                    TileSetAnimationsSelectPanel3.SelectedTileSet = Session.GetTileSet(selectedTile.AnimationSequence[2]);
                }

                if (selectedTile.AnimationSequence.Count >= 4)
                {
                    TileSetAnimationsSelectPanel4.SelectedTileSet = Session.GetTileSet(selectedTile.AnimationSequence[3]);
                }

                if (selectedTile.AnimationSequence.Count >= 5)
                {
                    TileSetAnimationsSelectPanel5.SelectedTileSet = Session.GetTileSet(selectedTile.AnimationSequence[4]);
                }
            }

            TileSetAnimationsSelectPanel2.Refresh();
            TileSetAnimationsSelectPanel3.Refresh();
            TileSetAnimationsSelectPanel4.Refresh();
            TileSetAnimationsSelectPanel5.Refresh();
        }


        private void TileSetAnimationsSelectPanel2_MouseClick(object sender, MouseEventArgs e)
        {
            TileSetAnimationsSet();
        }


        private void TileSetAnimationsSelectPanel3_MouseClick(object sender, MouseEventArgs e)
        {
            TileSetAnimationsSet();
        }

        private void TileSetAnimationsSelectPanel4_MouseClick(object sender, MouseEventArgs e)
        {
            TileSetAnimationsSet();
        }

        private void TileSetAnimationsSelectPanel5_MouseClick(object sender, MouseEventArgs e)
        {
            TileSetAnimationsSet();
        }


        private void TileSetAnimationsSet()
        {
            TileSetDefinition tileSetDefinition = TileSetAnimationsSelectPanel.SelectedTileSet;

            if (tileSetDefinition == null) return;
            
            Int32 t1 = TileSetAnimationsSelectPanel.SelectedTileSet != null ? TileSetAnimationsSelectPanel.SelectedTileSet.Key : -1;
            Int32 t2 = TileSetAnimationsSelectPanel2.SelectedTileSet != null ? TileSetAnimationsSelectPanel2.SelectedTileSet.Key : -1;
            Int32 t3 = TileSetAnimationsSelectPanel3.SelectedTileSet != null ? TileSetAnimationsSelectPanel3.SelectedTileSet.Key : -1;
            Int32 t4 = TileSetAnimationsSelectPanel4.SelectedTileSet != null ? TileSetAnimationsSelectPanel4.SelectedTileSet.Key : -1;
            Int32 t5 = TileSetAnimationsSelectPanel5.SelectedTileSet != null ? TileSetAnimationsSelectPanel5.SelectedTileSet.Key : -1;

            tileSetDefinition.SetAnimationSequence(t1, t2, t3, t4, t5);
        }


        #endregion

        #region Enemies
        private Int32 activeEnemyKey;
        private Boolean activeEnemyLoad;

        private void EnemiesDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            String value = EnemiesDataGridView.Rows[e.RowIndex].Cells[EnemiesDataGridView.Columns[0].Index].Value.ToString();
            Int32 enemyKey = Int32.Parse(value);

            activeEnemyKey = enemyKey;

            EnemyDefinition enemy = null;
            foreach(EnemyDefinition ed in this.Session.Enemies)
            {
                if (ed.Key == enemyKey) enemy = ed;
            }
            if (enemy == null) return;

            activeEnemyLoad = false;

            EnemiesLoadInventoryItemDropDowns();

            EnemiesNameText.Text = enemy.Name;
            EnemiesCharacterSetText.Text = enemy.CharacterSetKey.ToString();
            EnemiesAttackText.Text = enemy.Attack.ToString();
            EnemiesDefenseText.Text = enemy.Defence.ToString();
            EnemiesHealthText.Text = enemy.Health.ToString();
            EnemiesAttackSpeedText.Text = enemy.AttackSpeed.ToString();
            EnemiesHideIfVariableTrueText.Text = enemy.HideIfVariableTrue;
            EnemiesVariableToSetOnDeathText.Text = enemy.VariableToSetTrueUponDeath;
            EnemiesAttackTypeCombo.SelectedItem = (AttackTypes)enemy.AttackKey;
            EnemiesMovementTypeCombo.SelectedItem = (MovementTypes) enemy.MovementKey;

            EnemiesLoadPreview();

            //Load Enemy Inventory
            EnemiesInventory1Check.Checked = false;
            EnemiesInventory2Check.Checked = false;
            EnemiesInventory3Check.Checked = false;
            EnemiesInventory1Item.SelectedItem = null;
            EnemiesInventory2Item.SelectedItem = null;
            EnemiesInventory3Item.SelectedItem = null;
            EnemiesInventory1Quantity.Text = "0";
            EnemiesInventory2Quantity.Text = "0";
            EnemiesInventory3Quantity.Text = "0";
            EnemiesInventory1Chance.Text = "0";
            EnemiesInventory2Chance.Text = "0";
            EnemiesInventory3Chance.Text = "0";

            if (enemy.Inventory.Count >= 1)
            {
                EnemiesInventory1Check.Checked = true;
                EnemiesInventory1Quantity.Text = enemy.Inventory[0].Quantity.ToString();
                EnemiesInventory1Item.SelectedValue = enemy.Inventory[0].ItemKey;
                EnemiesInventory1Chance.Text = enemy.Inventory[0].ChanceToDrop.ToString();
            }
            if (enemy.Inventory.Count >= 2)
            {
                EnemiesInventory2Check.Checked = true;
                EnemiesInventory2Quantity.Text = enemy.Inventory[1].Quantity.ToString();
                EnemiesInventory2Item.SelectedValue = enemy.Inventory[1].ItemKey;
                EnemiesInventory2Chance.Text = enemy.Inventory[1].ChanceToDrop.ToString();
            }
            if (enemy.Inventory.Count >= 3)
            {
                EnemiesInventory3Check.Checked = true;
                EnemiesInventory3Quantity.Text = enemy.Inventory[2].Quantity.ToString();
                EnemiesInventory3Item.SelectedValue = enemy.Inventory[2].ItemKey;
                EnemiesInventory3Chance.Text = enemy.Inventory[2].ChanceToDrop.ToString();
            }


            activeEnemyLoad = true;
        }

        private void EnemiesLoadInventoryItemDropDowns()
        {
            KeyValuePair<Int32, String> obj;

            EnemiesInventory1Item.ValueMember = "Key";
            EnemiesInventory1Item.DisplayMember = "Value";
            EnemiesInventory2Item.ValueMember = "Key";
            EnemiesInventory2Item.DisplayMember = "Value";
            EnemiesInventory3Item.ValueMember = "Key";
            EnemiesInventory3Item.DisplayMember = "Value";

            IList<KeyValuePair<Int32, String>> items1 = new List<KeyValuePair<Int32, String>>();
            IList<KeyValuePair<Int32, String>> items2 = new List<KeyValuePair<Int32, String>>();
            IList<KeyValuePair<Int32, String>> items3 = new List<KeyValuePair<Int32, String>>();

            foreach (ItemDefinition item in this.Session.Items)
            {
                obj = new KeyValuePair<Int32, String>(item.Key, item.Name);
                items1.Add(obj);
                obj = new KeyValuePair<Int32, String>(item.Key, item.Name);
                items2.Add(obj);
                obj = new KeyValuePair<Int32, String>(item.Key, item.Name);
                items3.Add(obj);
            }

            EnemiesInventory1Item.DataSource = items1;
            EnemiesInventory2Item.DataSource = items2;
            EnemiesInventory3Item.DataSource = items3;


        }

        private void EnemiesLoadPreview()
        {
            Int32 characterSetKey = Int32.Parse(EnemiesCharacterSetText.Text);
            Int32 textureKey = -1;
            String filePath = "";

            foreach(CharacterSetDefinition characterSetDefinition in this.Session.CharacterSets)
            {
                if (characterSetDefinition.Key == characterSetKey) textureKey = characterSetDefinition.TextureKey;
            }

            foreach (RawResource texture in this.Session.Textures)
            {
                if (texture.Key == textureKey) filePath = texture.FilePath;
            }

            EnemiesTexturePreview.ImageLocation = RawResourceHelper.GetFilePathForTexture(this.Session.WorkingDirectory, filePath);
            EnemiesTexturePreview.SizeMode = PictureBoxSizeMode.Zoom;
        }

        private void EnemiesCharacterSetSelectButton_Click(object sender, EventArgs e)
        {
            CharacterSetSelectDialog dialog = new CharacterSetSelectDialog(this.Session);
            dialog.CharacterSetKey = Int32.Parse(EnemiesCharacterSetText.Text);

            DialogResult result = dialog.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                EnemiesCharacterSetText.Text = dialog.CharacterSetKey.ToString();
                EnemiesLoadPreview();
            }
        }

        private void EnemiesAddButton_Click(object sender, EventArgs e)
        {
            Int32 maxKey = -1;

            foreach(EnemyDefinition enemyDefinition in this.Session.Enemies)
            {
                if (maxKey < enemyDefinition.Key) maxKey = enemyDefinition.Key;
            }

            EnemyDefinition enemy = new EnemyDefinition()
            {
                Key = maxKey + 1,
                Name = ""
            };

            this.Session.Enemies.Add(enemy);

            EnemiesDataGridView.DataSource = null;
            EnemiesDataGridView.DataSource = this.Session.Enemies;
            EnemiesDataGridView.Refresh();
        }

        private void UpdateEnemy(object sender, EventArgs e)
        {
            if (activeEnemyLoad == false) return;

            EnemyDefinition enemy = null;
            foreach (EnemyDefinition ed in this.Session.Enemies)
            {
                if (ed.Key == activeEnemyKey) enemy = ed;
            }
            if (enemy == null) return;

            enemy.Name = EnemiesNameText.Text;
            enemy.CharacterSetKey = Int32.Parse(EnemiesCharacterSetText.Text);
            enemy.Attack = Int32.Parse(EnemiesAttackText.Text.Equals("") ? "0" : EnemiesAttackText.Text);
            enemy.Defence = Int32.Parse(EnemiesDefenseText.Text.Equals("") ? "0" : EnemiesDefenseText.Text);
            enemy.Health = Int32.Parse(EnemiesHealthText.Text.Equals("") ? "0" : EnemiesHealthText.Text);
            enemy.AttackSpeed = Double.Parse(EnemiesAttackSpeedText.Text.Equals("") ? "0" : EnemiesAttackSpeedText.Text);
            enemy.HideIfVariableTrue = EnemiesHideIfVariableTrueText.Text;
            enemy.VariableToSetTrueUponDeath = EnemiesVariableToSetOnDeathText.Text;
            enemy.AttackKey = (Int32) ((AttackTypes)EnemiesAttackTypeCombo.SelectedItem);
            enemy.MovementKey = (Int32) ((MovementTypes)EnemiesMovementTypeCombo.SelectedItem);

            //Save Enemy Inventory
            enemy.Inventory.Clear();
            if ((EnemiesInventory1Check.Checked) && (EnemiesInventory1Item.SelectedItem != null) && (EnemiesInventory1Quantity.Text.Equals("") == false))
            {
                enemy.Inventory.Add(new ItemContainer()
                {
                    ItemKey = Int32.Parse(EnemiesInventory1Item.SelectedValue.ToString()),
                    Quantity = Int32.Parse(EnemiesInventory1Quantity.Text),
                    ChanceToDrop = Double.Parse(EnemiesInventory1Chance.Text)
            });
            }
            if ((EnemiesInventory2Check.Checked) && (EnemiesInventory2Item.SelectedItem != null) && (EnemiesInventory2Quantity.Text.Equals("")==false))
            {
                enemy.Inventory.Add(new ItemContainer()
                {
                    ItemKey = Int32.Parse(EnemiesInventory2Item.SelectedValue.ToString()),
                    Quantity = Int32.Parse(EnemiesInventory2Quantity.Text),
                    ChanceToDrop = Double.Parse(EnemiesInventory2Chance.Text)
                });
            }
            if ((EnemiesInventory3Check.Checked) && (EnemiesInventory3Item.SelectedItem != null) && (EnemiesInventory3Quantity.Text.Equals("") == false))
            {
                enemy.Inventory.Add(new ItemContainer()
                {
                    ItemKey = Int32.Parse(EnemiesInventory3Item.SelectedValue.ToString()),
                    Quantity = Int32.Parse(EnemiesInventory3Quantity.Text),
                    ChanceToDrop = Double.Parse(EnemiesInventory3Chance.Text)
                });
            }
        }
        #endregion

        #region Items
        private Int32 activeItemKey;
        private Boolean activeItemLoad;

        private void ItemsGridview_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            String value = ItemsDataGridView.Rows[e.RowIndex].Cells[ItemsDataGridView.Columns[0].Index].Value.ToString();
            Int32 itemKey = Int32.Parse(value);

            activeItemKey = itemKey;

            ItemDefinition item = null;
            foreach(ItemDefinition i in this.Session.Items)
            {
                if (i.Key == itemKey) item = i;
            }
            if (item == null) return;

            activeItemLoad = false;

            ItemsNameText.Text = item.Name;
            ItemsItemTypeCombo.SelectedItem = (ItemDefinition.ItemType)item.ItemTypeKey;
            ItemsTextureText.Text = item.TextureKey.ToString();
            ItemsIsFixedPower.Checked = item.IsFixedPower;
            ItemsPowerText.Text = item.Power.ToString();
            ItemsDescriptionText.Text = item.Description;
            ItemsMaxCapacityText.Text = item.MaxCapacity.ToString();
            ItemsLoadPreview();

            activeItemLoad = true;
        }

        private void ItemsLoadPreview()
        {
            Int32 textureKey = Int32.Parse(ItemsTextureText.Text);
            String filePath = "";

            foreach (RawResource texture in this.Session.Textures)
            {
                if (texture.Key == textureKey) filePath = texture.FilePath;
            }

            ItemsTexturePreview.ImageLocation = RawResourceHelper.GetFilePathForTexture(this.Session.WorkingDirectory, filePath);
            ItemsTexturePreview.SizeMode = PictureBoxSizeMode.Zoom;
        }

        private void ItemsAddButton_Click(object sender, EventArgs e)
        {
            Int32 maxKey = -1;

            foreach (ItemDefinition itemDefinition in this.Session.Items)
            {
                if (maxKey < itemDefinition.Key) maxKey = itemDefinition.Key;
            }

            ItemDefinition item = new ItemDefinition()
            {
                Key = maxKey + 1,
                Name = ""
            };

            this.Session.Items.Add(item);

            ItemsDataGridView.DataSource = null;
            ItemsDataGridView.DataSource = this.Session.Items;
            ItemsDataGridView.Refresh();
        }

        private void ItemsTexturesButton_Click(object sender, EventArgs e)
        {
            TextureSelectDialog dialog = new TextureSelectDialog(this.Session);
            dialog.TextureKey = Int32.Parse(ItemsTextureText.Text);

            DialogResult result = dialog.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                ItemsTextureText.Text = dialog.TextureKey.ToString();
                ItemsLoadPreview();
            }
        }

        private void UpdateItem(object sender, EventArgs e)
        {
            if (activeItemLoad == false) return;

            ItemDefinition item = null;
            foreach (ItemDefinition i in this.Session.Items)
            {
                if (i.Key == activeItemKey) item = i;
            }
            if (item == null) return;

            item.Name = ItemsNameText.Text;
            item.ItemTypeKey = (Int32)((ItemDefinition.ItemType)ItemsItemTypeCombo.SelectedItem);
            item.TextureKey = Int32.Parse(ItemsTextureText.Text);
            item.IsFixedPower = ItemsIsFixedPower.Checked;
            item.Power = Int32.Parse(ItemsPowerText.Text.Equals("") ? "0" : ItemsPowerText.Text);
            item.Description = ItemsDescriptionText.Text;
            item.MaxCapacity = Int32.Parse(ItemsMaxCapacityText.Text.Equals("") ? "1" : ItemsMaxCapacityText.Text);
        }

        #endregion

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isGoodToClose == false)
            {
                e.Cancel = true;
            }
        }
    }
}
