using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

namespace Babebi4
{
	internal class GuiTable__SentenceWord : DataTable
	{
		private MainForm mainForm;

		internal DataSet DataSet__for__BindingSource { get ; private set; }

		private string current__Language__Code
		{
			get { return this.mainForm.Current__Language.Code; }
		}

		#region		Columns

		private		DataColumn SentenceLanguageWordIndices	;
		internal	DataColumn SentenceWordIndex			;
		private		DataColumn WordUniqueKeyString			;
		private		DataColumn WordMeaning					;
		private		DataColumn WordId						;

		#endregion	Columns

		public GuiTable__SentenceWord(MainForm mainForm) : base("SentenceWord_")
		{
			this.mainForm = mainForm;

			this.DataSet__for__BindingSource = new DataSet();

			this.DataSet__for__BindingSource.Tables.Add(this);

			#region		Columns

			this.SentenceLanguageWordIndices	= new DataColumn("SentenceLanguageWordIndex", typeof(string	));
			this.SentenceWordIndex				= new DataColumn("SentenceWordIndex"		, typeof(short	));
			this.WordUniqueKeyString			= new DataColumn("WordUniqueKeyString"		, typeof(string	));
			this.WordMeaning					= new DataColumn("WordMeaning"				, typeof(string	));
			this.WordId							= new DataColumn("WordId"					, typeof(int	));

			this.SentenceLanguageWordIndices	.AllowDBNull = false;
			this.SentenceWordIndex				.AllowDBNull = false;
			this.WordUniqueKeyString			.AllowDBNull = false;
			this.WordMeaning					.AllowDBNull = false;
			this.WordId							.AllowDBNull = false;

			this.SentenceLanguageWordIndices	.MaxLength = 32;
			this.WordUniqueKeyString			.MaxLength = 32;
			this.WordMeaning					.MaxLength = 256;

			this.Columns.Add(this.SentenceLanguageWordIndices	);
			this.Columns.Add(this.SentenceWordIndex				);
			this.Columns.Add(this.WordUniqueKeyString			);
			this.Columns.Add(this.WordMeaning					);
			this.Columns.Add(this.WordId						);

			#endregion	Columns

			this.PrimaryKey	= new DataColumn[] { this.SentenceWordIndex };

			this.mainForm.DataSet.SentenceWord.RowChanging	+= SentenceWord__RowChanging;
			this.mainForm.DataSet.SentenceWord.RowChanged	+= SentenceWord__RowChanged;
			this.mainForm.DataSet.SentenceWord.RowDeleting	+= SentenceWord__RowDeleting;

			this.mainForm.DataSet.Word.RowChanged			+= Word__RowChanged;
			this.mainForm.DataSet.Word_Language.RowChanged	+= Word_Language__RowChanged;

			this.mainForm.DataSet.SentenceWord_LanguageWord.RowChanged += SentenceWord_LanguageWord__RowChanged;
			this.mainForm.DataSet.SentenceWord_LanguageWord.RowDeleting += SentenceWord_LanguageWord__RowDeleting;
		}

		#region		events

		private void SentenceWord__RowChanging(object sender, DataRowChangeEventArgs e)
		{
			if (e.Action == DataRowAction.Commit)
			{
				return;
			}

			BabebiDataSet.SentenceWordRow sentenceWord = (BabebiDataSet.SentenceWordRow)(e.Row);

			if (sentenceWord.SentenceId != this.mainForm.Current__Sentence.Id)
			{
				return;
			}

			if (e.Action == DataRowAction.Change)
			{
				short existing = sentenceWord.Field<short>(this.mainForm.DataSet.SentenceWord.IndexColumn, DataRowVersion.Current);
				short modified = sentenceWord.Field<short>(this.mainForm.DataSet.SentenceWord.IndexColumn, DataRowVersion.Proposed);

				if (existing != modified)
				{
					DataRow guiDataRow = this.Find(existing);

					if (guiDataRow != null)
					{
						guiDataRow.SetField<short>(this.SentenceWordIndex, modified);
					}
				}
			}
		}
		private void SentenceWord__RowChanged(object sender, DataRowChangeEventArgs e)
		{
			if (e.Action == DataRowAction.Commit)
			{
				return;
			}

			BabebiDataSet.SentenceWordRow sentenceWord = (BabebiDataSet.SentenceWordRow)(e.Row);

			if (e.Action == DataRowAction.Add)
			{
				this.addGuiRow(sentenceWord);

				Word.Compute_Sentence__String(this.mainForm.Current__Sentence);
			}
		}
		private void SentenceWord__RowDeleting(object sender, DataRowChangeEventArgs e)
		{
			BabebiDataSet.SentenceWordRow sentenceWord = (BabebiDataSet.SentenceWordRow)(e.Row);

			if (e.Action == DataRowAction.Delete)
			{
				DataRow guiDataRow = this.Find(sentenceWord.Index);

				this.Rows.Remove(guiDataRow);
			}
		}

		private void Word__RowChanged(object sender, DataRowChangeEventArgs e)
		{
			if (e.Action == DataRowAction.Commit)
			{
				return;
			}

			BabebiDataSet.WordRow word = (BabebiDataSet.WordRow)(e.Row);

			if (e.Action == DataRowAction.Change)
			{
				foreach (DataRow guiDataRow in this.Rows)
				{
					if (guiDataRow.Field<int>(this.WordId) == word.Id)
					{
						if (guiDataRow.Field<string>(this.WordUniqueKeyString) != word.UniqueKeyString)
						{
							guiDataRow.SetField<string>(this.WordUniqueKeyString, word.UniqueKeyString);
						}
					}
				}
			}
		}
		private void Word_Language__RowChanged(object sender, DataRowChangeEventArgs e)
		{
			if (e.Action == DataRowAction.Commit)
			{
				return;
			}

			BabebiDataSet.Word_LanguageRow word_Language = (BabebiDataSet.Word_LanguageRow)(e.Row);

			if (word_Language.LanguageCode != this.current__Language__Code)
			{
				return;
			}

			if (e.Action == DataRowAction.Change)
			{
				foreach (DataRow guiDataRow in this.Rows)
				{
					if (guiDataRow.Field<int>(this.WordId) == word_Language.WordId)
					{
						if (guiDataRow.Field<string>(this.WordMeaning) != word_Language.Meaning)
						{
							guiDataRow.SetField<string>(this.WordMeaning, word_Language.Meaning);
						}
					}
				}
			}
		}

		private void SentenceWord_LanguageWord__Row___(DataRowChangeEventArgs e)
		{
			BabebiDataSet.SentenceWord_LanguageWordRow sentenceWord_LanguageWord = (BabebiDataSet.SentenceWord_LanguageWordRow)(e.Row);

			DataRow guiDataRow = this.Find(sentenceWord_LanguageWord.SentenceWordIndex);

			if (guiDataRow == null)
			{
				return;
			}

			string existingSentenceLanguageWordIndices = guiDataRow.Field<string>(this.SentenceLanguageWordIndices);

			string candidateSentenceLanguageWordIndices 
				= compute__sentenceLanguagewordIndices
				(sentenceWord_LanguageWord.SentenceWordRowParent);

			if (existingSentenceLanguageWordIndices != candidateSentenceLanguageWordIndices)
			{
				guiDataRow.SetField<string>(this.SentenceLanguageWordIndices, candidateSentenceLanguageWordIndices);
			}
		}
		private void SentenceWord_LanguageWord__RowChanged(object sender, DataRowChangeEventArgs e)
		{
			if (e.Action == DataRowAction.Commit)
			{
				return;
			}

			if (e.Action == DataRowAction.Add)
			{
				this.SentenceWord_LanguageWord__Row___(e);
			}
		}
		private void SentenceWord_LanguageWord__RowDeleting(object sender, DataRowChangeEventArgs e)
		{
			if (e.Action == DataRowAction.Commit)
			{
				return;
			}

			this.SentenceWord_LanguageWord__Row___(e);
		}

		#endregion	events

		internal DataRow Find(int sentenceWordIndex)
		{ 
			return this.Rows.Find(sentenceWordIndex);
		}

		internal void Populate()
		{ 
			this.Rows.Clear();

			foreach (BabebiDataSet.SentenceWordRow sentenceWord in this.mainForm.Current__Sentence.GetSentenceWordRows())
			{
				this.addGuiRow(sentenceWord);
			}
		}

		private DataRow addGuiRow(BabebiDataSet.SentenceWordRow sentenceWord)
		{
			BabebiDataSet.WordRow word = sentenceWord.WordRow;

			BabebiDataSet.Word_LanguageRow word_Language
				= this.mainForm.DataSet
				.Word_Language
				.FindByWordIdLanguageCode
				(
					word.Id,
					this.current__Language__Code
				);

			string sentenceLanguageWordIndices = compute__sentenceLanguagewordIndices(sentenceWord);

			DataRow dataRow
				= this.Rows.Add
				(
					sentenceLanguageWordIndices,    /// SentenceLanguageWordIndex	
					sentenceWord.Index,             /// SentenceWordIndex			
					word.UniqueKeyString,           /// WordUniqueKeyString		
					word_Language.Meaning,          /// WordMeaning				
					word.Id                         /// WordId					
				);

			return dataRow;
		}

		private static string compute__sentenceLanguagewordIndices(BabebiDataSet.SentenceWordRow sentenceWord)
		{
			List<short> languageWordIndexList = new List<short>();

			foreach
			(
				BabebiDataSet.SentenceWord_LanguageWordRow sentenceWord_LanguageWord
				in
				sentenceWord.GetSentenceWord_LanguageWordRows()
			)
			{
				languageWordIndexList.Add(sentenceWord_LanguageWord.Sentence_LanguageLanguageWordIndex);
			}

			languageWordIndexList.Sort();

			string sentenceLanguageWordIndices = "";
			int count = 0;
			foreach(short languageWordIndex in languageWordIndexList)
			{
				sentenceLanguageWordIndices
					+= (sentenceLanguageWordIndices == "" ? "" : ", ")
					+ languageWordIndex.ToString();

				count++;
			}
			if (count > 1)
			{
				sentenceLanguageWordIndices = "{ " + sentenceLanguageWordIndices + " }";
			}

			return sentenceLanguageWordIndices;
		}

		//internal void Compute__Sentence__String()
		//{
		//	Word.Compute_Sentence__String(this.mainForm.Current__Sentence);
		//}
	}
}
