/*
 * WineCfg app settings tabsheet
 *
 * Copyright 2004 Robert van Herk
 * Copyright 2004 Chris Morgan
 * Copyright 2004 Mike Hearn
 *
 * 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.1 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
 *
 */

#define NONAMELESSUNION
#include <windows.h>
#include <commdlg.h>
#include <wine/debug.h>
#include <stdio.h>
#include <assert.h>
#include "winecfg.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(winecfg);

static void update_comboboxes(HWND dialog)
{
  int i;
  const VERSION_DESC *pVer = NULL;

  char *winver, *dosver;
  
  /* retrieve the registry values */
  winver = get(keypath("Version"), "Windows", "");
  dosver = get(keypath("Version"), "DOS", "");

  /* empty winver/dosver means use automatic mode (ie the builtin dll linkage heuristics)  */
  
  WINE_TRACE("winver is %s\n", *winver != '\0' ? winver : "null (automatic mode)");
  WINE_TRACE("dosver is %s\n", *dosver != '\0' ? dosver : "null (automatic mode)");

  /* normalize the version strings */
  if (*winver != '\0')
  {
    if ((pVer = getWinVersions ()))
    {
      for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
      {
	if (!strcasecmp (pVer->szVersion, winver))
	{
	  SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, (WPARAM) (i + 1), 0);
	  WINE_TRACE("match with %s\n", pVer->szVersion);
	}
      }
    }
  }
  else /* no explicit setting */
  {
    WINE_TRACE("setting winver combobox to automatic/default\n");
    SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, 0, 0);
  }

  if (*dosver != '\0')
  {
    if ((pVer = getDOSVersions ()))
    {
      for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
      {
	if (!strcasecmp (pVer->szVersion, dosver))
	{
	  SendDlgItemMessage (dialog, IDC_DOSVER, CB_SETCURSEL,
			      (WPARAM) (i + 1), 0);
	  WINE_TRACE("match with %s\n", pVer->szVersion);
	}
      }
    }
  }
  else
  {
    WINE_TRACE("setting dosver combobox to automatic/default\n");
    SendDlgItemMessage (dialog, IDC_DOSVER, CB_SETCURSEL, 0, 0);
  }
  
  HeapFree(GetProcessHeap(), 0, winver);
  HeapFree(GetProcessHeap(), 0, dosver);
}

void
init_comboboxes (HWND dialog)
{
  int i;
  const VERSION_DESC *ver = NULL;

  
  SendDlgItemMessage(dialog, IDC_WINVER, CB_RESETCONTENT, 0, 0);
  SendDlgItemMessage(dialog, IDC_DOSVER, CB_RESETCONTENT, 0, 0);  
  
  /* add the default entries (automatic) which correspond to no setting  */
  if (currentApp)
  {
      SendDlgItemMessage(dialog, IDC_WINVER, CB_ADDSTRING, 0, (LPARAM) "Use global settings");
      SendDlgItemMessage(dialog, IDC_DOSVER, CB_ADDSTRING, 0, (LPARAM) "Use global settings");      
  }
  else
  {
      SendDlgItemMessage(dialog, IDC_WINVER, CB_ADDSTRING, 0, (LPARAM) "Automatically detect required version");
      SendDlgItemMessage(dialog, IDC_DOSVER, CB_ADDSTRING, 0, (LPARAM) "Automatically detect required version");
  }

  if ((ver = getWinVersions ()))
  {
    for (i = 0; *ver->szVersion || *ver->szDescription; i++, ver++)
    {
      SendDlgItemMessage (dialog, IDC_WINVER, CB_ADDSTRING,
			  0, (LPARAM) ver->szDescription);
    }
  }
  if ((ver = getDOSVersions ()))
  {
    for (i = 0; *ver->szVersion || *ver->szDescription ; i++, ver++)
    {
      SendDlgItemMessage (dialog, IDC_DOSVER, CB_ADDSTRING,
			  0, (LPARAM) ver->szDescription);
    }
  }
}

static void add_listview_item(HWND listview, char *text, void *association)
{
  LVITEM item;

  ZeroMemory(&item, sizeof(LVITEM));

  item.mask = LVIF_TEXT | LVIF_PARAM;
  item.pszText = text;
  item.cchTextMax = strlen(text);
  item.lParam = (LPARAM) association;
  item.iItem = ListView_GetItemCount(listview);

  ListView_InsertItem(listview, &item);
}

/* Called when the application is initialized (cannot reinit!)  */
static void init_appsheet(HWND dialog)
{
  HWND listview;
  HKEY key;
  int i;
  DWORD size;
  char appname[1024];

  WINE_TRACE("()\n");

  listview = GetDlgItem(dialog, IDC_APP_LISTVIEW);

  /* we use the lparam field of the item so we can alter the presentation later and not change code
   * for instance, to use the tile view or to display the EXEs embedded 'display name' */
  add_listview_item(listview, "Default Settings", NULL);

  /* because this list is only populated once, it's safe to bypass the settings list here  */
  if (RegOpenKey(config_key, "AppDefaults", &key) == ERROR_SUCCESS)
  {
      i = 0;
      size = sizeof(appname);
      while (RegEnumKeyEx(key, i, appname, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
      {
          add_listview_item(listview, appname, strdup(appname));

          i++;
          size = sizeof(appname);
      }

      RegCloseKey(key);
  }

  init_comboboxes(dialog);
  
  /* Select the default settings listview item  */
  {
      LVITEM item;
      
      ZeroMemory(&item, sizeof(item));
      
      item.mask = LVIF_STATE;
      item.iItem = 0;
      item.state = LVIS_SELECTED | LVIS_FOCUSED;
      item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;

      ListView_SetItem(listview, &item);
  }
  
}

/* there has to be an easier way than this  */
static int get_listview_selection(HWND listview)
{
  int count = ListView_GetItemCount(listview);
  int i;
  
  for (i = 0; i < count; i++)
  {
    if (ListView_GetItemState(listview, i, LVIS_SELECTED)) return i;
  }

  return -1;
}


/* called when the user selects a different application */
static void on_selection_change(HWND dialog, HWND listview)
{
  LVITEM item;
  char *oldapp = currentApp;
    
  WINE_TRACE("()\n");
  
  item.iItem = get_listview_selection(listview);
  item.mask = LVIF_PARAM;
  
  if (item.iItem == -1) return;
  
  ListView_GetItem(listview, &item);

  currentApp = (char *) item.lParam;

  if (currentApp)
  {
      WINE_TRACE("currentApp is now %s\n", currentApp);
      enable(IDC_APP_REMOVEAPP);
  }
  else
  {
      WINE_TRACE("currentApp=NULL, editing global settings\n");
      /* focus will never be on the button in this callback so it's safe  */
      disable(IDC_APP_REMOVEAPP);
  }

  /* reset the combo boxes if we changed from/to global/app-specific  */

  if ((oldapp && !currentApp) || (!oldapp && currentApp))
      init_comboboxes(dialog);
  
  update_comboboxes(dialog);

  set_window_title(dialog);
}

static void on_add_app_click(HWND dialog)
{
  char filetitle[MAX_PATH];
  char file[MAX_PATH];

  OPENFILENAME ofn = { sizeof(OPENFILENAME),
		       0, /*hInst*/0, "Wine Programs (*.exe,*.exe.so)\0*.exe;*.exe.so\0", NULL, 0, 0, NULL,
		       0, NULL, 0, "c:\\", "Select a Windows executable file",
		       OFN_SHOWHELP | OFN_HIDEREADONLY, 0, 0, NULL, 0, NULL };

  ofn.lpstrFileTitle = filetitle;
  ofn.lpstrFileTitle[0] = '\0';
  ofn.nMaxFileTitle = sizeof(filetitle);
  ofn.lpstrFile = file;
  ofn.lpstrFile[0] = '\0';
  ofn.nMaxFile = sizeof(file);

  if (GetOpenFileName(&ofn))
  {
      HWND listview = GetDlgItem(dialog, IDC_APP_LISTVIEW);
      int count = ListView_GetItemCount(listview);
      
      if (currentApp) free(currentApp);
      currentApp = strdup(filetitle);

      WINE_TRACE("adding %s\n", currentApp);
      
      add_listview_item(listview, currentApp, currentApp);

      ListView_SetItemState(listview, count, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);

      SetFocus(listview);
  }
  else WINE_TRACE("user cancelled\n");
}

static void on_remove_app_click(HWND dialog)
{
    HWND listview = GetDlgItem(dialog, IDC_APP_LISTVIEW);
    int selection = get_listview_selection(listview);
    char *section = keypath(""); /* AppDefaults\\whatever.exe\\ */

    WINE_TRACE("selection=%d, section=%s\n", selection, section);
    
    assert( selection != 0 ); /* user cannot click this button when "default settings" is selected  */

    section[strlen(section)] = '\0'; /* remove last backslash  */
    set(section, NULL, NULL); /* delete the section  */
    ListView_DeleteItem(listview, selection);

    SetFocus(listview);
}

static void on_winver_change(HWND dialog)
{
    int selection = SendDlgItemMessage(dialog, IDC_WINVER, CB_GETCURSEL, 0, 0);
    VERSION_DESC *ver = getWinVersions();

    if (selection == 0)
    {
        WINE_TRACE("automatic/default selected so removing current setting\n");
        set(keypath("Version"), "Windows", NULL);
    }
    else
    {
        WINE_TRACE("setting Version\\Windows key to value '%s'\n", ver[selection - 1].szVersion);
        set(keypath("Version"), "Windows", ver[selection - 1].szVersion);
    }

    /* enable the apply button  */
    SendMessage(GetParent(dialog), PSM_CHANGED, (WPARAM) dialog, 0);
}

static void on_dosver_change(HWND dialog)
{
    int selection = SendDlgItemMessage(dialog, IDC_DOSVER, CB_GETCURSEL, 0, 0);
    VERSION_DESC *ver = getDOSVersions();

    if (selection == 0)
    {
        WINE_TRACE("automatic/default selected so removing current setting\n");
        set(keypath("Version"), "DOS", NULL);
    }
    else
    {
        WINE_TRACE("setting Version\\DOS key to value '%s'\n", ver[selection - 1].szVersion);
        set(keypath("Version"), "DOS", ver[selection - 1].szVersion);
    }

    /* enable the apply button  */
    SendMessage(GetParent(dialog), PSM_CHANGED, (WPARAM) dialog, 0);
}

INT_PTR CALLBACK
AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
    case WM_INITDIALOG:
        init_appsheet(hDlg);
        break;

    case WM_SHOWWINDOW:
        set_window_title(hDlg);
        break;

    case WM_NOTIFY:
      switch (((LPNMHDR)lParam)->code)
      {
        case LVN_ITEMCHANGED:
            on_selection_change(hDlg, GetDlgItem(hDlg, IDC_APP_LISTVIEW));
            break;
        case PSN_APPLY:
            apply();
            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
            break;
      }
      
      break;
    
    case WM_COMMAND:
      switch(HIWORD(wParam)) {
        case CBN_SELCHANGE:
          switch(LOWORD(wParam)) {
            case IDC_WINVER:
              on_winver_change(hDlg);
              break;
            case IDC_DOSVER:
              on_dosver_change(hDlg);
              break;
          }
        case BN_CLICKED:
          switch(LOWORD(wParam)) {
            case IDC_APP_ADDAPP:
              on_add_app_click(hDlg);
              break;
            case IDC_APP_REMOVEAPP:
              on_remove_app_click(hDlg);
              break;
          }
          break;
      }

      break;
  }
  
  return 0;
}
