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
{
	internal partial class Form__BookSentence__CreateUpdate : Form
	{
		private MainForm	mainForm;
		private bool		trueForCreate__falseForUpdate;

		private string		current__language__Code
		{
			get { return this.mainForm.Current__Language.Code; }
		}
		private BabebiDataSet.LanguageRow	current__language
		{
			get { return this.mainForm.Current__Language; }
		}


		internal Form__BookSentence__CreateUpdate(MainForm mainForm, bool trueForCreate__falseForUpdate) : this()
		{
			this.mainForm						= mainForm;
			this.trueForCreate__falseForUpdate	= trueForCreate__falseForUpdate;

			if (!this.trueForCreate__falseForUpdate)
			{
				this.button.Text = "UPDATE";

				if (this.mainForm.Current__Sentence_Language != null)
				{
					this.textBox.Text = this.mainForm.Current__Sentence_Language.String;
				}
			}
		}

		private Form__BookSentence__CreateUpdate()
		{
			InitializeComponent();
		}

		private void button__Click(object sender, EventArgs e)
		{
			char[] sentenceSpliters = new char[] {' ', ',', ';', '.', '?', '!', '\'', '’' };

			string sentenceString;
			if (string.IsNullOrEmpty(textBox.Text))
			{
				sentenceString = "";
			}
			else
			{ 
				sentenceString = textBox.Text;
			}


			if (trueForCreate__falseForUpdate)
			{
				#region		compute the next BookSentence Index

				int bookSentenceIndex = 0;
				foreach (BabebiDataSet.BookSentenceRow bookSentence in this.mainForm.Current__Book.GetBookSentenceRows())
				{
					if (bookSentence.RowState == DataRowState.Deleted || bookSentence.RowState == DataRowState.Detached)
					{
						continue;
					}

					if (bookSentence.Index > bookSentenceIndex)
					{
						bookSentenceIndex = bookSentence.Index;
					}
				}
				bookSentenceIndex++;

				#endregion	compute the next BookSentence Index
				#region		search if the sentence is already existing or not ?

				BabebiDataSet.SentenceRow[] sentences 
					= 
					(BabebiDataSet.SentenceRow[])
					(this.mainForm.DataSet.Sentence.Select("String = '" + sentenceString + "'"));

				if (sentences.Length == 1)
				{
					this.mainForm.Current__Sentence = sentences[0];

					this.mainForm.Current__Sentence_Language
						= this.mainForm.DataSet
						.Sentence_Language
						.FindBySentenceIdLanguageCode
						(
							this.mainForm.Current__Sentence.Id,
							this.current__language__Code
						);
				}
				else
				{
					#region		compute the next Sentence Id

					long sentenceId = 0;
					foreach (BabebiDataSet.SentenceRow sentence in this.mainForm.DataSet.Sentence)
					{
						if (sentence.RowState == DataRowState.Deleted || sentence.RowState == DataRowState.Detached)
						{
							continue;
						}

						if (sentence.Id > sentenceId)
						{
							sentenceId = sentence.Id;
						}
					}
					sentenceId++;

					#endregion	compute the next Sentence Id

					this.mainForm.Current__Sentence = this.mainForm.DataSet.Sentence.AddSentenceRow(sentenceId, "");

					this.mainForm.Current__Sentence_Language
						= this.mainForm.DataSet
						.Sentence_Language
						.AddSentence_LanguageRow
						(
							this.mainForm.Current__Sentence,
							this.current__language,
							sentenceString
						);

					string[] sentenceSubStrings = sentenceString.Split(sentenceSpliters);

					for (short index = 0; index < Convert.ToInt16(sentenceSubStrings.Length); index++)
					{
						string subString = sentenceSubStrings[Convert.ToInt32(index)];

						BabebiDataSet.LanguageWordRow languageWord
							= this.mainForm.DataSet.LanguageWord
							.FindByLanguageCodeString
							(
								this.current__language__Code,
								subString
							);

						if (languageWord == null)
						{
							languageWord
								= this.mainForm.DataSet.LanguageWord
								.AddLanguageWordRow
								(
									this.current__language,
									subString
								);
						}
					
						BabebiDataSet.Sentence_LanguageLanguageWordRow sentence_LanguageLanguageWord
							= this.mainForm.DataSet.Sentence_LanguageLanguageWord
							.AddSentence_LanguageLanguageWordRow
							(
								this.mainForm.Current__Sentence.Id,
								this.current__language__Code, 
								index,
								languageWord.String
							);
					}
				}

				#endregion	search if the sentence is already existing or not ?
	
				this.mainForm.Current__BookSentence	
					= this.mainForm.DataSet.BookSentence
					.AddBookSentenceRow
					(
						this.mainForm.Current__Book, 
						bookSentenceIndex, 
						this.mainForm.Current__Sentence
					);
			}
			else /// (!trueForCreate__falseForUpdate)
			{
				#region		return if no change

				if (sentenceString == this.mainForm.Current__Sentence_Language.String)
				{
					this.DialogResult = DialogResult.OK;

					this.Close();

					return;
				}
				
				#endregion	return if no change

				sentenceString = sentenceString.Trim();

				#region		search if the sentence is already existing or not ?

				BabebiDataSet.SentenceRow priorSentence = this.mainForm.Current__Sentence;

				BabebiDataSet.SentenceRow[] sentences 
					= 
					(BabebiDataSet.SentenceRow[])
					(this.mainForm.DataSet.Sentence.Select("String = '" + sentenceString + "'"));

				if (sentences.Length == 1)
				{
					this.mainForm.Current__Sentence = sentences[0];

					this.mainForm.Current__Sentence_Language
						= this.mainForm.DataSet
						.Sentence_Language
						.FindBySentenceIdLanguageCode
						(
							this.mainForm.Current__Sentence.Id,
							this.current__language__Code
						);

					/// on va tout récupérer : Sentence_LanguageLanguageWords + SentenceWords + links 
					/// => plus rien à faire
				}
				else
				{
					#region about Current__Sentence and Current__Sentence_Language

					if (this.mainForm.Current__Sentence.GetBookSentenceRows().Length == 1)
					{
						/// la Sentence est captive de la Booksentence : on va la réajuter.

						priorSentence = null;   /// pour signifier que la Sentence row a bien été conservée

						this.mainForm.Current__Sentence_Language.String = sentenceString;
					}
					else
					{
						/// la Sentence n'est pas captive de la Booksentence : 
						/// on est obligé d'en refaire une autre. Evidement toute la traduction sera
						/// à (re)faire.

						#region		compute the next Sentence Id

						long sentenceId = 0;
						foreach (BabebiDataSet.SentenceRow sentence in this.mainForm.DataSet.Sentence)
						{
							if (sentence.RowState == DataRowState.Deleted || sentence.RowState == DataRowState.Detached)
							{
								continue;
							}

							if (sentence.Id > sentenceId)
							{
								sentenceId = sentence.Id;
							}
						}
						sentenceId++;

						#endregion	compute the next Sentence Id

						this.mainForm.Current__Sentence = this.mainForm.DataSet.Sentence.AddSentenceRow(sentenceId, "");

						this.mainForm.Current__Sentence_Language
							= this.mainForm.DataSet
							.Sentence_Language
							.AddSentence_LanguageRow
							(
								this.mainForm.Current__Sentence,
								this.current__language,
								sentenceString
							);
					}

					#endregion	about Current__Sentence and Current__Sentence_Language
					#region		adapting about Words

					/// la cible
					string[] sentenceSubStrings = sentenceString.Split(sentenceSpliters);
					short sentenceSubStrings__Length = Convert.ToInt16(sentenceSubStrings.Length);

					/// l'existant
					BabebiDataSet.Sentence_LanguageLanguageWordRow[] sentence_LanguageLanguageWords
						= this.mainForm.Current__Sentence_Language.GetSentence_LanguageLanguageWordRows();	

					short sentence_LanguageLanguageWords__Length = Convert.ToInt16(sentence_LanguageLanguageWords.Length);
					
					short nextLastIndex = sentence_LanguageLanguageWords__Length;

					Dictionary<string, Dictionary<short, BabebiDataSet.Sentence_LanguageLanguageWordRow>> dico 
						= new Dictionary<string, Dictionary<short, BabebiDataSet.Sentence_LanguageLanguageWordRow>>();
					foreach 
					(
						BabebiDataSet.Sentence_LanguageLanguageWordRow sentence_LanguageLanguageWord 
						in 
						sentence_LanguageLanguageWords
					)
					{
						string	languageWordString	= sentence_LanguageLanguageWord.LanguageWordString;
						short	index				= sentence_LanguageLanguageWord.Index;

						if (languageWordString == "")
						{
							continue;
						}

						Dictionary<short, BabebiDataSet.Sentence_LanguageLanguageWordRow> subDico;

						if (!dico.ContainsKey(languageWordString))
						{
							subDico = new Dictionary<short, BabebiDataSet.Sentence_LanguageLanguageWordRow>();

							dico.Add(languageWordString, subDico);
						}
						else
						{ 
							subDico = dico[languageWordString];
						}

						subDico.Add(index, sentence_LanguageLanguageWord);
					}

					for (short index = 0; index < sentenceSubStrings__Length ; index++)
					{
						string languageWordString = sentenceSubStrings[Convert.ToInt32(index)];

						if (languageWordString == "")
						{
							continue;
						}

						#region		create the LanguageWord, if not already existing

						BabebiDataSet.LanguageWordRow languageWord
							= this.mainForm.DataSet.LanguageWord
							.FindByLanguageCodeString
							(
								this.current__language__Code,
								languageWordString
							);

						if (languageWord == null)
						{
							languageWord
								= this.mainForm.DataSet.LanguageWord
								.AddLanguageWordRow
								(
									this.current__language,
									languageWordString
								);
						}

						#endregion	create the LanguageWord, if not already existing

						/// try to find the row with the same languageWordString
						BabebiDataSet.Sentence_LanguageLanguageWordRow	sentence_LanguageLanguageWord__same_languageWordString = null;
						short											sentence_LanguageLanguageWord__same_languageWordString__Index = -1;
						if (dico.ContainsKey(languageWordString))
						{ 
							Dictionary<short, BabebiDataSet.Sentence_LanguageLanguageWordRow> subDico = dico[languageWordString];

							sentence_LanguageLanguageWord__same_languageWordString = subDico.First().Value;

							sentence_LanguageLanguageWord__same_languageWordString__Index
								= sentence_LanguageLanguageWord__same_languageWordString.Index;
						}

						/// try to find the row with the same index
						BabebiDataSet.Sentence_LanguageLanguageWordRow sentence_LanguageLanguageWord__same_index
							= this.mainForm.DataSet
							.Sentence_LanguageLanguageWord
							.FindBySentenceIdLanguageCodeIndex
							(
								this.mainForm.Current__Sentence.Id,
								this.current__language__Code, 
								index
							);

						if
						(
							sentence_LanguageLanguageWord__same_languageWordString == null
							&&
							sentence_LanguageLanguageWord__same_index == null
						)
						{
							this.mainForm.DataSet
								.Sentence_LanguageLanguageWord
								.AddSentence_LanguageLanguageWordRow
								(
									this.mainForm.Current__Sentence.Id,
									this.current__language__Code,
									index,
									languageWordString
								);
						}
						else if
						(
							sentence_LanguageLanguageWord__same_languageWordString == null
							&&
							sentence_LanguageLanguageWord__same_index != null
						)
						{
							#region		removing in the dico

							dico[sentence_LanguageLanguageWord__same_index.LanguageWordString]
								.Remove(sentence_LanguageLanguageWord__same_index.Index);

							if (dico[sentence_LanguageLanguageWord__same_index.LanguageWordString].Count == 0)
							{
								dico.Remove(sentence_LanguageLanguageWord__same_index.LanguageWordString);
							}

							#endregion	removing in the dico

							sentence_LanguageLanguageWord__same_index.LanguageWordString = languageWordString;
						}
						else if
						(
							sentence_LanguageLanguageWord__same_languageWordString != null
							&&
							sentence_LanguageLanguageWord__same_index == null
						)
						{
							sentence_LanguageLanguageWord__same_languageWordString.Index = index;

							#region		removing in the dico

							dico[languageWordString].Remove(sentence_LanguageLanguageWord__same_languageWordString__Index);

							if (dico[languageWordString].Count == 0)
							{
								dico.Remove(languageWordString);
							}

							#endregion	removing in the dico
						}
						else if
						(
							sentence_LanguageLanguageWord__same_languageWordString != null
							&&
							sentence_LanguageLanguageWord__same_index != null
						)
						{
							if (sentence_LanguageLanguageWord__same_languageWordString != sentence_LanguageLanguageWord__same_index)
							{
								BabebiDataSet.Sentence_LanguageLanguageWordRow sentence_LanguageLanguage__moved_at_the_end
									= this.mainForm.DataSet.Sentence_LanguageLanguageWord
									.FindBySentenceIdLanguageCodeIndex
									(
										this.mainForm.Current__Sentence.Id,
										this.current__language__Code,
										sentence_LanguageLanguageWord__same_languageWordString.Index
									);
								sentence_LanguageLanguage__moved_at_the_end.Index = nextLastIndex;
								nextLastIndex++;

								sentence_LanguageLanguageWord__same_index.Index = sentence_LanguageLanguageWord__same_languageWordString.Index;

								sentence_LanguageLanguageWord__same_languageWordString.Index = index;
							}
							
							#region		removing in the dico

							dico[languageWordString].Remove(sentence_LanguageLanguageWord__same_languageWordString__Index);

							if (dico[languageWordString].Count == 0)
							{
								dico.Remove(languageWordString);
							}

							#endregion	removing in the dico
						}
						else
						{ 
							throw new Exception();
						}
					}

					foreach (Dictionary<short, BabebiDataSet.Sentence_LanguageLanguageWordRow> subDico in dico.Values)
					{
						foreach (BabebiDataSet.Sentence_LanguageLanguageWordRow sentence_LanguageLanguageWord in subDico.Values)
						{
							this.mainForm.DataSet
							.Sentence_LanguageLanguageWord
							.RemoveSentence_LanguageLanguageWordRow
							(sentence_LanguageLanguageWord);
						}
					}

					#endregion	adapting about Words
				}

				#endregion	search if the sentence is already existing or not ?

				if (this.mainForm.Current__BookSentence.SentenceRow != this.mainForm.Current__Sentence)
				{
					this.mainForm.Current__BookSentence.SentenceRow = this.mainForm.Current__Sentence;
				}

				#region		delete priorSentence if not used

				if (priorSentence != null && priorSentence.GetBookSentenceRows().Length == 0)
				{
					this.mainForm.DataSet.Sentence.RemoveSentenceRow(priorSentence);	/// will cascade on sentence_Language.
				}

				#endregion	delete priorSentence if not used
			}

			this.DialogResult = DialogResult.OK;

			this.Close();
		}
	}
}
