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 MainForm : Form
	{
		private void display__no__Pattern()
		{
			#region		visibilité de la combo Extension

			if (this.label__Pattern__Extension.Visible)
			{
				this.label__Pattern__Extension.Visible = false;
			}

			if (this.comboBox__Pattern__Extension.Visible)
			{
				this.comboBox__Pattern__Extension.Visible = false;
			}

			#endregion	visibilité de la combo Extension

			MainForm.ShowSelectedTabPageInTabControl
			(
				this.tabControl__Pattern__Extension, 
				null,
				this.tabPage__Pattern__Extension__ByInsertion,
				this.tabPage__Pattern__Extension__FromPattern
			);
		}		
		
		private void populate__Pattern()
		{
			if 
			(
				this.Current__WordOrPattern__of__Pattern == null
				||
				this.Current__WordOrPattern__of__Pattern.SubscriberId != this.Current__Pattern.Id
			)
			{ 
				this.Current__WordOrPattern__of__Pattern = this.Current__Pattern.WordOrPatternRowParent;
			}



			/// fill the 3 (base) Fields.
			this.textBox__Pattern__Id.Text					= this.Current__Pattern.Id.ToString();
			this.textBox__Pattern__UniqueKeyString.Text		= this.Current__Pattern.UniqueKeyString;
			this.textBox__Pattern_Language__Meaning.Text	= this.Current__Pattern_Language.Meaning;


			if (this.Current__Pattern.ModeCode == ModeCode_ExNihilo)
			{
				#region		visibilité de la combo et du tabControl Extension

				if (this.label__Pattern__Extension.Visible)
				{
					this.label__Pattern__Extension.Visible = false;
				}
				if (this.comboBox__Pattern__Extension.Visible)
				{
					this.comboBox__Pattern__Extension.Visible = false;
				}

				if (this.tabControl__Pattern__Extension.Visible)
				{
					this.tabControl__Pattern__Extension.Visible = false;
				}

				#endregion	visibilité de la combo et du tabControl Extension
			}
			else
			{ 
				#region		visibilité de la combo et du tabControl Extension

				if (!this.label__Pattern__Extension.Visible)
				{
					this.label__Pattern__Extension.Visible = true;
				}
				if (!this.comboBox__Pattern__Extension.Visible)
				{
					this.comboBox__Pattern__Extension.Visible = true;
				}

				if (!this.tabControl__Pattern__Extension.Visible)
				{
					this.tabControl__Pattern__Extension.Visible = true;
				}

				#endregion	visibilité de la combo et du tabControl Extension

				string priorModeCode;
				switch (this.comboBox__Pattern__Extension.SelectedIndex)
				{
					case -1	: priorModeCode = null							; break;
					case  0	: priorModeCode = MainForm.ModeCode_NotDefined	; break;
					case  1	: priorModeCode = MainForm.ModeCode_ByInsertion	; break;
					case  2	: priorModeCode = MainForm.ModeCode_FromPattern	; break;
					default: throw new Exception();
				}

				switch (this.Current__Pattern.ModeCode)
				{
					case MainForm.ModeCode_NotDefined	: this.comboBox__Pattern__Extension.SelectedIndex = 0; break;	
					case MainForm.ModeCode_ByInsertion	: this.comboBox__Pattern__Extension.SelectedIndex = 1; break;	
					case MainForm.ModeCode_FromPattern	: this.comboBox__Pattern__Extension.SelectedIndex = 2; break;	
					default: throw new Exception();
				}

				/// si le ModeCode est toujours le même alors il faut "déclencher" l'event a la main.
				if (this.Current__Pattern.ModeCode == priorModeCode)
				{ 
					this.comboBox__Pattern__Extension__SelectedIndexChanged();
				}
			}

			#region		children : WordFromPatterns

			this.guiTable__WordFromPattern__of__Current__Pattern.Populate();

			if (this.guiTable__WordFromPattern__of__Current__Pattern.Rows.Count == 0)
			{
				this.button__Pattern__Children__WordFromPattern__Update.Visible = false;
				this.button__Pattern__Children__WordFromPattern__Delete.Visible = false;
				this.button__Pattern__Children__WordFromPattern__Focus.Visible	= false;
			}
			else
			{ 
				this.button__Pattern__Children__WordFromPattern__Update.Visible = true;
				this.button__Pattern__Children__WordFromPattern__Delete.Visible = true;
				this.button__Pattern__Children__WordFromPattern__Focus.Visible	= true;
			}

			#endregion	children : WordFromPatterns
			#region		children : PatternFromPatterns

			this.guiTable__PatternFromPattern__of__Current__Pattern.Populate();

			if (this.guiTable__PatternFromPattern__of__Current__Pattern.Rows.Count == 0)
			{
				this.button__Pattern__Children__PatternFromPattern__Update.Visible = false;
				this.button__Pattern__Children__PatternFromPattern__Delete.Visible = false;
				this.button__Pattern__Children__PatternFromPattern__Focus.Visible	= false;
			}
			else
			{ 
				this.button__Pattern__Children__PatternFromPattern__Update.Visible = true;
				this.button__Pattern__Children__PatternFromPattern__Delete.Visible = true;
				this.button__Pattern__Children__PatternFromPattern__Focus.Visible	= true;
			}

			#endregion	children : PatternFromPatterns
			#region		children : PatternByInsertions

			this.guiTable__PatternByInsertion__of__Current__Pattern.Populate();

			if (this.guiTable__PatternByInsertion__of__Current__Pattern.Rows.Count == 0)
			{
				this.button__PatternByInsertion__of__Current__Pattern__Update.Visible = false;
				this.button__PatternByInsertion__of__Current__Pattern__Delete.Visible = false;
				this.button__PatternByInsertion__of__Current__Pattern__Focus.Visible	= false;
			}								   
			else							   
			{ 								   
				this.button__PatternByInsertion__of__Current__Pattern__Update.Visible = true;
				this.button__PatternByInsertion__of__Current__Pattern__Delete.Visible = true;
				this.button__PatternByInsertion__of__Current__Pattern__Focus.Visible	= true;
			}

			#endregion	children : PatternByInsertions
		}

		internal bool DeletePattern(BabebiDataSet.PatternRow pattern)
		{
			#region		check if the associated WordOrPattern is the parent of some Pattern-ByInsertion.

			BabebiDataSet.PatternByInsertionRow[] patternByInsertions
				= pattern.WordOrPatternRowParent.GetPatternByInsertionRows();

			if (patternByInsertions.Length > 0)
			{
				string patternByInsertionWordIds = "";
				string patternByInsertionUniquekeyStrings = "";
				string patternByInsertionMeanings = "";

				bool firstDone = false;
				foreach (BabebiDataSet.PatternByInsertionRow patternByInsertion in patternByInsertions)
				{
					BabebiDataSet.Pattern_LanguageRow pattern_Language
						= this.DataSet.Pattern_Language
						.FindByPatternIdLanguageCode
						(	
							patternByInsertion.Id, 
							this.Current__Language.Code
						);

					if (!firstDone)
					{
						patternByInsertionWordIds			+= pattern_Language.PatternId.ToString();
						patternByInsertionUniquekeyStrings	+= pattern_Language.PatternRow.UniqueKeyString;
						patternByInsertionMeanings			+= pattern_Language.Meaning;

						firstDone = true;
					}
					else
					{ 
						patternByInsertionWordIds			+= ", " + pattern_Language.PatternId.ToString();
						patternByInsertionUniquekeyStrings	+= ", " + pattern_Language.PatternRow.UniqueKeyString;
						patternByInsertionMeanings			+= ", '" + pattern_Language.Meaning + "'";
					}
				}

				MessageBox.Show
				(
					"This DELETE command aborts because this Pattern cannot be deleted due to the fact that it is still the parent of " +
					patternByInsertions.Length.ToString() +
					" 'Patterns (By insertion)', the Ids, 'Unique Key String's, and Meanings of which are :\n\n" +
					"   - Ids = { " + patternByInsertionWordIds + " },\n\n" +
					"   - UKSs = { " + patternByInsertionUniquekeyStrings + " },\n\n" +
					"   - Meanings = { " + patternByInsertionMeanings + " }.", 
					"Has child Patterns (By Insertion).", 
					MessageBoxButtons.OK,	
					MessageBoxIcon.Error
				);
				return false;				
			}

			#endregion	check if the associated WordOrPattern is the parent of some Pattern-ByInsertion.
			#region		check if this Pattern is the parent of some 'From Pattern' Words or Patterns.

			BabebiDataSet.FromPatternRow[] fromPatterns	= pattern.GetFromPatternRows();

			if (fromPatterns.Length > 0)
			{
				/// the Words first...

				string fromPatternIds = "";
				string fromPatternUniquekeyStrings = "";
				string fromPatternMeanings = "";

				int		count = 0;

				bool firstDone = false;
				foreach (BabebiDataSet.FromPatternRow fromPattern in fromPatterns)
				{
					if (fromPattern.SubscriberCode != MainForm.SubscriberCode_Word)
					{
						continue;
					}

					count++;

					BabebiDataSet.Word_LanguageRow word_Language
						= this.DataSet.Word_Language
						.FindByWordIdLanguageCode
						(	
							fromPattern.SubscriberId, 
							this.Current__Language.Code
						);

					if (!firstDone)
					{
						fromPatternIds				+= word_Language.WordId.ToString();
						fromPatternUniquekeyStrings	+= word_Language.WordRowParent.UniqueKeyString;
						fromPatternMeanings			+= word_Language.Meaning;

						firstDone = true;
					}
					else
					{ 
						fromPatternIds				+= ", "		+ word_Language.WordId.ToString();
						fromPatternUniquekeyStrings	+= ", "		+ word_Language.WordRowParent.UniqueKeyString;
						fromPatternMeanings			+= ", '"	+ word_Language.Meaning + "'";
					}
				}

				if (count > 0)
				{
					MessageBox.Show
					(
						"This DELETE command aborts because this Pattern cannot be deleted due to the fact that it is still the parent of " +
						count.ToString() +
						" 'Words (From Parent)', the Ids, 'Unique Key String's, and Meanings of which are :\n\n" +
						"   - Ids = { " + fromPatternIds + " },\n\n" +
						"   - UKSs = { " + fromPatternUniquekeyStrings + " },\n\n" +
						"   - Meanings = { " + fromPatternMeanings + " }.",
						"Has child Patterns (By Insertion).",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error
					);

					return false;
				}

				/// ... and then the Patterns.

				fromPatternIds = "";
				fromPatternUniquekeyStrings = "";
				fromPatternMeanings = "";

				count = 0;

				firstDone = false;
				foreach (BabebiDataSet.FromPatternRow fromPattern in fromPatterns)
				{
					if (fromPattern.SubscriberCode != MainForm.SubscriberCode_Pattern)
					{
						continue;
					}

					count++;

					BabebiDataSet.Pattern_LanguageRow pattern_Language
						= this.DataSet.Pattern_Language
						.FindByPatternIdLanguageCode
						(	
							fromPattern.SubscriberId, 
							this.Current__Language.Code
						);

					if (!firstDone)
					{
						fromPatternIds				+= pattern_Language.PatternId.ToString();
						fromPatternUniquekeyStrings	+= pattern_Language.PatternRow.UniqueKeyString;
						fromPatternMeanings			+= pattern_Language.Meaning;

						firstDone = true;
					}
					else
					{ 
						fromPatternIds				+= ", "		+ pattern_Language.PatternId.ToString();
						fromPatternUniquekeyStrings	+= ", "		+ pattern_Language.PatternRow.UniqueKeyString;
						fromPatternMeanings			+= ", '"	+ pattern_Language.Meaning + "'";
					}
				}

				MessageBox.Show
				(
					"This DELETE command aborts because this Pattern cannot be deleted due to the fact that it is still the parent of " +
					count.ToString() +
					" 'Patterns (From Parent)', the Ids, 'Unique Key String's, and Meanings of which are :\n\n" +
					"   - Ids = { " + fromPatternIds + " },\n\n" +
					"   - UKSs = { " + fromPatternUniquekeyStrings + " },\n\n" +
					"   - Meanings = { " + fromPatternMeanings + " }.",
					"Has child Patterns (By Insertion).",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error
				);

				return false;
			}

			#endregion	check if the associated WordOrPattern is the parent of some Pattern-ByInsertion.
			#region		if Pattern is a 'Pattern-By insertion', then Delete its LetterOrSymbol Cluster, if it is its only user.

			if (pattern.ModeCode == MainForm.ModeCode_ByInsertion)
			{
				BabebiDataSet.PatternByInsertionRow patternByInsertion
					= this.DataSet.PatternByInsertion
					.FindById(pattern.Id);

				if (patternByInsertion.LetterOrSymbolClusterRow.GetPatternByInsertionRows().Length == 1)
				{
					this.DataSet.LetterOrSymbolCluster.RemoveLetterOrSymbolClusterRow(patternByInsertion.LetterOrSymbolClusterRow);
				}
			}

			#endregion	if Pattern is a 'Pattern-By insertion', then Delete its LetterOrSymbol Cluster, if it is its only user.
			#region		if Word is a 'Word-From Pattern', then Delete its 11P FromPattern row.

			if (pattern.ModeCode == MainForm.ModeCode_FromPattern)
			{
				BabebiDataSet.PatternFromPatternRow patternFromPattern
					= this.DataSet.PatternFromPattern
					.FindById(pattern.Id);

					this.DataSet.FromPattern.RemoveFromPatternRow(patternFromPattern.FromPatternRowParent);
			}

			#endregion	if Word is a 'Word-From Pattern', then Delete its 11P FromPattern row.

			this.DataSet.WordOrPattern.RemoveWordOrPatternRow(pattern.WordOrPatternRowParent); 

			return true;
		}

		#region		buttons de commandes

		private void button__Pattern__Find_Click(object sender, EventArgs e)
		{
			Form__Pattern__Find form = new Form__Pattern__Find(this);

			if (form.ShowDialog() == DialogResult.Cancel)
			{
				return;
			}

			this.populate__Pattern();
		}

		private void button__Pattern__FindById_Click(object sender, EventArgs e)
		{
			Form__Pattern__FindById form = new Form__Pattern__FindById(this);

			if (form.ShowDialog() == DialogResult.Cancel)
			{
				return;
			}

			this.populate__Pattern();
		}

		private void button__Pattern__Create_Click(object sender, EventArgs e)
		{
			Form__Pattern__CreateUpdate form = new Form__Pattern__CreateUpdate(this, true);

			if (form.ShowDialog(this) == DialogResult.OK)
			{
				this.populate__Pattern();
			}
		}

		private void button__Pattern__Update_Click(object sender, EventArgs e)
		{
			Form__Pattern__CreateUpdate form = new Form__Pattern__CreateUpdate(this, false);

			if (form.ShowDialog(this) == DialogResult.OK)
			{
				this.populate__Pattern();
			}
		}

		private void button__Pattern__Delete_Click(object sender, EventArgs e)
		{
			if (this.Current__Pattern == null)
			{
				MessageBox.Show("There is no 'Pattern' to delete.", "Empty", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return; 
			}

			#region		checking of the children of the Pattern (PatternByInsertions)

			BabebiDataSet.WordOrPatternRow wordOrPattern 
				= this.Current__Pattern.WordOrPatternRowParent;

			BabebiDataSet.PatternByInsertionRow[] childPatternByInsertions 
				= wordOrPattern
				.GetPatternByInsertionRows();

			if (childPatternByInsertions.Length > 0)
			{
				string childPatternString = "";

				/// was parenthood
				foreach (BabebiDataSet.PatternByInsertionRow childPatternByInsertion in childPatternByInsertions)
				{
					string childPatternUniqueKeyString = childPatternByInsertion.PatternRowParent.UniqueKeyString;

					childPatternString += (childPatternString == "" ? "" : ", ") + childPatternUniqueKeyString; 
				}

				MessageBox.Show
				(
					"Unable to delete this Pattern because it has still " + 
					childPatternByInsertions.Length.ToString() + 
					" 'Pattern(s) - By insertion -' children: (" + 
					childPatternString + "). \n\n" +
					"All those 'Pattern(s) (By insertion)' children have to be deleted first before being able to delete this (parent) pattern."
					, 
					"This pattern has children"
				);

				return;
			}

			#endregion	checking of the children of the Pattern (>> PatternByInsertions)
			#region		checking of the children of its parent 11P WordOrPattern (>> FromPatterns)

			BabebiDataSet.FromPatternRow[] childFromPatterns 
				= this.Current__Pattern
				.GetFromPatternRows();

			if (childFromPatterns.Length > 0)
			{
				int numberOfChildPatterns = 0;
				string childPatternString = "";

				int numberOfChildWords = 0;
				string childWordString = "";

				foreach (BabebiDataSet.FromPatternRow childFromPattern in childFromPatterns)
				{
					switch (childFromPattern.SubscriberCode)
					{
						case MainForm.SubscriberCode_Pattern :
						{ 
							numberOfChildPatterns++;

							string childPatternUniqueKeyString 
								= this.DataSet.Pattern.FindById(childFromPattern.SubscriberId)
								.UniqueKeyString;

							childPatternString += (childPatternString == "" ? "" : ", ") + childPatternUniqueKeyString; 

							break;
						}
						case MainForm.SubscriberCode_Word:
						{ 
							numberOfChildWords++;

							string childWordUniqueKeyString 
								= this.DataSet.Word.FindById(childFromPattern.SubscriberId)
								.UniqueKeyString;

							childWordString += (childWordString == "" ? "" : ", ") + childWordUniqueKeyString; 

							break;
						}
						default:
						{ 
							break;
						}
					}
				}

				if (numberOfChildPatterns > 0)
				{
					MessageBox.Show
					(
						"Unable to delete this Pattern because it is still the parent of " +
						numberOfChildPatterns.ToString() +
						" 'Pattern (From Pattern)' children.\n\n" +
						"All those child Patterns have to be deleted first before being able to delete this parent pattern.\n\n" +
						"The list of Patterns to delete is: '" + childPatternString + "'.",
						"This pattern is still parent."
					);
				}

				if (numberOfChildWords > 0)
				{
					MessageBox.Show
					(
						"Unable to delete this Pattern because it is still the parent of " +
						numberOfChildWords.ToString() +
						" 'Word (From Pattern)' children.\n\n" +
						"All those child Words have to be deleted first before being able to delete this parent pattern.\n\n" +
						"The list of Words to delete is: '" + childWordString + "'.",
						"This pattern is still parent."
					);
				}

				return;
			}

			#endregion	checking of the children of its parent 11P WordOrPattern (>> FromPatterns)

			DialogResult dialogResult 
				= MessageBox.Show
				(
					"Do you really want to delete the 'Pattern' : [" + 
					this.Current__Pattern.UniqueKeyString +
					"] that means : '" +
					this.Current__Pattern_Language.Meaning +
					"'.",
					"Deleting", 
					MessageBoxButtons.YesNo, 
					MessageBoxIcon.Question
				);
			if (dialogResult == DialogResult.No)
			{
				return;
			}

			if (this.Current__Pattern.ModeCode == ModeCode_ExNihilo)
			{
				/// le mode ExNihilo est géré spécifiquement => il est viré ici (pas pas la combo).
				
				BabebiDataSet.PatternExNihiloRow patternExNihilo = this.DataSet.PatternExNihilo.FindById(this.Current__Pattern.Id);
				
				this.DataSet.SymbolCluster.RemoveSymbolClusterRow(patternExNihilo.SymbolClusterRow);
				
				/// pour mémoire seulement puisque le remove du dessus cascade sur PatternExNihilo.
				//	this.DataSet.PatternExNihilo.RemovePatternExNihiloRow(this.Current__PatternExNihilo);
			}
			else if (this.Current__Pattern.ModeCode == ModeCode_ByInsertion)
			{
				this.remove__PatternByInsertion();
			}
			else if (this.Current__Pattern.ModeCode == ModeCode_FromPattern)
			{
				this.remove__PatternFromPattern();
			}

			this.DataSet.Pattern.RemovePatternRow(this.Current__Pattern);

			this.DataSet.WordOrPattern.RemoveWordOrPatternRow(wordOrPattern);

			#region		cleaning of the 'base' information.

			this.Current__WordOrPattern__of__Pattern = null;

			this.Current__Pattern = null;
			this.Current__Pattern_Language = null;

			this.Current__WordOrPattern__of__PatternByInsertion__Parent = null;


			this.textBox__Pattern__Id.Text					= null;
			this.textBox__Pattern__UniqueKeyString.Text		= null;
			this.textBox__Pattern_Language__Meaning.Text	= null;

			#endregion	cleaning of the 'base' information.
		}

		#endregion	buttons de commandes
		#region		comboBox__Pattern__Extension__SelectedIndexChanged

		/// <summary>
		/// 2 methodes car on veut que le process se fasse même si la valeur de la combo est 
		/// la même que précédement...
		/// </summary>
		private void comboBox__Pattern__Extension__SelectedIndexChanged()
		{
			#region		get the Mode Name from the verbose selected item

			string selectedItem = (string)(this.comboBox__Pattern__Extension.SelectedItem);
			string modeName;

					if (selectedItem.StartsWith(MainForm.ModeName_NotDefined	))	{ modeName = MainForm.ModeName_NotDefined	; }
			else	if (selectedItem.StartsWith(MainForm.ModeName_ByInsertion	))	{ modeName = MainForm.ModeName_ByInsertion	; }
			else	if (selectedItem.StartsWith(MainForm.ModeName_FromPattern	))	{ modeName = MainForm.ModeName_FromPattern	; }
			else																	{ throw new Exception(selectedItem); }

			#endregion	get the Mode Name from the verbose selected item

			switch (modeName)
			{
				case MainForm.ModeName_NotDefined:
				{
					MainForm.ShowSelectedTabPageInTabControl
					(
						this.tabControl__Pattern__Extension,
						null,
						this.tabPage__Pattern__Extension__FromPattern,
						this.tabPage__Pattern__Extension__ByInsertion
					);


					/// cleaning if the currently displayed Extension is not the one of current Pattern.
					if (this.Current__PatternFromPattern != null && this.Current__PatternFromPattern.Id != this.Current__Pattern.Id)
					{ 
						this.populate__PatternFromPattern(PopulatingType.Cleaning);
					}
					else if (this.Current__PatternByInsertion != null && this.Current__PatternByInsertion.Id != this.Current__Pattern.Id)
					{ 
						this.Populate__PatternByInsertion(PopulatingType.Cleaning);
					}

					/// removing of the currently displayed Extension because it belongs to the current Pattern.
					if (this.Current__PatternFromPattern != null && this.Current__PatternFromPattern.Id == this.Current__Pattern.Id)
					{ 
						this.remove__PatternFromPattern();
					}
					else if (this.Current__PatternByInsertion != null && this.Current__PatternByInsertion.Id == this.Current__Pattern.Id)
					{ 
						this.remove__PatternByInsertion();
					}
					
					break;
				}
				case MainForm.ModeName_FromPattern:
				{
					MainForm.ShowSelectedTabPageInTabControl
					(
						this.tabControl__Pattern__Extension, 
						this.tabPage__Pattern__Extension__FromPattern,
						this.tabPage__Pattern__Extension__ByInsertion
					);

					if (this.Current__Pattern.ModeCode != ModeCode_FromPattern)
					{
						this.button__Pattern__FromPattern__CreateUpdate.Text = "CREATE";

						this.button__Pattern__FromPattern__CreateUpdate__Click(); 
					}
					else
					{
						this.populate__PatternFromPattern(PopulatingType.FindingRowsAndSettingFields);
					}

					break;
				}
				case MainForm.ModeName_ByInsertion:
				{
					MainForm.ShowSelectedTabPageInTabControl
					(
						this.tabControl__Pattern__Extension, 
						this.tabPage__Pattern__Extension__ByInsertion,
						this.tabPage__Pattern__Extension__FromPattern
					);

					if (this.Current__Pattern.ModeCode != ModeCode_ByInsertion)
					{
						this.button__Pattern__ByInsertion__CreateUpdate.Text = "CREATE";

						this.button__Pattern__ByInsertion__CreateUpdate__Click(); 
					}
					else
					{
						this.Populate__PatternByInsertion(PopulatingType.FindingRowsAndSettingFields);
					}

					break;
				}
				default: { throw new NotImplementedException(modeName); }
			}
		}
		private void comboBox__Pattern__Extension__SelectedIndexChanged(object sender, EventArgs e)
		{
			this.comboBox__Pattern__Extension__SelectedIndexChanged();
		}

		internal void RemovePriorPatternExtensionIfAny()
		{
			if (!string.IsNullOrEmpty(this.Current__Pattern.ModeCode))
			{
				switch (this.Current__Pattern.ModeCode)
				{
					case MainForm.ModeCode_FromPattern:
					{
						this.remove__PatternFromPattern();

						break;
					}
					case MainForm.ModeCode_ByInsertion:
					{
						this.remove__PatternByInsertion();

						break;
					}
					default:
					{

						throw new Exception(this.Current__Pattern.ModeCode);
					}
				}
			}
			else
			{
				/// cela doit provenir du fait que la combo n'était pas selectionnée
				/// => on passe donc de l'état gazeux à l'état '(not defined)'.
			}
		}

		#endregion	comboBox__Pattern__Extension__SelectedIndexChanged
		#region		search a Pattern methods

		/// <summary>
		/// return true if only 1.
		/// return false if N with 1 matching.
		/// return null if N with no matching.
		/// </summary>
		internal bool? textBox__Pattern__UniqueKeyString__TextChanged
		(
			TextBox								textBox__Pattern__UniqueKeyString	,
			TextBox								textBox__Pattern__Meaning			,
			DataTable							guiTable__Pattern					,
			string								hide_this_Pattern__UniqueKeyString	,
		out BabebiDataSet.PatternRow			selected__Pattern, 
		out BabebiDataSet.Pattern_LanguageRow	selected__Pattern_Language
		)
		{
			bool? b_ = this.textBox__Search__UniqueKeyString__TextChanged
				(
					false,
					textBox__Pattern__UniqueKeyString	,
					textBox__Pattern__Meaning			,
					guiTable__Pattern					,
					hide_this_Pattern__UniqueKeyString	,
				out DataRow	selected__DataRow_, 
				out DataRow	selected__DataRow_Language_
				);

			if (b_.HasValue)
			{
				selected__Pattern			= (BabebiDataSet.PatternRow			)selected__DataRow_;
				selected__Pattern_Language	= (BabebiDataSet.Pattern_LanguageRow)selected__DataRow_Language_;
			}
			else
			{ 
				selected__Pattern = null;
				selected__Pattern_Language = null;
			}

			return b_;

			#region		(version typée)
			/*
			/// returned values if no selection => return false.
			selected__Pattern = null;
			selected__Pattern_Language	= null;

			string pattern__UniqueKeyString = textBox__Pattern__UniqueKeyString.Text;

			if (string.IsNullOrEmpty(pattern__UniqueKeyString))
			{
				return null;
			}

			textBox__Pattern__Meaning.Text = null;

			guiTable__Pattern.Clear();

			if (pattern__UniqueKeyString.Length < 2)
			{ 
				return null;
			}

			string filter =	"UniqueKeyString LIKE '*" + pattern__UniqueKeyString + "*'";

			if (hide_this_Pattern__UniqueKeyString != null)
			{
				filter += " AND NOT(UniqueKeyString = '" + hide_this_Pattern__UniqueKeyString + "')";
			}
					
			DataRow[] selectedPatterns = this.DataSet.Pattern.Select(filter);

			if (selectedPatterns.Length == 1)
			{
				selected__Pattern	= (BabebiDataSet.PatternRow)(selectedPatterns[0]);

				selected__Pattern_Language
					= this.DataSet.Pattern_Language
					.FindByPatternIdLanguageCode(selected__Pattern.Id, this.Current__Language.Code);

				this.textBox__Pattern__UniqueKeyString	.Text	= null;

				return true;
			}
			else
			{
				DataRow matchingGuiDataRow = null;

				foreach (BabebiDataSet.PatternRow selectedPattern in selectedPatterns)
				{
					BabebiDataSet.Pattern_LanguageRow selectedPattern_Language
						= this.DataSet.Pattern_Language
						.FindByPatternIdLanguageCode
						(
							selectedPattern.Id,
							this.Current__Language.Code
						);

					DataRow guiDataRow 
						= guiTable__Pattern.Rows
						.Add
						(
							selectedPattern.Id,
							selectedPattern.UniqueKeyString,
							selectedPattern_Language.Meaning
						);

					if (matchingGuiDataRow == null && selectedPattern.UniqueKeyString == pattern__UniqueKeyString)
					{
						matchingGuiDataRow = guiDataRow;
					}
				}

				if (matchingGuiDataRow != null)
				{
					int		selectedId = (int)(matchingGuiDataRow["Id"]);

					selected__Pattern
						= this.DataSet.Pattern
						.FindById(selectedId);
			
					selected__Pattern_Language
						= this.DataSet.Pattern_Language
						.FindByPatternIdLanguageCode(selectedId, this.Current__Language.Code);

					return false;
				}
				else
				{
					return null; 
				}
			}
			*/
			#endregion	(version typée)
		}

		/// <summary>
		/// return true if only 1.
		/// return false if N with 1 matching.
		/// return null if N with no matching.
		/// </summary>
		internal bool? textBox__Pattern__Meaning__TextChanged
		(
			TextBox								textBox__Pattern__UniqueKeyString,
			TextBox								textBox__Pattern__Meaning,
			DataTable							guiTable__Pattern,
		out BabebiDataSet.PatternRow			selected__Pattern, 
		out BabebiDataSet.Pattern_LanguageRow	selected__Pattern_Language
		)
		{
			bool? b_ = this.textBox__Search__Meaning__TextChanged
				(
					false,
					textBox__Pattern__UniqueKeyString	,
					textBox__Pattern__Meaning			,
					guiTable__Pattern					,
				out DataRow	selected__DataRow_, 
				out DataRow	selected__DataRow_Language_
				);

			if (b_.HasValue)
			{
				selected__Pattern			= (BabebiDataSet.PatternRow			)selected__DataRow_;
				selected__Pattern_Language	= (BabebiDataSet.Pattern_LanguageRow)selected__DataRow_Language_;
			}
			else
			{ 
				selected__Pattern = null;
				selected__Pattern_Language = null;
			}

			return b_;

			#region		(version typée)
			/*
			/// returned values if no selection => return false.
			selected__Pattern = null;
			selected__Pattern_Language						= null;

			string parent__meaning = textBox__Pattern__Meaning.Text;

			if (string.IsNullOrEmpty(parent__meaning))
			{
				return null;
			}

			textBox__Pattern__UniqueKeyString.Text = null;

			guiTable__Pattern.Clear();

			if (parent__meaning.Length < 2)
			{
				return null;
			}

			DataRow[] selectedPattern_Languages
				= this.DataSet.Pattern_Language
				.Select
				(
					"LanguageCode = '" + this.Current__Language.Code + "' AND Meaning LIKE '*" + parent__meaning + "*'"
				);

			if (selectedPattern_Languages.Length == 1)
			{
				selected__Pattern_Language = (BabebiDataSet.Pattern_LanguageRow)(selectedPattern_Languages[0]);

				selected__Pattern = selected__Pattern_Language.PatternRow;

				textBox__Pattern__Meaning.Text = null;

				return true;
			}
			else
			{
				DataRow matchingGuiDataRow = null;

				foreach (BabebiDataSet.Pattern_LanguageRow selectedPattern_Language_ in selectedPattern_Languages)
				{
					BabebiDataSet.PatternRow selectedPattern = selectedPattern_Language_.PatternRow;

					DataRow guiDataRow
						= guiTable__Pattern
						.Rows
						.Add
						(
							selectedPattern_Language_.PatternId,
							selectedPattern.UniqueKeyString,
							selectedPattern_Language_.Meaning
						);

					if (matchingGuiDataRow == null && selectedPattern_Language_.Meaning == parent__meaning)
					{
						matchingGuiDataRow = guiDataRow;
					}
				}

				if (matchingGuiDataRow != null)
				{
					int selectedId = (int)(matchingGuiDataRow["Id"]);

					selected__Pattern
						= this.DataSet.Pattern
						.FindById(selectedId);
			
					selected__Pattern_Language
						= this.DataSet.Pattern_Language
						.FindByPatternIdLanguageCode(selectedId, this.Current__Language.Code);

					return false;
				}
				else
				{
					return null;
				}
			}
			*/

			#endregion	(version typée)
		}

		#endregion	search a Pattern methods
		#region		functions

		/// next Word Id
		internal int PatternId__Next()
		{
			return this.Word_Pattern__Id__Next(false);
		}

		/// Id
		internal void Pattern__Id__TextChanged(TextBox_WEM textBox_WEM__PatternId, ref int patternId)
		{	
			
			this.Word_Pattern__Id__TextChanged(false, textBox_WEM__PatternId, ref patternId);
		}

		/// UniqueKeyString
		internal void Pattern__UniqueKeyString__TextChanged(TextBox_WEM textBox_WEM__PatternUniqueKeyString)
		{
			this.Word_Pattern__UniqueKeyString__TextChanged(false, textBox_WEM__PatternUniqueKeyString);

			if (textBox_WEM__PatternUniqueKeyString == null)
			{
				return;
			}

			string pattern__uniqueKeyString = textBox_WEM__PatternUniqueKeyString.Text();

			List<BabebiDataSet.LetterOrSymbolRow> letterOrSymbolList = new List<BabebiDataSet.LetterOrSymbolRow>();
			
			string invalidcharacterString = this.Split_a_string_into_LetterOrSymbols(pattern__uniqueKeyString, letterOrSymbolList);

			if (invalidcharacterString != null)
			{
				textBox_WEM__PatternUniqueKeyString.SetError("The 'Unique Key String' of the Pattern contains the invalid character : '" + invalidcharacterString + "'.", "Invalid character");

				return;
			}

			bool hasOneSymbolAtLeast = false;
			foreach (BabebiDataSet.LetterOrSymbolRow letterOrSymbol in letterOrSymbolList)
			{
				if (letterOrSymbol.ModeCode == MainForm.ModeCode_Symbol)
				{ 
					hasOneSymbolAtLeast = true;

					break;
				}
			}
			if (!hasOneSymbolAtLeast)
			{
				/// insupportable ! mais comment faire ?

				//MessageBox.Show
				//(
				//	"The 'Unique Key String' of the PATTERN does not contain any symbol (but it could be on purpose).", 
				//	"WARNING",
				//	MessageBoxButtons.OK,
				//	MessageBoxIcon.Information
				//);

				return;
			}
		}

		/// Meaning
		internal void Pattern__Meaning__TextChanged(TextBox_WEM textBox_WEM__PatternMeaning)
		{
			this.Word_Pattern__Meaning__TextChanged(false, textBox_WEM__PatternMeaning);
		}

		/// create a Pattern without extension
		internal void Create__Pattern
		(
			int		pattern__Id,
			string	pattern__UniqueKeyString,
			string	pattern_Language__Meaning,
		out	BabebiDataSet.WordOrPatternRow		current__WordOrPattern__of__Word,
		out	BabebiDataSet.PatternRow			current__Pattern,					
		out	BabebiDataSet.Pattern_LanguageRow	current__Pattern_Language,			
			string modeCode = MainForm.ModeCode_NotDefined
		)
		{
			this.Create__Word_Pattern
			(
				false,
				pattern__Id,
				pattern__UniqueKeyString,
				pattern_Language__Meaning,
				null,
			out	DataRow	current__WordOrPattern__of__Word_,
			out	DataRow	current__Pattern_,					
			out	DataRow	current__Pattern_Language_,			
				modeCode
			);

			current__WordOrPattern__of__Word = (BabebiDataSet.WordOrPatternRow		)current__WordOrPattern__of__Word_	;
			current__Pattern				 = (BabebiDataSet.PatternRow			)current__Pattern_					;					
			current__Pattern_Language		 = (BabebiDataSet.Pattern_LanguageRow	)current__Pattern_Language_			;
		}

		/// Update a word without extension
		internal void Update__Pattern
		(
			int		pattern__Id,
			string	pattern__UniqueKeyString,
			string	pattern_Language__Meaning,
			BabebiDataSet.WordOrPatternRow		current__WordOrPattern,	/// indispensable pour pouvoir updater l'Id...					
			BabebiDataSet.PatternRow			current__Pattern,					
			BabebiDataSet.Pattern_LanguageRow	current__Pattern_Language
		)
		{
			this.Update__Word_Pattern
			(
				false,
				pattern__Id,
				pattern__UniqueKeyString,
				pattern_Language__Meaning,
				null,
				current__WordOrPattern,	
				current__Pattern,					
				current__Pattern_Language,
			out BabebiDataSet.LanguageWordRow	current__LanguageWord_	/// pas utilisée
			);
		}

		internal void Ctor__CreateUpdate__Pattern
		(
			Form		form,
			Button		button__CreateUpdate,
			Button		button__Clone,
			string		modeName,
			Label		label__Pattern__Id,
			Label		label__Pattern__UniqueKeyString,
			Label		label__Pattern_Language__Meaning,
			TextBox		textBox__Pattern__Id,
			TextBox		textBox__Pattern__UniqueKeyString,
			TextBox		textBox__Pattern_Language__Meaning,
			bool		isUniqueKeyStringComputed,
		out	TextBox_WEM textBox_WEM__Pattern__Id,
		out	TextBox_WEM textBox_WEM__Pattern__UniqueKeyString,
		out	TextBox_WEM textBox_WEM__Pattern_Language__Meaning,
			bool trueForCreate__falseForUpdate,
		ref int	pattern__Id,
			BabebiDataSet.PatternRow			current__Pattern,					
			BabebiDataSet.Pattern_LanguageRow	current__Pattern_Language
		)
		{
			BabebiDataSet.WordType_LanguageRow wordType_Language__DUMMY = null;

			this.Ctor__CreateUpdate__Word_Pattern
			(
				false,
				form,
				button__CreateUpdate,
				button__Clone,
				modeName,
				label__Pattern__Id,
				label__Pattern__UniqueKeyString,
				label__Pattern_Language__Meaning,
				null,
				textBox__Pattern__Id,
				textBox__Pattern__UniqueKeyString,
				textBox__Pattern_Language__Meaning,
				null,
				isUniqueKeyStringComputed,
			out	TextBox_WEM textBox_WEM__Pattern__Id_,
			out	TextBox_WEM textBox_WEM__Pattern__UniqueKeyString_,
			out	TextBox_WEM textBox_WEM__Pattern_Language__Meaning_,
			out	ComboBox_WEM comboBox_WEM__WordType_Language__Name_,
				trueForCreate__falseForUpdate,
			ref pattern__Id,
			ref wordType_Language__DUMMY,
				current__Pattern,					
				current__Pattern_Language
			);
			textBox_WEM__Pattern__Id				= textBox_WEM__Pattern__Id_					;
			textBox_WEM__Pattern__UniqueKeyString	= textBox_WEM__Pattern__UniqueKeyString_	;
			textBox_WEM__Pattern_Language__Meaning	= textBox_WEM__Pattern_Language__Meaning_	;
		}

		internal void Clone__Pattern
		(
			TextBox textBox__Pattern__UniqueKeyString,
			TextBox textBox__Pattern_Language__Meaning,
			bool	isUniqueKeyFieldComputed,
			BabebiDataSet.PatternRow			current__Pattern,					
			BabebiDataSet.Pattern_LanguageRow	current__Pattern_Language
		)
		{
			this.Clone__Word_Pattern
			(
				false,
				textBox__Pattern__UniqueKeyString,
				textBox__Pattern_Language__Meaning,
				null,
				isUniqueKeyFieldComputed,
				current__Pattern,
				current__Pattern_Language
			);
		}

		#endregion	functions
	}
}