using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Babebi4
{
	/// aurait pu être procédural...

	internal class MeaningParser
	{
		internal	MainForm	MainForm;
		private		string		meaning;

		internal string	ErrorMessage = null;

		internal List<string> LanguageWordStrings;

		public MeaningParser(MainForm mainForm, string	meaning)
		{
			this.MainForm	= mainForm;
			this.meaning	= meaning.Trim();

			this.LanguageWordStrings	= new List<string>();
		}

		internal bool Parse()
		{ 
			char firstChar;
			char lastChar;

			#region		remove final the " (...)" that may contain ','

			lastChar = this.meaning[this.meaning.Length - 1];

			if (lastChar == ')')
			{
				int lengthToRemove = 1;
				char c;
				do
				{ 
					lengthToRemove++;

					if (lengthToRemove > this.meaning.Length)
					{
						break;
					}

					c = this.meaning[this.meaning.Length - lengthToRemove];
				}
				while(c != '(');

				if (lengthToRemove  > this.meaning.Length)
				{
					this.ErrorMessage = "There is a closing parenthesis that is not preceded by an opening parenthesis.";
						
					return false;
				}

				this.meaning = this.meaning.Substring(0, this.meaning.Length - lengthToRemove);

				this.meaning = this.meaning.TrimEnd();
			}

			#endregion	remove final the " (...)" that may contain ','


			string[] subMeanings = this.meaning.Split( new char[] { ',' } , StringSplitOptions.RemoveEmptyEntries);

			foreach (string subMeaning in subMeanings)
			{
				string subMeaning_ = subMeaning.Trim();

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

				#region		remove " (...)"

				lastChar = subMeaning_[subMeaning_.Length - 1];

				if (lastChar == ')')
				{
					int lengthToRemove = 1;
					char c;
					do
					{ 
						lengthToRemove++;

						if (lengthToRemove > subMeaning_.Length)
						{
							break;
						}

						c = subMeaning_[subMeaning_.Length - lengthToRemove];
					}
					while(c != '(');

					if (lengthToRemove  > subMeaning_.Length)
					{
						this.ErrorMessage = "There is a closing parenthesis that is not preceded by an opening parenthesis.";
						
						return false;
					}

					subMeaning_ = subMeaning_.Substring(0, subMeaning_.Length - lengthToRemove);

					subMeaning_ = subMeaning_.TrimEnd();
				}

				#endregion	remove " (...)"

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

				firstChar	= subMeaning_[0];
				lastChar	= subMeaning_[subMeaning_.Length - 1];

				if (firstChar == '{' && lastChar == '}')
				{
					if (!this.parse__fullString(ref subMeaning_))
					{
						return false;
					}
				}
				else if (firstChar == '[' && lastChar == ']')
				{
					if (!this.parse__fullString(ref subMeaning_))
					{
						return false;
					}

					if (!this.parse__subStrings(subMeaning_))
					{
						return false;
					}
				}
				else
				{
					if (!this.parse__subStrings(subMeaning_))
					{
						return false;
					}
				}
			}

			return true;
		}

		private bool parse__fullString(ref string subMeaning_)	
		{ 
			subMeaning_ = subMeaning_.Substring(1, subMeaning_.Length - 2);

			if (subMeaning_.Length > 32)
			{
				this.ErrorMessage = "The maximum length for a 'Language Word' is 32.";

				return false;
			}

			this.LanguageWordStrings.Add(subMeaning_);

			return true;
		}

		internal List<string> SubSubMeaningList_that_will_become_languageWords;

		private bool parse__subStrings(string subMeaning_)
		{
			string[] subSubMeanings 
				= subMeaning_.Split
				( 
					new char[] { ' ' , '\'', '’'}, 
					StringSplitOptions.RemoveEmptyEntries
				);

			if (subSubMeanings.Length > 1)
			{
				this.SubSubMeaningList_that_will_become_languageWords = new List<string>();

				Form__SubStrings form__SubStrings = new Form__SubStrings(this, subSubMeanings);

				DialogResult dialogResult__Form__SubStrings = form__SubStrings.ShowDialog();
				if (dialogResult__Form__SubStrings == DialogResult.Cancel)
				{
					return true;
				}

				subSubMeanings = this.SubSubMeaningList_that_will_become_languageWords.ToArray();
			}

			foreach (string subMeaningSubString in subSubMeanings)
			{
				if (subMeaningSubString.Length > 32)
				{
					this.ErrorMessage = "The maximum length for a 'Language Word' is 32.";

					return false;
				}

				this.LanguageWordStrings.Add(subMeaningSubString);
			}
		
			return true;	
		}

	}
}
