using System;
using System.Runtime.InteropServices;

namespace ToolboxSnippetsInstaller
{
	class MessageFilter : IOleMessageFilter
	{
		//
		// Publiczny interfejs API

		public static void Register()
		{
			IOleMessageFilter newfilter = new MessageFilter(); 

			IOleMessageFilter oldfilter = null; 
			CoRegisterMessageFilter(newfilter, out oldfilter);
		}

		public static void Revoke()
		{
			IOleMessageFilter oldfilter = null; 
			CoRegisterMessageFilter(null, out oldfilter);
		}

		//
		// Implementacja interfejsu IOleMessageFilter
    
		int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr lpInterfaceInfo) 
		{
			System.Diagnostics.Debug.WriteLine("IOleMessageFilter::HandleInComingCall");

			return 0; //SERVERCALL_ISHANDLED
		}

		int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
		{
			System.Diagnostics.Debug.WriteLine("IOleMessageFilter::RetryRejectedCall");

			if (dwRejectType == 2 ) //SERVERCALL_RETRYLATER
			{
				System.Diagnostics.Debug.WriteLine("Retry call later");
				return 99; //natychmiastowe ponowienie, jeżeli return >=0 & <100
			}
			return -1; //anulowanie wywołania
		}

		int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
		{
			System.Diagnostics.Debug.WriteLine("IOleMessageFilter::MessagePending");

			return 2; //PENDINGMSG_WAITDEFPROCESS 
		}

		//
		// Implementacja

		[DllImport("Ole32.dll")]
		private static extern int CoRegisterMessageFilter(IOleMessageFilter newfilter, out IOleMessageFilter oldfilter);
	}

	[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),    
	InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	interface IOleMessageFilter // zamierzona zmiana nazwy w celu uniknięcia pomyłki z System.Windows.Forms.IMessageFilter
	{
		[PreserveSig]
		int HandleInComingCall( 
			int dwCallType, 
			IntPtr hTaskCaller, 
			int dwTickCount, 
			IntPtr lpInterfaceInfo);

		[PreserveSig]
		int RetryRejectedCall( 
			IntPtr hTaskCallee, 
			int dwTickCount,
			int dwRejectType);

		[PreserveSig]
		int MessagePending( 
			IntPtr hTaskCallee, 
			int dwTickCount,
			int dwPendingType);
	}
}
