/*
 * Drive management UI code
 *
 * Copyright 2003 Mark Westcott
 * Copyright 2003 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
 *
 */

#include <winreg.h>
#include <wine/debug.h>
#include <stdlib.h>
#include <stdio.h>
#include <shellapi.h>
#include <shlguid.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <string.h>
#include <assert.h>

#include "winecfg.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(winecfg);

/*******************************************************************/
/*  the configuration properties affected by this code             */
/*******************************************************************/
static BOOL initialized = FALSE;

void initDriveDlg (HWND hDlg)
{
    int i;
    for (i = 0; i < config.driveCount; i++) {
	int itemIndex;
	DRIVE_DESC *drive = DPA_GetPtr(config.pDrives, i);
	char *title = malloc(MAX_NAME_LENGTH);
	
	WINE_TRACE("Iterating, item %d of %d, drive=%p\n", i, config.driveCount, drive);
	assert(drive);

	WINE_TRACE("Adding %s to the listbox\n", drive->szName);

	/* the first SendMessage call adds the string and returns the index, the second associates that index with it */
	snprintf(title, MAX_NAME_LENGTH, "Drive %s (%s)", drive->szName, drive->szLabel);
	itemIndex = SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_ADDSTRING ,(WPARAM) -1, (LPARAM) title);
	SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) itemIndex);
	free(title);
    }
    
    initialized = TRUE;
}


void saveDriveDlgSettings (HWND hDlg)
{

}



/******************************************************************************/
/*  The Drive Editing Dialog                                                  */
/******************************************************************************/
#define DRIVE_MASK_BIT(B) 1<<(toupper(B)-'A')

typedef struct{
  char *sCode;
  char *sDesc;
} code_desc_pair;

static code_desc_pair type_pairs[] = {
  {"hd", "Local hard disk"},
  {"network", "Network share" },
  {"floppy", "Floppy disk"},
  {"cdrom", "CD-ROM"}
};
#define DRIVE_TYPE_DEFAULT 1

static code_desc_pair fs_pairs[] = {
  {"win95", "Long file names"},
  {"msdos", "MS-DOS 8 character file names"},
  {"unix", "UNIX file names"}
};
#define DRIVE_FS_DEFAULT 0

long drive_available_mask(DRIVE_DESC *pCurrentDrive)
{
  int i;
  DRIVE_DESC *pDrive;
  long result = 0;
  
  for( i=0; i < config.pDrives->nItemCount; ++i) {
    pDrive = (DRIVE_DESC *) DPA_GetPtr( config.pDrives, i );
    if(pDrive) {
      result |= DRIVE_MASK_BIT(pDrive->szName[0]);
    }
  }
  
  result = ~result; /*flag unused, not used*/
  result |= DRIVE_MASK_BIT(pCurrentDrive->szName[0]);
  WINE_TRACE( "finished drive letter loop with %ld\n", result );

  return result;
}

void fill_drive_droplist(long mask, DRIVE_DESC *pCurrentDrive, HWND hDlg)
{
  int i;
  int selection;
  int count;
  int next_letter;
  char sName[4] = "A:";

  for( i=0, count=0, selection=-1, next_letter=-1; i <= 'Z'-'A'; ++i ) {
    if( mask & DRIVE_MASK_BIT('A'+i) ) {
      sName[0] = 'A' + i;
      SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_ADDSTRING, 0, (LPARAM) sName );
      
      if( toupper(pCurrentDrive->szName[0]) == 'A' + i ) {
	selection = count;
      }
      
      if( i >= 2 && next_letter == -1){ /*default drive is first one of C-Z */
	next_letter = count;
      }
      
      count++;
    }
  }
  
  if( selection == -1 ) {
    selection = next_letter;
  }
  
  SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_SETCURSEL, selection, 0 );
}


void enable_cdrom_box(HWND hDlg, int bEnable)
{
  EnableWindow( GetDlgItem( hDlg, IDC_BOX_CDROM ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_RADIO_AUTODETECT ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_RADIO_ASSIGN ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_EDIT_DEVICE ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_BROWSE_DEVICE ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_EDIT_SERIAL ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_EDIT_LABEL ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SERIAL ), bEnable );
  EnableWindow( GetDlgItem( hDlg, IDC_STATIC_LABEL ), bEnable );
}


INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  int i;
  int selection;

  switch (uMsg)  {
    case WM_INITDIALOG: {
	DRIVE_DESC* pDrive = (DRIVE_DESC *)lParam;
	
	SetProp(hDlg, "PDRIVE", pDrive);

	/* Fill in the list boxes */
	/* Drive letters */
	fill_drive_droplist( drive_available_mask( pDrive ), pDrive, hDlg );

	/* drive type*/
	for( i=0, selection=-1; i < sizeof(type_pairs)/sizeof(code_desc_pair); i++) {
	  SendDlgItemMessage(hDlg, IDC_COMBO_TYPE, CB_ADDSTRING, 0,
			     (LPARAM) type_pairs[i].sDesc);
	  if(strcasecmp(type_pairs[i].sCode, pDrive->szType) == 0){
	    selection = i;
	  }
	}
	
	if( selection == -1 ) {
	  selection = DRIVE_TYPE_DEFAULT;
	}
	SendDlgItemMessage(hDlg, IDC_COMBO_TYPE, CB_SETCURSEL, selection, 0);

	/* FileSystem name handling */
	for( i=0, selection=-1; i < sizeof(fs_pairs)/sizeof(code_desc_pair); i++) {
	  SendDlgItemMessage(hDlg, IDC_COMBO_NAMES, CB_ADDSTRING, 0,
			     (LPARAM) fs_pairs[i].sDesc);
	  if(strcasecmp(fs_pairs[i].sCode, pDrive->szFS) == 0){
	    selection = i;
	  }
	}
	
	if( selection == -1 ) {
	  selection = DRIVE_FS_DEFAULT;
	}
	SendDlgItemMessage(hDlg, IDC_COMBO_NAMES, CB_SETCURSEL, selection, 0);

       
	/* removeable media properties */
	SendDlgItemMessage(hDlg, IDC_EDIT_SERIAL, WM_SETTEXT, 0,(LPARAM)pDrive->szSerial);
	SendDlgItemMessage(hDlg, IDC_EDIT_LABEL, WM_SETTEXT, 0,(LPARAM)pDrive->szLabel);
	SendDlgItemMessage(hDlg, IDC_EDIT_DEVICE, WM_SETTEXT, 0,(LPARAM)pDrive->szDevice);
	if( strcmp("cdrom", pDrive->szType) == 0 ||
	    strcmp("floppy", pDrive->szType) == 0) {
	  if( (strlen( pDrive->szDevice ) == 0) &&
	      ((strlen( pDrive->szSerial ) > 0) || (strlen( pDrive->szLabel ) > 0)) ) {
	    selection = IDC_RADIO_ASSIGN;
	  }
	  else {
	    selection = IDC_RADIO_AUTODETECT;
	  }
	
	  enable_cdrom_box( hDlg, 1 );
	}
	else {
	  enable_cdrom_box( hDlg, 0 );
	}
	
	CheckRadioButton( hDlg, IDC_RADIO_AUTODETECT, IDC_RADIO_ASSIGN, selection );
	SendDlgItemMessage(hDlg, IDC_EDIT_PATH, WM_SETTEXT, 0,(LPARAM)pDrive->szPath);
	break;
      }

    case WM_COMMAND:
      switch (LOWORD(wParam))
	{
	case IDC_COMBO_TYPE:
	  switch( HIWORD(wParam)) 
	    {
	    case CBN_SELCHANGE:
	      selection = SendDlgItemMessage( hDlg, IDC_COMBO_TYPE, CB_GETCURSEL, 0, 0);
	      if( selection == 2 || selection == 3 ) { /* cdrom or floppy */
		enable_cdrom_box( hDlg, 1 );
	      }
	      else {
		enable_cdrom_box( hDlg, 0 );
	      }
	      break;
	    }
	  break;

	case ID_BUTTON_OK:
	  {
	    DRIVE_DESC *pDrive = GetProp(hDlg, "PDRIVE");
	    char buffer[MAX_NAME_LENGTH];
	    
	    /* fixme: do it in a cleanup */
	    RemoveProp(hDlg, "PDRIVE");

	    ZeroMemory(&buffer[0], MAX_NAME_LENGTH);
	    GetWindowText(GetDlgItem(hDlg, IDC_EDIT_PATH), buffer, MAX_NAME_LENGTH);
	    if (strlen(buffer) > 0) {
	      strncpy(pDrive->szName, buffer, MAX_NAME_LENGTH);
	      
	      /* only fill in the other values if we have a path */
	      selection = SendDlgItemMessage( hDlg, IDC_COMBO_TYPE, CB_GETCURSEL, 0, 0);
	      strncpy(pDrive->szType, type_pairs[selection].sCode, MAX_NAME_LENGTH);
	      
	      selection = SendDlgItemMessage( hDlg, IDC_COMBO_NAMES, CB_GETCURSEL, 0, 0);
	      strncpy(pDrive->szFS, fs_pairs[selection].sCode, MAX_NAME_LENGTH);
	      
	      selection = SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_GETCURSEL, 0, 0);
	      SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_GETLBTEXT, selection, (WPARAM)buffer);
	      strncpy(pDrive->szName, buffer, MAX_NAME_LENGTH);
	      pDrive->szName[1] = 0; /* truncate to only the letter */

	      if( strncmp( pDrive->szType, "cdrom", MAX_NAME_LENGTH ) == 0) {
		if( IsDlgButtonChecked( hDlg, IDC_RADIO_ASSIGN ) == BST_CHECKED ) {
		  GetWindowText(GetDlgItem(hDlg, IDC_EDIT_LABEL), buffer, 
				MAX_NAME_LENGTH);
		  strncpy(pDrive->szLabel, buffer, MAX_NAME_LENGTH);
		  GetWindowText(GetDlgItem(hDlg, IDC_EDIT_SERIAL), buffer, 
				MAX_NAME_LENGTH);
		  strncpy(pDrive->szSerial, buffer, MAX_NAME_LENGTH);
		  pDrive->szDevice[0] = 0;
		}
		else {
		  GetWindowText(GetDlgItem(hDlg, IDC_EDIT_DEVICE), buffer, 
				MAX_NAME_LENGTH);
		  strncpy(pDrive->szDevice, buffer, MAX_NAME_LENGTH);
		  pDrive->szLabel[0] = 0;
		  pDrive->szSerial[0] = 0;
		}
	      }
	      else {
		pDrive->szLabel[0] = 0;
		pDrive->szSerial[0] = 0;
		pDrive->szDevice[0] = 0;
	      }
	      EndDialog(hDlg, wParam);
	    }
	    else { /* missing a path */
	      MessageBox( hDlg, "Please enter a valid path", "ERROR", MB_OK );
	    }
	    return TRUE;
	    
	  }

	  
	  /* Fall through. */
	  
	case ID_BUTTON_CANCEL:
	  /* fixme: do it in a cleanup */
	  RemoveProp(hDlg, "PDRIVE");
	  EndDialog(hDlg, wParam);
	  return TRUE;
	}
    }
  return FALSE;
}


/***************************************************************************/
/*  The Actual Property Sheet Page                                         */
/***************************************************************************/

INT_PTR CALLBACK
DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  int selection = -1;

  switch (uMsg)
    {
    case WM_INITDIALOG:
      break;
      
    case WM_COMMAND:
      switch (LOWORD(wParam))
	{
	case IDC_LIST_DRIVES:
	  switch( HIWORD( wParam ) )
	    {
	    case LBN_DBLCLK:
	      selection = -1;
	      break;
	    }
	case IDC_BUTTON_ADD:
	  if (HIWORD(wParam)==BN_CLICKED) {
	    DRIVE_DESC* pDrive = malloc(sizeof(DRIVE_DESC));
	    
	    /* adding a new drive */
	    ZeroMemory(pDrive, sizeof(*pDrive));
	    DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT2),
			   NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) pDrive );
	    /* if pDrive is blank, free the memory, otherwise, add the pointer to HDPA and add to listbox */
	    if (!(pDrive->szName[0]))
	      free(pDrive);
	    else {
	      char DRIVE_NAME[7];
	      int pos;
	      
	      ZeroMemory(DRIVE_NAME,sizeof(DRIVE_NAME));
	      strcat(DRIVE_NAME, "Drive \0");
	      strncat(DRIVE_NAME, pDrive->szName, 1);
	      pos = SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_ADDSTRING ,(WPARAM) -1, (LPARAM) DRIVE_NAME);
	      SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETITEMDATA, pos, (LPARAM) pos);
	      DPA_InsertPtr(config.pDrives, pos, pDrive);
	    }
	  }
	  break;
	case IDC_BUTTON_EDIT:
	  if (HIWORD(wParam)==BN_CLICKED) {
	    int nItem = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES),  LB_GETCURSEL, 0, 0);
	    int i = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_GETITEMDATA, nItem, 0);
	    DRIVE_DESC* pDrive = DPA_GetPtr(config.pDrives, i);
	    
	    if (pDrive != NULL) {
	      DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT2),
			     NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) pDrive );
	      SetProp(hDlg, "PDRIVE", pDrive);
	    }
	  }
	  break;
	case IDC_BUTTON_REMOVE:
	  if (HIWORD(wParam)==BN_CLICKED) {
	    int nItem = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_GETCURSEL, 0, 0);
	    SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_DELETESTRING, (WPARAM) nItem, (LPARAM) 0 );
	    free(DPA_GetPtr(config.pDrives, nItem));
	  }

	default:
	  /** SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); */
	  break;
	}
      break;

    case WM_NOTIFY:
      switch(((LPNMHDR)lParam)->code)
	{
	case PSN_KILLACTIVE: {
	  /* validate user info.  Lets just assume everything is okay for now */
	  SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
	}
	case PSN_APPLY: {
	  /* should probably check everything is really all rosy :) */
	  saveDriveDlgSettings (hDlg);
	  SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
	}
	case PSN_SETACTIVE: {
	  if (!initialized)
	    initDriveDlg (hDlg);

	}
	}

    default:
      break;
    }
  return FALSE;
}
