using System;                           /* IntPtr */
using System.Runtime.InteropServices;   /* DLLImport */

namespace GhostAPI
{
	public struct gsapi_revision_t
	{
		public IntPtr product;
		public IntPtr copyright;
		public int revision;
		public int revisiondate;
	}

	public enum gs_set_param_type
	{ 
		gs_spt_invalid =   -1,
		gs_spt_null =		0,   /* void * is NULL */
		gs_spt_bool =		1,   /* void * is NULL (false) or non-NULL (true) */
		gs_spt_int =		2,   /* void * is a pointer to an int */
		gs_spt_float =		3,   /* void * is a float * */
		gs_spt_name =		4,   /* void * is a char * */
		gs_spt_string =		5,   /* void * is a char * */
		gs_spt_long =		6,   /* void * is a long * */
		gs_spt_i64 =		7,   /* void * is a int64_t * */
		gs_spt_size_t =		8    /* void * is a size_t * */
	};

	public enum gsEncoding
	{
		GS_ARG_ENCODING_LOCAL = 0,
		GS_ARG_ENCODING_UTF8 = 1,
		GS_ARG_ENCODING_UTF16LE = 2
	};

	static class gsConstants
	{
		public const int E_QUIT = -101;
		public const int GS_READ_BUFFER = 32768;
		public const int DISPLAY_UNUSED_LAST = (1 << 7);
		public const int DISPLAY_COLORS_RGB = (1 << 2);
		public const int DISPLAY_DEPTH_8 = (1 << 11);
		public const int DISPLAY_LITTLEENDIAN = (1 << 16);
        public const int DISPLAY_BIGENDIAN = (0 << 16);
	}

	class ghostapi
	{
#if MONO
    private const string lib_dll = "libgpdl.so";
#else
#if WIN64
#if !GHOSTPDL
		private const string lib_dll = "gsdll64.dll";
#else
		private const string lib_dll = "gpdldll64.dll";
#endif
#else
#if !GHOSTPDL
		private const string lib_dll = "gsdll32.dll";
#else
		private const string lib_dll = "gpdldll32.dll";
#endif
#endif
#endif
        /* Callback proto for stdio */
        public delegate int gsStdIOHandler(IntPtr caller_handle, IntPtr buffer, int len);

		/* Callback proto for poll function */
		public delegate int gsPollHandler(IntPtr caller_handle);

		/* Callout proto */
		public delegate int gsCallOut(IntPtr callout_handle, IntPtr device_name, int id, int size, IntPtr data);

		[DllImport(lib_dll, EntryPoint = "gsapi_revision", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_revision(ref gsapi_revision_t vers, int size);

		[DllImport(lib_dll, EntryPoint = "gsapi_new_instance", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_new_instance(out IntPtr pinstance,
			IntPtr caller_handle);

		[DllImport(lib_dll, EntryPoint = "gsapi_delete_instance", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern void gsapi_delete_instance(IntPtr instance);

		[DllImport(lib_dll, EntryPoint = "gsapi_init_with_args", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_init_with_args(IntPtr instance, int argc,
			IntPtr argv);

		[DllImport(lib_dll, EntryPoint = "gsapi_exit", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_exit(IntPtr instance);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_arg_encoding", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_arg_encoding(IntPtr instance,
			int encoding);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_stdio", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_stdio(IntPtr instance,
			gsStdIOHandler stdin, gsStdIOHandler stdout, gsStdIOHandler stderr);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_stdio_with_handle", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_stdio_with_handle(IntPtr instance,
			gsStdIOHandler stdin, gsStdIOHandler stdout, gsStdIOHandler stderr, IntPtr caller_handle);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_poll", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_poll(IntPtr instance, gsPollHandler pollfn);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_poll_with_handle", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_poll_with_handle(IntPtr instance, gsPollHandler pollfn,
			IntPtr caller_handle);

		[DllImport(lib_dll, EntryPoint = "gsapi_get_default_device_list", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_get_default_device_list(IntPtr instance,
			ref IntPtr list, ref int listlen);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_default_device_list", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_default_device_list(IntPtr instance,
			IntPtr list, ref int listlen);

		[DllImport(lib_dll, EntryPoint = "gsapi_run_string", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_run_string(IntPtr instance, IntPtr command,
			int usererr, ref int exitcode);

		[DllImport(lib_dll, EntryPoint = "gsapi_run_string_with_length", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_run_string_with_length(IntPtr instance, IntPtr command,
			uint length, int usererr, ref int exitcode);

		[DllImport(lib_dll, EntryPoint = "gsapi_run_file", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_run_file(IntPtr instance, IntPtr filename,
			int usererr, ref int exitcode);

		[DllImport(lib_dll, EntryPoint = "gsapi_run_string_begin", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_run_string_begin(IntPtr instance,
			int usererr, ref int exitcode);

		[DllImport(lib_dll, EntryPoint = "gsapi_run_string_continue", CharSet = CharSet.Ansi,
		CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_run_string_continue(IntPtr instance,
			IntPtr command, int count, int usererr, ref int exitcode);

		[DllImport(lib_dll, EntryPoint = "gsapi_run_string_end", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_run_string_end(IntPtr instance,
			int usererr, ref int exitcode);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_display_callback", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_display_callback(IntPtr pinstance, IntPtr caller_handle);

		[DllImport(lib_dll, EntryPoint = "gsapi_add_control_path", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_add_control_path(IntPtr instance, int type, IntPtr path);

		[DllImport(lib_dll, EntryPoint = "gsapi_remove_control_path", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_remove_control_path(IntPtr instance, int type, IntPtr path);

		[DllImport(lib_dll, EntryPoint = "gsapi_purge_control_paths", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern void gsapi_purge_control_paths(IntPtr instance, int type);

		[DllImport(lib_dll, EntryPoint = "gsapi_activate_path_control", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern void gsapi_activate_path_control(IntPtr instance, int enable);

		[DllImport(lib_dll, EntryPoint = "gsapi_is_path_control_active", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_is_path_control_active(IntPtr instance);

		[DllImport(lib_dll, EntryPoint = "gsapi_set_param", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_set_param(IntPtr instance, gs_set_param_type type,
			IntPtr param, IntPtr value);

		[DllImport(lib_dll, EntryPoint = "gsapi_register_callout", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_register_callout(IntPtr instance, gsCallOut callout,
			IntPtr callout_handle);

		[DllImport(lib_dll, EntryPoint = "gsapi_deregister_callout", CharSet = CharSet.Ansi,
			CallingConvention = CallingConvention.StdCall)]
		public static extern int gsapi_deregister_callout(IntPtr instance, gsCallOut callout,
			IntPtr callout_handle);
	}
}
