/***********************************************************************
 *
 Copyright © 1995 - 1998, 3Com Corporation or its subsidiaries ("3Com").  
 All rights reserved.
   
 This software may be copied and used solely for developing products for 
 the Palm Computing platform and for archival and backup purposes.  Except 
 for the foregoing, no part of this software may be reproduced or transmitted 
 in any form or by any means or used to make any derivative work (such as 
 translation, transformation or adaptation) without express written consent 
 from 3Com.

 3Com reserves the right to revise this software and to make changes in content 
 from time to time without obligation on the part of 3Com to provide notification 
 of such revision or changes.  
 3COM MAKES NO REPRESENTATIONS OR WARRANTIES THAT THE SOFTWARE IS FREE OF ERRORS 
 OR THAT THE SOFTWARE IS SUITABLE FOR YOUR USE.  THE SOFTWARE IS PROVIDED ON AN 
 "AS IS" BASIS.  3COM MAKES NO WARRANTIES, TERMS OR CONDITIONS, EXPRESS OR IMPLIED, 
 EITHER IN FACT OR BY OPERATION OF LAW, STATUTORY OR OTHERWISE, INCLUDING WARRANTIES, 
 TERMS, OR CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 
 SATISFACTORY QUALITY.

 TO THE FULL EXTENT ALLOWED BY LAW, 3COM ALSO EXCLUDES FOR ITSELF AND ITS SUPPLIERS 
 ANY LIABILITY, WHETHER BASED IN CONTRACT OR TORT (INCLUDING NEGLIGENCE), FOR 
 DIRECT, INCIDENTAL, CONSEQUENTIAL, INDIRECT, SPECIAL, OR PUNITIVE DAMAGES OF 
 ANY KIND, OR FOR LOSS OF REVENUE OR PROFITS, LOSS OF BUSINESS, LOSS OF INFORMATION 
 OR DATA, OR OTHER FINANCIAL LOSS ARISING OUT OF OR IN CONNECTION WITH THIS SOFTWARE, 
 EVEN IF 3COM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

 3Com, HotSync, Palm Computing, and Graffiti are registered trademarks, and 
 Palm III and Palm OS are trademarks of 3Com Corporation or its subsidiaries.

 IF THIS SOFTWARE IS PROVIDED ON A COMPACT DISK, THE OTHER SOFTWARE AND 
 DOCUMENTATION ON THE COMPACT DISK ARE SUBJECT TO THE LICENSE AGREEMENT 
 ACCOMPANYING THE COMPACT DISK.
 
 *****************************************************************************
 *
 * PROJECT:  Touchdown
 * FILE:     ExpenseCurrency.c
 * AUTHOR:	 Art Lamb: August 27, 1995
 *
 * DECLARER: Expense
 *
 * DESCRIPTION:
 *	  This file contains routines the manage currencies.
 *
 **********************************************************************/

#include <Pilot.h>
#include <CharAttr.h>

#define	NON_PORTABLE
#include <MemoryPrv.h>

#include "Expense.h"

/***********************************************************************
 *
 *	Internal Structutes
 *
 ***********************************************************************/
typedef struct {
	CharPtr 	countryName;
	Word		currencyID;
} CountrySortType;



/***********************************************************************
 *
 * FUNCTION:    CurrencyGetCountryName
 *
 * DESCRIPTION: This routine returns the country name for the specified 
 *              currency.
 *
 * PARAMETERS:  currency - currency
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/29/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencyGetCountryName (Word currency, CharPtr name)
{
	Word								index;
	ExpenseAppInfoPtr 			appInfoP;
	CountryPreferencesType *	resP;
			

	if (currency >= countryFirst && currency <= countryLast)
		{
  		resP = MemHandleLock (DmGetResource (sysResTCountries, sysResIDCountries));
		StrCopy (name, resP[currency].countryName);
		MemPtrUnlock (resP);
		}

	else if (currency >= currencyCustom1 && currency <= currencyCustom4)
		{
		appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
		index = currency - currencyCustom1;
		StrCopy (name, appInfoP->currencies[index].country);
		MemPtrUnlock (appInfoP);
		}
	
	else
		{
		*name = 0;
		}
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyGetDecimalSeperator
 *
 * DESCRIPTION: This routine returns the decimal seperator character 
 *              for the specified currency.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/30/96	Initial Revision
 *			trm	7/22/97	Feture request to have number format changed to user defined.
 *
 ***********************************************************************/
Char CurrencyGetDecimalSeperator (Word currency)
{
	Char thousandSeparator;
	Char decimalSeparator;

	if (currency >= countryFirst && currency <= countryLast)
		{
		LocGetNumberSeparators ((NumberFormatType) PrefGetPreference (prefNumberFormat),
			&thousandSeparator, &decimalSeparator);
		}

	return (decimalSeparator);
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyGetDecimalPlaces
 *
 * DESCRIPTION: This routine returns the decimal positions 
 *              for the specified currency.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	9/11/96	Initial Revision
 *
 ***********************************************************************/
Word CurrencyGetDecimalPlaces (Word currency)
{
	Char decimalPlaces;
	CountryPreferencesType *	resP;


	if (currency >= countryFirst && currency <= countryLast)
		{
  		resP = MemHandleLock (DmGetResource (sysResTCountries, sysResIDCountries));
		
		decimalPlaces = resP[currency].currencyDecimalPlaces;
		
		MemPtrUnlock (resP);
		}
		
	else
		decimalPlaces = 2;

	return (decimalPlaces);
}


/***********************************************************************
 *
 * FUNCTION:    CountryCompare
 *
 * DESCRIPTION: Case blind comparision of two country names. This routine is 
 *              used as a callback routine when sorting the the country list.
 *
 * PARAMETERS:  c1 - a country name (null-terminated)
 *              c2 - a country name (null-terminated)
 *
 * RETURNED:    if c1 > c2  - a positive integer
 *              if c1 = c2  - zero
 *              if c1 < c2  - a negative integer
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/29/96	Initial Revision
 *
 ***********************************************************************/
static Int CountryCompare (CountrySortType *c1, CountrySortType *c2, Long other)
{
	return StrCaselessCompare (c1->countryName, c2->countryName);
}


/***********************************************************************
 *
 * FUNCTION:    CountrySelect
 *
 * DESCRIPTION: This routine creates a list of currency symbols.
 *  
 * PARAMETERS:  listP        - list in which to place the categories
 *              currencyName - name of the current currency
 *					 name         - name of the country (returned)
 *
 * RETURNED:    true if a defferent cunntry is selected
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
static Boolean CountrySelect (ListPtr lst, BytePtr currencyP, CharPtr name)

{
	Int								i;
	Int								listIndex;
	Int								selection;
	Int								newSelection;
	Boolean							changed = false;
	CharPtr							str;
	CharPtr							noneStrP;
	CharPtr							listItems [countryCount + maxCurrenciesDisplayed];
	CountrySortType				countries [countryCount + maxCurrenciesDisplayed];
	CurrencyInfoPtr 				currencies;
	ExpenseAppInfoPtr 			appInfoP;
	CountryPreferencesType *	countryPreferencesP;
			

	// Get the system resource that contains the country name.
  	countryPreferencesP = MemHandleLock (DmGetResource (sysResTCountries, sysResIDCountries));

	// Get the block the contains the custom currencies.
	appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
	currencies = appInfoP->currencies;

	// Build a sorted list of country names.
	listIndex = 0;
	for (i = 0; i < countryCount; i++)
		{
		countries[listIndex].countryName = countryPreferencesP[i].countryName;
		countries[listIndex].currencyID = i;
		listIndex++;
		}

	for (i = 0; i < maxCustomCurrencies; i++)
		{
		if (*currencies [i].country)
			{
			countries[listIndex].countryName = currencies[i].country;
			countries[listIndex].currencyID = currencyCustom1 + i;
			listIndex++;
			}
		}
		
	SysQSort (countries, listIndex, sizeof (CountrySortType), (CmpFuncPtr)CountryCompare, 0);
		
	
	// End "None" choice to the end of the list.
	noneStrP = MemHandleLock (DmGetResource (strRsc, noneStrID));
	countries[listIndex].countryName = noneStrP;
	countries[listIndex].currencyID = currencyNone;
	listIndex++;


	// Initial the choices, selection and height of the list.
	selection = noListSelection;
	for (i = 0; i < listIndex; i++)
		{
		listItems[i] = countries[i].countryName;
		if (*currencyP == countries[i].currencyID)
			selection = i;
		}

	LstSetListChoices (lst, listItems, listIndex);
	LstSetSelection (lst, selection);
	if (selection != noListSelection)
		LstMakeItemVisible  (lst, selection);
	else
		LstMakeItemVisible  (lst, 0);

	// Display the country list.
	newSelection = LstPopupList (lst);

	// If a new country was selected then return the county name and id.
	 if (newSelection != -1 && newSelection != selection)
		{
		*currencyP = countries[newSelection].currencyID;

		// Make a copy of the currency name, it's going to freed.
		if (name)
			{
			str = LstGetSelectionText (lst, newSelection);
			StrCopy (name, str);
			}
		changed = true;		
		}


	MemPtrUnlock (noneStrP);
	MemPtrUnlock (appInfoP);
	MemPtrUnlock (countryPreferencesP);
	
	return (changed);
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyGetSymbol
 *
 * DESCRIPTION: This routine returns the symbol of the specified 
 *              currency.
 *
 * PARAMETERS:  currency - Currency to select
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/28/96	Initial Revision
 *
 ***********************************************************************/
void CurrencyGetSymbol (Word currency, CharPtr symbol)
{
	Word								index;
	ExpenseAppInfoPtr 			appInfoP;
	CountryPreferencesType *	resP;
			

	if (currency >= countryFirst && currency <= countryLast)
		{
  		resP = MemHandleLock (DmGetResource (sysResTCountries, sysResIDCountries));
		if (currency == HomeCountry)
			StrCopy (symbol, resP[currency].currencySymbol);
		else
			StrCopy (symbol, resP[currency].uniqueCurrencySymbol);
		MemPtrUnlock (resP);
		}

	else if (currency >= currencyCustom1 && currency <= currencyCustom4)
		{
		appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
		index = currency - currencyCustom1;
		StrCopy (symbol, appInfoP->currencies[index].symbol);
		MemPtrUnlock (appInfoP);
		}
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyCreateList
 *
 * DESCRIPTION: This routine creates a list of currency symbols.
 *
 * PARAMETERS:  listP - list in which to place the categories
 *					 currentCurrency - Currency to select
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencyCreateList (ListPtr listP, Word currentCurrency)
{
	Int								count;
	Int								listIndex;
	Int								selection;
	Word								i;
	Word								size;
	CharPtr							ptr;
	CharPtr							items;
	CharPtr							editingStr;
	CharPtr							listItems [maxCurrenciesDisplayed + 1];
	CharPtr * 						itemsPtr;
	CurrencyInfoPtr 				currencies;
	ExpenseAppInfoPtr 			appInfoP;
	CountryPreferencesType *	countryPrefP;
			

	appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
	currencies = appInfoP->currencies;

  	countryPrefP = MemHandleLock (DmGetResource (sysResTCountries, sysResIDCountries));


	// For each Currency not empty, copy it's string to the list's
	// item list.
	listIndex = 0;
	for (i = 0; i < maxCurrenciesDisplayed; i++)
		{
		if (Currencies[i] >= countryFirst && Currencies[i] <= countryLast)
			{
			if (Currencies[i] == HomeCountry)
				listItems[listIndex++] = countryPrefP[Currencies[i]].currencySymbol;
			else
				listItems[listIndex++] = countryPrefP[Currencies[i]].uniqueCurrencySymbol;
			}

		else if (Currencies[i] >= currencyCustom1 && Currencies[i] <= currencyCustom4)
			{
			listItems[listIndex++] = currencies [Currencies[i] - currencyCustom1].symbol;
			}
		}
		
		
	// Add "edit currencies" item to the end of the list.
	editingStr = MemHandleLock(DmGetResource(strRsc, editingCurenciesStrID));
	listItems[listIndex++] = editingStr;
	

	// Allocate a block to hold the items in the list.
	if (listIndex > 0)
		{
		size = (listIndex) * sizeof (CharPtr);
		itemsPtr = MemPtrNew (size);

		// Allocate a block to hold the country names.
		size = 0;
		for (i = 0; i < listIndex; i++)
			size += StrLen (listItems[i]) + 1;
		items = MemPtrNew (size);


		// Copy the country names into the list.
		ptr = items;
		for (i = 0; i < listIndex; i++)
			{
			itemsPtr[i] = ptr;
			StrCopy (ptr, listItems[i]);
			ptr += StrLen (listItems[i]) + 1;
			}
		}
	else
		{
		itemsPtr = NULL;
		items = NULL;
		}
	
	LstSetListChoices (listP, itemsPtr, listIndex);
	LstSetHeight (listP, listIndex);


	// The the selection of the list to the passed curency.
	selection = noListSelection;
	count = 0;
	for (i = 0; i < maxCurrenciesDisplayed; i++)
		{
		if (Currencies[i] != currencyNone)
			{
			if (Currencies[i] == currentCurrency)
				{
				selection = count;
				break;
				}
			else
				count++;
			}
		}
	LstSetSelection (listP, selection);
	

	MemPtrUnlock (editingStr);
	MemPtrUnlock (appInfoP);
	MemPtrUnlock (countryPrefP);
}



/***********************************************************************
 *
 * FUNCTION:    CurrencySelect
 *
 * DESCRIPTION: This routine process the selection and editting of
 *              Currencies. 
 *
 * PARAMETERS:  frm          - form the contains the currency popup list
 *              lst          - pointer to the popup list
 *              currencyP    - 
 *              currencyName - name of the current currency
 *
 * RETURNED:    This routine returns true if any of the following conditions
 *					 are true:
 *					 	- the current currency is renamed
 *					 	- the current currency is deleted
 *					 	- the current currency is merged with another currency
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/95	Initial Revision
 *
 ***********************************************************************/
Boolean CurrencySelect (ListPtr lst, WordPtr currencyP, CharPtr currencyName)

{
	CharPtr		str;
	Short			i;
	Short			count;
	Short			newSelection;
	short			curSelection;
	Boolean		currencyEdited = false;
	Word 			currency;
	
	currency = *currencyP;
	
	// If the currency trigger is part of the title, then the "all" item
	// should be in the list.
	CurrencyCreateList (lst, currency);

	// Make sure the list is entirely visible.
	// zzz Need a LstGetPosition function.
	LstSetPosition (lst, lst->bounds.topLeft.x, lst->bounds.topLeft.y);

	curSelection = LstGetSelection (lst);
	newSelection = LstPopupList (lst);


	// Was the  "edit Currencies ..." item selected?
	if (newSelection == LstGetNumberOfItems (lst) - 1)
		{
		// We'll treat moving a currency like selecting a diffent currency. 
		FrmPopupForm (CurrencySelectDialog);
		}

	// Was a new currency selected?
	else if ((newSelection != curSelection) && (newSelection != -1))
		{
		// Make a copy of the currency name, it's going to freed.
		if (currencyName)
			{
			str = LstGetSelectionText (lst, newSelection);
			StrCopy (currencyName, str);
			}
		
		// Get the currency id that corresponds to the list item selected.
		count = 0;
		for (i = 0; i < maxCurrenciesDisplayed; i++)
			{
			if (Currencies[i] != currencyNone)
				{
				if (count == newSelection)
					{
					currency = Currencies[i];
					break;
					}
				else
					count++;
				}
			}
		}


	// Free the memory allocated for the list choices.
	if (lst->itemsText[0])
		MemPtrFree (lst->itemsText[0]);

	if (lst->itemsText)
		MemPtrFree (lst->itemsText);


	*currencyP = currency;
	return (currencyEdited);
}


/***********************************************************************
 *
 * FUNCTION:    CurrencySelectCurrency
 *
 * DESCRIPTION: This routine select a currency that will be displayed
 *              in the currency sysmbol popup list.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/29/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencySelectCountry (Word ctlID, BytePtr currencies)
{
	Word index;
	ListPtr lst;
	CharPtr label;
	ControlPtr ctl;

	switch (ctlID)
		{
		case CurrencySelectCurr1Trigger: index = 0;		break;
		case CurrencySelectCurr2Trigger: index = 1;		break;
		case CurrencySelectCurr3Trigger: index = 2;		break;
		case CurrencySelectCurr4Trigger: index = 3;		break;
		case CurrencySelectCurr5Trigger: index = 4;		break;
		}

	lst = GetObjectPtr (CurrencySelectCountryList);
	ctl = GetObjectPtr (ctlID);
	label = CtlGetLabel (ctl);

	if (CountrySelect (lst, &currencies[index], label))
		{
		CtlSetLabel (ctl, label);
		}
}


/***********************************************************************
 *
 * FUNCTION:    CurrencySelectInit
 *
 * DESCRIPTION: This routine initializes the Currency Properties
 *              Dialog Box.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/29/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencySelectInit (void)
{
	Int i;
	Word id;
	CharPtr label;
	CharPtr rscP;
	ControlPtr ctl;
			
	for (i = 0; i < 5; i++)
		{
		switch (i)
			{
			case 0:	id  = CurrencySelectCurr1Trigger;		break;
			case 1:	id  = CurrencySelectCurr2Trigger;		break;
			case 2:	id  = CurrencySelectCurr3Trigger;		break;
			case 3:	id  = CurrencySelectCurr4Trigger;		break;
			case 4:	id  = CurrencySelectCurr5Trigger;		break;
			}

		ctl = GetObjectPtr (id);
		label = CtlGetLabel (ctl);
		CurrencyGetCountryName (Currencies [i], label);
		
		if (*label)
			CtlSetLabel (ctl, label);
		else
			{
			rscP = MemHandleLock (DmGetResource (strRsc, noneStrID));
			StrCopy (label, rscP);
			CtlSetLabel (ctl, label);
			MemPtrUnlock (rscP);
			}
		}
}


/***********************************************************************
 *
 * FUNCTION:    CurrencySelectHandleEvent
 *
 * DESCRIPTION: This routine is the event handler for the Currency
 *              Selection Dialog Box.  This dialog is used to specify
 *              which currency symbol appear to the currency popup
 *              list.
 *
 * PARAMETERS:  event  - a pointer to an EventType structure
 *
 * RETURNED:    true if the event was handled and should not be passed
 *              to a higher level handler.
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/29/96	Initial Revision
 *
 ***********************************************************************/
Boolean CurrencySelectHandleEvent (EventPtr event)
{
	static Byte	currencies [maxCurrenciesDisplayed];
	
	FormPtr frm;
	Boolean handled = false;

	if (event->eType == ctlSelectEvent)
		{
		switch (event->data.ctlSelect.controlID)
			{
			case CurrencySelectOkButton:
				MemMove (Currencies, currencies, sizeof (Currencies));
				FrmReturnToForm (0);
				handled = true;
				break;

			case CurrencySelectCancelButton:
				FrmReturnToForm (0);
				handled = true;
				break;

			case CurrencySelectCurr1Trigger:
			case CurrencySelectCurr2Trigger:
			case CurrencySelectCurr3Trigger:
			case CurrencySelectCurr4Trigger:
			case CurrencySelectCurr5Trigger:
				CurrencySelectCountry (event->data.ctlSelect.controlID, currencies);
				break;				
			}
		}

	else if (event->eType == frmOpenEvent)
		{
		frm = FrmGetActiveForm ();
		CurrencySelectInit ();
		FrmDrawForm (frm);
		MemMove (currencies, Currencies, sizeof (currencies));
		handled = true;
		}

	return (handled);
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyPropApply
 *
 * DESCRIPTION: This routine applies the changes made in the CurrencyPropences
 *					 Dialog.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencyPropApply (void)
{
	Int i;
	ULong offset;
	CharPtr ptr;
	CharPtr textP;
	FieldPtr fld;
	CurrencyInfoPtr currency;
	ExpenseAppInfoPtr appInfoP;
			
	appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
	currency = &appInfoP->currencies[CurrentCustomCurrency];
	
	// Set the country, symbol, and exchange rate fields to the 
	// values in the application info block.
	for (i = 0; i < 2; i++)
		{
		switch (i)
			{
			case 0:
				fld = GetObjectPtr (CurrencyPropCountryField);
				ptr = currency->country;
				break;
				
			case 1:
				fld = GetObjectPtr (CurrencyPropSymbolField);
				ptr = currency->symbol;
				break;
			}


		if (FldDirty (fld))
			{
			textP = FldGetTextPtr (fld);
			offset = ptr - (CharPtr) appInfoP;
			DmWrite (appInfoP, offset, textP, StrLen(textP)+1);
			}
		}

	MemPtrUnlock (appInfoP);	


	// If the custom currency appears in the list of popup currencies
	// an its name is blank then remove it from the list.
	fld = GetObjectPtr (CurrencyPropCountryField);
	textP = FldGetTextPtr (fld);
	if (! *textP)
		{
		for (i = 0; i < maxCustomCurrencies; i++)
			{
			if (Currencies[i] == (CurrentCustomCurrency + currencyCustom1))
				Currencies[i] = currencyNone;
			}
		}
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyPropInit
 *
 * DESCRIPTION: This routine initializes the Currency Properties
 *              Dialog Box.
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencyPropInit (void)
{
	Int i;
	Word len;
	CharPtr ptr;
	CharPtr textP;
	VoidHand textH;
	FieldPtr fld;
	CurrencyInfoPtr currency;
	ExpenseAppInfoPtr appInfoP;
			
	appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
	currency = &appInfoP->currencies[CurrentCustomCurrency];
	
	// Set the country, symbol, and exchange rate fields to the 
	// values in the application info block.
	for (i = 0; i < 2; i++)
		{
		switch (i)
			{
			case 0:
				fld = GetObjectPtr (CurrencyPropCountryField);
				ptr = currency->country;
				break;
				
			case 1:
				fld = GetObjectPtr (CurrencyPropSymbolField);
				ptr = currency->symbol;
				break;
			}

		if (*ptr)
			{
			len = StrLen (ptr) + 1;
			textH = MemHandleNew (len);
			textP = MemHandleLock (textH);
			MemMove (textP, ptr, len);
			FldSetTextHandle (fld, textH);
			MemHandleUnlock (textH);
			}
		}

	MemPtrUnlock (appInfoP);	
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyPropHandleEvent
 *
 * DESCRIPTION: This routine is the event handler for the Currency
 *              Properties Dialog Box.
 *
 * PARAMETERS:  event  - a pointer to an EventType structure
 *
 * RETURNED:    true if the event was handled and should not be passed
 *              to a higher level handler.
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
Boolean CurrencyPropHandleEvent (EventPtr event)
{
	FormPtr frm;
	Boolean handled = false;

	if (event->eType == ctlSelectEvent)
		{
		switch (event->data.ctlSelect.controlID)
			{
			case CurrencyPropOkButton:
				CurrencyPropApply ();
				FrmGotoForm (CurrencyDialog);
				handled = true;
				break;

			case CurrencyPropCancelButton:
				FrmGotoForm (CurrencyDialog);
				handled = true;
				break;
				
			}
		}

	else if (event->eType == frmOpenEvent)
		{
		frm = FrmGetActiveForm ();
		CurrencyPropInit ();
		FrmDrawForm (frm);
		handled = true;
		}

	return (handled);
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyInit
 *
 * DESCRIPTION: This routine initializes the Currency Dialog.  
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
static void CurrencyInit (void)
{
	Int i;
	Word len;
	CharPtr rscP;
	CharPtr label;
	ControlPtr ctl;
	CurrencyInfoPtr currencies;
	ExpenseAppInfoPtr appInfoP;
			
	appInfoP = MemHandleLock (ExpenseGetAppInfo (ExpenseDB));
	currencies = appInfoP->currencies;

	// Set the labels the the currency selectors
	for (i = 0 ; i < maxCustomCurrencies; i++)
		{
		ctl = GetObjectPtr (CurrencyCountry1Selector + i);
		label = CtlGetLabel (ctl);

		if (currencies[i].country[0] != 0)
			StrCopy (label, currencies[i].country);

		// If the name is blank display "Country 1" or "Country 2" or ...
		else
			{
			rscP = MemHandleLock (DmGetResource (strRsc, countryStrID));
			len = StrLen (rscP);
			if (len > maxCurrencyNameLen - 2) 
				len = maxCurrencyNameLen - 2;
			StrNCopy (label, rscP, len);
			label [len++] = i + '1';
			label [len] = 0;
			MemPtrUnlock (rscP);
			}

		CtlSetLabel (ctl, label);
		}

	MemPtrUnlock (appInfoP);	
}


/***********************************************************************
 *
 * FUNCTION:    CurrencyHandleEvent
 *
 * DESCRIPTION: This routine is the event handler for the Custom
 *              Currencies Dialog Box
 *
 * PARAMETERS:  event  - a pointer to an EventType structure
 *
 * RETURNED:    true if the event was handled and should not be passed
 *              to a higher level handler.
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	8/27/96	Initial Revision
 *
 ***********************************************************************/
Boolean CurrencyHandleEvent (EventPtr event)
{
	FormPtr frm;
	Boolean handled = false;

	if (event->eType == ctlSelectEvent)
		{
		switch (event->data.ctlSelect.controlID)
			{
			case CurrencyOkButton:
				FrmReturnToForm (0);
				FrmUpdateForm (0, updateCustomCurrencyChanged);
				handled = true;
				break;

			case CurrencyCancelButton:
				FrmReturnToForm (0);
				handled = true;
				break;
				
			case CurrencyCountry1Selector:
			case CurrencyCountry2Selector:
			case CurrencyCountry3Selector:
			case CurrencyCountry4Selector:
				CurrentCustomCurrency = event->data.ctlSelect.controlID - 
					CurrencyCountry1Selector;
				FrmGotoForm (CurrencyPropDialog);
				break;
			}
		}

	else if (event->eType == frmOpenEvent)
		{
		frm = FrmGetActiveForm ();
		CurrencyInit ();
		FrmDrawForm (frm);
		handled = true;
		}

	return (handled);
}


