namespace Binge.Generators.Dummy
{
	using System;
	using System.Collections;
	using System.Text;
	using Binge;
	using Binge.Bits;
	using Binge.Generators;

	public class Generator: Binge.Bits.Object, IGenerator
	{
		private Indentation tab;

		private void Start (string name, string type, bool throttled)
		{
			Console.WriteLine ("{0} [{1}] Start {2} {3}", tab, name, type, throttled ? "(throttled)" : "");
			tab++;
		}

		private void End (string name, string type, bool throttled)
		{
			tab--;
			Console.WriteLine ("{0} [{1}] End {2} {3}", tab, name, type, throttled ? "(throttled)" : "");
		}

		private void Found (string name, string type, bool throttled)
		{
			Console.WriteLine ("{0} [{1}] Found {2} {3}", tab, name, type, throttled ? "(throttled)" : "");
		}

		public Generator ()
		{
			tab = new Indentation ();
		}

		public void Generate (Hashtable namespaces, string dir)
		{
			IDictionaryEnumerator de = namespaces.GetEnumerator ();

			while (de.MoveNext ())
				Generate (de.Value as Namespace);
		}

		protected void Generate (Namespace ns)
		{
			Start (ns.Name, "Namespace", ns.Throttled);

			foreach (Interface iface in ns.Interfaces)
				Generate (iface);

			foreach (Binge.Bits.Enum enm in ns.Enums)
				Generate (enm);

 			foreach (Class klass in ns.Classes)
				Generate (klass);

			End (ns.Name, "Namespace", ns.Throttled);
		}

		protected void Generate (Binge.Bits.Attribute attr)
		{
			Found (attr.Name, "Attribute", false);
		}

		protected void Generate (Interface iface)
		{
			Start (iface.Name, "Interface", iface.Throttled);

			// FIXME Implement interfaces

			End (iface.Name, "Interface", iface.Throttled);
		}

		protected void Generate (Binge.Bits.Enum enm)
		{
			Start (enm.NativeName, "Enum", enm.Throttled);

			foreach (EnumItem item in enm.Items)
				Generate (item);

			End (enm.NativeName, "Enum", enm.Throttled);
		}

		protected void Generate (EnumItem item)
		{
			Found (item.NativeName, "EnumItem", false);
		}

		protected void Generate (Class klass)
		{
			Start (klass.NativeName, "Class", klass.Throttled);

			foreach (Binge.Bits.Attribute attr in klass.Attributes)
				Generate (attr);

			foreach (Interface iface in klass.Implements)
				Generate (iface);

			foreach (Property prop in klass.Properties)
				Generate (prop);

			foreach (Constructor ctor in klass.Constructors)
				Generate (ctor);

			foreach (Destructor dtor in klass.Destructors)
				Generate (dtor);

			foreach (Method method in klass.Methods)
				Generate (method);

			End (klass.NativeName, "Class", klass.Throttled);
		}

		protected void Generate (Property prop)
		{
			Found (prop.NativeName, "Property", prop.Throttled);
		}

		protected void Generate (Constructor ctor)
		{
			Start ("Constructor", "", ctor.Throttled);

				foreach (Binge.Bits.Attribute attr in ctor.Attributes)
					Generate (attr);

				foreach (Parameter param in ctor.Parameters)
					Generate (param);

			End ("Constructor", "", ctor.Throttled);
		}

		protected void Generate (Destructor dtor)
		{
			Start ("Destructor", "", dtor.Throttled);
			End ("Destructor", "", dtor.Throttled);
		}

		protected void Generate (Method method)
		{
			Start (method.NativeName, "Method", method.Throttled);

			foreach (Binge.Bits.Attribute attr in method.Attributes)
				Generate (attr);

			foreach (Parameter param in method.Parameters)
				Generate (param);

			End (method.NativeName, "Method", method.Throttled);
		}

		protected void Generate (Parameter param)
		{
			Found (param.NativeName, "Parameter", false);
		}
	}
}
