/* GIO - GLib Input, Output and Streaming Library
 * 
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"

#include <string.h>

#include "gcontenttypeprivate.h"
#include "gwin32appinfo.h"
#include "gappinfo.h"
#include "gioerror.h"
#include "gfile.h"
#include <glib/gstdio.h>
#include "glibintl.h"

#include <windows.h>
#include <shlwapi.h>

#include "gioalias.h"

#ifndef ASSOCF_INIT_BYEXENAME
#define ASSOCF_INIT_BYEXENAME 0x00000002
#endif

/* These were wrong in MingW */
#define REAL_ASSOCSTR_COMMAND 1
#define REAL_ASSOCSTR_EXECUTABLE 2
#define REAL_ASSOCSTR_FRIENDLYDOCNAME 3
#define REAL_ASSOCSTR_FRIENDLYAPPNAME 4

#ifndef AssocQueryString
#pragma message("AssocQueryString not available with SDK used")
#endif

static void g_win32_app_info_iface_init (GAppInfoIface *iface);

struct _GWin32AppInfo
{
  GObject parent_instance;
  wchar_t *id;
  char *id_utf8;
  gboolean id_is_exename;
  char *executable;
  char *name;
  gboolean no_open_with;
};

G_DEFINE_TYPE_WITH_CODE (GWin32AppInfo, g_win32_app_info, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (G_TYPE_APP_INFO,
						g_win32_app_info_iface_init))


static void
g_win32_app_info_finalize (GObject *object)
{
  GWin32AppInfo *info;

  info = G_WIN32_APP_INFO (object);

  g_free (info->id);
  g_free (info->id_utf8);
  g_free (info->name);
  g_free (info->executable);

  G_OBJECT_CLASS (g_win32_app_info_parent_class)->finalize (object);
}

static void
g_win32_app_info_class_init (GWin32AppInfoClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  
  gobject_class->finalize = g_win32_app_info_finalize;
}

static void
g_win32_app_info_init (GWin32AppInfo *local)
{
}

static GAppInfo *
g_desktop_app_info_new_from_id (wchar_t *id /* takes ownership */,
				gboolean id_is_exename)
{
#ifdef AssocQueryString
  ASSOCF flags;
#endif
  wchar_t buffer[1024];
  DWORD buffer_size;
  GWin32AppInfo *info;
  HKEY app_key;
  
  info = g_object_new (G_TYPE_WIN32_APP_INFO, NULL);
  info->id = id; /* Takes ownership */
  info->id_utf8 = g_utf16_to_utf8 (id, -1, NULL, NULL, NULL);  
  info->id_is_exename = id_is_exename;

#ifdef AssocQueryString  
  flags = 0;
  if (id_is_exename)
    flags |= ASSOCF_INIT_BYEXENAME;

  buffer_size = 1024;
  if (AssocQueryStringW(flags,
			REAL_ASSOCSTR_EXECUTABLE,
			id,
			NULL,
			buffer,
			&buffer_size) == S_OK)
    info->executable = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
 
  buffer_size = 1024;
  if (AssocQueryStringW(flags,
			REAL_ASSOCSTR_FRIENDLYAPPNAME,
			id,
			NULL,
			buffer,
			&buffer_size) == S_OK)
    info->name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
#endif

  if (info->name == NULL)
    {
      /* TODO: Should look up name from executable resources */
      if (info->executable)
	info->name = g_path_get_basename (info->executable);
      else
	info->name = g_strdup (info->id_utf8);
    }

#ifdef AssocQueryString
  if (AssocQueryKeyW(flags,
		     ASSOCKEY_APP,
		     info->id,
		     NULL,
		     &app_key) == S_OK)
    {
      if (RegQueryValueExW (app_key, L"NoOpenWith", 0,
			    NULL, NULL, NULL) == ERROR_SUCCESS)
	info->no_open_with = TRUE;
      RegCloseKey (app_key);
    }
#endif
  
  return G_APP_INFO (info);
}

static wchar_t *
dup_wstring (wchar_t *str)
{
  gsize len;
  for (len = 0; str[len] != 0; len++)
    ;
  return (wchar_t *)g_memdup (str, (len + 1) * 2);
}

static GAppInfo *
g_win32_app_info_dup (GAppInfo *appinfo)
{
  GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo);
  GWin32AppInfo *new_info;
  
  new_info = g_object_new (G_TYPE_WIN32_APP_INFO, NULL);

  new_info->id = dup_wstring (info->id);
  new_info->id_utf8 = g_strdup (info->id_utf8);
  new_info->id_is_exename = info->id_is_exename;
  new_info->name = g_strdup (info->name);
  new_info->executable = g_strdup (info->executable);
  new_info->no_open_with = info->no_open_with;
  
  return G_APP_INFO (new_info);
}

static gboolean
g_win32_app_info_equal (GAppInfo *appinfo1,
                        GAppInfo *appinfo2)
{
  GWin32AppInfo *info1 = G_WIN32_APP_INFO (appinfo1);
  GWin32AppInfo *info2 = G_WIN32_APP_INFO (appinfo2);

  if (info1->executable == NULL ||
      info2->executable == NULL)
    return FALSE;
  
  return strcmp (info1->executable, info2->executable) == 0;
}

static const char *
g_win32_app_info_get_id (GAppInfo *appinfo)
{
  GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo);

  return info->id_utf8;
}

static const char *
g_win32_app_info_get_name (GAppInfo *appinfo)
{
  GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo);

  if (info->name == NULL)
    return _("Unnamed");
  
  return info->name;
}

static const char *
g_win32_app_info_get_description (GAppInfo *appinfo)
{
  /* Win32 has no app descriptions */
  return NULL;
}

static const char *
g_win32_app_info_get_executable (GAppInfo *appinfo)
{
  GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo);
  
  return info->executable;
}

static GIcon *
g_win32_app_info_get_icon (GAppInfo *appinfo)
{
  /* GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); */

  /* TODO: How to handle icons */
  return NULL;
}

static gboolean
g_win32_app_info_launch (GAppInfo           *appinfo,
			 GList              *files,
			 GAppLaunchContext  *launch_context,
			 GError            **error)
{
  GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo);
#ifdef AssocQueryString
  ASSOCF flags;
#endif
  HKEY class_key;
  SHELLEXECUTEINFOW exec_info = {0};
  GList *l;

  /* TODO:  What might startup_id mean on win32? */
#ifdef AssocQueryString  
  flags = 0;
  if (info->id_is_exename)
    flags |= ASSOCF_INIT_BYEXENAME;

  if (AssocQueryKeyW (flags,
		      ASSOCKEY_SHELLEXECCLASS,
		      info->id,
		      NULL,
		      &class_key) != S_OK)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't find application"));
      return FALSE;
    }
#endif

  for (l = files; l != NULL; l = l->next)
    {
      char *path = g_file_get_path (l->data);
      wchar_t *wfilename = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);

      g_free (path);
      
      memset (&exec_info, 0, sizeof (exec_info));
      exec_info.cbSize = sizeof (exec_info);
      exec_info.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_CLASSKEY;
      exec_info.lpFile = wfilename;     
      exec_info.nShow = SW_SHOWNORMAL;
      exec_info.hkeyClass = class_key;
      
      if (!ShellExecuteExW (&exec_info))
	{
	  char *message_utf8 = g_win32_error_message (GetLastError ());

	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Error launching application: %s"), message_utf8);
	  g_free (message_utf8);
	  
	  g_free (wfilename);
	  RegCloseKey (class_key);
	  return FALSE;
	}
      
      g_free (wfilename);
    }
  
  RegCloseKey (class_key);
  
  return TRUE;
}

static gboolean
g_win32_app_info_supports_uris (GAppInfo *appinfo)
{
  return FALSE;
}

static gboolean
g_win32_app_info_supports_files (GAppInfo *appinfo)
{
  return TRUE;
}

static gboolean
g_win32_app_info_launch_uris (GAppInfo           *appinfo,
			      GList              *uris,
			      GAppLaunchContext  *launch_context,
			      GError            **error)
{
  g_set_error_literal (error, G_IO_ERROR, 
                       G_IO_ERROR_NOT_SUPPORTED, 
                       _("URIs not supported"));
  return FALSE;
}

static gboolean
g_win32_app_info_should_show (GAppInfo *appinfo)
{
  GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo);

  if (info->no_open_with)
    return FALSE;
  
  return TRUE;
}

static gboolean
g_win32_app_info_set_as_default_for_type (GAppInfo    *appinfo,
                                          const char  *content_type,
                                          GError     **error)
{
  g_set_error_literal (error, G_IO_ERROR, 
                       G_IO_ERROR_NOT_SUPPORTED, 
                       _("association changes not supported on win32"));
  return FALSE;
}

GAppInfo *
g_app_info_create_from_commandline (const char           *commandline,
				    const char           *application_name,
				    GAppInfoCreateFlags   flags,
				    GError              **error)
{
  g_set_error_literal (error, G_IO_ERROR, 
                       G_IO_ERROR_NOT_SUPPORTED, 
                       _("Association creation not supported on win32"));
  return NULL;
}


static void
g_win32_app_info_iface_init (GAppInfoIface *iface)
{
  iface->dup = g_win32_app_info_dup;
  iface->equal = g_win32_app_info_equal;
  iface->get_id = g_win32_app_info_get_id;
  iface->get_name = g_win32_app_info_get_name;
  iface->get_description = g_win32_app_info_get_description;
  iface->get_executable = g_win32_app_info_get_executable;
  iface->get_icon = g_win32_app_info_get_icon;
  iface->launch = g_win32_app_info_launch;
  iface->supports_uris = g_win32_app_info_supports_uris;
  iface->supports_files = g_win32_app_info_supports_files;
  iface->launch_uris = g_win32_app_info_launch_uris;
  iface->should_show = g_win32_app_info_should_show;
  iface->set_as_default_for_type = g_win32_app_info_set_as_default_for_type;
}

static void
enumerate_open_with_list (HKEY    dir_key,
			  GList **prognames)
{
  DWORD index;
  wchar_t name[256];
  DWORD name_len, nbytes;
  wchar_t data[256];
  wchar_t *data_alloc;
  DWORD type;

  /* Must also look inside for a,b,c, + MRUList */
  index = 0;
  name_len = 256;
  nbytes = sizeof (data) - 2;
  while (RegEnumValueW (dir_key,
		        index,
		        name,
		        &name_len,
		        0,
		        &type,
		        (LPBYTE)data,
		        &nbytes) == ERROR_SUCCESS)
    {
      data[nbytes/2] = '\0';
      if (type == REG_SZ &&
	  /* Ignore things like MRUList, just look at 'a', 'b', 'c', etc */
	  name_len == 1)
	{
	  data_alloc = (wchar_t *)g_memdup (data, nbytes + 2);
	  data_alloc[nbytes/2] = 0;
	  *prognames = g_list_prepend (*prognames, data_alloc);
	}
      index++;
      name_len = 256;
      nbytes = sizeof (data) - 2;
    }
  
  index = 0;
  name_len = 256;
  while (RegEnumKeyExW (dir_key,
		        index,
		        name,
		        &name_len,
		        NULL,
		        NULL,
		        NULL,
		        NULL) == ERROR_SUCCESS)
    {
      *prognames = g_list_prepend (*prognames, g_memdup (name, (name_len + 1) * 2));
      index++;
      name_len = 256;
    }
}

static void
enumerate_open_with_progids (HKEY dir_key,
			     GList **progids)
{
  DWORD index;
  wchar_t name[256];
  DWORD name_len, type;

  index = 0;
  name_len = 256;
  while (RegEnumValueW (dir_key,
		        index,
		        name,
		        &name_len,
		        0,
		        &type,
		        NULL,
		        0) == ERROR_SUCCESS)
    {
      *progids = g_list_prepend (*progids, g_memdup (name, (name_len + 1) * 2));
      index++;
      name_len = 256;
    }
}

static void
enumerate_open_with_root (HKEY    dir_key,
			  GList **progids,
			  GList **prognames)
{
  HKEY reg_key = NULL;
  
  if (RegOpenKeyExW (dir_key, L"OpenWithList", 0,
		     KEY_READ, &reg_key) == ERROR_SUCCESS)
    {
      enumerate_open_with_list (reg_key, prognames);
      RegCloseKey (reg_key);
    }
  
  if (RegOpenKeyExW (dir_key, L"OpenWithProgids", 0,
		     KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS)
    {
      enumerate_open_with_progids (reg_key, progids);
      RegCloseKey (reg_key);
    }
}

static gboolean
app_info_in_list (GAppInfo *info, 
                  GList    *list)
{
  while (list != NULL)
    {
      if (g_app_info_equal (info, list->data))
	return TRUE;
      list = list->next;
    }
  return FALSE;
}

GList *
g_app_info_get_all_for_type (const char *content_type)
{
  GList *progids = NULL;
  GList *prognames = NULL;
  HKEY reg_key, sys_file_assoc_key, reg_key2;
  wchar_t percieved_type[128];
  DWORD nchars, key_type;
  wchar_t *wc_key;
  GList *l;
  GList *infos;

  wc_key = g_utf8_to_utf16 (content_type, -1, NULL, NULL, NULL);
  if (RegOpenKeyExW (HKEY_CLASSES_ROOT, wc_key, 0,
		     KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS)
    {
      enumerate_open_with_root (reg_key, &progids, &prognames);

      nchars = sizeof (percieved_type) / sizeof(wchar_t);
      if (RegQueryValueExW (reg_key, L"PerceivedType", 0,
			    &key_type, (LPBYTE) percieved_type, &nchars) == ERROR_SUCCESS)
	{
	  if (key_type == REG_SZ &&
	      RegOpenKeyExW (HKEY_CLASSES_ROOT, L"SystemFileAssociations", 0,
			     KEY_QUERY_VALUE, &sys_file_assoc_key) == ERROR_SUCCESS)
	    {
	      if (RegOpenKeyExW (sys_file_assoc_key, percieved_type, 0,
				 KEY_QUERY_VALUE, &reg_key2) == ERROR_SUCCESS)
		{
		  enumerate_open_with_root (reg_key2, &progids, &prognames);
		  RegCloseKey (reg_key2);
		}

	      RegCloseKey (sys_file_assoc_key);
	    }
	}
      RegCloseKey (reg_key);
    }

  if (RegOpenKeyExW (HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts", 0,
		     KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS)
    {
      if (RegOpenKeyExW (reg_key, wc_key, 0,
			 KEY_QUERY_VALUE, &reg_key2) == ERROR_SUCCESS)
	{
	  enumerate_open_with_root (reg_key2, &progids, &prognames);
	  RegCloseKey (reg_key2);
	}
      
      RegCloseKey (reg_key);
    }

  infos = NULL;
  for (l = prognames; l != NULL; l = l->next)
    {
      GAppInfo *info;

      /* l->data ownership is taken */
      info = g_desktop_app_info_new_from_id ((wchar_t *)l->data, TRUE);
      if (app_info_in_list (info, infos))
	g_object_unref (info);
      else
	infos = g_list_prepend (infos, info);
    }
  g_list_free (prognames);

  for (l = progids; l != NULL; l = l->next)
    {
      GAppInfo *info;

      /* l->data ownership is taken */
      info = g_desktop_app_info_new_from_id ((wchar_t *)l->data, FALSE);
      if (app_info_in_list (info, infos))
	g_object_unref (info);
      else
	infos = g_list_prepend (infos, info);
    }
  g_list_free (progids);
  
  g_free (wc_key);
  return g_list_reverse (infos);
}

GAppInfo *
g_app_info_get_default_for_type (const char *content_type,
				 gboolean    must_support_uris)
{
  wchar_t *wtype;
  wchar_t buffer[1024];
  DWORD buffer_size;

  wtype = g_utf8_to_utf16 (content_type, -1, NULL, NULL, NULL);

  /* Verify that we have some sort of app registered for this type */
#ifdef AssocQueryString
  buffer_size = 1024;
  if (AssocQueryStringW (0,
		  	 REAL_ASSOCSTR_COMMAND,
			 wtype,
			 NULL,
			 buffer,
			 &buffer_size) == S_OK)
    /* Takes ownership of wtype */
    return g_desktop_app_info_new_from_id (wtype, FALSE);
#endif

  g_free (wtype);
  return NULL;
}

GAppInfo *
g_app_info_get_default_for_uri_scheme (const char *uri_scheme)
{
  /* TODO: Implement */
  return NULL;
}

GList *
g_app_info_get_all (void)
{
  DWORD index;
  wchar_t name[256];
  DWORD name_len;
  HKEY reg_key;
  GList *infos;
  GAppInfo *info;

  if (RegOpenKeyExW (HKEY_CLASSES_ROOT, L"Applications", 0,
		     KEY_READ, &reg_key) != ERROR_SUCCESS)
    return NULL;

  infos = NULL;
  index = 0;
  name_len = 256;
  while (RegEnumKeyExW (reg_key,
		        index,
		        name,
		        &name_len,
		        NULL,
		        NULL,
		        NULL,
		        NULL) == ERROR_SUCCESS)
    {
      wchar_t *name_dup = g_memdup (name, (name_len+1)*2);
      /* name_dup ownership is taken */
      info = g_desktop_app_info_new_from_id (name_dup, TRUE);
      infos = g_list_prepend (infos, info);
      
      index++;
      name_len = 256;
    }
  
  RegCloseKey (reg_key);

  return g_list_reverse (infos);
}

void
g_app_info_reset_type_associations (const char *content_type)
{
  /* nothing to do */
}
