using System;

namespace Omega
{
	public class Variable: AST.Node
	{
		protected int h;
		protected string n;
		protected bool g;

		public static Variable CreateGlobal (string n)
		{
			return new Variable(n, true);
		}

		public Variable (int h)
		{
			this.g = false;

			Initialize(h);
		}

		public Variable (string n, bool g)
		{
			if (this.g = g)
				Initialize(DllInterface.Global_Create(n));
			else
			{
				this.h = 0;
				this.n = n;
			}
		}

		public Variable (string n) :
			this (n, false)
		{
		}

		public Variable () :
			this(null)
		{
		}

		public void Initialize (int h)
		{
			if (Initialized)
				throw new InvalidOperationException();

			this.h = h;
			this.n = null;
		}

		public bool Initialized
		{
			get
			{
				return h != 0 && n == null;
			}
		}

		public bool Global
		{
			get
			{
				return g;
			}
		}

		public static explicit operator int (Variable v)
		{
			if (!v.Initialized)
				throw new InvalidOperationException();

			return v.h;
		}

		public override bool Equals (object o)
		{
			if (o is Variable)
			{
				Variable v = (Variable)o;

				if (!Initialized && !v.Initialized)
					return n == v.n;
				else
					return h == v.h;
			}
			else
				return false;
		}

		public override int GetHashCode ()
		{
			return base.GetHashCode();
		}

		public string Name
		{
			get
			{
				if (Initialized)
					return DllInterface.Variable_GetName(h);
				else
					return n;
			}
		}
	}
}