using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Babebi4
{
	public partial class Form__WordByInsertion__of__Current__Word__CreateUpdate : Form
	{
		private MainForm					mainForm;
		private bool						trueForCreate__falseForUpdate;

		#region		shortcuts

		private BabebiDataSet				dataSet;
		private BabebiDataSet.LanguageRow	currentLanguage		;
		private string						currentLanguageCode	;

		private BabebiDataSet.WordRow		current__Word;	/// this is the Word that is the parent/origin of the currently created/updated Word-ByInsertion.

		#endregion	shortcuts
		#region		variables

		private int	word__Id = -1;
		private short selected__InsertionIndex = -1;
		private BabebiDataSet.WordType_LanguageRow selected__WordType_Language = null;
		private BabebiDataSet.LetterClusterRow selected__LetterCluster = null;

		/// <summary>
		/// La décomposition du LetterCluster en Babebi Letters valides.
		/// Indispensable pour :
		///		- compter jusqu'au Insertion Index pour réaliser l'insertion,
		///		- créer les LetterClusterLetters.
		/// </summary>
		List<BabebiDataSet.LetterRow> letterList = new List<BabebiDataSet.LetterRow>();
		
		#endregion	variables
		#region		error management

		private TextBox_WEM		textBox_WEM__Id					;
		private TextBox_WEM		textBox_WEM__UniqueKeyString	;
		private TextBox_WEM		textBox_WEM__Meaning			;
		private ComboBox_WEM	comboBox_WEM__WordType			;
																
		private ComboBox_WEM	comboBox_WEM__InsertionIndex	;
		private TextBox_WEM		textBox_WEM__LetterClusterString;

		#endregion	error management
		#region		ctors

		public Form__WordByInsertion__of__Current__Word__CreateUpdate(MainForm mainForm, bool trueForCreate__falseForUpdate) : this()
		{
			this.mainForm						= mainForm;
			this.trueForCreate__falseForUpdate	= trueForCreate__falseForUpdate;

			#region		shortcuts

			this.dataSet				= this.mainForm.DataSet;
			this.currentLanguage		= this.mainForm.Current__Language;
			this.currentLanguageCode	= this.mainForm.Current__Language.Code;
			this.current__Word			= this.mainForm.Current__Word;

			#endregion	shortcuts
			#region		(base)

			this.mainForm.Ctor__CreateUpdate__Word
			(
				this,
				this.button__CreateUpdate,
				this.button__Clone, 
				MainForm.ModeName_ByInsertion,
				this.label__Word__Id					,
				this.label__Word__ComputedString		,
				this.label__Word_Language__Meaning		,
				this.label__WordType_LanguageName		,
				this.textBox__Word__Id					,
				this.textBox__Word__ComputedString		,
				this.textBox__Word_Language__Meaning	,
				this.comboBox__WordType_LanguageName	,
				true,
			out	TextBox_WEM		textBox_WEM__Word__Id_				,
			out	TextBox_WEM		textBox_WEM__Word__ComputedString_	,
			out	TextBox_WEM		textBox_WEM__Word_Language__Meaning_,
			out	ComboBox_WEM	comboBox_WEM__WordType_LanguageName_,
				this.trueForCreate__falseForUpdate,
			ref this.word__Id,
			ref this.selected__WordType_Language,
				this.mainForm.Current__Word__of__WordByInsertion__of__Current__Word,					
				this.mainForm.Current__Word_Language__of__WordByInsertion__of__Current__Word
			);
			this.textBox_WEM__Id				= textBox_WEM__Word__Id_				;
			this.textBox_WEM__UniqueKeyString	= textBox_WEM__Word__ComputedString_	;
			this.textBox_WEM__Meaning			= textBox_WEM__Word_Language__Meaning_;
			this.comboBox_WEM__WordType			= comboBox_WEM__WordType_LanguageName_;

			#endregion	(base)
			#region		(mode)

			#region		error management

			string insertionIndexString;
			if (this.mainForm.Current__WordByInsertion__of__Current__Word != null)
			{
				insertionIndexString
					= MainForm.Convert__InsertionIndex__into__ComboBoxSelectedItem
					(
						this.mainForm.Current__WordByInsertion__of__Current__Word.InsertionIndex
					);
			}
			else
			{ 
				insertionIndexString = null;
			}

			this.comboBox_WEM__InsertionIndex	 
				= new ComboBox_WEM
				(
					this.label__InsertionIndex, 
					this.comboBox__InsertionIndex, 
					"The 'Insertion Index' has not been selected.", 
					"Missing 'Insertion Index'", 
					(this.trueForCreate__falseForUpdate ? null : insertionIndexString)
				);
				
			this.textBox_WEM__LetterClusterString
				= new TextBox_WEM
				(
					this.label__LetterClusterString, 
					this.textBox__LetterClusterString, 
					"The 'Letter Cluster' has not been selected.", 
					"Missing 'Letter Cluster'", 
					(
						this.trueForCreate__falseForUpdate 
						? 
						null 
						: 
						this.mainForm.Current__WordByInsertion__of__Current__Word.LetterClusterRow.String
					)
				);

			#endregion	error management

			if (this.trueForCreate__falseForUpdate)
			{
				this.comboBox__InsertionIndex.SelectedIndex = 0;	/// ce choix est 'At the end' qui ne pose jamais de problème.
				this.selected__InsertionIndex = 32;
			}
			else
			{
				this.selected__InsertionIndex				= this.mainForm.Current__WordByInsertion__of__Current__Word.InsertionIndex;
				this.comboBox__InsertionIndex.SelectedItem	= insertionIndexString;

				this.selected__LetterCluster			= this.mainForm.Current__WordByInsertion__of__Current__Word.LetterClusterRow;
				this.textBox__LetterClusterString.Text	= this.selected__LetterCluster.String;
				                                                            
				this.compute__ComputedString();
			}

			#endregion	(mode)
		}

		public Form__WordByInsertion__of__Current__Word__CreateUpdate()
		{
			InitializeComponent();
		}

		#endregion	ctors
		#region		(base) events
 
		private void button__Clone__Click(object sender, EventArgs e)
		{
			this.mainForm.Clone__Word
			(
				null,
				this.textBox__Word_Language__Meaning,
				this.comboBox__WordType_LanguageName,
				true,
				this.mainForm.Current__Word__of__WordByInsertion__of__Current__Word,					
				this.mainForm.Current__Word_Language__of__WordByInsertion__of__Current__Word
			);
		}

		#region		Word__Id

		private void textBox__Word__Id__KeyPress(object sender, KeyPressEventArgs e)
		{
			MainForm.Integer__KeyPress(e);
		}
		private void textBox__Word__Id__TextChanged(object sender, EventArgs e)
		{
			if (this.textBox_WEM__Id != null)
			{
				this.mainForm.Word__Id__TextChanged(this.textBox_WEM__Id, ref this.word__Id);
			}
		}
		private void textBox__Word__Id__Leave(object sender, EventArgs e)
		{
			if (this.textBox_WEM__Id.HasError && string.IsNullOrEmpty(this.textBox__Word__Id.Text))
			{
				this.textBox_WEM__Id.ShowMessageBox();
			}
		}

		#endregion	Word__Id
		#region		Word_Language__Meaning

		private void textBox__Word_Language__Meaning__TextChanged(object sender, EventArgs e)
		{
			if (this.textBox_WEM__Meaning != null)
			{
				this.mainForm.Word__Meaning__TextChanged(this.textBox_WEM__Meaning);
			}
		}

		private void textBox__Word_Language__Meaning__Leave(object sender, EventArgs e)
		{
			if (this.textBox_WEM__Meaning.HasError && string.IsNullOrEmpty(this.textBox__Word_Language__Meaning.Text))
			{
				this.textBox_WEM__Meaning.ShowMessageBox();
			}
		}

		#endregion	Word_Language__Meaning
		#region		ComputedString

		private void textBox__Word__ComputedString__TextChanged(object sender, EventArgs e)
		{
			if (this.textBox_WEM__UniqueKeyString != null)
			{
				this.mainForm.Word__UniqueKeyString__TextChanged(this.textBox_WEM__UniqueKeyString);
			}
		}

		#endregion	ComputedString
		#region		WordType_LanguageName

		private void comboBox__WordType_LanguageName_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (this.comboBox_WEM__WordType != null)
			{
			this.selected__WordType_Language 
				=
				(
					(WordTypeComboBoxItem)
					(this.comboBox__WordType_LanguageName.SelectedItem)
				)
				.Row;

				this.comboBox_WEM__WordType.ClearError();
			}
		}

		#endregion	WordType_LanguageName

		#endregion	(base) events
		#region		(mode events)

		private void comboBox__InsertionIndex__SelectedIndexChanged(object sender, EventArgs e)
		{
			this.mainForm.ComboBox__InsertionIndex__SelectedIndexChanged
				(
					this.comboBox_WEM__InsertionIndex,
					Convert.ToInt16( this.mainForm.Current__Word.UniqueKeyString.Length ),
				ref this.selected__InsertionIndex
				);

			this.compute__ComputedString();

			#region		(ancienne version)
			/*
			this.selected__InsertionIndex
				= MainForm.Convert__ComboBoxSelectedItem__into__InsertionIndex
				(
					(string)
					(this.comboBox__InsertionIndex.SelectedItem)
				);

			if
			(
				this.selected__InsertionIndex != 32
				&&
				this.selected__InsertionIndex > this.current__Word.UniqueKeyString.Length
			)
			{
				string errorMessage
					= "The selected 'Insertion Index' (" + this.selected__InsertionIndex.ToString() 
					+ ") is too high because the length of 'Unique Key String' of the parent Word is only " 
					+ this.current__Word.UniqueKeyString.Length.ToString() + ".";

				this.comboBox_WEM__InsertionIndex.SetError(errorMessage, "Too high Insertion Index");

				this.textBox__Word__ComputedString.Text = null;

				this.comboBox_WEM__InsertionIndex.ShowMessageBox();

				return;
			}
			else
			{
				this.comboBox_WEM__InsertionIndex.ClearError();

				this.Compute__ComputedString();
			}
			*/
			#endregion	(ancienne version)
		}

		private void textBox__LetterClusterString__TextChanged(object sender, EventArgs e)
		{
			this.mainForm.textBox__LetterClusterString__TextChanged
			(
				this.textBox_WEM__LetterClusterString, 
			ref this.selected__LetterCluster,
				this.letterList
			);

			this.compute__ComputedString();

			#region		(ancienne version)
			/*
			string letterClusterString = this.textBox__LetterClusterString.Text;

			this.ranks__letters.Clear();

			if
			(
				!this.trueForCreate__falseForUpdate
				&&
				letterClusterString == this.mainForm.Current__WordByInsertion__of__Current__Word.LetterClusterRow.String
			)
			{
				this.selected__LetterCluster = this.mainForm.Current__WordByInsertion__of__Current__Word.LetterClusterRow;

				this.textBox_WEM__LetterClusterString.ClearError();
			}
			else
			{
				DataRow[] letterClusterdataRows 
					= this.dataSet.LetterCluster.Select("String = '" + letterClusterString + "'");

				if (letterClusterdataRows.Length == 0)
				{
					/// the LetterCluster does not exit yet => so, is the input string valid or not?

					#region		check if the LetterCluster string only contains valid Letters

					short rank = -1;
					for (int i = 0; i < letterClusterString.Length; i++)
					{
						rank++;

						char thisChar = letterClusterString[i];

						if (i < letterClusterString.Length - 1)
						{
							char nextChar = letterClusterString[i + 1];

							string doubleLetterString = new string(new char[] { thisChar, nextChar });

							BabebiDataSet.LetterRow doubleLetter
								= this.dataSet.Letter.FindByString(doubleLetterString);

							if (doubleLetter != null)
							{
								this.ranks__letters.Add(rank, doubleLetter);

								rank++;

								continue;
							}
						}

						string monoLetterString = new string(new char[] { thisChar });

						BabebiDataSet.LetterRow monoLetter
							= this.dataSet.Letter.FindByString(monoLetterString);

						if (monoLetter == null)
						{
							this.textBox__Word__ComputedString.Text = null;

							this.textBox_WEM__LetterClusterString 
								.SetError
								(
									"The 'Letter Cluster' string contains the invalid character: '" + monoLetterString + "'.",
									"Invalid character"
								);


							return;
						}
						else
						{
							ranks__letters.Add(rank, monoLetter);
						}
					}

					this.selected__LetterCluster = null;    /// will be created while click the UPDATE button, which is a proof that this value is not so important...

					this.textBox_WEM__LetterClusterString.ClearError();

					#endregion	check if the LetterCluster string only contains valid Letters
				}
				else if (letterClusterdataRows.Length == 1)
				{
					this.selected__LetterCluster = (BabebiDataSet.LetterClusterRow)(letterClusterdataRows[0]); 
				}
				else
				{
					throw new Exception();
				}
			}

			this.compute__ComputedString();
			*/
			#endregion	(ancienne version)
		}

		#endregion	(mode events)

		public void compute__ComputedString()
		{
			#region		trapping error about InsertionIndex & LetterClusterString

			if
			(
				this.comboBox_WEM__InsertionIndex.HasError
				||
				this.textBox_WEM__LetterClusterString.HasError
			)
			{
				this.textBox__Word__ComputedString.Text = null;
				
				return;
			}

			#endregion	trapping error about InsertionIndex & LetterClusterString

			string parentString			= this.current__Word.UniqueKeyString;
			string letterClusterString	= this.textBox__LetterClusterString.Text;

			#region		trapping error about a__a_OR_e__e_OR_o__o

			if 
			(
				this.mainForm.Is_a__a_OR_e__e_OR_o__o
				(
					parentString, 
					letterClusterString,
					this.selected__InsertionIndex,
					this.textBox_WEM__UniqueKeyString
				)
			)
			{
				return;
			}

			#endregion	trapping error about a__a_OR_e__e_OR_o__o
			#region		current__Word__UniqueKeyString.Length + letterClusterString.Length > 32 ?

			if(parentString.Length + letterClusterString.Length > 32)
			{
				this.textBox__Word__ComputedString.Text = null;

				string errorMessage
					= "The sum of the lenghts of:\n" 
					+ "   - the current Word 'Unique Key String' and\n" 
					+ "   - the 'Letter Cluster String'\n" 
					+ "is bigger than 32, which would produce a too long Word (Word max. lenght = 32).";

				this.textBox_WEM__UniqueKeyString.SetError(errorMessage, "Too long (computed) 'Unique Key String'");

				return;
			}

			#endregion	current__Word__UniqueKeyString.Length + letterClusterString.Length > 32 ?

			string computedString 
				= WordByInsertion.Compute_UniqueKeyString
				(
					this.current__Word, 
					this.selected__InsertionIndex, 
					letterClusterString
				);

			this.textBox__Word__ComputedString.Text = computedString;	/// on affiche le resultat même s'il cause une error.
		}

		private void button__CreateUpdate__Click(object sender, EventArgs e)
		{
			#region		checking

			if (this.textBox_WEM__Id.HasError)
			{
				this.textBox_WEM__Id.ShowMessageBox();

				return;
			}
			if (this.comboBox_WEM__InsertionIndex.HasError)
			{
				this.comboBox_WEM__InsertionIndex.ShowMessageBox();

				return;
			}
			if (this.textBox_WEM__LetterClusterString.HasError)
			{
				this.textBox_WEM__LetterClusterString.ShowMessageBox();

				return;
			}
			if (this.textBox_WEM__UniqueKeyString.HasError)
			{
				this.textBox_WEM__UniqueKeyString.ShowMessageBox();

				return;
			}
			if (this.textBox_WEM__Meaning.HasError)
			{
				this.textBox_WEM__Meaning.ShowMessageBox();

				return;
			}
			if (this.comboBox_WEM__WordType.HasError)
			{
				this.comboBox_WEM__WordType.ShowMessageBox();

				return;
			}

			#endregion	checking

			/// usefull in both Create or Update modes.
			if (this.selected__LetterCluster == null)
			{
				this.selected__LetterCluster = this.mainForm.build__LetterCluster(this.letterList);
			}

			if (this.trueForCreate__falseForUpdate)
			{
				#region		(base)

				this.mainForm.Create__Word
				(
					this.word__Id,
					this.textBox__Word__ComputedString.Text,
					this.textBox__Word_Language__Meaning.Text,
					this.selected__WordType_Language.WordTypeRow,
				out BabebiDataSet.WordOrPatternRow	current__WordOrPattern,
				out BabebiDataSet.WordRow			current__Word,
				out BabebiDataSet.Word_LanguageRow	current__Word_Language,
				out BabebiDataSet.LanguageWordRow	current__LanguageWord, 
					MainForm.ModeCode_ByInsertion
				);

				this.mainForm.Current__WordOrPattern__of__WordByInsertion__of__Current__Word	= current__WordOrPattern;
				this.mainForm.Current__Word__of__WordByInsertion__of__Current__Word				= current__Word;
				this.mainForm.Current__Word_Language__of__WordByInsertion__of__Current__Word	= current__Word_Language;
				this.mainForm.Current__LanguageWord												= current__LanguageWord;

				#endregion	(base)
				#region		(mode)

				this.mainForm.Current__WordByInsertion__of__Current__Word
					= this.dataSet.WordByInsertion
					.AddWordByInsertionRow
					(
						this.word__Id,
						this.current__Word,
						this.selected__InsertionIndex,
						this.selected__LetterCluster,
						MainForm.ModeCode_ByInsertion
					);

				#endregion	(mode)
			}
			else
			{
				#region		(base)

				this.mainForm.Update__Word
				(
					this.word__Id,
					this.textBox__Word__ComputedString.Text,
					this.textBox__Word_Language__Meaning.Text,
					this.selected__WordType_Language.WordTypeRow,
					this.mainForm.Current__WordOrPattern__of__WordByInsertion__of__Current__Word,
					this.mainForm.Current__Word__of__WordByInsertion__of__Current__Word,
					this.mainForm.Current__Word_Language__of__WordByInsertion__of__Current__Word,
				out BabebiDataSet.LanguageWordRow current__LanguageWord	/// renvoie null si toujours le même.
				);

				if (current__LanguageWord != null)
				{
					this.mainForm.Current__LanguageWord = current__LanguageWord;
				}

				#endregion	(base)
				#region		(mode)

				/// about InsertionIndex
				if (this.selected__InsertionIndex != this.mainForm.Current__WordByInsertion__of__Current__Word.InsertionIndex)
				{
					this.mainForm.Current__WordByInsertion__of__Current__Word.InsertionIndex = this.selected__InsertionIndex;
				}

				/// about LetterCluster
				this.mainForm.Set_LetterCluster_and_remove_prior_if_not_used_by_other
				(	
					this.selected__LetterCluster,
					this.mainForm.Current__WordByInsertion__of__Current__Word
				);
 
				#endregion	(mode)
			}

			this.DialogResult = DialogResult.OK;

			this.Close();
		}
	}
}
