using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using glue.Debugging;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	sealed public class SingleUserTray : Tray
	{
		public SingleUserTray(int tix, TypeMgr tm, int next_mark, int next_id)
			: base(tix, tm, next_mark, next_id)
		{
			for (int i = 0; i < Pools.Length; i++)
				Pools[i] = new SingleUserTrayConstraintPool(this, i);
		}

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 
		/// </summary>
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		sealed public class SingleUserTrayConstraintPool : ConstraintPool
		{
			public SingleUserTrayConstraintPool(Tray tr, int i_feat)
				: base(tr, i_feat)
			{
			}

			Dictionary<Int32, Edge> dict = new Dictionary<Int32, Edge>();

			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 
			/// </summary>
			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			public override Edge GetEdge(Int32 m)
			{
				Debug.Assert(m != 0);
				Edge c;
				dict.TryGetValue(m, out c);
				return c;
			}

			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 
			/// </summary>
			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			public override bool TryGetEdge(int m, out Edge e)
			{
				Debug.Assert(m != 0);
				return dict.TryGetValue(m, out e);
			}

			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// Store the constraint for the specified mark. Handle Edge value semantics properly.
			/// Allows detached mark to be set for bare or atomic types
			/// </summary>
			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			public override void SetEdge(Int32 m, Edge c)
			{
				Debug.Assert(m != 0 && m >= tr._protect_mark && c.FlagsId != 0);
				dict[m] = c;
			}

			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 
			/// </summary>
			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			public override void RemoveEdge(Int32 m)
			{
				Debug.Assert(m != 0 && m >= tr._protect_mark);
				dict.Remove(m);
			}


			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 
			/// </summary>
			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			public override bool TryRemoveEdge(Int32 m, out Edge e)
			{
				Debug.Assert(m != 0 && m >= tr._protect_mark);
				return dict.TryGetValue(m, out e) ? dict.Remove(m) : false;
			}

			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 
			/// </summary>
			///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			public override bool ContainsInMark(Int32 m)
			{
				Debug.Assert(m != 0);
				return dict.ContainsKey(m);
			}

			public override int Count { get { return dict.Count; } }

			public override IEnumerable<int> Marks { get { return dict.Keys; } }

			public override IEnumerable<Edge> Edges { get { return dict.Values; } }

			public override IEnumerable<KeyValuePair<int, Edge>> PoolEdges { get { return dict; } }
		};
	};
}