using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

using miew.Debugging;
using miew.Enumerable;
using miew.String;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///
	///
	///
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public unsafe partial class TypeMgr
	{
		public Edge CreateEdge(Type t, int m, bool f_coref)
		{
			Debug.Assert(t != null && t.tm == this);

			Edge.Flag f;
			if (t == StringType)
				f = Edge.Flag.EtmString;
			else
			{
				f = (Edge.Flag)t.m_id;
				if ((t.m_flags & Type.Flags.HasAnyFeatures) > 0)
					f |= Edge.Flag.EtmNonBareType;
			}

			if (f_coref)
				f |= Edge.Flag.Coreference;

			/// Caller may not submit a non-bare mark if the requirements for a non-bare mark are not met
			/// Caller must submit the mark to recycle. Otherwise, use the Tfs functions.
			if (((f & (Edge.Flag.Coreference | Edge.Flag.EtmNonBareType)) == 0) != (m == 0))
				throw new Exception();
			return new Edge(f, m);
		}

		public Type GetEdgeType(Edge.Flag f)
		{
			if ((f & Edge.Flag.EtmMask) == Edge.Flag.EtmString)
				return StringType;
			int mid = (int)(f & Edge.Flag.MultiIdMask);
			return mid == 0 ? TopType : type_arr[mid];
		}

		public bool IsTopId(Edge e)
		{
			return (int)(e.FlagsId & (Edge.Flag.MultiIdMask | Edge.Flag.EtmMask)) == 0;
		}

		public bool IsStringValue(Edge.Flag f)
		{
			return (f & Edge.Flag.EtmMask) == Edge.Flag.EtmString && (f & Edge.Flag.MultiIdMask) != 0;
		}

		public String GetStringValue(Edge.Flag f)
		{
			int sid;
			if ((f & Edge.Flag.EtmMask) != Edge.Flag.EtmString || (sid = (int)(f & Edge.Flag.MultiIdMask)) == 0)
				return null;
			return strings.Get(sid);
		}
	};
}