// App.custom - customization for App.cs
//
// Author(s):
//	Stephane Delcroix  <stephane@delcroix.org>
//
// Copyright (c) 2009 Stephane Delcroix
//
// This is open source software. See COPYING for details.
//

		public App (string name, string startup_id, params object [] commands) : this (name, startup_id)
		{
			for (int i = 0; i < commands.Length; i+=2)
				AddCommand (commands[i] as string, (int)commands[i+1]);
		}

		[GLib.CDeclCallback]
		delegate int MessageReceivedVMDelegate (IntPtr app, int command, IntPtr message_data, uint time_);

		static MessageReceivedVMDelegate MessageReceivedVMCallback;

		static int messagereceived_cb (IntPtr app, int command, IntPtr message_data, uint time_)
		{
			try {
				App app_managed = GLib.Object.GetObject (app, false) as App;
				Unique.Response raw_ret = app_managed.OnMessageReceived (command, message_data == IntPtr.Zero ? null : (Unique.MessageData) GLib.Opaque.GetOpaque (message_data, typeof (Unique.MessageData), false), time_);
				return (int) raw_ret;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call doesn't return
				throw e;
			}
		}

		static void OverrideMessageReceived (GLib.GType gtype)
		{
			if (MessageReceivedVMCallback == null)
				MessageReceivedVMCallback = new MessageReceivedVMDelegate (messagereceived_cb);
			OverrideVirtualMethod (gtype, "message-received", MessageReceivedVMCallback);
		}

		[GLib.DefaultSignalHandler(Type=typeof(Unique.App), ConnectionMethod="OverrideMessageReceived")]
		protected virtual Unique.Response OnMessageReceived (int command, Unique.MessageData message_data, uint time_)
		{
			GLib.Value ret = new GLib.Value (Unique.ResponseGType.GType);
			GLib.ValueArray inst_and_params = new GLib.ValueArray (4);
			GLib.Value[] vals = new GLib.Value [4];
			vals [0] = new GLib.Value (this);
			inst_and_params.Append (vals [0]);
			vals [1] = new GLib.Value (command);
			inst_and_params.Append (vals [1]);
			vals [2] = new GLib.Value (message_data);
			inst_and_params.Append (vals [2]);
			vals [3] = new GLib.Value (time_);
			inst_and_params.Append (vals [3]);
			g_signal_chain_from_overridden (inst_and_params.ArrayPtr, ref ret);
			foreach (GLib.Value v in vals)
				v.Dispose ();
			Unique.Response result = (Unique.Response) (Enum) ret;
			ret.Dispose ();
			return result;
		}

		[GLib.Signal("message-received")]
		event Unique.MessageReceivedHandler InternalMessageReceived {
			add {
				GLib.Signal sig = GLib.Signal.Lookup (this, "message-received", typeof (Unique.MessageReceivedArgs));
				sig.AddDelegate (value);
			}
			remove {
				GLib.Signal sig = GLib.Signal.Lookup (this, "message-received", typeof (Unique.MessageReceivedArgs));
				sig.RemoveDelegate (value);
			}
		}

		MessageReceivedHandler received_handler;

		public event MessageReceivedHandler MessageReceived {
			add {
				if (received_handler == null)
					InternalMessageReceived += MessageReceivedWrapper;
				received_handler = (MessageReceivedHandler)Delegate.Combine (received_handler, value);
			}
			remove {
				received_handler = (MessageReceivedHandler)Delegate.Remove (received_handler, value);
				if (received_handler == null)
					InternalMessageReceived -= MessageReceivedWrapper;
			}
		}

		[GLib.ConnectBefore]
		void MessageReceivedWrapper (object sender, MessageReceivedArgs e)
		{
			MessageReceivedHandler eh = received_handler;
			if (eh == null)
				return;
			foreach (MessageReceivedHandler d in eh.GetInvocationList ()) {
				if (e.RetVal != null && (Response)e.RetVal != Response.Passthrough)
					break;
				d (sender, e);
			}
		}


