using ActionGame.GameArtifacts.Models.Characters;
using ActionGame.GameResources.Models;
using ActionGame.RawResources.Models;
using GameMaker.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Windows.Forms;


namespace GameMaker.UI
{
    public partial class NonPlayerCharacterDialog : Form
    {
        private NonPlayerCharacterDefinition nonPlayerCharacterDefinition;
        private Session session;

        private NonPlayerCharacterDialog()
        {
            
        }

        public NonPlayerCharacterDialog(Session session)
        {
            this.session = session;

            InitializeComponent();

            Dictionary<Int32, String> activationSource = new Dictionary<Int32, String>();
            foreach(NonPlayerCharacterDefinition.Activation activation in Enum.GetValues(typeof(NonPlayerCharacterDefinition.Activation)))
            {
                activationSource.Add((Int32)activation, activation.ToString());
            }
            ActivationSelect.DataSource = new BindingSource(activationSource, null);
            ActivationSelect.DisplayMember = "Value";
            ActivationSelect.ValueMember = "Key";

            Dictionary<Int32, String> movementSource = new Dictionary<Int32, String>();
            foreach (MovementTypes movement in Enum.GetValues(typeof(MovementTypes)))
            {
                movementSource.Add((Int32)movement, movement.ToString());
            }
            MovementSelect.DataSource = new BindingSource(movementSource, null);
            MovementSelect.DisplayMember = "Value";
            MovementSelect.ValueMember = "Key";

            PlotGridView.AutoGenerateColumns = false;
            PlotGridView.AllowUserToAddRows = true;
            PlotGridView.AllowUserToDeleteRows = true;
            PlotGridView.AllowUserToResizeRows = true;

            PlotColumnType.Items.Clear();
            String[] types = Enum.GetNames(typeof(PlotItem.Types));
            PlotColumnType.Items.Add("");
            foreach (String type in types)
            {
                PlotColumnType.Items.Add(type);
            }

            PlotColumnItem.Items.Clear();
            PlotColumnItem.ValueMember = "Key";
            PlotColumnItem.DisplayMember = "Name";
            PlotColumnItem.Items.Add(new ItemDefinition() { Key = -1, Name = "" });
            foreach (ItemDefinition item in session.Items)
            {
                PlotColumnItem.Items.Add(item);
            }
        }


        public NonPlayerCharacterDefinition NonPlayerCharacterDefinition
        {
            get
            {
                return nonPlayerCharacterDefinition;
            }
            set
            {
                nonPlayerCharacterDefinition = value;

                this.ActivationSelect.SelectedValue = nonPlayerCharacterDefinition.ActivationKey;
                this.MovementSelect.SelectedValue = nonPlayerCharacterDefinition.MovementKey;
                this.CharacterSetKeyText.Text = nonPlayerCharacterDefinition.CharacterSetKey.ToString();
                this.CharacterSetNameText.Text = GetCharacterSetName(nonPlayerCharacterDefinition.CharacterSetKey);
                this.HideIfVariableTrueText.Text = nonPlayerCharacterDefinition.HideIfVariableTrue;
                this.ShowIfVariableTrueText.Text = nonPlayerCharacterDefinition.ShowIfVariableTrue;

                PopulatePlotGridview(nonPlayerCharacterDefinition.PlotScriptText);
            }
        }

        private void NonPlayerCharacterDialog_Load(object sender, EventArgs e)
        {
            
        }

        private void CancelDialogButton_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Hide();
        }

        private void ConfirmDialogButton_Click(object sender, EventArgs e)
        {
            this.nonPlayerCharacterDefinition = new NonPlayerCharacterDefinition()
            {
                PlotScriptText = GetJsonTextFromPlotGridview(),
                CharacterSetKey = Int32.Parse(this.CharacterSetKeyText.Text),
                ActivationKey = (Int32)ActivationSelect.SelectedValue,
                MovementKey = (Int32) MovementSelect.SelectedValue,
                HideIfVariableTrue = HideIfVariableTrueText.Text,
                ShowIfVariableTrue = ShowIfVariableTrueText.Text
            };

            this.DialogResult = DialogResult.OK;
            this.Hide();
        }

        
        private String GetCharacterSetName(Int32 key)
        {
            String name = "";

            foreach(CharacterSetDefinition characterSet in this.session.CharacterSets)
            {
                if(characterSet.Key == key)
                {
                    foreach(RawResource texture in this.session.Textures)
                    {
                        if(texture.Key == characterSet.TextureKey)
                        {
                            name = texture.FilePath;
                        }
                    }
                }
            }

            return name;
        }

        private void CharacetSetChooseButton_Click(object sender, EventArgs e)
        {
            CharacterSetSelectDialog dialog = new CharacterSetSelectDialog(session);

            DialogResult result = dialog.ShowDialog();
            if(result == DialogResult.OK)
            {
                this.CharacterSetKeyText.Text = dialog.CharacterSetKey.ToString();
                this.CharacterSetNameText.Text = GetCharacterSetName(dialog.CharacterSetKey);
            }
        }


        private void PopulatePlotGridview(String jsonPlotScriptText)
        {
            IList<PlotItem> plot = JsonConvert.DeserializeObject<List<PlotItem>>(jsonPlotScriptText);
            PlotGridView.Rows.Clear();
            foreach (PlotItem item in plot)
            {
                PlotGridView.Rows.Add(new object[] { item.Type.ToString(), item.Value, item.VariableName, item.VariableValue, item.ItemKey == null ? -1 : item.ItemKey, item.Quantity, item.Health, item.Attack, item.Defence });
            }
        }


        private String GetJsonTextFromPlotGridview()
        {
            List<ExpandoObject> plot = new List<ExpandoObject>();

            foreach(DataGridViewRow row in PlotGridView.Rows)
            {
                if (row.IsNewRow == false)
                {
                    dynamic item = new ExpandoObject();

                    if (row.Cells[0].Value != null)
                    {
                        item.Type = (PlotItem.Types)Enum.Parse(typeof(PlotItem.Types), (String)row.Cells[0].Value);
                    }
                    else
                    {
                        item.Type = PlotItem.Types.Text;
                    }

                    if (row.Cells[1].Value != null)
                    {
                        item.Value = (String)row.Cells[1].Value;
                    }

                    if(row.Cells[2].Value != null)
                    {
                        item.VariableName = (String)row.Cells[2].Value;
                        if (row.Cells[3].Value != null)
                        {
                            item.VariableValue = (Boolean)row.Cells[3].Value;
                        }
                        else
                        {
                            item.VariableValue = false;
                        }
                    }
                    
                    if ((row.Cells[4].Value != null) && (((Int32)row.Cells[4].Value) != -1))
                    {
                        item.ItemKey = (Int32)row.Cells[4].Value;
                        if (row.Cells[5].Value != null) item.Quantity = Int32.Parse(row.Cells[5].Value.ToString());
                    }

                    if (row.Cells[6].Value != null) item.Health = Int32.Parse(row.Cells[6].Value.ToString());
                    if (row.Cells[7].Value != null) item.Attack = Int32.Parse(row.Cells[7].Value.ToString());
                    if (row.Cells[8].Value != null) item.Defence = Int32.Parse(row.Cells[8].Value.ToString());

                    plot.Add(item);
                }
            }

            String plotText = JsonConvert.SerializeObject(plot);

            return plotText;
        }

    }
}
