/*
 * WineCfg libraries tabsheet
 *
 * Copyright 2004 Robert van Herk
 *
 * 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 "winecfg.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(winecfg);

typedef enum _DLGMODE
{
	DLL,
	APP,
	GLOBAL,
} DLGMODE;

typedef enum _DLLMODE {
	BUILTIN_NATIVE,
	NATIVE_BUILTIN,
	BUILTIN,
	NATIVE,
	DISABLE,
	UNKNOWN /*Special value indicating an erronous DLL override mode*/
} DLLMODE;

static void removeSpaces(char* in, char* out)
{
  int i,j;
  j = 0;
  for (i = 0; i < strlen(in); i++)
  {
    if (in[i] != ' ')
    {
      out[j] = in[i];
      j++;
    }
  }
  out[j] = 0;
}

static DLLMODE Str2DLLMode(char* c)
{
  /*Parse a string into a DLLMode*/ 
  char* d = HeapAlloc(GetProcessHeap(), 0, sizeof(c));
  removeSpaces(c,d);
  if (strcmp (d, "builtin,native") == 0) {
    return BUILTIN_NATIVE;
  } else
  if (strcmp (d, "native,builtin") == 0) {
    return NATIVE_BUILTIN;
  } else
  if (strcmp (d, "native") == 0){
    return NATIVE;
  } else
  if (strcmp (d, "builtin") == 0) {
    return BUILTIN;
  } else
  if (strcmp (d, "") == 0) {
    return DISABLE;
  } else
    return UNKNOWN;
}

static char* DLLMode2Str(DLLMODE mode)
{
  char* res;
  switch (mode) {
    case NATIVE:
      res = "native";
      break;
    case BUILTIN:
      res = "builtin";
      break;
    case NATIVE_BUILTIN:
      res = "native, builtin";
      break;
    case BUILTIN_NATIVE:
      res = "builtin, native";
      break;
    case DISABLE:
      res = "";
      break;
    default:
      res = "unknown";
  }
  return strdup(res);
}

typedef struct _DLLOVERRIDE
{
	char* lpcKey;    /*The actual dll name*/
	DLLMODE mode;
} DLLOVERRIDE, *LPDLLOVERRIDE;

static LPDLLOVERRIDE CreateDLLOverride(char* lpcKey)
{
	LPDLLOVERRIDE out = HeapAlloc(GetProcessHeap(),0,sizeof(DLLOVERRIDE));
	out->lpcKey = strdup (lpcKey);
	return out;
}

static VOID FreeDLLOverride(LPDLLOVERRIDE ldo)
{
	if (ldo->lpcKey)
		free(ldo->lpcKey);
	HeapFree(GetProcessHeap(),0,ldo);
}

typedef struct _APPL
{
	BOOL isGlobal;
	char* lpcApplication;
	char* lpcSection; /*Registry section*/
} APPL, *LPAPPL;

static LPAPPL CreateAppl(BOOL isGlobal, char* application, char* section)
{
	LPAPPL out;
	out = HeapAlloc(GetProcessHeap(),0,sizeof(APPL));
	out->lpcApplication = strdup(application);
	out->lpcSection = strdup(section);
	out->isGlobal = isGlobal;
	return out;
}

static VOID FreeAppl(LPAPPL lpAppl)
{
	if (lpAppl->lpcApplication)
		free(lpAppl->lpcApplication); /* The strings were strdup-ped, so we use "free" */
	if (lpAppl->lpcSection)
		free(lpAppl->lpcSection);
	HeapFree(GetProcessHeap(),0,lpAppl);
}

typedef struct _ITEMTAG
{
	LPAPPL lpAppl;
	LPDLLOVERRIDE lpDo;
} ITEMTAG, *LPITEMTAG;

static LPITEMTAG CreateItemTag()
{
	LPITEMTAG out;
	out = HeapAlloc(GetProcessHeap(),0,sizeof(ITEMTAG));
	out->lpAppl = 0;
	out->lpDo = 0;
	return out;
}

static VOID FreeItemTag(LPITEMTAG lpit)
{
	if (lpit->lpAppl)
		FreeAppl(lpit->lpAppl);
	if (lpit->lpDo)
		FreeDLLOverride(lpit->lpDo);
	HeapFree(GetProcessHeap(),0,lpit);
}

static VOID UpdateDLLList(HWND hDlg, char* dll)
{
	/*Add if it isn't already in*/
	if (SendDlgItemMessage(hDlg, IDC_DLLLIST, CB_FINDSTRING, 1, (LPARAM) dll) == CB_ERR)
		SendDlgItemMessage(hDlg,IDC_DLLLIST,CB_ADDSTRING,0,(LPARAM) dll);
}

static VOID LoadLibrarySettings(LPAPPL appl /*DON'T FREE, treeview will own this*/, HWND hDlg, HWND hwndTV)
{
	HKEY key;
	int i;
	DWORD size;
	DWORD readSize;
	char name [255];
	char read [255];
	LPITEMTAG lpIt;
	TVINSERTSTRUCT tis;	
	HTREEITEM hParent;
	LPDLLOVERRIDE lpdo;
	
	WINE_TRACE("opening %s\n", appl->lpcSection);
	if (RegOpenKey (configKey, appl->lpcSection, &key) == ERROR_SUCCESS)
	{
		i = 0;
		size = 255;
		readSize = 255;
		
		lpIt = CreateItemTag();
		lpIt->lpAppl = appl;

		tis.hParent = NULL;
		tis.hInsertAfter = TVI_LAST;
		tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
		tis.u.item.pszText = appl->lpcApplication;
		tis.u.item.lParam = (LPARAM)lpIt;
		hParent = TreeView_InsertItem(hwndTV,&tis);
		tis.hParent = hParent;

		while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
		{                           
			WINE_TRACE("Reading value %s, namely %s\n", name, read);
			
			lpIt = CreateItemTag();
			lpdo = CreateDLLOverride(name);
			lpIt->lpDo = lpdo;
			tis.u.item.lParam = (LPARAM)lpIt;
			tis.u.item.pszText = name;
			
			lpdo->mode = Str2DLLMode(read);
			
			TreeView_InsertItem(hwndTV,&tis);
			UpdateDLLList(hDlg, name);
			i ++; size = 255; readSize = 255;
		}
		RegCloseKey(key);
	}
}

static VOID SetEnabledDLLControls(HWND dialog, DLGMODE dlgmode)
{
	if (dlgmode == DLL) {
		enable(IDC_RAD_BUILTIN);
		enable(IDC_RAD_NATIVE);
		enable(IDC_RAD_BUILTIN_NATIVE);
		enable(IDC_RAD_NATIVE_BUILTIN);
		enable(IDC_RAD_DISABLE);
		enable(IDC_DLLS_REMOVEDLL);
	} else {
		disable(IDC_RAD_BUILTIN);
		disable(IDC_RAD_NATIVE);
		disable(IDC_RAD_BUILTIN_NATIVE);
		disable(IDC_RAD_NATIVE_BUILTIN);
		disable(IDC_RAD_DISABLE);
		disable(IDC_DLLS_REMOVEDLL);
	}

	if (dlgmode == APP) {
		enable(IDC_DLLS_REMOVEAPP);
	}
	else {
		disable(IDC_DLLS_REMOVEAPP);
	}
}

static VOID OnInitLibrariesDlg(HWND hDlg)
{
	HWND hwndTV;
	LPAPPL lpAppl;
	HKEY applKey;
	int i;
	DWORD size;
	char appl [255];
	char lpcKey [255];
	FILETIME ft;

	hwndTV = GetDlgItem(hDlg,IDC_TREE_DLLS);
	lpAppl = CreateAppl(TRUE,"Global DLL Overrides", "DllOverrides");
	LoadLibrarySettings(lpAppl, hDlg, hwndTV);
	
	/*And now the application specific stuff:*/
	if (RegOpenKey(configKey, "AppDefaults", &applKey) == ERROR_SUCCESS) {
		i = 0;
		size = 255;
		while (RegEnumKeyEx(applKey, i, appl, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
		{
			sprintf(lpcKey, "AppDefaults\\%s\\DllOverrides", appl);
			lpAppl = CreateAppl(FALSE,appl, lpcKey);
			LoadLibrarySettings(lpAppl, hDlg, hwndTV);
			i++; size = 255;
		}
		RegCloseKey(applKey);
	}

	SetEnabledDLLControls(hDlg, GLOBAL);
}

static VOID OnTreeViewChangeItem(HWND hDlg, HWND hTV)
{
	TVITEM ti;
	LPITEMTAG lpit;
	int buttonId;

	ti.mask = TVIF_PARAM;
	ti.hItem = TreeView_GetSelection(hTV);
	if (TreeView_GetItem (hTV, &ti))
	{
		lpit = (LPITEMTAG) ti.lParam;
		if (lpit->lpDo)
		{
			WINE_TRACE("%s\n", lpit->lpDo->lpcKey);
			buttonId = IDC_RAD_BUILTIN;
			switch (lpit->lpDo->mode)
			{
				case NATIVE:
					buttonId = IDC_RAD_NATIVE;
					break;
				case BUILTIN:
					buttonId = IDC_RAD_BUILTIN;
					break;
				case NATIVE_BUILTIN:
					buttonId = IDC_RAD_NATIVE_BUILTIN;
					break;
				case BUILTIN_NATIVE:
					buttonId = IDC_RAD_BUILTIN_NATIVE;
					break;
				case DISABLE:
					buttonId = IDC_RAD_DISABLE;
					break;
				case UNKNOWN:
					buttonId = -1;
					break;
			}
			CheckRadioButton(hDlg, IDC_RAD_BUILTIN, IDC_RAD_DISABLE, buttonId);
			SetEnabledDLLControls(hDlg, DLL);
		} else {
			if (lpit->lpAppl)
			{
				if (lpit->lpAppl->isGlobal == TRUE)
					SetEnabledDLLControls(hDlg, GLOBAL);
				else
					SetEnabledDLLControls(hDlg, APP);
			}
		}
	}
}

static VOID SetDLLMode(HWND hDlg, DLLMODE mode)
{
	HWND hTV;
	TVITEM ti;
	LPITEMTAG lpit;
	char* cMode;
	TVITEM tiPar;
	LPITEMTAG lpitPar;

	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
	ti.mask = TVIF_PARAM;
	ti.hItem = TreeView_GetSelection(hTV);
	if (TreeView_GetItem (hTV, &ti))
	{
		lpit = (LPITEMTAG) ti.lParam;
		if (lpit->lpDo)
		{
			lpit->lpDo->mode = mode;
			cMode = DLLMode2Str (mode);
			/*Find parent, so we can read registry section*/
			tiPar.mask = TVIF_PARAM;
			tiPar.hItem = TreeView_GetParent(hTV, ti.hItem);
			if (TreeView_GetItem(hTV,&tiPar))
			{
				lpitPar = (LPITEMTAG) tiPar.lParam;
				if (lpitPar->lpAppl)
				{
					addTransaction(lpitPar->lpAppl->lpcSection, lpit->lpDo->lpcKey, ACTION_SET, cMode);
				}
			}
			free(cMode);
		}
	}
}

static VOID OnBuiltinClick(HWND hDlg)
{
	SetDLLMode(hDlg, BUILTIN);
}

static VOID OnNativeClick(HWND hDlg)
{
	SetDLLMode(hDlg, NATIVE);
}

static VOID OnBuiltinNativeClick(HWND hDlg)
{
	SetDLLMode(hDlg, BUILTIN_NATIVE);
}

static VOID OnNativeBuiltinClick(HWND hDlg)
{
	SetDLLMode(hDlg, NATIVE_BUILTIN);
}

static VOID OnDisableClick(HWND hDlg)
{
	SetDLLMode(hDlg, DISABLE);
}

static VOID OnTreeViewDeleteItem(NMTREEVIEW* nmt)
{
	FreeItemTag((LPITEMTAG)(nmt->itemOld.lParam));
}

static VOID OnAddDLLClick(HWND hDlg)
{
	HWND hTV;
	TVITEM ti;
	LPITEMTAG lpit;
	LPITEMTAG lpitNew;
	TVITEM childti;
	char dll [255];
	BOOL doAdd;
	TVINSERTSTRUCT tis;

	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
	ti.mask = TVIF_PARAM;
	ti.hItem = TreeView_GetSelection(hTV);
	if (TreeView_GetItem (hTV, &ti))
	{
		lpit = (LPITEMTAG) ti.lParam;
		if (lpit->lpDo) { /*Is this a DLL override (that is: a subitem), then find the parent*/
			ti.hItem = TreeView_GetParent(hTV, ti.hItem);
			if (TreeView_GetItem(hTV,&ti)) {
				lpit = (LPITEMTAG) ti.lParam;
			} else return;
		}
	} else return;
	/*Now we should have an parent item*/
	if (lpit->lpAppl)
	{
		lpitNew = CreateItemTag();
		SendDlgItemMessage(hDlg,IDC_DLLLIST,WM_GETTEXT,(WPARAM)255, (LPARAM) dll);
		if (strlen(dll) > 0) {
			/*Is the dll already in the list? If so, don't do it*/
			doAdd = TRUE;
			childti.mask = TVIF_PARAM;
			if ((childti.hItem = TreeView_GetNextItem(hTV, ti.hItem, TVGN_CHILD))) {
				/*Retrieved first child*/
				while (TreeView_GetItem (hTV, &childti))
				{
					if (strcmp(((LPITEMTAG)childti.lParam)->lpDo->lpcKey,dll) == 0) {
						doAdd = FALSE;
						break;
					}
					childti.hItem = TreeView_GetNextItem(hTV, childti.hItem, TVGN_NEXT);
				}
			}
			if (doAdd)
			{
				lpitNew->lpDo = CreateDLLOverride(dll);
				lpitNew->lpDo->mode = NATIVE;
				tis.hInsertAfter = TVI_LAST;
				tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
				tis.u.item.pszText = dll;
				tis.u.item.lParam = (LPARAM)lpitNew;
				tis.hParent = ti.hItem;
				TreeView_InsertItem(hTV,&tis);
				UpdateDLLList(hDlg, dll);
				addTransaction(lpit->lpAppl->lpcSection, dll, ACTION_SET, "native");
			} else MessageBox(hDlg, "A DLL with that name is already in this list...", "", MB_OK | MB_ICONINFORMATION);
		}
	} else return;
}

static VOID OnRemoveDLLClick(HWND hDlg)
{
	HWND hTV;
	TVITEM ti;
	LPITEMTAG lpit;
	TVITEM tiPar;
	LPITEMTAG lpitPar;

	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
	ti.mask = TVIF_PARAM;
	ti.hItem = TreeView_GetSelection(hTV);
	if (TreeView_GetItem (hTV, &ti)) {
		lpit = (LPITEMTAG) ti.lParam;
		if (lpit->lpDo)
		{
			/*Find parent for section*/
			tiPar.mask = TVIF_PARAM;
			tiPar.hItem = TreeView_GetParent(hTV, ti.hItem);
			if (TreeView_GetItem(hTV,&tiPar))
			{
				lpitPar = (LPITEMTAG) tiPar.lParam;
				if (lpitPar->lpAppl)
				{
					addTransaction(lpitPar->lpAppl->lpcSection, lpit->lpDo->lpcKey, ACTION_REMOVE, NULL);
					TreeView_DeleteItem(hTV,ti.hItem);
				}
			}
		}
	}
}

static VOID OnAddApplicationClick(HWND hDlg)
{
	char szFileTitle [255];
	char szFile [255];
	char lpcKey [255];

	TVINSERTSTRUCT tis;
	LPITEMTAG lpit;
	OPENFILENAME ofn = { sizeof(OPENFILENAME),
		0, /*hInst*/0, "Wine Programs (*.exe,*.exe.so)\0*.exe;*.exe.so\0", NULL, 0, 0, NULL,
		0, NULL, 0, NULL, NULL,
		OFN_SHOWHELP, 0, 0, NULL, 0, NULL };

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

	if (GetOpenFileName(&ofn))
	{
		tis.hParent = NULL;
		tis.hInsertAfter = TVI_LAST;
		tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
		tis.u.item.pszText = szFileTitle;
		lpit = CreateItemTag();
		sprintf(lpcKey, "AppDefaults\\%s\\DllOverrides", szFileTitle);
		lpit->lpAppl = CreateAppl(FALSE,szFileTitle,lpcKey);
		tis.u.item.lParam = (LPARAM)lpit;
		TreeView_InsertItem(GetDlgItem(hDlg,IDC_TREE_DLLS), &tis);
		setConfigValue(lpcKey,NULL,NULL);
	}
}

static VOID OnRemoveApplicationClick(HWND hDlg)
{
	HWND hTV;
	TVITEM ti;
	LPITEMTAG lpit;

	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
	ti.mask = TVIF_PARAM;
	ti.hItem = TreeView_GetSelection(hTV);
	if (TreeView_GetItem (hTV, &ti)) {
		lpit = (LPITEMTAG) ti.lParam;
		if (lpit->lpAppl)
		{
			addTransaction(lpit->lpAppl->lpcSection, NULL, ACTION_REMOVE, NULL);
			TreeView_DeleteItem(hTV,ti.hItem);
		}
	}
}

INT_PTR CALLBACK
LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_INITDIALOG:
		OnInitLibrariesDlg(hDlg);
		break;  
	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->code) {
		case TVN_SELCHANGED: {
				switch(LOWORD(wParam)) {
				case IDC_TREE_DLLS:
					OnTreeViewChangeItem(hDlg, GetDlgItem(hDlg,IDC_TREE_DLLS));
					break;
				}
			}
			break;
		case TVN_DELETEITEM:
			OnTreeViewDeleteItem ((LPNMTREEVIEW)lParam);
			break;
		}
		break;
	case WM_COMMAND:
		switch(HIWORD(wParam)) {
		case BN_CLICKED:
			switch(LOWORD(wParam)) {
			case IDC_RAD_BUILTIN:
				OnBuiltinClick(hDlg);
				break;
			case IDC_RAD_NATIVE:
				OnNativeClick(hDlg);
				break;
			case IDC_RAD_BUILTIN_NATIVE:
				OnBuiltinNativeClick(hDlg);
				break;
			case IDC_RAD_NATIVE_BUILTIN:
				OnNativeBuiltinClick(hDlg);
				break;
			case IDC_RAD_DISABLE:
				OnDisableClick(hDlg);
				break;
			case IDC_DLLS_ADDAPP:
				OnAddApplicationClick(hDlg);
				break;
			case IDC_DLLS_REMOVEAPP:
				OnRemoveApplicationClick(hDlg);
				break;
			case IDC_DLLS_ADDDLL:
				OnAddDLLClick(hDlg);
				break;
			case IDC_DLLS_REMOVEDLL:
				OnRemoveDLLClick(hDlg);
				break;
			}
			break;
		}
		break;
	}

	return 0;
}
