using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using agree.itsdb;
using miew.String;
using miew.Enumerable;
using miew.Tokenization;

using Type = System.Type;
using Expression = System.Linq.Expressions.Expression;

namespace agree.Wpf
{
	public class MyUserControl : UserControl
	{
		public static readonly DependencyProperty ItsdbDatabaseProperty;

		public static readonly DependencyProperty ItsdbSelectedTableProperty;

		static MyUserControl()
		{
			{
				FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(
					null,
					FrameworkPropertyMetadataOptions.None,
					(dobj, e) =>
					{
					});

				ItsdbDatabaseProperty = DependencyProperty.Register("ItsdbDatabase", typeof(ItsdbDatabase), typeof(ItsdbWindow), metadata);
			}
			{
				FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(
					null,
					FrameworkPropertyMetadataOptions.None,
					(dobj, e) =>
					{
						Debug.WriteLine("updating selected table dp");
					});

				ItsdbSelectedTableProperty = DependencyProperty.Register("ItsdbSelectedTable", typeof(IitsdbTable), typeof(ItsdbWindow), metadata);
			}
		}
	};

	/// <summary>
	/// Interaction logic for ItsdbWindow.xaml
	/// </summary>
	public partial class ItsdbWindow : MyUserControl
	{
		public ItsdbWindow()
		{
			InitializeComponent();
		}
	};

	public class ItsdbDocument : AgreeDocument
	{

		public ItsdbDocument(agree.ISysObj so)
		{
			ItsdbDatabase db = new ItsdbDatabase(so,
				//"/home/glenn/erg/tsdb/gold/hike"
				"/programming/analytical-grammar/grammars/erg/tsdb/gold/hike"
				);
#if false

			IitsdbTable jt = db.TableFromAnonymousItems("table1", "table1",
				db.ParseTable.Join(db.ItemTable, p => p.i_id, i => i.i_id, (p, i) =>
				{
					return new
					{
						p.i_id,
						i.i_input,
						p.treal,
						p.readings,
						p.unifications,
					};
				}));

			using (StreamWriter sw2 = new StreamWriter(@"\programming\analytical-grammar\lkb-dump2.txt"))
			{
				foreach (dynamic item in jt)
				{
					sw2.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", item.i_id, item.i_input.Trim(), item.treal, item.readings, item.unifications );
				}
			}
#endif

#if false
			agree.Grammar grm = so as agree.Grammar;
			if (grm != null)
			{
				using (StreamWriter sw2 = new StreamWriter(@"d:\programming\analytical-grammar\erg-test-items2.txt"))
				{
					//var erg_tok = new erg_funcs.ErgTokenizer(s => 
					//    {
					//        /// crude lookup verification, but prevent the lexical entry 'The Maltese Falcon' from 
					//        /// accepting  sentence-initial 'The' when we actually want the tokenizer to lowercase it.
					//        return grm.lex[s].Any(q => q.Lemmata.Count == 1);
					//    });

					foreach (dynamic item in jt)
					{
						String s_item = item.i_input.Trim();

						TokenizedString ts = new TokenizedString(s_item, grm.Parser.Tokenizer);

						try
						{
							var ax = grm.lex.AnalyzeHypothesis(ts, grm.loadtray);
							var bx = ax.Analyses.UnionMany(tok => tok.ChartSpan.Range);
							var x = Enumerable.Range(0, ax.ChartSize).Except(bx).ToArray();
							if (x.Length > 0)
								sw2.WriteLine("{0}", x.Select(ix => ts.MinimalSpanText(new glue.Tokenization.Span(ix, ix))).StringJoin(" "));
							else
								sw2.WriteLine("{0}", s_item);
						}
						catch (agree.CyclicUnificationException)
						{
							sw2.WriteLine("*** stack overflow ***");
						}
					}
				}
			}
#endif
			this.Title = "[incr tsdb()] database";

			ItsdbWindow w = new ItsdbWindow();

			w.SetValue(ItsdbWindow.ItsdbDatabaseProperty, db);
			w.SetValue(ItsdbWindow.ItsdbSelectedTableProperty, db.Tables[0]);

			//w.DataContext = db;

			this.Content = w;
		}

	};


}