using GameMaker.Models;
using System;
using System.Windows.Forms;
using GameMaker.UI;
using ActionGame.GameResources.Models;
using ActionGame.RawResources.Models;


namespace GameMaker
{
    public partial class WorldForm : Form
    {
        private Session session;
        private WorldDefinition world;

        public enum EditMode { Tile, Door, NPC, Enemy };


        public WorldForm(Session session, WorldDefinition world)
        {
            InitializeComponent();

            this.session = session;
            this.world = world;
            this.Text = "World - " + world.Name;

            TileSetSelector.TextureKey = -1;
            TileSetSelector.Session = this.session;

            TileSetTexture.ValueMember = "Key";
            TileSetTexture.DisplayMember = "FilePath";
            TileSetTexture.DataSource = this.session.GetListOfTexturesUsedByTileSets();

            WorldPreview.SongSelectComobBox = CellMusicSelect;
            WorldPreview.World = this.world;
            WorldPreview.AllowClicks = true;
            WorldPreview.CellSize = 24;
            WorldPreview.WorldCellEditPanel = WorldCellEditPanel;
            WorldPreview.Refresh();

            WorldCellEditPanel.Session = this.session;
            WorldCellEditPanel.TileSetSelectPanel = TileSetSelector;
        }

        private void WorldForm_Load(object sender, EventArgs e)
        {
            LoadEditModes();
            LoadSongs();
        }

        private void LoadSongs()
        {
            CellMusicSelect.Items.Clear();

            foreach(RawResource song in this.session.Songs)
            {
                CellMusicSelect.Items.Add(song);
            }
        }

        private void LoadEditModes()
        {
            foreach(EditMode m in Enum.GetValues(typeof(EditMode)))
            {
                EditModeList.Items.Add(m);
            }

            EditModeList.SelectedIndex = 0;
        }

        private void TileSetTexture_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (TileSetTexture.SelectedValue == null) return;

            TileSetSelector.TextureKey = Int32.Parse(TileSetTexture.SelectedValue.ToString());
            TileSetSelector.Refresh();
        }

        private void AddCellButton_Click(object sender, EventArgs e)
        {
            if (WorldPreview.SelectedCell == null)
            {
                MessageBox.Show("No space selected");
                return;
            }

            if (this.world.Cells.Contains(WorldPreview.SelectedCell))
            {
                MessageBox.Show("Cell already exists");
                return;
            }

            WorldCellDefinition cell = WorldPreview.SelectedCell;
            cell.Initialize();
            this.world.Cells.Add(cell);

            WorldPreview.SelectedCell = null;
            WorldPreview.Refresh();
        }

        private void DeleteCellButton_Click(object sender, EventArgs e)
        {
            if(WorldPreview.SelectedCell == null)
            {
                MessageBox.Show("No cell selected");
                return;
            }

            if(this.world.Cells.Contains(WorldPreview.SelectedCell) == false)
            {
                MessageBox.Show("Cell does not exist");
                return;
            }

            DialogResult result = MessageBox.Show("Are you sure you want to delete this cell?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
            {
                this.world.Cells.Remove(WorldPreview.SelectedCell);

                if (WorldCellEditPanel.WorldCell == WorldPreview.SelectedCell)
                {
                    WorldCellEditPanel.WorldCell = null;
                    WorldCellEditPanel.Refresh();
                }

                WorldPreview.SelectedCell = null;
                WorldPreview.Refresh();
            }
        }

        private void EditModeList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (EditModeList.SelectedIndex == -1) return;

            EditMode newMode = (EditMode)Enum.Parse(typeof(EditMode), EditModeList.SelectedItem.ToString());

            if(newMode == EditMode.Tile)
            {
                AddItemButton.Visible = false;
                DeleteItemButton.Visible = false;
            }
            else
            {
                AddItemButton.Visible = true;
                DeleteItemButton.Visible = true;
            }

            WorldCellEditPanel.EditMode = newMode;
            WorldCellEditPanel.Refresh();
        }

        private void AddItemButton_Click(object sender, EventArgs e)
        {
            if (WorldCellEditPanel.SelectedTileX == null)
            {
                MessageBox.Show("Select a tile");
                return;
            }

            if(WorldCellEditPanel.EditMode == EditMode.Door)
            {
                AddDoor();
            }
            else if (WorldCellEditPanel.EditMode == EditMode.NPC)
            {
                AddNPC();
            }
            else if (WorldCellEditPanel.EditMode == EditMode.Enemy)
            {
                AddEnemy();
            }
        }

        private void DeleteItemButton_Click(object sender, EventArgs e)
        {
            if (WorldCellEditPanel.SelectedTileX == null)
            {
                MessageBox.Show("Select a tile");
                return;
            }

            if (WorldCellEditPanel.EditMode == EditMode.Door)
            {
                RemoveDoor();
            }
            else if (WorldCellEditPanel.EditMode == EditMode.NPC)
            {
                RemoveNPC();
            }
            else if (WorldCellEditPanel.EditMode == EditMode.Enemy)
            {
                RemoveEnemy();
            }
        }

        private void CellMusicSelect_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CellMusicSelect.SelectedItem == null) return;
            if (WorldCellEditPanel.WorldCell == null) return;

            RawResource song = (RawResource)CellMusicSelect.SelectedItem;

            WorldCellEditPanel.WorldCell.SongKey = song.Key;
        }


        private void AddDoor()
        {
            DoorDefinition currentDoor = WorldCellEditPanel.GetSelectedDoor();

            WorldPositionSelectDialog dialog = new WorldPositionSelectDialog(this.session);

            if (currentDoor != null)
            {
                WorldPosition currentPosition = new WorldPosition()
                {
                    WorldMapKey = currentDoor.DestinationMapKey,
                    WorldCellX = currentDoor.DestinationCellX,
                    WorldCellY = currentDoor.DestinationCellY,
                    PositionX = currentDoor.DestinationTileX,
                    PositionY = currentDoor.DestinationTileY
                };

                dialog.WorldPosition = currentPosition;
            }

            DialogResult result = dialog.ShowDialog();

            if (result == DialogResult.OK)
            {
                WorldPosition newPosition = dialog.WorldPosition;

                if (currentDoor != null)
                {
                    //update
                    currentDoor.DestinationMapKey = newPosition.WorldMapKey;
                    currentDoor.DestinationCellX = newPosition.WorldCellX;
                    currentDoor.DestinationCellY = newPosition.WorldCellY;
                    currentDoor.DestinationTileX = newPosition.PositionX;
                    currentDoor.DestinationTileY = newPosition.PositionY;
                }
                else
                {
                    //add
                    DoorDefinition newDoor = new DoorDefinition()
                    {
                        DestinationMapKey = newPosition.WorldMapKey,
                        DestinationCellX = newPosition.WorldCellX,
                        DestinationCellY = newPosition.WorldCellY,
                        DestinationTileX = newPosition.PositionX,
                        DestinationTileY = newPosition.PositionY,
                        X = WorldCellEditPanel.SelectedTileX.Value,
                        Y = WorldCellEditPanel.SelectedTileY.Value
                    };

                    WorldCellEditPanel.WorldCell.Doors.Add(newDoor);
                    WorldCellEditPanel.Refresh();
                }
            }
        }


        private void RemoveDoor()
        {
            DoorDefinition door = WorldCellEditPanel.GetSelectedDoor();

            if (door == null)
            {
                MessageBox.Show("No door selected");
            }
            else
            {
                DialogResult result = MessageBox.Show("Are you sure?", "Confirm", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    WorldCellEditPanel.WorldCell.Doors.Remove(door);
                    WorldCellEditPanel.Refresh();
                }
            }
        }


        private void AddNPC()
        {
            NonPlayerCharacterDefinition currentNPC = WorldCellEditPanel.GetSelectedNPC();
            NonPlayerCharacterDialog dialog = new NonPlayerCharacterDialog(this.session);

            if(currentNPC != null)
            {
                dialog.NonPlayerCharacterDefinition = currentNPC;
            }

            DialogResult result = dialog.ShowDialog();
            if(result == DialogResult.OK)
            {
                NonPlayerCharacterDefinition newNPC = dialog.NonPlayerCharacterDefinition;

                if(currentNPC != null)
                {
                    //update
                    currentNPC.ActivationKey = newNPC.ActivationKey;
                    currentNPC.CharacterSetKey = newNPC.CharacterSetKey;
                    currentNPC.MovementKey = newNPC.MovementKey;
                    currentNPC.PlotScriptText = newNPC.PlotScriptText;
                    currentNPC.HideIfVariableTrue = newNPC.HideIfVariableTrue;
                    currentNPC.ShowIfVariableTrue = newNPC.ShowIfVariableTrue;
                }
                else
                {
                    //add
                    newNPC.TileX = WorldCellEditPanel.SelectedTileX.Value;
                    newNPC.TileY = WorldCellEditPanel.SelectedTileY.Value;

                    WorldCellEditPanel.WorldCell.NPCs.Add(newNPC);
                    WorldCellEditPanel.Refresh();
                }
            }
        }


        private void RemoveNPC()
        {
            NonPlayerCharacterDefinition npc = WorldCellEditPanel.GetSelectedNPC();

            if (npc == null)
            {
                MessageBox.Show("No NPC selected");
            }
            else
            {
                DialogResult result = MessageBox.Show("Are you sure?", "Confirm", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    WorldCellEditPanel.WorldCell.NPCs.Remove(npc);
                    WorldCellEditPanel.Refresh();
                }
            }
        }


        private void AddEnemy()
        {
            EnemyDefinitionPlacement currentEnemyPlacement = WorldCellEditPanel.GetSelectedEnemyPlacement();
            EnemySelectDialog dialog = new EnemySelectDialog(this.session);

            if (currentEnemyPlacement != null)
            {
                dialog.EnemyKey = currentEnemyPlacement.Key;
            }

            DialogResult result = dialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                Int32 enemyKey = dialog.EnemyKey;

                if (currentEnemyPlacement != null)
                {
                    //update
                    currentEnemyPlacement.Key = enemyKey;
                }
                else
                {
                    //add
                    EnemyDefinitionPlacement enemyPlacement = new EnemyDefinitionPlacement()
                    {
                        Key = enemyKey,
                        TileX = WorldCellEditPanel.SelectedTileX.Value,
                        TileY = WorldCellEditPanel.SelectedTileY.Value
                    };

                    WorldCellEditPanel.WorldCell.EnemyDefinitionPlacements.Add(enemyPlacement);
                    WorldCellEditPanel.Refresh();
                }
            }
        }


        private void RemoveEnemy()
        {
            EnemyDefinitionPlacement currentEnemyPlacement = WorldCellEditPanel.GetSelectedEnemyPlacement();

            if (currentEnemyPlacement == null)
            {
                MessageBox.Show("No Enemy selected");
            }
            else
            {
                DialogResult result = MessageBox.Show("Are you sure?", "Confirm", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    WorldCellEditPanel.WorldCell.EnemyDefinitionPlacements.Remove(currentEnemyPlacement);
                    WorldCellEditPanel.Refresh();
                }
            }
        }


    }
}
