using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

using miew.Enumerable;
using miew.String;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[Serializable]
	public sealed partial class Config
	{
		public Config()
		{
			this.types = new Types(this);

			this.system = new System(this);

			this.grammar = new Grammar(this);

			this.parser = new Parser(this);
		}

		public Parser parser;

		public NodeLabels nodeLabels = new NodeLabels();

		public System system;

		public Types types = new Types();

		public Grammar grammar;

		public struct Types
		{
			public Types(Config cfg)
			{
				this.top_type = "⊤";// "*top*";
				this.string_type = "string";

				this.typs_list = "*list*";
				this.typs_empty_list = "*null*";
				this.typs_diff_list = "diff-list";

				this.f_list_head = "first";
				this.f_list_tail = "rest";
				this.f_dlist_list = "list";
				this.f_dlist_last = "last";
			}
			public String top_type;
			public String string_type;

			public String typs_list;
			public String typs_empty_list;
			public String typs_diff_list;

			public String f_list_head;
			public String f_list_tail;
			public String f_dlist_list;
			public String f_dlist_last;
		};

		public struct Grammar
		{
			Config cfg;
			public Grammar(Config cfg)
				: this()
			{
				this.cfg = cfg;
				this.key_daughter_path = new FsPath("key-arg");
				this.orth_path = new FsPath("stem");
				this.rule_args_path = new FsPath("args");
				this.typs_key_daughter = "+";
			}

			public List<String> start_symbols;

			public String head_dtr_path;
			public String typs_key_daughter;

			public FsPath orth_path;
			public FsPath rule_args_path;
			public FsPath key_daughter_path;
		};


		public struct System
		{
			Config cfg;
			public System(Config cfg)
			{
				this.cfg = cfg;
				this.f_multithreading = true;
				this.tw_debug = null;
				this.submitter = new Submitter(cfg);
			}

			bool f_multithreading;
			public bool MultiThreading
			{
				get { return f_multithreading; }
				set
				{
					f_multithreading = value;
					if (!f_multithreading)
						cfg.parser.c_tasks_max = -1;
				}
			}

			public TextWriter tw_debug;

			public Submitter submitter;

			public struct Submitter
			{
				Config cfg;
				public Submitter(Config cfg)
				{
					this.cfg = cfg;
					this.c = 1;
					this.skipitems = 0;
					this.takeitems = int.MaxValue;
				}

				int c;
				public int TaskCount
				{
					get { return c; }
					set { c = value; }
				}

				public int skipitems;
				public int takeitems;
			};
		};
	};
}