using System;
using System.Windows.Forms;
using MVShareStore;

namespace MVConfigHandler.forms
{
	/// <summary>
	/// Edit the Data Items in the supplied DataPack / DataShare or DataStore. Add, Delete, Insert Data Items. Modify the Data Items already there. Then Save, Post or Repost the DataPack / DataShare or DataStore after it has been modified.
	/// </summary>
	public partial class EditDataItems : Form
	{
		/// <summary>
		/// Edit the Data Items in the supplied DataPack / DataShare or DataStore. Add, Delete, Insert Data Items. Modify the Data Items already there. Then Save, Post or Repost the DataPack / DataShare or DataStore after it has been modified.
		/// </summary>
		/// <param name="config">The MV Config File to be edited</param>
		public EditDataItems(MVConfigFile config) {
			InitializeComponent();

			if (config == null) config = new MVConfigFile();
			ConfigFile = config;
			RefreshList(ConfigFile);
			StatusBar.Items[0].Text = this.Text = "List / Edit the Data Items / Config Entries in the Config File";

			if (ConfigFile.getCount() == 0) setLoad();
		}

		/// <summary>
		/// The Config File to list / edit the data items in
		/// </summary>
		public MVConfigFile ConfigFile { get; private set; } = null;

		private void ListView_Resize(object sender, EventArgs e) {
			ListView.Columns[3].Width = ListView.Width - (ListView.Columns[0].Width + ListView.Columns[1].Width + ListView.Columns[2].Width + 5);
		}

		private void SelectedIndex_Changed(object sender, EventArgs e) {
			if ((ListView.Items.Count > 0) && (ListView.SelectedItems.Count > 0)) {
				InsertBtn.Enabled = EditBtn.Enabled = DeleteBtn.Enabled = true;
				InsertDataItemsContextMenuItem.Enabled = EditDataItemContextMenuItem.Enabled = DeleteDataItemContextMenuItem.Enabled = true;
				_currentItem = ListView.SelectedItems[0];
				_currentIndex = ListView.SelectedIndices[0];
			}
			else
				_currentIndex = -1;
		}

		private void ListView_KeyDown(object sender, KeyEventArgs e) {
			if (e.Control && e.KeyCode == Keys.A) AddBtn_Click(sender, e);
			if (e.KeyCode == Keys.Enter) EditBtn_Click(sender, e);
			else if (e.KeyCode == Keys.Insert) InsertBtn_Click(sender, e);
			else if (e.KeyCode == Keys.Delete) DeleteBtn_Click(sender, e);
			if (e.KeyCode == Keys.Escape) CancelBtn_Click(sender, e);
		}

		private void ListView_DoubleClick(object sender, EventArgs e) {
			EditBtn_Click(sender, e);
		}

		private void AddBtn_Click(object sender, EventArgs e) {
			AddDataItem addDataItem = null;
			addDataItem = new AddDataItem(ConfigFile);

			//	If all was good then merge the AddDataItem DataPack with ours and refresh the Data Item list in the form.
			if (addDataItem.ShowDialog() == DialogResult.OK) {
				if (addDataItem.DataItems.ItemCount > 0) {
					ConfigFile.getData().AddRange(addDataItem.DataItems);
					RefreshList(ConfigFile);
				}
			}
			if (ListView.Items.Count > 0) setSavePost();
		}

		private void InsertBtn_Click(object sender, EventArgs e) {
			if ((_currentItem == null) || (_currentIndex == -1)) return;

			int index = _currentIndex;
			AddDataItem addDataItem = null;
			addDataItem = new AddDataItem(ConfigFile, null, index);

			if (addDataItem.ShowDialog() == DialogResult.OK) {
				if (addDataItem.DataItems.ItemCount > 0) {
					ConfigFile.getData().InsertRange(index, addDataItem.DataItems);
					RefreshList(ConfigFile);
				}
			}
			if (ListView.Items.Count > 0) setSavePost();
		}

		private void EditBtn_Click(object sender, EventArgs e) {
			if ((_currentItem == null) || (_currentIndex == -1)) return;
			string name = _currentItem.SubItems[2].Text;
			DataItem dataItem = null;

			AddDataItem addDataItem = null;
			EditDataItems editDataItems = null;
			DialogResult result = DialogResult.Cancel;

			//	Get the current DataItem and select whether to use the AddDataItem form or the EditDataItems form
			dataItem = ConfigFile.getData().Items[_currentIndex];

			//	See which form we need to create and display
			if (dataItem.Type == MVShareStore.DataType.TYPE.DATAPACK) {
				MVConfigFile config = new MVConfigFile(dataItem.DatapackValue);
				editDataItems = new EditDataItems(config);
			}
			else
				addDataItem = new AddDataItem(ConfigFile, dataItem);

			//	If this is a DataPack then go straight to another copy of this EditDataItems form
			if (dataItem.Type == MVShareStore.DataType.TYPE.DATAPACK) {
				if ((result = editDataItems.ShowDialog()) == DialogResult.OK) {
					dataItem.DatapackValue = editDataItems.ConfigFile.getData();
				}
			}
			//	Otherwise go to the normal Add Data Items form
			else {
				if((result = addDataItem.ShowDialog()) == DialogResult.OK)
					dataItem = addDataItem.DataItem;
			}

			//	User clicked Close so show the result of their changes
			if (result == DialogResult.OK) {
				int index = _currentIndex;
				ListView.Items[index].SubItems[1].Text = _currentItem.SubItems[1].Text = dataItem.Desc;
				ListView.Items[index].SubItems[2].Text = _currentItem.SubItems[2].Text = dataItem.Name;
				ListView.Items[index].SubItems[3].Text = _currentItem.SubItems[3].Text = dataItem.AsStringValue;

				//	Now update the DataPack / DataShare backing this form. Use both available functions in order to fully test them
				string error = null;
				if (!string.IsNullOrEmpty(name)) {
					if (ConfigFile.getData().Edit(name, dataItem) == null)
						MessageBox.Show(error = setStatusBar("Error editing DataItem " + name + " : " + Data.LastError), "Edit Config File Data Item", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
				else {
					if (ConfigFile.getData().Edit(Convert.ToInt32(_currentItem.Text), dataItem) == null)
						MessageBox.Show(error = setStatusBar("Error editing DataItem: " + Data.LastError), "Edit Config File Data Item", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
				if (string.IsNullOrEmpty(error))
					setStatusBar("Data Item " + name + " successfully edited");
			}
			if (ListView.Items.Count > 0) setSavePost();
		}

		private void DeleteBtn_Click(object sender, EventArgs e) {
			int index = _currentIndex;
			int count = 0;

			if ((_currentItem == null) || (_currentIndex == -1)) return;

			//	TODO - Populate Code Field
			DataItem dataItem = DataItem.CreateDataItem(MVShareStore.DataType.getDataType(_currentItem.SubItems[1].Text), _currentItem.SubItems[3].Text, _currentItem.SubItems[2].Text, null);

			if (!string.IsNullOrEmpty(dataItem.Name)) {
				if (!ConfigFile.delEntry(dataItem.Name)) {
					count = -1;
					MessageBox.Show(setStatusBar("Error editing deleting DataItem " + dataItem.Name + " : " + Data.LastError), "Delete DataPack Data Item", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
			else {
				if (!ConfigFile.delEntry(Convert.ToInt32(_currentItem.Text))) {
					count = -1;
					MessageBox.Show(setStatusBar("Error deleting DataItem: " + Data.LastError), "Delete DataPack Data Item", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

			if (count > -1) {
				ListView.Items[index].Remove();
				setStatusBar("Data Item " + dataItem.Name + " successfully deleted. " + ConfigFile.getCount() + " Data Item(s) left in the Config File");
			}
			if (ListView.Items.Count > 0) setSavePost();
		}

		private void MultiBtn_Click(object sender, EventArgs e) {
			if (_load) {
				ConfigFile = new MVConfigFile(null, null);
				setStatusBar(ConfigFile.getCount() + " Data Items / Config Entries loaded from " + Data.LastFile);
				RefreshList(ConfigFile);
				if (ListView.Items.Count > 0) setSavePost();
			}
			else if (_save) {
				if (ConfigFile.saveFile()) {
					MessageBox.Show("The Config File has been saved as " + Data.LastFile, "Config File Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
					setStatusBar("The Config File has been saved as " + Data.LastFile);
				}
				else {
					MessageBox.Show("Unable to save the Config File. Error: " + Data.LastError, "Config File Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
					setStatusBar("Unable to save the Config File. Error: " + Data.LastError);
				}
			}
		}

		private void CancelBtn_Click(object sender, EventArgs e) {
			Close();
		}

		private void CloseBtn_Click(object sender, EventArgs e) {
			if(ConfigFile.getDirty()) Data.CurrentDataPack = ConfigFile.getData();
			Close();
		}

		private void setLoad() {
			LoadSavePostBtn.Visible = LoadSavePostBtn.Enabled = true;
			LoadSavePostBtn.Text = "Load";
			ToolTip.SetToolTip(LoadSavePostBtn, "Populate the Data Items in this Config File from a Config / DataStore file previously save to disk");
			_load = true;
		}

		private void setSavePost() {
			if (_save) return;
			LoadSavePostBtn.Visible = LoadSavePostBtn.Enabled = true;
			LoadSavePostBtn.Text = "Save";
			ToolTip.SetToolTip(LoadSavePostBtn, "Save the Data Items in this Config File to a file on disk");
			_load = false;
			_save = true;
		}

		private void RefreshList(MVConfigFile config) {
			if(config == null) return;

			//	TODO - This is where we can test some MVConfigFile get and find functions.

			int index = 0;
			ListView.Items.Clear();
			if(config.getCount() > 0) {
				foreach(DataItem item in config.getData()) {
					ListViewItem listItem = new ListViewItem(index.ToString());
					listItem.SubItems.Add(item.Desc);
					listItem.SubItems.Add(item.Name);
					listItem.SubItems.Add(item.AsStringValue);
					ListView.Items.Add(listItem);
					index++;
				}
			}
		}

		private string setStatusBar(string status) {
			StatusBar.Items[0].Text = status;
			return status;
		}

		private ListViewItem _currentItem = null;
		private int _currentIndex = -1;
		private bool _load = false;
		private bool _save = false;
	}
}
