/*
	WinSTon

	Favourites Property Page
*/

#include "..\includes\winston.h"
#include "..\includes\debug.h"
#include "..\includes\dialog.h"
#include "..\includes\file.h"
#include "..\includes\floppy.h"
#include "..\includes\memory.h"
#include "..\includes\misc.h"
#include "..\includes\reset.h"
#include "..\includes\screen.h"
#include "..\includes\tos.h"
#include "..\includes\view.h"

HWND FavhWnd;											// Handle of favourites dialog page
HIMAGELIST hTreeIcons;									// Tree icons
HTREEITEM hSelectedItem;								// Selected Item(or NULL)
FAVOURITE_FOLDER *pEditFolder;							// Folder to edit
FAVOURITE_DISC *pEditDisc;								// Disc image to edit
BOOL bEditDialog;										// Set to TRUE if dialog is 'Edit' version, else 'Add'
int nExistingChecks;									// Counter for discs when checking is exist
unsigned int DiscExistTimer;							// Timer used to check if disc exist
char szFavouriteFileName[2][MAX_FILENAME_LENGTH];		// Filenames to pass to favourites when choose 'Add Disc'

//-----------------------------------------------------------------------
/*
	Init Favourites
*/
void Dialog_Favourites_Init(void)
{
	// Create a masked image list large enough to hold the icons. 
    hTreeIcons = ImageList_Create(16, 16, TRUE, 6, 0); 
 
    // Load the icon resources, and add the icons to the image list. 
    ImageList_AddIcon(hTreeIcons, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON26)));	// Root Item
    ImageList_AddIcon(hTreeIcons, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON23)));	// Folder
    ImageList_AddIcon(hTreeIcons, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON24)));	// Disc
    ImageList_AddIcon(hTreeIcons, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON25)));	// Disc(Crossed-out)
    ImageList_AddIcon(hTreeIcons, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON27)));	// Grey Disc
    ImageList_AddIcon(hTreeIcons, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON28)));	// Grey Disc(Crossed-out)
}
  
//-----------------------------------------------------------------------
/*
	UnInit Favourites
*/
void Dialog_Favourites_UnInit(void)
{
	// Free icons
	ImageList_Destroy(hTreeIcons);
}
    
//-----------------------------------------------------------------------
/*
	Set defaults for Favourites
*/
void Dialog_Favourites_SetDefaults(void)
{
	// Set defaults for Favourites
	ConfigureParams.Favourites.bCheckDiscs = TRUE;
	ConfigureParams.Favourites.bOnlyShowIfExist = FALSE;
}

//-----------------------------------------------------------------------
/*
	Enable item according to options states
*/
void Dialog_Favourites_EnableItems(HWND hDlg)
{
	FAVOURITE_DISC *pDisc;
	BOOL bOnItem,bOnEditItem,bRunItem;

	// Selected item? If on 'root' turn off as this item cannot be modified
	bOnEditItem = bOnItem = hSelectedItem ? TRUE:FALSE;
	if (hSelectedItem==Favourites.DiscImages.hItem)
		bOnEditItem = FALSE;

	// Can add disc or folder?
	Dialog_EnableItem(hDlg,IDC_BUTTON_FAVADDFOLDER,bOnItem);
	Dialog_EnableItem(hDlg,IDC_BUTTON_FAVADDDISC,bOnItem);

	// Have we selected an item? If not disable 'Edit'
	Dialog_EnableItem(hDlg,IDC_BUTTON_FAVEDIT,bOnEditItem);
	// Save for 'Delete'
	Dialog_EnableItem(hDlg,IDC_BUTTON_FAVDELETE,bOnEditItem);

	// Set if can 'Run' - must be in disc image
	bRunItem = FALSE;
	pDisc = Favourites_FindDiscByHandle(hSelectedItem);
	if (pDisc) {
		// If on disc and known not to fail enable!
		if (!pDisc->bFails)
			bRunItem = TRUE;
	}
	Dialog_EnableItem(hDlg,IDC_BUTTON_FAVRUN,bRunItem);
}

//-----------------------------------------------------------------------
/*
	Set icon of disc favourite, cross out if cannot find and grey out if disc does not run
*/
void Dialog_Favourites_SetDiscExistIcon(FAVOURITE_DISC *pDisc,TVITEM *pTVItem)
{
	// Check if exists - MUST have called 'Dialog_DoesDiscExist' to set this flag before get here
	if (pDisc->bDiscExists) {
		pTVItem->iImage =
		pTVItem->iSelectedImage = pDisc->bFails ? FAVOURITE_ICON_GREY_DISC : FAVOURITE_ICON_DISC;
	}
	else {
		pTVItem->iImage =
		pTVItem->iSelectedImage = pDisc->bFails ? FAVOURITE_ICON_GREY_CROSSED_DISC : FAVOURITE_ICON_CROSSED_DISC;
	}
}

//-----------------------------------------------------------------------
/*
	Add Top-Level Folder item into tree
*/
HTREEITEM Dialog_Favourites_AddTreeTopLevelFolder(HWND hDlg)
{
	TVINSERTSTRUCT InsStruct;
	HTREEITEM hItem;

	// Add into tree
	InsStruct.hParent = NULL;
	InsStruct.hInsertAfter = TVI_SORT;
	InsStruct.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_IMAGE|TVIF_SELECTEDIMAGE;		// Folder(has children)
	InsStruct.item.hItem = 0;
	InsStruct.item.state = 0;
	InsStruct.item.stateMask = 0;
	InsStruct.item.pszText = Favourites.DiscImages.szFolder;
	InsStruct.item.cchTextMax = strlen(Favourites.DiscImages.szFolder)+1;
	InsStruct.item.iImage =
	InsStruct.item.iSelectedImage = FAVOURITE_ICON_ROOT;
	InsStruct.item.cChildren = 1;						// 1 or more
	InsStruct.item.lParam = 0;

	hItem = (HTREEITEM)SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_INSERTITEM,0,(LPARAM)&InsStruct);
	Favourites.DiscImages.hItem = hItem;								// Store handle so can reference later
	return(hItem);
}

//-----------------------------------------------------------------------
/*
	Add Folder item into tree
*/
HTREEITEM Dialog_Favourites_AddTreeFolder(HWND hDlg,HTREEITEM hRootItem,FAVOURITE_FOLDER *pFolder)
{
	TVINSERTSTRUCT InsStruct;
	HTREEITEM hItem;

	// Add into tree
	InsStruct.hParent = hRootItem;
	InsStruct.hInsertAfter = TVI_SORT;
	InsStruct.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_IMAGE|TVIF_SELECTEDIMAGE;		// Folder(has children)
	InsStruct.item.hItem = 0;
	InsStruct.item.state = 0;
	InsStruct.item.stateMask = 0;
	InsStruct.item.pszText = pFolder->szFolder;
	InsStruct.item.cchTextMax = strlen(pFolder->szFolder)+1;
	InsStruct.item.iImage =
	InsStruct.item.iSelectedImage = FAVOURITE_ICON_FOLDER;
	InsStruct.item.cChildren = 1;						// 1 or more
	InsStruct.item.lParam = 0;

	hItem = (HTREEITEM)SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_INSERTITEM,0,(LPARAM)&InsStruct);
	pFolder->hItem = hItem;								// Store handle so can reference later
	return(hItem);
}

//-----------------------------------------------------------------------
/*
	Add Disc Image item into tree
*/
void Dialog_Favourites_AddTreeDisc(HWND hDlg,HTREEITEM hItem,FAVOURITE_DISC *pDisc, BOOL bSort)
{
	TVINSERTSTRUCT InsStruct;

	// Add into tree(these are sorted when added all entries)
	InsStruct.hParent = hItem;
	InsStruct.hInsertAfter = bSort ? TVI_SORT : TVI_FIRST;
	InsStruct.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
	InsStruct.item.hItem = 0;
	InsStruct.item.state = 0;
	InsStruct.item.stateMask = 0;
	InsStruct.item.pszText = pDisc->szTitle;
	InsStruct.item.cchTextMax = strlen(pDisc->szTitle)+1;
	InsStruct.item.iImage =
	InsStruct.item.iSelectedImage = pDisc->bFails ? FAVOURITE_ICON_GREY_DISC : FAVOURITE_ICON_DISC;
	InsStruct.item.cChildren = 0;
	InsStruct.item.lParam = 0;
	// Set icon to show if disc exists
	Dialog_Favourites_SetDiscExistIcon(pDisc,&InsStruct.item);

	hItem = (HTREEITEM)SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_INSERTITEM,0,(LPARAM)&InsStruct);
	pDisc->hItem = hItem;								// Store handle so can reference later
}

//-----------------------------------------------------------------------
/*
	Update details in tree item and re-sort
*/
void Dialog_Favourites_UpdateTreeFolder(HWND hDlg,HTREEITEM hItem,FAVOURITE_FOLDER *pFolder)
{
	TVITEM TVItem;

	// Read structure
	TVItem.hItem = hItem;
	TVItem.mask = 0;
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_GETITEM,0,(LPARAM)&TVItem);
	
	// Set new text
	TVItem.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
	TVItem.iImage =
	TVItem.iSelectedImage = FAVOURITE_ICON_FOLDER;
	TVItem.cChildren = 1;								// 1 or more
	TVItem.pszText = pFolder->szFolder;
	TVItem.cchTextMax = strlen(pFolder->szFolder)+1;

	// Write details back so user can see icon!
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SETITEM,0,(LPARAM)&TVItem);
	// And re-sort, need to use folder handle
	if (pFolder->pParentFolder)
		SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SORTCHILDREN,0,(LPARAM)pFolder->pParentFolder->hItem);
	// And tag as no selection
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SELECTITEM,TVGN_CARET,(LPARAM)NULL);
}

//-----------------------------------------------------------------------
/*
	Update details in tree item and re-sort
*/
void Dialog_Favourites_UpdateTreeDisc(HWND hDlg,HTREEITEM hItem,FAVOURITE_DISC *pDisc)
{
	FAVOURITE_FOLDER *pFolder;
	TVITEM TVItem;

	// Read structure
	TVItem.hItem = hItem;
	TVItem.mask = 0;
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_GETITEM,0,(LPARAM)&TVItem);
	
	// Show disc icon, or cross out if not found on system
	Dialog_DoesDiscExist(pDisc);
	Dialog_Favourites_SetDiscExistIcon(pDisc,&TVItem);
	// Set new text
	TVItem.pszText = pDisc->szTitle;
	TVItem.cchTextMax = strlen(pDisc->szTitle)+1;
	TVItem.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;

	// Write details back so user can see icon!
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SETITEM,0,(LPARAM)&TVItem);
	// And re-sort, need to use folder handle
	pFolder = pDisc->pParentFolder;
	if (pFolder)
		SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SORTCHILDREN,0,(LPARAM)pFolder->hItem);
	// And tag as no selection
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SELECTITEM,TVGN_CARET,(LPARAM)NULL);
}

//-----------------------------------------------------------------------
/*
	Populate Tree Favourites with Disc Images
*/
BOOL Dialog_Favourites_PopulateDiscs(HWND hDlg,HTREEITEM hItem,FAVOURITE_DISC *pDisc)
{
	BOOL bCheckExistingImages=FALSE;

	// Add disc details
	while(pDisc) {
		// Add disc details
		if (!pDisc->hItem) {
			// See if only wish to add disc which actually exist on drive
			if (DialogParams.Favourites.bOnlyShowIfExist) {
				// If disc doesn't exist, skip adding it to list
				if (!pDisc->bAlreadyChecked)			// Only check if not checked before
					Dialog_DoesDiscExist(pDisc);
				if (!pDisc->bDiscExists)				// Skip if not found
					goto bypass_disc;
			}
			Dialog_Favourites_AddTreeDisc(hDlg,hItem,pDisc,FALSE);
			// Have checked if exist yet? If not, set to
			if (!pDisc->bAlreadyChecked)
				bCheckExistingImages = pDisc->bCheckIfDiscExists = TRUE;
bypass_disc:;
		}

		pDisc = pDisc->pNextDisc;
	}

	// Now sort order(faster than if order each as insert into list)
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SORTCHILDREN,0,(LPARAM)hItem);

	// Return TRUE if need to scan images to see if exist
	return(bCheckExistingImages);
}

//-----------------------------------------------------------------------
/*
	Populate Tree Favourites with Folders
*/
void Dialog_Favourites_PopulateFolders(HWND hDlg,HTREEITEM hRootItem,FAVOURITE_FOLDER *pFolder)
{
	HTREEITEM hItem;

	// Add folder details
	while(pFolder) {
		// Add this parent folder
		hItem = Dialog_Favourites_AddTreeFolder(hDlg,hRootItem,pFolder);
		// Don't populate disc images and this takes a lot of CPU so leave this - do it when user clicks to open folder

		// Add any child folders
		Dialog_Favourites_PopulateFolders(hDlg,hItem,pFolder->pNextChildFolder);

		pFolder = pFolder->pNextFolder;
	}
}

//-----------------------------------------------------------------------
/*
	Test if disc image is found on hard-drive and set icon
*/
void Dialog_Favourites_ScanIfDiscExists(HWND hDlg,HTREEITEM hItem,FAVOURITE_DISC *pDisc)
{
	TVITEM TVItem;

	// Read structure
	TVItem.hItem = hItem;
	TVItem.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_GETITEM,0,(LPARAM)&TVItem);
	
	// Show disc icon, or cross out if not found on system
	Dialog_DoesDiscExist(pDisc);
	Dialog_Favourites_SetDiscExistIcon(pDisc,&TVItem);

	// Write details back so user can see icon!
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SETITEM,0,(LPARAM)&TVItem);
}

//-----------------------------------------------------------------------
/*
	Scan each disc in set icon if disc is found on system
	If none of the discs needed checking, return FALSE
*/
BOOL Dialog_Favourites_ScanForExistingDiscImages_ScanDiscs(HWND hDlg,FAVOURITE_DISC *pDisc)
{
	BOOL bAllImagesChecked=FALSE;

	// Add disc details
	while(pDisc && (nExistingChecks<NUM_EXISTINGCHECKS)) {
		// Add disc details
		if ( (pDisc->hItem) && (pDisc->bCheckIfDiscExists) ) {
			Dialog_Favourites_ScanIfDiscExists(hDlg,pDisc->hItem,pDisc);
			// Set so don't check next time
			pDisc->bCheckIfDiscExists = FALSE;
			pDisc->bAlreadyChecked = TRUE;
			bAllImagesChecked = TRUE;
			// Increase counter so check in 'chunks' to keep processing time down
			nExistingChecks++;
		}

		pDisc = pDisc->pNextDisc;
	}

	return(bAllImagesChecked);
}

//-----------------------------------------------------------------------
/*
	Scan each folder to see if disc images are present on system and set icons
*/
void Dialog_Favourites_ScanForExistingDiscImages_ScanFolders(HWND hDlg,FAVOURITE_FOLDER *pFolder)
{
	// Set count - only check for 'x' discs so we don't use too much processor time
	nExistingChecks = 0;

	// Scan folder details
	while(pFolder && (nExistingChecks<NUM_EXISTINGCHECKS)) {
		// Scan any discs in this folder, set 'bCheckIfDiscExists' to FALSE if all are checked
		if ( (pFolder->bCheckIfDiscExists) && (nExistingChecks<NUM_EXISTINGCHECKS) )
			pFolder->bCheckIfDiscExists = Dialog_Favourites_ScanForExistingDiscImages_ScanDiscs(hDlg,pFolder->pDiscs);
		// Scan any child folders
		if (nExistingChecks<NUM_EXISTINGCHECKS)
			Dialog_Favourites_ScanForExistingDiscImages_ScanFolders(hDlg,pFolder->pNextChildFolder);

		pFolder = pFolder->pNextFolder;
	}
}

//-----------------------------------------------------------------------
/*
	Scan each disc image to see if present on system and set icons
*/
void Dialog_Favourites_ScanForExistingDiscImages(HWND hDlg)
{
	// Scan each folder/disc image checking flags and update disc icons accordingly
	Dialog_Favourites_ScanForExistingDiscImages_ScanFolders(hDlg,Favourites.DiscImages.pNextChildFolder);
}

//-----------------------------------------------------------------------
/*
	Delete Item(folder or disc image) from Favourites
*/
BOOL Dialog_Favourites_DeleteItem(HWND hDlg,HTREEITEM hSelectedItem)
{
	FAVOURITE_FOLDER *pFolder;
	FAVOURITE_DISC *pDisc;
	char szString[1024];

	// Was it a folder or disc image?
	pFolder = Favourites_FindFolderByHandle(hSelectedItem);
	if (pFolder) {										// It was a folder?
		// Ask user if want to delete
		sprintf(szString,"Are you sure you want to delete favourites folder\n'%s'?\n\nWARNING: This will remove all contents of the folder.",pFolder->szFolder);
		if (MessageBox(hDlg,szString,"Delete Folder",MB_YESNO | MB_DEFBUTTON2 | MB_ICONSTOP)==IDYES) {
			// Delete from Tree
			SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_DELETEITEM,0,(LPARAM)pFolder->hItem);
			// And delete from favourites
			Favourites_DeleteFolders(pFolder);
			// Set modified
			Favourites.bChanged = TRUE;

			return(TRUE);
		}
	}
	else {
		pDisc = Favourites_FindDiscByHandle(hSelectedItem);
		if (pDisc) {									// It was a disc image?
			// Ask user if want to delete
			sprintf(szString,"Are you sure you want to delete favourite disc image\n'%s'?",pDisc->szTitle);
			if (MessageBox(hDlg,szString,"Delete Disc Image",MB_YESNO | MB_DEFBUTTON2 | MB_ICONSTOP)==IDYES) {
				// Delete from Tree
				SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_DELETEITEM,0,(LPARAM)pDisc->hItem);
				// And delete from favourites
				Favourites_DeleteDisc(pDisc);
				// Set modified
				Favourites.bChanged = TRUE;

				return(TRUE);
			}
		}
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
	Write settings into dialog
*/
void Dialog_Favourites_WriteFolderPopulate(HWND hDlg)
{
	// Write details
	Dialog_SetText(hDlg,IDC_EDIT_FOLDER,pEditFolder->szFolder);

	// Set window text
	if (bEditDialog)
		SetWindowText(hDlg,"Edit Favourites Folder");
	else
		SetWindowText(hDlg,"Add Favourites Folder");
}

//-----------------------------------------------------------------------
/*
	Read settings back from dialog
*/
void Dialog_Favourites_ReadFolderPopulate(HWND hDlg)
{
	// Read items
	Dialog_ReadText(hDlg,IDC_EDIT_FOLDER,pEditFolder->szFolder);
}

//-----------------------------------------------------------------------
/*
	Folder dialog
*/
BOOL PASCAL EditFolderDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message) {
		case WM_INITDIALOG:
			Dialog_Favourites_WriteFolderPopulate(hWnd);
			return(FALSE);

		case WM_COMMAND:
			switch(wParam) {
				case IDOK:
					Dialog_Favourites_ReadFolderPopulate(hWnd);
					EndDialog(hWnd,TRUE);
					return(TRUE);

				case IDCANCEL:
					EndDialog(hWnd,FALSE);
					return(TRUE);
				}
			break;
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
	Edit Folder
*/
BOOL Dialog_Favourites_EditFolder(HWND hWnd, FAVOURITE_FOLDER *pFolder,BOOL bUpdate)
{
	PROC lpfnDlgProc;
	BOOL bRet;

	// Open dialog
	pEditFolder = pFolder;								// Copy to global!
	bEditDialog = bUpdate;
	lpfnDlgProc = MakeProcInstance((PROC)EditFolderDlgProc,hInst);
	bRet = DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG_FOLDER),hWnd,(DLGPROC)lpfnDlgProc,NULL);
	// And update tree, re-sort, and set no selection
	if (bRet) {
		if (bUpdate)
			Dialog_Favourites_UpdateTreeFolder(FavhWnd,hSelectedItem,pEditFolder);
		// Set modified
		Favourites.bChanged = TRUE;
	}
	return(bRet);
}

//-----------------------------------------------------------------------
/*
	Write settings into dialog
*/
void Dialog_Favourites_WriteDiscImagePopulate(HWND hDlg)
{
	// Write details
	Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_NAME,pEditDisc->szTitle);
	Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_DISCA,pEditDisc->szDiscImages[0]);
	Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_DISCB,pEditDisc->szDiscImages[1]);
	Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_TOS,pEditDisc->szTOSImage);

	// Set window text
	if (bEditDialog)
		SetWindowText(hDlg,"Edit Favourite Disc Image");
	else
		SetWindowText(hDlg,"Add Favourite Disc Image");
}

//-----------------------------------------------------------------------
/*
	Read settings back from dialog
*/
void Dialog_Favourites_ReadDiscImagePopulate(HWND hDlg)
{
	// Read items
	Dialog_ReadText(hDlg,IDC_EDIT_DISCIMAGE_NAME,pEditDisc->szTitle);
	Dialog_ReadText(hDlg,IDC_EDIT_DISCIMAGE_DISCA,pEditDisc->szDiscImages[0]);
	Dialog_ReadText(hDlg,IDC_EDIT_DISCIMAGE_DISCB,pEditDisc->szDiscImages[1]);
	Dialog_ReadText(hDlg,IDC_EDIT_DISCIMAGE_TOS,pEditDisc->szTOSImage);
}

//-----------------------------------------------------------------------
/*
	Browse for disc image and TOS files
*/
void Dialog_Favourites_BrowseDiscImageAFile(HWND hDlg)
{
	// Browse for file and change edit box if OK
	if (File_OpenSelectDlg(hWnd,pEditDisc->szDiscImages[0],FILEFILTER_DISCFILES,FALSE,FALSE))
		Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_DISCA,pEditDisc->szDiscImages[0]);
}

void Dialog_Favourites_BrowseDiscImageBFile(HWND hDlg)
{
	// Browse for file and change edit box if OK
	if (File_OpenSelectDlg(hWnd,pEditDisc->szDiscImages[1],FILEFILTER_DISCFILES,FALSE,FALSE))
		Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_DISCB,pEditDisc->szDiscImages[1]);
}

void Dialog_Favourites_BrowseTOSImageFile(HWND hDlg)
{
	// Browse for file and change edit box if OK
	if (File_OpenSelectDlg(hWnd,pEditDisc->szTOSImage,FILEFILTER_TOSROM,FALSE,FALSE))
		Dialog_SetText(hDlg,IDC_EDIT_DISCIMAGE_TOS,pEditDisc->szTOSImage);
}

//-----------------------------------------------------------------------
/*
	Disc Image dialog
*/
BOOL PASCAL EditDiscDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message) {
		case WM_INITDIALOG:
			Dialog_Favourites_WriteDiscImagePopulate(hWnd);
			return(FALSE);

		case WM_COMMAND:
			switch(wParam) {
				case IDC_BUTTON_DISCIMAGE_DISCA:
					Dialog_Favourites_BrowseDiscImageAFile(hWnd);
					return(TRUE);
				case IDC_BUTTON_DISCIMAGE_DISCB:
					Dialog_Favourites_BrowseDiscImageBFile(hWnd);
					return(TRUE);
				case IDC_BUTTON_DISCIMAGE_TOS:
					Dialog_Favourites_BrowseTOSImageFile(hWnd);
					return(TRUE);

				case IDOK:
					Dialog_Favourites_ReadDiscImagePopulate(hWnd);
					EndDialog(hWnd,TRUE);
					return(TRUE);

				case IDCANCEL:
					EndDialog(hWnd,FALSE);
					return(TRUE);
				}
			break;
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
	Edit Disc Image
*/
BOOL Dialog_Favourites_EditDisc(HWND hWnd,FAVOURITE_DISC *pDisc, BOOL bUpdate)
{
	PROC lpfnDlgProc;
	BOOL bRet;

	// Open dialog
	pEditDisc = pDisc;									// Copy to global!
	bEditDialog = bUpdate;
	lpfnDlgProc = MakeProcInstance((PROC)EditDiscDlgProc,hInst);
	bRet = DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG_DISCIMAGE),hWnd,(DLGPROC)lpfnDlgProc,NULL);
	// And update tree, check if disc exists, re-sort, and set no selection
	if (bRet) {
		if (bUpdate)
			Dialog_Favourites_UpdateTreeDisc(FavhWnd,hSelectedItem,pEditDisc);
		// Set modified
		Favourites.bChanged = TRUE;
	}
	return(bRet);
}

//-----------------------------------------------------------------------
/*
	Add disc image to folder
*/
void Dialog_Favourites_AddDiscImage(HWND hWnd, FAVOURITE_FOLDER *pFolder)
{
	FAVOURITE_DISC *pNewDisc;
	FAVOURITE_DISC NewDisc;
	int i;

	// Clear new disc structure, set with chosen disc
	memset(&NewDisc,0x0,sizeof(FAVOURITE_DISC));
	strcpy(NewDisc.szDiscImages[0],szFavouriteFileName[0]);
	strcpy(NewDisc.szDiscImages[1],szFavouriteFileName[1]);
	// Set details
	if (Dialog_Favourites_EditDisc(hWnd,&NewDisc,FALSE)) {
		// Create structure
		pNewDisc = Favourites_AddDisc(pFolder);
		// Copy details into structure
		strcpy(pNewDisc->szTitle,NewDisc.szTitle);
		for(i=0; i<4; i++)
			strcpy(pNewDisc->szDiscImages[i],NewDisc.szDiscImages[i]);
		strcpy(pNewDisc->szTOSImage,NewDisc.szTOSImage);
		pNewDisc->bCheckIfDiscExists = TRUE;
		pFolder->bCheckIfDiscExists = TRUE;
		// And update, sort
		Dialog_Favourites_AddTreeDisc(hWnd,pFolder->hItem,pNewDisc,TRUE);
		// Set modified
		Favourites.bChanged = TRUE;
		// Clear passed filenames
		strcpy(szFavouriteFileName[0],"");
		strcpy(szFavouriteFileName[1],"");
	}
}

//-----------------------------------------------------------------------
/*
	Add new folder as child of 'pFolder'
*/
void Dialog_Favourites_AddFolder(HWND hWnd, FAVOURITE_FOLDER *pFolder)
{
	FAVOURITE_FOLDER *pNewFolder;
	FAVOURITE_FOLDER NewFolder;

	// Clear new folder structure
	memset(&NewFolder,0x0,sizeof(FAVOURITE_FOLDER));
	// Set details
	if (Dialog_Favourites_EditFolder(hWnd,&NewFolder,FALSE)) {
		// Always add as child
		if (pFolder->pNextChildFolder)
			pNewFolder = Favourites_AddFolder(pFolder);
		else
			pNewFolder = Favourites_AddChildFolder(pFolder);
		// Copy details into structure
		strcpy(pNewFolder->szFolder,NewFolder.szFolder);
		// And update
		Dialog_Favourites_AddTreeFolder(hWnd,pFolder->hItem,pNewFolder);
		// Set modified
		Favourites.bChanged = TRUE;
	}
}

//-----------------------------------------------------------------------
/*
	Edit Item(folder or disc image) in Favourites
*/
void Dialog_Favourites_EditItem(HWND hDlg,HTREEITEM hSelectedItem)
{
	FAVOURITE_FOLDER *pFolder;
	FAVOURITE_DISC *pDisc;

	// Was it a folder or disc image?
	pFolder = Favourites_FindFolderByHandle(hSelectedItem);
	if (pFolder)											// It was a folder?
		Dialog_Favourites_EditFolder(hDlg,pFolder,TRUE);	// Edit it
	else {
		pDisc = Favourites_FindDiscByHandle(hSelectedItem);
		if (pDisc)											// It was a disc image?
			Dialog_Favourites_EditDisc(hDlg,pDisc,TRUE);		// Edit it
	}
}

//-----------------------------------------------------------------------
/*
	Create disc filename, using default disc directory is image is not absolute path
*/
void Dialog_Favourites_BuildDiscFileName(char *pszDiscImage,char *pszFileName)
{
	// Is absolute path?
	if (File_IsRootFileName(pszDiscImage)) {
		// Yes, use as is
		strcpy(pszFileName,pszDiscImage);
	}
	else {
		// No, add in directory
		sprintf(pszFileName,"%s%s",ConfigureParams.DiscImage.szDiscImageDirectory,pszDiscImage);
	}
}

//-----------------------------------------------------------------------
/*
	Create TOS filename, using default TOS directory is image is not absolute path
*/
void Dialog_Favourites_BuildTOSFileName(char *pszTOSImage,char *pszFileName)
{
	// Is absolute path?
	if (File_IsRootFileName(pszTOSImage)) {
		// Yes, use as is
		strcpy(pszFileName,pszTOSImage);
	}
	else {
		// No, get directory of TOS from dialog
		File_GetDirectoryString(ConfigureParams.TOSGEM.szTOSImageFileName,pszFileName);
		// And add on TOS name
		strcat(pszFileName,pszTOSImage);
	}
}

//-----------------------------------------------------------------------
/*
	Open Microsoft Explorer and take the user to the URL
*/
void Dialog_Favourites_DownloadDiscImage(FAVOURITE_DISC *pDisc)
{
	char szString[MAX_FILENAME_LENGTH];

	// Do we have an associated URL?
	if (strlen(pDisc->szURLAddress)>0) {
		// Bring up web to URL, add URLBASE is need to(ie noes not start with 'http'
		if (!strnicmp(pDisc->szURLAddress,"http",4))
			strcpy(szString,pDisc->szURLAddress);
		else {
			// Build up address using global URL
			sprintf(szString,"%s%s",Favourites.szURLBaseAddress,pDisc->szURLAddress);
			// Over-ride with folder URL?
			if (pDisc->pParentFolder) {
				if (strlen(pDisc->pParentFolder->szURLBaseAddress)>0)
					sprintf(szString,"%s%s",pDisc->pParentFolder->szURLBaseAddress,pDisc->szURLAddress);
			}
		}
		WinSTon_GoWeb(szString,TRUE);
	}
}

//-----------------------------------------------------------------------
/*
	Return TRUE if disc exists
*/
BOOL Dialog_DoesDiscExist(FAVOURITE_DISC *pDisc)
{
	char szFileName[MAX_FILENAME_LENGTH];
	BOOL bFoundImage=FALSE;

	// Make first disc name, if cannot find use alternate name
	Dialog_Favourites_BuildDiscFileName(pDisc->szDiscImages[0],szFileName);
	if (File_FindPossibleExtFileName(szFileName,pszDiscImageNameExts))
		bFoundImage = TRUE;
	else {
		// Try alternate file
		Dialog_Favourites_BuildDiscFileName(pDisc->szDiscImages[2],szFileName);
		if (File_FindPossibleExtFileName(szFileName,pszDiscImageNameExts))
			bFoundImage = TRUE;
	}

	// Store TRUE/FALSE for updating icons etc...
	pDisc->bDiscExists = bFoundImage;

	return(bFoundImage);
}

//-----------------------------------------------------------------------
/*
	Scan to see if clicked on image and run it!
*/
void Dialog_Favourites_RunClickedImage(HWND hDlg)
{
	FAVOURITE_DISC *pDisc;
	char szFileName[MAX_FILENAME_LENGTH],szString[MAX_FILENAME_LENGTH];
	BOOL bOK;
	int Ret,DriveA,DriveB;

	// Did we click on a disc image, rather than a folder?
	if (hSelectedItem) {
		// Scan through all out favourite entries looking for a handle match - this mean we can use duplicates
		pDisc = Favourites_FindDiscByHandle(hSelectedItem);
		// Did find one?
		if (pDisc) {
			// And does run
			if (!pDisc->bFails) {
				// Set new TOS filename, if have one else use selected from dialog
				if (strlen(pDisc->szTOSImage)>0) {
					bOverrideTOSImage = TRUE;
					Dialog_Favourites_BuildTOSFileName(pDisc->szTOSImage,szTOSImageOverrideFileName);
					// Do it exist? If not warn user, first find possible extension!
					File_FindPossibleExtFileName(szTOSImageOverrideFileName,pszTOSNameExts);
					if (!File_Exists(szTOSImageOverrideFileName)) {
						sprintf(szString,"Unable to find TOS image '%s'.\n\nWARNING: This may prevent the disc image from running correctly.",szTOSImageOverrideFileName);
						MessageBox(hWnd,szString,PROG_NAME,MB_OK | MB_ICONSTOP);
					}
				}
				else
					bOverrideTOSImage = FALSE;

				// Run image
				DriveA = 0;	DriveB = 1;
				// If have possible alternative filename, check which one to use!
				if (strlen(pDisc->szDiscImages[2])>0) {
					// Make first disc name, if cannot find use alternate name
					Dialog_Favourites_BuildDiscFileName(pDisc->szDiscImages[0],szFileName);
					if (!File_FindPossibleExtFileName(szFileName,pszDiscImageNameExts)) {
						DriveA = 2;	DriveB = 3;			// Alternative filenames for images
					}
				}

				// Insert disc B first so keep string filename if error
				Dialog_Favourites_BuildDiscFileName(pDisc->szDiscImages[DriveB],szFileName);
				Floppy_InsertDiscIntoDrive(0,szFileName);
				Dialog_Favourites_BuildDiscFileName(pDisc->szDiscImages[DriveA],szFileName);
				bOK = Floppy_InsertDiscIntoDrive(0,szFileName);
				if (!bOK) {
					// Unable to load disc image, show error to user
					if (strlen(pDisc->szDiscImages[0])>0) {
						// Can we send user to web for disc image?
						if (strlen(pDisc->szURLAddress)>0) {
							// Ask user if they wish to download image
							sprintf(szString,"Unable to find disc image '%s'.\n\nWould you like to download the disc from the Internet?",szFileName);
							Ret = MessageBox(hWnd,szString,PROG_NAME,MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION);
							if (Ret==IDYES)
								Dialog_Favourites_DownloadDiscImage(pDisc);
						}
						else {
							// Inform user we couldn't find the favourite disc
							sprintf(szString,"Unable to find disc image '%s'.",pDisc->szDiscImages[0]);
							MessageBox(hWnd,szString,PROG_NAME,MB_OK | MB_ICONSTOP);
						}
					}
				}
				else {
					Reset_Cold();
					Screen_Draw();
					View_ToggleWindowsMouse(MOUSE_ST);
					WinSTon_UnPauseEmulation();
				}

				// And choose 'OK' on property sheet
				PropSheet_PressButton(PropHWnd,PSBTN_OK);
			}
		}
	}
}

//-----------------------------------------------------------------------
/*
	User clicked on item, enable 'Download' button if not on system
*/
void Dialog_Favourites_ClickedOnItem(HWND hDlg,HTREEITEM hSelectedItem)
{
	FAVOURITE_DISC *pDisc;

	// Disable by default
	Dialog_EnableItem(hDlg,IDC_BUTTON_FAVDOWNLOAD,FALSE);

	// Was this a disc image?
	pDisc = Favourites_FindDiscByHandle(hSelectedItem);
	// Did find one?
	if (pDisc) {
		// Do the disc exists on the system? If not, enable button if have download web-address
		if (!Dialog_DoesDiscExist(pDisc)) {
			if (strlen(pDisc->szURLAddress)>0)
				Dialog_EnableItem(hDlg,IDC_BUTTON_FAVDOWNLOAD,TRUE);
		}
	}

	// Enable buttons
	Dialog_Favourites_EnableItems(hDlg);
}

//-----------------------------------------------------------------------
/*
	Add all folder/discs to tree view
*/
void Dialog_Favourites_FillTree(HWND hDlg)
{
	// Add top-level entry into Tree view
	Dialog_Favourites_AddTreeTopLevelFolder(hDlg);
	// Add all entries into Tree dialog
	Dialog_Favourites_PopulateFolders(hDlg,Favourites.DiscImages.hItem,Favourites.DiscImages.pNextChildFolder);
	hSelectedItem = NULL;

	// Expand root item
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_EXPAND,(WPARAM)TVE_EXPAND,(LPARAM)Favourites.DiscImages.hItem);
}

//-----------------------------------------------------------------------
/*
	Write settings into dialog page
*/
void Dialog_Favourites_WritePopulate(HWND hDlg)
{
	// Copy filenames from floppy drives
	strcpy(szFavouriteFileName[0],EmulationDrives[0].szFileName);
	strcpy(szFavouriteFileName[1],EmulationDrives[1].szFileName);

	// Set items
	Dialog_SetButton(hDlg,IDC_CHECK_FAVSCANDISCS,DialogParams.Favourites.bCheckDiscs);
	Dialog_SetButton(hDlg,IDC_CHECK_FAVHIDEDISCS,DialogParams.Favourites.bOnlyShowIfExist);

	// Set icons for use in the tree view
	SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SETIMAGELIST,(WPARAM)TVSIL_NORMAL,(LPARAM)hTreeIcons);

	// Add all items
	Dialog_Favourites_FillTree(hDlg);

	// Set timer, update disc images icons on this count
	DiscExistTimer = SetTimer(hDlg,3,20,NULL);

	Dialog_Favourites_EnableItems(hDlg);

	bOKDialog = TRUE;
}

//-----------------------------------------------------------------------
/*
	Read settings back from dialog page
*/
void Dialog_Favourites_ReadPopulate(HWND hDlg)
{
	// Stop timer
	KillTimer(hDlg,DiscExistTimer);
	// Read items
	DialogParams.Favourites.bCheckDiscs = Dialog_ReadButton(hDlg,IDC_CHECK_FAVSCANDISCS);
	DialogParams.Favourites.bOnlyShowIfExist = Dialog_ReadButton(hDlg,IDC_CHECK_FAVHIDEDISCS);	
	// Clean up handles as we dynamically insert items into tree
	Favourites_Clean();
}

//-----------------------------------------------------------------------
/*
	Favourites Property page handler
*/
BOOL FAR PASCAL Dialog_Favourites_DlgProc(HWND hDlg, UINT Message, UINT wParam, LONG lParam)
{
	FAVOURITE_FOLDER *pFolder;
	FAVOURITE_DISC *pDisc;

	switch(Message) {
		case WM_INITDIALOG:
			// Set handle for global use(to update tree from other dialogs)
			FavhWnd = hDlg;
			Dialog_Favourites_WritePopulate(hDlg);
			// Don't set 'nLastOpenPage'
			return(TRUE);

		case WM_TIMER:
			// Scan for disc images on hard-drive, limit per time so keep Windows running
			// If disabled, do nothing(leaves flags alone so get updated when re-enable)
			if (DialogParams.Favourites.bCheckDiscs)
				Dialog_Favourites_ScanForExistingDiscImages(hDlg);
			return(TRUE);

		case WM_NOTIFY:
			switch(((NMHDR *)lParam)->code) {
				case NM_DBLCLK:
					Dialog_Favourites_RunClickedImage(hDlg);
					return(TRUE);
				case TVN_SELCHANGED:
					hSelectedItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem;
					// Enable buttons accordingly
					Dialog_Favourites_ClickedOnItem(hDlg,hSelectedItem);
					return(TRUE);
				case TVN_ITEMEXPANDING:
					hSelectedItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem;
					// Enable buttons accordingly
					Dialog_Favourites_ClickedOnItem(hDlg,hSelectedItem);
					// Fill-in items
					if ( ((LPNMTREEVIEW)lParam)->action&TVE_EXPAND ) {						
						// Find handle of folder clicked on
						pFolder = Favourites_FindFolderByHandle(hSelectedItem);
						if (pFolder) {	// Add discs to folder							
							SetCursor(Cursors[CURSOR_HOURGLASS]);
							// Add discs, set flag so will update icons to show discs which are runnable
							pFolder->bCheckIfDiscExists = Dialog_Favourites_PopulateDiscs(hDlg,pFolder->hItem,pFolder->pDiscs);
							SetCursor(Cursors[CURSOR_ARROW]);
						}
					}
					return(FALSE);
				case PSN_RESET:
				case PSN_APPLY:
					// If OK or CANCEL call this to reset items
					Dialog_Favourites_ReadPopulate(hDlg);
					return(TRUE);
				case PSN_HELP:
					WinSTon_GoWeb("help\\options\\favourites.html",FALSE);
					return(TRUE);
			}
			break;

		case WM_HELP:
			// Open help
			WinSTon_GoWeb("help\\options\\favourites.html",FALSE);
			return(TRUE);

		case WM_COMMAND:
			switch(LOWORD(wParam)) {
				case IDC_BUTTON_FAVADDFOLDER:
					// Find parent folder, and add child if one found
					pFolder = Favourites_FindParentFolderByHandle(hSelectedItem);
					if (pFolder==NULL)
						pFolder = &Favourites.DiscImages;
					Dialog_Favourites_AddFolder(hDlg,pFolder);
					hSelectedItem = NULL;
					// And tag as no selection
					SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SELECTITEM,TVGN_CARET,(LPARAM)NULL);
					// Enable buttons accordingly
					Dialog_Favourites_ClickedOnItem(hDlg,hSelectedItem);
					return(TRUE);

				case IDC_BUTTON_FAVADDDISC:
					// Find parent folder
					pFolder = Favourites_FindParentFolderByHandle(hSelectedItem);
					if (pFolder)						// Add add to this
						Dialog_Favourites_AddDiscImage(hDlg,pFolder);
					return(TRUE);

				case IDC_BUTTON_FAVEDIT:
					// Have we highlighted a disc image?
					if (hSelectedItem)
						Dialog_Favourites_EditItem(hDlg,hSelectedItem);
					return(TRUE);
				case IDC_BUTTON_FAVDELETE:
					// Have we highlighted a disc image?
					if (hSelectedItem) {
						// If delete reset selection
						if (Dialog_Favourites_DeleteItem(hDlg,hSelectedItem))
							hSelectedItem = NULL;
						// And tag as no selection
						SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_SELECTITEM,TVGN_CARET,(LPARAM)NULL);
					}
					// Enable buttons accordingly
					Dialog_Favourites_ClickedOnItem(hDlg,hSelectedItem);
					return(TRUE);
				case IDC_BUTTON_FAVDOWNLOAD:
					// Have we highlighted a disc image?
					if (hSelectedItem) {
						// Scan through all out favourite entries looking for a handle match - this mean we can use duplicates
						pDisc = Favourites_FindDiscByHandle(hSelectedItem);
						// Did find one? If so, download!
						if (pDisc)
							Dialog_Favourites_DownloadDiscImage(pDisc);
					}
					return(TRUE);
				case IDC_CHECK_FAVSCANDISCS:
					// Read back now so can update accordingly
					DialogParams.Favourites.bCheckDiscs = Dialog_ReadButton(hDlg,IDC_CHECK_FAVSCANDISCS);
					return(TRUE);
				case IDC_CHECK_FAVHIDEDISCS:
					// Read back now so can update accordingly
					DialogParams.Favourites.bOnlyShowIfExist = Dialog_ReadButton(hDlg,IDC_CHECK_FAVHIDEDISCS);
					// Delete all entries
					SendDlgItemMessage(hDlg,IDC_TREE_FAVOURITE,TVM_DELETEITEM,0,(LPARAM)TVI_ROOT);
					// Clean all handles
					Favourites_Clean();
					// And fill with new ones
					Dialog_Favourites_FillTree(hDlg);
					return(TRUE);

				case IDC_BUTTON_FAVRUN:
					Dialog_Favourites_RunClickedImage(hDlg);
					return(TRUE);
			}
			break;
	}

	return(FALSE);	// Not Processed!
}
