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
	{
		#region		functions

		internal static void FromPatternLetter__fill__dataGridView
		(
			SortedDictionary<short, Letter>	ranks__letters,
			DataTable						guiTable__FromPatternLetter
		)
		{
			guiTable__FromPatternLetter.Clear();

			foreach (KeyValuePair<short, Letter> rank__letter in ranks__letters)
			{
				short	rank	= rank__letter.Key;
				Letter	letter	= rank__letter.Value;

				guiTable__FromPatternLetter.Rows.Add(rank, letter.TypeCode, letter.String);
			}
		}

		internal void FromPatternLetter__populate_controls
		(
			short		rank, 
			string		letterTypeCode, 
			string		letterString,
			TextBox		textBox__FocusedRank,
			TextBox		textBox__FocusedLetter,
			ComboBox	comboBox__SelectedLetter
		)
		{
			if (rank != -1)
			{
				#region		fill the items of the comboBox__SelectedLetter according to letterTypeCode (V or C).

				comboBox__SelectedLetter.Items.Clear();

				if (letterTypeCode == MainForm.TypeCode_Vowel)
				{
					comboBox__SelectedLetter.Items.AddRange(this.VowelStrings);
				}
				else if (letterTypeCode == MainForm.TypeCode_Consonant)
				{
					comboBox__SelectedLetter.Items.AddRange(this.ConsonantStrings);
				}
				else
				{
					throw new Exception(letterTypeCode);
				}

				#endregion	fill the items of the comboBox__SelectedLetter according to letterTypeCode (V or C).

				textBox__FocusedRank.Text = rank.ToString();
				textBox__FocusedLetter.Text = letterString;

				comboBox__SelectedLetter.SelectedItem = letterString;
			}
			else
			{ 
				comboBox__SelectedLetter.SelectedIndex = -1;
				comboBox__SelectedLetter.Items.Clear();

				textBox__FocusedRank	.Text = null;
				textBox__FocusedLetter	.Text = null;
			}
		}

		internal void FromPatternLetter__bindingSource__CurrentChanged
		(
			BindingSource	bindingSource__FromPatternLetter,
			DataColumn		dataColumn__FromPatternLetter__Rank,
			DataColumn		dataColumn__FromPatternLetter__LetterTypeCode,
			DataColumn		dataColumn__FromPatternLetter__LetterString,
			TextBox			textBox__FocusedRank,
			TextBox			textBox__FocusedLetter,
			ComboBox		comboBox__SelectedLetter
		)
		{
			short	rank			;
			string	letterTypeCode	;
			string	letterString	;

			if (bindingSource__FromPatternLetter.Current != null)
			{
				DataRow fromPatternLetterDataRow = ((DataRowView)(bindingSource__FromPatternLetter.Current)).Row;

				rank			= (short	)(fromPatternLetterDataRow[dataColumn__FromPatternLetter__Rank			]);
				letterTypeCode	= (string	)(fromPatternLetterDataRow[dataColumn__FromPatternLetter__LetterTypeCode]);
				letterString	= (string	)(fromPatternLetterDataRow[dataColumn__FromPatternLetter__LetterString	]);
			}
			else
			{ 
				rank			= -1;		/// value that will trigger the cleaning of the controls below.
				letterTypeCode	= null;		/// value not used
				letterString	= null;		/// value not used
			}

			this.FromPatternLetter__populate_controls
			(
				rank, 
				letterTypeCode, 
				letterString,
				textBox__FocusedRank,
				textBox__FocusedLetter,
				comboBox__SelectedLetter
			);
		}

		internal static void FromPatternLetter__comboBox__SelectedLetter__SelectedIndexChanged
		(
			TextBox							textBox__FocusedRank,
			TextBox							textBox__FocusedLetter,
			ComboBox						comboBox__SelectedLetter,
			SortedDictionary<short, Letter>	ranks__letters,
			DataTable						guiTable__FromPatternLetter,
			DataColumn						dataColumn__FromPatternLetter__LetterString
		)
		{
			string	letterString = (string)(comboBox__SelectedLetter.SelectedItem);

			if (comboBox__SelectedLetter.SelectedItem != null)
			{
				short rank = Convert.ToInt16(textBox__FocusedRank.Text);

				if (ranks__letters[rank].String != letterString)
				{
					Letter letter = new Letter(ranks__letters[rank].TypeCode, letterString);
					ranks__letters[rank] = letter;
				}

				DataRow focusedDataRow = guiTable__FromPatternLetter.Rows.Find(rank);
				if ((string)(focusedDataRow[dataColumn__FromPatternLetter__LetterString]) != letterString)
				{
					focusedDataRow[dataColumn__FromPatternLetter__LetterString] = letterString;
				}
			}
			textBox__FocusedLetter.Text = letterString;
		}

		internal static void FromPattern__comboBox__GuiHorizontalShift__SelectedIndexChanged(ComboBox_WEM comboBox_WEM__GuiHorizontalShift, ref	short selected__GuiHorizontalShift)
		{
			selected__GuiHorizontalShift = Int16.Parse( comboBox_WEM__GuiHorizontalShift.Get() );

			comboBox_WEM__GuiHorizontalShift.ClearError();
		}

		internal void FromPattern__Create
		(
			string								subscriberCode,
			int									subscriberId,
			BabebiDataSet.PatternRow			pattern__PARENT,
			short								guiHorizontalShift,
			SortedDictionary<short, Letter>		ranks__letters,
			out BabebiDataSet.FromPatternRow	current__FromPattern
		)
		{ 
				/// FromPattern
				current__FromPattern
					= this.DataSet.FromPattern
					.AddFromPatternRow
					(
						subscriberCode,
						subscriberId,
						pattern__PARENT,
						guiHorizontalShift
					);
								
				/// FromPatternLetters
				foreach(KeyValuePair<short, Letter> rank__letter in ranks__letters)
				{
					short	rank	= rank__letter.Key;
					Letter	letter	= rank__letter.Value;

					this.DataSet.FromPatternLetter
						.AddFromPatternLetterRow
						(
							subscriberCode,
							subscriberId,
							rank,
							letter.TypeCode,
							letter.String
						);
				}
		}


		internal static string	Compute__LetterDictionaryString__for_Pattern(BabebiDataSet.FromPatternRow fromPattern, BabebiDataSet.FromPatternLetterRow fromPatternLetter__SKIP = null)
		{
			string letterDictionaryString = "";

			BabebiDataSet.FromPatternLetterRow[] fromPatternLetters = fromPattern.GetFromPatternLetterRows();

			if (fromPatternLetter__SKIP != null)
			{
				List<BabebiDataSet.FromPatternLetterRow> fromPatternLetterList = new List<BabebiDataSet.FromPatternLetterRow>();

				foreach (BabebiDataSet.FromPatternLetterRow fromPatternLetter in fromPatternLetters)
				{
					if (fromPatternLetter != fromPatternLetter__SKIP)
					{
						fromPatternLetterList.Add(fromPatternLetter);
					}
				}
				fromPatternLetters = fromPatternLetterList.ToArray();
			}

			bool isMono = fromPatternLetters.Length == 1;

			letterDictionaryString += (isMono ? "" : "{");

			foreach(BabebiDataSet.FromPatternLetterRow fromPatternLetter in fromPatternLetters)
			{
				if (letterDictionaryString != "" && letterDictionaryString != "{")
				{
					letterDictionaryString += ", ";
				}

				letterDictionaryString += " ( ";
				letterDictionaryString += fromPatternLetter.Rank.ToString();
				letterDictionaryString += " ; ";
				letterDictionaryString += fromPatternLetter.LetterString;
				letterDictionaryString += " ) ";
			}

			letterDictionaryString += (isMono ? "" : "}");
			return letterDictionaryString;
		}

		/// <summary>
		/// dans le cas des Words, comme tous les symboles doivent être substitués, 
		/// les ranks sont inutiles puisqu'ils valent : { 1, 2, 3...}.
		/// </summary>
		/// <param name="wordFromPattern"></param>
		/// <returns></returns>
		internal static string	Compute__LetterDictionaryString__for_Word(BabebiDataSet.FromPatternRow fromPattern, BabebiDataSet.FromPatternLetterRow fromPatternLetter__SKIP = null)
		{
			string letterDictionaryString = "";

			BabebiDataSet.FromPatternLetterRow[] fromPatternLetters = fromPattern.GetFromPatternLetterRows();

			if (fromPatternLetter__SKIP != null)
			{
				List<BabebiDataSet.FromPatternLetterRow> fromPatternLetterList = new List<BabebiDataSet.FromPatternLetterRow>();

				foreach (BabebiDataSet.FromPatternLetterRow fromPatternLetter in fromPatternLetters)
				{
					if (fromPatternLetter != fromPatternLetter__SKIP)
					{
						fromPatternLetterList.Add(fromPatternLetter);
					}
				}
				fromPatternLetters = fromPatternLetterList.ToArray();
			}

			bool isMono = fromPatternLetters.Length == 1;

			letterDictionaryString += (isMono ? "" : "{");

			foreach(BabebiDataSet.FromPatternLetterRow fromPatternLetter in fromPatternLetters)
			{
				if (letterDictionaryString != "" && letterDictionaryString != "{")
				{
					letterDictionaryString += ", ";
				}

				letterDictionaryString += fromPatternLetter.LetterString;
			}

			letterDictionaryString += (isMono ? "" : "}");
			return letterDictionaryString;
		}

		internal		int		Compute__Sorting(BabebiDataSet.FromPatternRow fromPattern, BabebiDataSet.FromPatternLetterRow fromPatternLetter__SKIP = null)
		{
			BabebiDataSet.FromPatternLetterRow[] fromPatternLetters = fromPattern.GetFromPatternLetterRows();

			if (fromPatternLetter__SKIP != null)
			{
				List<BabebiDataSet.FromPatternLetterRow> fromPatternLetterList = new List<BabebiDataSet.FromPatternLetterRow>();

				foreach (BabebiDataSet.FromPatternLetterRow fromPatternLetter in fromPatternLetters)
				{
					if (fromPatternLetter != fromPatternLetter__SKIP)
					{
						fromPatternLetterList.Add(fromPatternLetter);
					}
				}
				fromPatternLetters = fromPatternLetterList.ToArray();
			}
			
			int positionMultiplier = 1;
			for (int i = 0; i < fromPatternLetters.Length; i++)
			{
				positionMultiplier *= 31;
			}

			SortedDictionary<short, BabebiDataSet.LetterRow> ranks__letterRows 
				= new SortedDictionary<short, BabebiDataSet.LetterRow>();

			foreach (BabebiDataSet.FromPatternLetterRow fromPatternLetter in fromPatternLetters)
			{
				ranks__letterRows.Add(fromPatternLetter.Rank, fromPatternLetter.LetterRowParent);
			}

			
			int sorting = 0;
			foreach (BabebiDataSet.LetterRow letter in ranks__letterRows.Values)
			{
				positionMultiplier /= 31;

				int rank = Convert.ToInt32(letter.Rank);

				sorting += rank * positionMultiplier;
			}

			return sorting;
		}

		/// complète le ranks__letters fourni avec current FromPatternLetters
		internal static void Restore__ranks__letters__from__FromPatternLetters
		(
			BabebiDataSet.FromPatternRow	fromPatternRow, 
			SortedDictionary<short, Letter>	ranks__letters
		)
		{ 
			BabebiDataSet.FromPatternLetterRow[] fromPatternLetterRows = fromPatternRow.GetFromPatternLetterRows();
			foreach (BabebiDataSet.FromPatternLetterRow fromPatternLetterRow in fromPatternLetterRows)
			{
				if (ranks__letters.ContainsKey(fromPatternLetterRow.Rank))
				{
					continue;
				}

				/// Letter est une enum.
				Letter letter 
					= new Letter
					(
						fromPatternLetterRow.LetterRowParent.TypeCode,
						fromPatternLetterRow.LetterRowParent.String
					);

				ranks__letters.Add(fromPatternLetterRow.Rank, letter);
			}
		}

		#endregion	functions
	}
}
