/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * The GIMP Help Browser for Win32
 * 
 * Interface based on Help Browser:
 * Copyright (C) 1999 Sven Neumann <sven@gimp.org>
 *                    Michael Natterer <mitschel@cs.tu-berlin.de>
 *
 * Windows specific implementation:
 * Copyright (C) 1999 Hans Breuer <Hans@Breuer.Org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include <string.h> 
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include "libgimp/gimp.h"

#include "libgimp/stdplugins-intl.h"

#undef RGB
//#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <direct.h>
#include <io.h>


/*  defines  */

#define GIMP_HELP_EXT_NAME      "extension_gimp_help_browser"
#define GIMP_HELP_TEMP_EXT_NAME "extension_gimp_help_browser_temp"

#define GIMP_HELP_PREFIX        "help"

/*  the three help notebook pages  */
/*
   Context \
   Index    >-> Implement as HTML Frame ?
   Help    /
 */

/* globals */
DWORD g_dwidInst = 0L; 
static gchar * current_locale = "C";

/*  GIMP plugin stuff  */

static void query (void);
static void run   (const gchar     *name,
                   gint             nparams, 
                   const GimpParam *param,
		   gint            *nreturn_vals,
                   GimpParam      **return_vals);

GimpPlugInInfo PLUG_IN_INFO =
{
	NULL,   /*  init_proc   */
	NULL,   /*  quit_proc   */
	query,  /*  query_proc  */
	run,    /*  run_proc    */
};

static gboolean temp_proc_installed = FALSE;

/*  forward declaration  */
HDDEDATA CALLBACK 
DdeCallBack( UINT type, 
			 UINT fmt, 
			 HCONV hconv, 
			 HSZ hsz1, HSZ hsz2, 
			 HDDEDATA hData, 
			 DWORD dwData1, DWORD dwData2);

static gboolean
report_if_missing(gchar* path);

/* implementation */
gboolean
open_browser (gchar *path)
{
	gchar  *root_dir;
	gchar  *sPage;

	HDDEDATA hRetVal;
	HCONV hConv = NULL;

	root_dir = g_strconcat ( gimp_data_directory(), 
							 G_DIR_SEPARATOR_S,
							 GIMP_HELP_PREFIX, NULL);

	if (_chdir (root_dir) == -1)
	{
		gimp_message ("GIMP Help Browser Error.\n"
					  "Couldn't find my root html directory.");
		return FALSE;
	}

	if (0L == g_dwidInst)
	{
		gimp_message("Dde Initialization Failed...");
		return FALSE;
	}

	/* 
	 * Built the correct path
	 */
	if (g_path_is_absolute (path))
		sPage = g_strdup(path);
	else
	{
		sPage = g_strconcat(root_dir, G_DIR_SEPARATOR_S,
							path, NULL);
	}

	if (!report_if_missing(sPage))
	{
		/* Connect to the Netscape server. */
		HSZ hszService;
		HSZ hszTopic;
		char sExecutable[_MAX_PATH*2];

		hszService = DdeCreateStringHandle(g_dwidInst, "NETSCAPE", CP_WINANSI);
		hszTopic = DdeCreateStringHandle(g_dwidInst, "WWW_OpenURL", CP_WINANSI);
		hConv = DdeConnect(g_dwidInst, hszService, hszTopic, NULL);
	}

	if (NULL == hConv)
	{
		/* try to execute filename */
		HINSTANCE hInst = NULL;
		hInst = ShellExecute ( NULL, /* hWnd */
							   "open",
							   sPage,
							   NULL, /* no parameters */
							   gimp_directory (), /* needs a valid working dir */
							   0); /* show command */

		if ((int)hInst > 32) // it works
			return TRUE;
		else
		{
			gimp_message("Unable to start/communicate with BROWSER ...");
			return FALSE;
		}
	}

	/* Convert the Item into string handle and pass it to server. */
	{
		HSZ hszItem;
		unsigned char *psWinId;
		gchar* sItem;

		/* Add quotes to the URL argument as it's of type 
		 * qcs (quoted string)
	     * "\"%s\",,0,0,,,NETREPORT", sPage); // 0 for New Window.
		 *  0xFFFFFFFF for last active Window
		 */
		sItem = g_strdup_printf("\"%s\",,0xFFFFFFFF,0,,,NETREPORT", sPage);
		
		hszItem = DdeCreateStringHandle( g_dwidInst, sItem, CP_WINANSI);
		hRetVal = DdeClientTransaction ( NULL, 0ul, hConv, hszItem, 
										 CF_TEXT, XTYP_REQUEST, 1000L, NULL);

		psWinId = DdeAccessData(hRetVal,NULL);
		g_print("Window ID %s\n", psWinId);
#if 0
		/* Memory and handles leaked???
		 * BUT using The Right Things causes crashes ...  
		 */

		DdeFreeStringHandle( g_dwidInst, hszItem );
		g_free(sItem);
		/* call DdeUnaccessData when finished */
		DdeUnaccessData( psWinId );
#endif
	}

	g_free(sPage);
	g_free(root_dir);

	return TRUE;
}

static gboolean
open_url (gchar *path)
{
  /* Find the browser
   */
  

  g_dwidInst = 0UL; /* 0 or valid! */
  DdeInitialize(&g_dwidInst, DdeCallBack, 
                APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0UL);

  if (!open_browser (path))
    return FALSE;

  // Uninitialize dde application.
  if (g_dwidInst) DdeUninitialize(g_dwidInst);
	      

  return TRUE;
}

static gboolean
report_if_missing(gchar* path)
{
	if (-1 != _access(path, 4)) /* read permission ... */
		return FALSE;
	/* try to remove anchor */
	if (strrchr(path, '#'))
	{
		gchar* real_path = g_strdup(path);
		gboolean bMissing = TRUE;
		g_strdelimit (real_path, "#",'\0');
		bMissing = (-1 != _access(real_path, 4));

		g_free(real_path);
		if (!bMissing)
			return FALSE; /* file found ... */
	}
	/*
	 * File doesn't exist, todo: built the error page
	 */
	gimp_message("Helpbrowser page missing: %s\n", path);
	return TRUE; /* was missing */
}

MAIN ()

static void
query (void)
{
  static GimpParamDef args[] =
  {
    { GIMP_PDB_INT32,  "run_mode", "Interactive" },
    { GIMP_PDB_STRING, "help_path", "" },
    { GIMP_PDB_STRING, "locale"  , "Language to use" },
    { GIMP_PDB_STRING, "help_file", "Path of a local document to open. "
                                    "Can be relative to GIMP_HELP_PATH." }
  };

  gimp_install_procedure (GIMP_HELP_EXT_NAME,
                          "Browse the GIMP help pages.",
                          "",
                          "Sven Neumann <sven@gimp.org>, "
                          "Michael Natterer <mitschel@cs.tu-berlin.de>, "
                          "Hans Breuer <Hans@Breuer.Org>",
                          "Sven Neumann & Michael Natterer & Hans Breuer",
                          "1999",
                          NULL,
                          "",
                          GIMP_EXTENSION,
                          G_N_ELEMENTS (args), 0,
                          args, NULL);
}

static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam **return_vals)
{
	static GimpParam values[1];
	GimpRunMode run_mode;
	GimpPDBStatusType status = GIMP_PDB_SUCCESS;
        gchar       *help_path    = NULL;
        gchar       *locale       = NULL;
        gchar       *help_file    = NULL;
	gchar *path;

	run_mode = param[0].data.d_int32;

	values[0].type = GIMP_PDB_STATUS;
	values[0].data.d_status = status;

	*nreturn_vals = 1;
	*return_vals = values;

	INIT_I18N ();

	if (strcmp (name, GIMP_HELP_EXT_NAME) == 0)
	{
	  /*  set default values  */
	  help_path = g_strconcat (gimp_data_directory(), G_DIR_SEPARATOR_S, 
				   GIMP_HELP_PREFIX, NULL);
	  locale    = g_strdup ("C");
	  help_file = g_strdup ("welcome.html");

		switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
        case GIMP_RUN_NONINTERACTIVE:
	case GIMP_RUN_WITH_LAST_VALS:
			/*  Make sure all the arguments are there!  */
			if (   (nparams != 3) 
				|| !param[2].data.d_string 
				|| !strlen (param[2].data.d_string))
			{
				g_print("Helpbrowser: invalid args or api change?\n");
				path = g_strdup ("welcome.html");
			}
			else
			{
				/* FIXME: use locale
				 * locale = g_strdup (param[1].data.d_string);
				 */
				path = g_strdup (param[2].data.d_string);
			}
			break;
        default:
	  status = GIMP_PDB_CALLING_ERROR;
			break;
        }

		g_strdelimit (path, "/", G_DIR_SEPARATOR);

		if (status == GIMP_PDB_SUCCESS)
		{
			if (!open_url (path))
				values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
			else
				values[0].data.d_status = GIMP_PDB_SUCCESS;

			g_free (path);
		}
		else
			values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
	}
	else
		g_assert_not_reached ();
}

/*
 * Dde call back function.
 */
HDDEDATA CALLBACK 
DdeCallBack( UINT type, 
			 UINT fmt,
			 HCONV hconv, 
			 HSZ hsz1, HSZ hsz2, 
			 HDDEDATA hData, 
			 DWORD dwData1,	DWORD dwData2)	
{
	/* Being a simple client application not taking care of 
	 * any transaction. simply return NULL
	 */
	return (HDDEDATA) NULL;
}
