using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Serialization;

using miew.String;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public partial struct Edge
	{
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// Edge consists of only two fields:
		/// 1. FlagsId (32-bits)
		/// 2. Mark (32-bits)
		/// </summary>
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if DEBUG
		[DebuggerDisplay("{Edge._FlagsReport(this.FlagsId, true),nq}")]
#endif
		readonly public Flag FlagsId;

#if DEBUG
		[DebuggerDisplay("{Edge.FormatMark(this),nq}")]
#endif
		readonly public Int32 Mark;

		public static Edge PrunedEdge = new Edge(Edge.Flag.PrunedDuringParsing, 0);

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// Regarding the FlagsId field:
		/// </summary>
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if DEBUG
		[DebuggerDisplay("{Edge._FlagsReport(this, true),nq}")]
#endif
		[Flags]
		public enum Flag
		{
			Coreference			= unchecked((int)0x80000000),
			PrunedDuringParsing = 0x40000000,

			/// mutually exclusive edge type modes:
			EtmMask				= 0x30000000,
			EtmConfigMapped		= 0x30000000,
			EtmString			= 0x20000000,
			EtmNonBareType		= 0x10000000,

			LowestFlagValue		= EtmNonBareType,

			//Readonly			= 0x08000000,
			//FlagMask			= 0xFF000000,

			MultiIdMask			= 0x0FFFFFFF,

			Bottom		= -1,
		};

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsCoreferenced { get { return FlagsId < 0; } }

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// C O N S T R U C T O R
		/// </summary>
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		public Edge(Flag force_flagsid, int force_mark)
		{
			this.FlagsId = force_flagsid;
			this.Mark = force_mark;
		}

		public override int GetHashCode()
		{
			return Mark + (int)FlagsId;
		}

#if !DEBUG
		public String ToString(TypeMgr tm)
		{
			return tm.GetEdgeType(FlagsId).Name;
		}
#endif
	};
}