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
{
	/// <summary>
	/// Dans cette Form, le WordDerivating ne peut pas être changé :
	/// c'est à partir de lui que le nouveau mot est créé.
	/// </summary>
	public partial class Form__WordDerivated__of__WordDerivating__CreateUpdate : Form
	{
		private MainForm						mainForm;
		private bool							trueForCreate__falseForUpdate;

		#region		variables

		private BabebiDataSet					dataSet				;
		private BabebiDataSet.LanguageRow		current__Language	;
		private string							currentLanguageCode	;
		private BabebiDataSet.WordDerivatingRow	current__WordDerivating						;
		private BabebiDataSet.WordRow			current__Word__of__WordDerivating			;
		private BabebiDataSet.Word_LanguageRow	current__Word_Language__of__WordDerivating	;

		private int word__Id = -1;

		private BabebiDataSet.WordType_LanguageRow			selected__WordType_Language			;
		private BabebiDataSet.DerivatedWordType_LanguageRow	selected__DerivatedWordType_Language;
		private BabebiDataSet.Derivating_LanguageRow		selected__Derivating_Language		;

		#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		;

		#endregion	error management
		#region		ctors

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

			#region		short-cuts

			this.dataSet = this.mainForm.DataSet;
			this.current__Language = this.mainForm.Current__Language;
			this.currentLanguageCode = this.mainForm.Current__Language.Code;
			this.current__WordDerivating = this.mainForm.Current__WordDerivating;

			this.current__Word__of__WordDerivating
				= this.current__WordDerivating.WordRowParent;

			this.current__Word_Language__of__WordDerivating
				= this.dataSet.Word_Language
				.FindByWordIdLanguageCode
				(
					this.current__Word__of__WordDerivating.Id,
					this.currentLanguageCode
				);

			#endregion	short-cuts
			#region		about the parent WordDerivating

			this.textBox__Derivating_From__String.Text = this.current__Word__of__WordDerivating.UniqueKeyString;    /// Read-only
			this.textBox__Derivating_From__Meaning.Text = this.current__Word_Language__of__WordDerivating.Meaning;           /// Read-only

			#endregion	about the parent WordDerivating
			#region		(base)

			this.mainForm.Ctor__CreateUpdate__Word
			(
				this,
				this.button__CreateUpdate,
				this.button__Clone,
				MainForm.ModeName_Derivated,
				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__WordDerivated__of__WordDerivating,
				this.mainForm.Current__Word_Language__of__WordDerivated__of__WordDerivating
			);
			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)

			bool complexCloning = false;
			BabebiDataSet.DerivatingRow derivatingRow = null;
			if (this.trueForCreate__falseForUpdate)
			{
				if (this.current__WordDerivating.WordRowParent.ModeCode == MainForm.ModeCode_FromPattern)
				{
					BabebiDataSet.WordFromPatternRow wordFromPattern
						= this.dataSet.WordFromPattern.FindById(this.current__WordDerivating.WordId);

					BabebiDataSet.FromPatternRow[] siblingFromPatterns
						= wordFromPattern.FromPatternRowParent.PatternRow.GetFromPatternRows();

					foreach (BabebiDataSet.FromPatternRow siblingFromPattern in siblingFromPatterns)
					{
						if (siblingFromPattern.SubscriberCode == MainForm.SubscriberCode_Pattern)
						{
							continue;
						}

						BabebiDataSet.WordFromPatternRow siblingWordFromPattern
							= this.dataSet.WordFromPattern.FindById(siblingFromPattern.SubscriberId);

						if (siblingWordFromPattern.WordRowParent.HasDerivating)
						{
							BabebiDataSet.WordDerivatingRow siblingWordDerivating
								= this.dataSet.WordDerivating.FindByWordId(siblingFromPattern.SubscriberId);

							BabebiDataSet.WordDerivatedRow[] siblingWordDerivateds
								= siblingWordDerivating.GetWordDerivatedRows();

							if (siblingWordDerivateds.Length > 1)
							{
								complexCloning = false;
								break;
							}
							else if (siblingWordDerivateds.Length == 1)
							{
								BabebiDataSet.WordDerivatedRow siblingWordDerivated = siblingWordDerivateds[0];

								if (derivatingRow == null)
								{
									complexCloning = true;
									derivatingRow = siblingWordDerivated.DerivatingRowParent;
								}
								else
								{
									if (derivatingRow.Id != siblingWordDerivated.DerivatingId)
									{
										complexCloning = false;
										break;
									}
								}
							}
						}
					}
				}
			}

			if (complexCloning)
			{
				#region		WordType

				this.selected__WordType_Language
					= this.dataSet.WordType_Language
					.FindByWordTypeIdLanguageCode
					(
						derivatingRow.DerivatingWordType_DerivatedWordTypeRowParent.DerivatedWordTypeRow.WordTypeId,
						this.currentLanguageCode
					);

				this.comboBox__WordType_LanguageName.SelectedItem
					= new WordTypeComboBoxItem(this.selected__WordType_Language);

				#endregion	WordType
				#region		DerivatedWordType

				/// on séte avec la valeur existante après que la Combo a été préparée par la WordType précédente.
				this.selected__DerivatedWordType_Language
					= this.dataSet.DerivatedWordType_Language
					.FindByDerivatedWordTypeIdLanguageCode
					(
						derivatingRow.DerivatedWordTypeId,
						this.currentLanguageCode
					);

				this.comboBox__DerivatedWordType.SelectedItem
					= new DerivatedWordTypeComboBoxItem(this.selected__DerivatedWordType_Language);

				#endregion	DerivatedWordType
				#region		Derivating

				/// on séte avec la valeur existante après que la Combo a été préparée par la DerivatedWordType précédente.

				this.selected__Derivating_Language
					= this.dataSet.Derivating_Language
					.FindByDerivatingIdLanguageCode
					(
						derivatingRow.Id,
						this.currentLanguageCode
					);

				this.comboBox__Derivating.SelectedItem
					= new DerivatingComboBoxItem(this.selected__Derivating_Language);

				#endregion	Derivating
			}
			else
			{
				#region		DerivatedWordType

				if (trueForCreate__falseForUpdate)
				{
					/// rien à faire car la combox est pilotée par l'event de la Combo WordType.
				}
				else
				{
					/// on séte avec la valeur existante après que la Combo a été préparée par la WordType précédente.
					this.selected__DerivatedWordType_Language
						= this.dataSet.DerivatedWordType_Language
						.FindByDerivatedWordTypeIdLanguageCode
						(
							this.mainForm.Current__WordDerivated__of__WordDerivating.DerivatedWordTypeId,
							this.currentLanguageCode
						);

					this.comboBox__DerivatedWordType.SelectedItem
						= new DerivatedWordTypeComboBoxItem(this.selected__DerivatedWordType_Language);
				}

				#endregion	DerivatedWordType
				#region		Derivating

				if (trueForCreate__falseForUpdate)
				{
					/// rien à faire car piloté par l'event de la Combo DerivatedWordType.
				}
				else
				{
					/// on séte avec la valeur existante après que la Combo a été préparée par la DerivatedWordType précédente.

					this.selected__Derivating_Language
						= this.dataSet.Derivating_Language
						.FindByDerivatingIdLanguageCode
						(
							this.mainForm.Current__WordDerivated__of__WordDerivating.DerivatingId,
							this.currentLanguageCode
						);

					this.comboBox__Derivating.SelectedItem
						= new DerivatingComboBoxItem(this.selected__Derivating_Language);
				}

				#endregion	Derivating
			}
		}

		public Form__WordDerivated__of__WordDerivating__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__WordDerivated__of__WordDerivating,					
				this.mainForm.Current__Word_Language__of__WordDerivated__of__WordDerivating
			);
		}

		#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)
		{
			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)
			{
				this.textBox_WEM__Id.ShowMessageBox();
			}
		}

		#endregion	Word__Id
		#region		Word_Language__Meaning

		private void textBox__Word_Language__Meaning__TextChanged(object sender, EventArgs e)
		{
			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)
			{
				this.textBox_WEM__Meaning.ShowMessageBox();
			}
		}

		#endregion	Word_Language__Meaning
		#region		ComputedString

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

		#endregion	ComputedString

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

		private void comboBox__WordType__SelectedIndexChanged(object sender, EventArgs e)
		{
			if (this.comboBox_WEM__WordType != null)
			{ 
				this.comboBox_WEM__WordType.ClearError();
			}

			WordTypeComboBoxItem selectedWordTypeComboBoxItem = (WordTypeComboBoxItem)(this.comboBox__WordType_LanguageName.SelectedItem);

			this.selected__WordType_Language = selectedWordTypeComboBoxItem.Row;

			List<DerivatedWordTypeComboBoxItem> derivatedWordTypeComboBoxItems = new List<DerivatedWordTypeComboBoxItem>();
			foreach
			(
				BabebiDataSet.DerivatedWordType_LanguageRow theDerivatedWordType_Language
				in
				this.selected__WordType_Language.GetDerivatedWordType_LanguageRows()
			)
			{
				bool isCompatibleWithWorDerivating = false;
				foreach 
				(
					BabebiDataSet.DerivatingWordType_DerivatedWordTypeRow theDerivatingWordType_DerivatedWordType
					in 
					theDerivatedWordType_Language.DerivatedWordTypeRowParent.GetDerivatingWordType_DerivatedWordTypeRows()
				)
				{
					if (theDerivatingWordType_DerivatedWordType.DerivatingWordTypeRow == this.current__WordDerivating.DerivatingWordTypeRowParent)
					{
						isCompatibleWithWorDerivating = true;
					}
				}
				if (! isCompatibleWithWorDerivating)
				{
					continue;
				}

				DerivatedWordTypeComboBoxItem theDerivatedWordTypeComboBoxItem 
					= new DerivatedWordTypeComboBoxItem(theDerivatedWordType_Language);

				derivatedWordTypeComboBoxItems.Add(theDerivatedWordTypeComboBoxItem);
			}

			this.comboBox__DerivatedWordType.Items.Clear();

			if (derivatedWordTypeComboBoxItems.Count != 1)
			{
				this.comboBox__DerivatedWordType.Items.AddRange(derivatedWordTypeComboBoxItems.ToArray());

				this.comboBox__DerivatedWordType.Text = null;
			}
			else
			{
				DerivatedWordTypeComboBoxItem theUniqueDerivatedWordTypeComboBoxItem = derivatedWordTypeComboBoxItems[0];

				this.comboBox__DerivatedWordType.Items.Add(theUniqueDerivatedWordTypeComboBoxItem);

				this.comboBox__DerivatedWordType.SelectedItem = theUniqueDerivatedWordTypeComboBoxItem;
			}
		}

		private void comboBox__DerivatedWordType__SelectedIndexChanged(object sender, EventArgs e)
		{
			DerivatedWordTypeComboBoxItem selectedDerivatedWordTypeComboBoxItem 
				= (DerivatedWordTypeComboBoxItem)(this.comboBox__DerivatedWordType.SelectedItem);

			this.selected__DerivatedWordType_Language = selectedDerivatedWordTypeComboBoxItem.Row;

			BabebiDataSet.DerivatingWordType_DerivatedWordTypeRow selected__DerivatingWordType_DerivatedWordType
				= this.mainForm.DataSet.DerivatingWordType_DerivatedWordType
				.FindByDerivatingWordTypeIdDerivatedWordTypeId
				(
					this.current__WordDerivating.DerivatingWordTypeId,
					this.selected__DerivatedWordType_Language.DerivatedWordTypeId
				);

			List<DerivatingComboBoxItem> derivatingComboBoxItems = new List<DerivatingComboBoxItem>();
			foreach
			(
				BabebiDataSet.DerivatingRow theDerivating
				in
				selected__DerivatingWordType_DerivatedWordType.GetDerivatingRows()
			)
			{
				BabebiDataSet.Derivating_LanguageRow theDerivating_Language
					=
					(BabebiDataSet.Derivating_LanguageRow)
					(this.mainForm.DataRow__Language(theDerivating));

				derivatingComboBoxItems.Add(new DerivatingComboBoxItem(theDerivating_Language));
			}

			this.comboBox__Derivating.Items.Clear();

			if (derivatingComboBoxItems.Count != 1)
			{
				this.comboBox__Derivating.Items.AddRange(derivatingComboBoxItems.ToArray());

				this.comboBox__Derivating.Text = null;
			}
			else
			{
				DerivatingComboBoxItem theUniqueDerivatingComboBoxItem = derivatingComboBoxItems[0];

				this.comboBox__Derivating.Items.Add(theUniqueDerivatingComboBoxItem);

				this.comboBox__Derivating.SelectedItem = theUniqueDerivatingComboBoxItem;
			}
		}

		private void comboBox__Derivating__SelectedIndexChanged(object sender, EventArgs e)
		{
			this.selected__Derivating_Language 
				= 
				(
					(DerivatingComboBoxItem)
					(this.comboBox__Derivating.SelectedItem)
				)
				.Row;

			this.compute__ComputedString();
		}

		#endregion	(mode) events

		private void compute__ComputedString()
		{
			this.textBox__Word__ComputedString.Text
				= WordDerivated.Compute_UniqueKeyString
				(
					this.current__WordDerivating, 
					this.selected__Derivating_Language.DerivatingRowParent
				);
		}

		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.selected__WordType_Language == null)
			{
				MessageBox.Show("The 'Word Type' is not selected.", "Missing 'Word Type'", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			if (this.selected__DerivatedWordType_Language == null)
			{
				MessageBox.Show("The 'Derivated Word Type' is not selected.", "Missing 'Derivated Word Type'", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			if (this.selected__Derivating_Language == null)
			{
				MessageBox.Show("The 'Derivating' is not selected.", "Missing Derivating", MessageBoxButtons.OK, MessageBoxIcon.Error);
				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;
			}

			#endregion	checking

			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_Derivated
				);

				this.mainForm.Current__WordOrPattern__of__WordDerivated__of__WordDerivating	= current__WordOrPattern;
				this.mainForm.Current__Word__of__WordDerivated__of__WordDerivating			= current__Word;
				this.mainForm.Current__Word_Language__of__WordDerivated__of__WordDerivating	= current__Word_Language;
				this.mainForm.Current__LanguageWord											= current__LanguageWord;

				#endregion	(base)
				#region		(mode)

				this.mainForm.Current__WordDerivated__of__WordDerivating
					= this.dataSet.WordDerivated
					.AddWordDerivatedRow
					(
						this.word__Id,
						MainForm.ModeCode_Derivated,
						this.selected__WordType_Language.WordTypeId,
						this.selected__DerivatedWordType_Language.DerivatedWordTypeId,
						this.current__WordDerivating.WordId,
						this.current__WordDerivating.DerivatingWordTypeId,
						this.selected__Derivating_Language.DerivatingRowParent.Id
					);

				#endregion	(mode)
			}
			else
			{ 
				this.mainForm.Current__Word__of__WordDerivated__of__WordDerivating.BeginEdit();
				this.mainForm.Current__WordDerivated__of__WordDerivating.BeginEdit();

				#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__WordDerivated__of__WordDerivating,
					this.mainForm.Current__Word__of__WordDerivated__of__WordDerivating,
					this.mainForm.Current__Word_Language__of__WordDerivated__of__WordDerivating,
				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)

				this.mainForm.Current__WordDerivated__of__WordDerivating.WordTypeId
					= this.selected__WordType_Language.WordTypeId;

				this.mainForm.Current__WordDerivated__of__WordDerivating.DerivatedWordTypeRowParent
					= this.selected__DerivatedWordType_Language.DerivatedWordTypeRowParent;

				this.mainForm.Current__WordDerivated__of__WordDerivating.DerivatingRowParent
					= this.selected__Derivating_Language.DerivatingRowParent;

				#endregion	(mode)

				this.mainForm.Current__Word__of__WordDerivated__of__WordDerivating.EndEdit();
				this.mainForm.Current__WordDerivated__of__WordDerivating.EndEdit();
			}

			this.DialogResult = DialogResult.OK;

			this.Close();
		}
	}
}
