/*
================================ COPYRIGHT ================================
The contents of this file are subject to the VTech Informations Ltd. License
of VT-OS Ver. 1.1 operating system (the "License"); you may not use this 
file except in compliance with the License.  

Software distributed under the License is distributed on an "AS IS" basis, 
WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License 
for the specific language governing rights and limitations under the License.
  
The Original Code is VT-OS Ver. 1.1 Operating System, released 
on October 1st, 1999
	
The Initial Developer of the Original Code is VTech Informations Ltd.  All 
codes are Copyright (C) VTech Informations Ltd. 1999.  All Rights Reserved.
===========================================================================
*/

/*
===========================================================================
File        :   voxmdb.c
Author(s)   :   Jason Ngan
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   application c file
Revision    :   1.1
Note        :   None
===========================================================================
*/              


#include "stdafx.h"
#include "voxmemo.h"
#include "voxmdef.h"
#include "sndmgr.h"
#include "sysetup.h"


/*****************************************************************
********************** Global Variables **************************
*****************************************************************/
DatabaseID	VoxMemo_dbid;
RecordID	VoxMemo_rec_id;
SHORT		DisplayAction;
BOOLEAN		DisplayActionEnable;

UWORD		TotalLen;
SHORT		VoxMemoTime;
SHORT		VoxMemoTime2;

/*****************************************************************
* Function:	VoxMemoInitMDBGlobal
* Purpose: 	This function is used to initialize the global variables
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
******************************************************************/
BOOLEAN VoxMemoInitMDBGlobal(BOOLEAN is_restart)
{
	BYTE	*buffer;
	UWORD	byte_read;
	DatabaseID	VoxMemo_dbid;
	
	if (is_restart)
	{
		VoxMemoTime = 0;
		VoxMemoTime2 = 0;
		DisplayActionEnable = FALSE;
	}
	else
	{
		if (DataFindDB(VOXDB, &VoxMemo_dbid) != TRUE)
			return FALSE;
		if (DataGetField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_DisplayAction, &buffer, &byte_read) != TRUE)
			return FALSE;
		DisplayAction = *(SHORT*)buffer;
		qfree(buffer);
		if (DataGetField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_TotalLen, &buffer, &byte_read) != TRUE)
			return FALSE;
		TotalLen = *(UWORD*)buffer;
		qfree(buffer);
		if (DataGetField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_VoxMemoTime, &buffer, &byte_read) != TRUE)
			return FALSE;
		VoxMemoTime = *(USHORT*)buffer;
		qfree(buffer);
		if (DataGetField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_VoxMemoTime2, &buffer, &byte_read) != TRUE)
			return FALSE;
		VoxMemoTime2 = *(USHORT*)buffer;
		qfree(buffer);
		
	}
	
	return TRUE;
}



/*****************************************************************
* Function:	VoxMemoDatabaseInit
* Purpose: 	This function is used to simulate and initialse the 
*				the datebase in the PDA.Try to preset some records in 
*				the database
* Scope:		application
* Input:		None
* Output:		None
* Return:		TRUE if success
*				FALSE if no memory
* Comment: 	This function should be called in the StartApplication() function.
*****************************************************************/
BOOLEAN VoxMemoDatabaseInit(BOOLEAN is_restart)
{
	USHORT		i = 0;
	
	/* New Database */
	if (!DataFindDB(VOXDB, &VoxMemo_dbid))
		if (DataNewDB(VOXDB, 1, VOXAPP, &VoxMemo_dbid) == ERR_DATA_NO_SPACE)
			return FALSE;
		if (DataOpenDB(VoxMemo_dbid, F_TIME_DATE, OPEN_RW) != TRUE)
			return FALSE;
		
		if (is_restart)
		{
			
			if (DataNewRecordWithID(VoxMemo_dbid, VOXMEMO_MAIN_APP_SAVE, 0, 14) != TRUE)
				return FALSE;
			if (DataNewRecordWithID(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, 0, 5) != TRUE)
				return FALSE;
			/* Open Database */
		}
		
		return TRUE;
}



/*****************************************************************
* Function:	VoxMemoMDBAppSave
* Purpose: 	This function is called to save the data in 
the expense database when it is called to stopped
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		TRUE if success
*				FALSE if the database not found
* Comment: 	None
******************************************************************/
BOOLEAN VoxMemoMDBAppSave(void)
{
	
	
	if (DataWriteField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_VoxMemo_rec_id, sizeof(RecordID), (BYTE*)&VoxMemo_rec_id) != TRUE)
		return FALSE;
	if (DataWriteField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_DisplayAction, sizeof(SHORT), (BYTE*)&DisplayAction) != TRUE)
		return FALSE;
	if (DataWriteField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_TotalLen, sizeof(UWORD), (BYTE*)&TotalLen) != TRUE)
		return FALSE;
	if (DataWriteField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_VoxMemoTime, sizeof(USHORT), (BYTE*)&VoxMemoTime) != TRUE)
		return FALSE;
	if (DataWriteField(VoxMemo_dbid, VOXMEMO_MDB_APP_SAVE, F_VoxMemoTime2, sizeof(USHORT), (BYTE*)&VoxMemoTime2) != TRUE)
		return FALSE;
	
	return TRUE;
}



/*****************************************************************
* Function:	VoxMemoDatabaseClose
* Purpose: 	This function is used to close all opened 
*				record and database before leaving the application
* Scope:		application
* Input:		None
* Output:		None
* Return:		TRUE if success
*				FALSE if the database not found
* Comment: 	This function should be called in the StopApplication
*****************************************************************/
BOOLEAN VoxMemoDatabaseClose(void)
{
	
	if (DataCloseDB(VoxMemo_dbid) != TRUE)
		return FALSE;
	
	return TRUE;
}

/*****************************************************************
* Function:	VoxMemoDeleteRecord
* Purpose: 	This function is used to delete voxmemo record 
* Scope:		application
* Input:		Archive			Save the archive on PC or not
* Output:		None
* Return:		TRUE if success
*				FALSE if otherwise
* Comment: 	This function should be called in the StopApplication
*****************************************************************/
BOOLEAN VoxMemoDeleteRecord(BOOLEAN archive)
{
	
	DataCloseRecord(VoxMemo_dbid, VoxMemo_rec_id);
	if (DataDeleteRecord(VoxMemo_dbid, VoxMemo_rec_id, archive) != TRUE);
	return FALSE;
	
	return TRUE;
}

/********************************************************
* Function:	VoxMemoDisplayTime
* Purpose: 	This function is called to display the timing status
*				when memo is recording or playing 
* Scope:		application
* Input:		None		
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void VoxMemoDisplayTime(void)
{
	if (DisplayActionEnable)
	{
		switch(DisplayAction)
		{
		case DISPLAY_REC:
			VoxMemoDisplayRecTime();
			return;
		case DISPLAY_PLAY:
			VoxMemoDisplayPlayTime();
			return;
		}
	}
	return;
}

/********************************************************
* Function:	VoxMemoDisplayRecTime
* Purpose: 	This function is called to display the timing status
*				when memo is recording
* Scope:		application
* Input:		Event		
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void VoxMemoDisplayRecTime(void)
{
	BYTE		sbuffer[10];
	
	if (VoxMemoTime > 3598)
	{
		EvtAppendEvt(SND_MGR_EVT, LOW_MEM, 0, 0, NULL);
		return;
	}
	
	/* append a low memory event */
	if (VoxMemoTime2 < 1)
	{
		EvtAppendEvt(SND_MGR_EVT, LOW_MEM, 0, 0, NULL);
		return;
	}
	
	/* display time recorded */
	VoxMemoNum2Time(++VoxMemoTime, sbuffer, FALSE);
	StringSetText(STRING_VOXMEMO_REC_RECTIME, sbuffer);
	StringDrawString(STRING_VOXMEMO_REC_RECTIME);
	
	/* display time remaining */
	VoxMemoNum2Time(--VoxMemoTime2, sbuffer, FALSE);
	StringSetText(STRING_VOXMEMO_REC_REMTIME, sbuffer);
	StringDrawString(STRING_VOXMEMO_REC_REMTIME);
	
	/* set the scrollbar value */
	ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_REC, VoxMemoTime%15, 14, 0, 1, 15);
	ScrollbarDrawScrollbar(SCROLLBAR_VOXMEMO_REC);
	
	return;
}

/********************************************************
* Function:	VoxMemoDisplayPlayTime
* Purpose: 	This function is called to display the timing status
*				when memo is playing 
* Scope:		application
* Input:		Event		
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void VoxMemoDisplayPlayTime(void)
{
	BYTE		sbuffer[10];
	
	/* append a record end event */
	
	if (VoxMemoTime2 < 1)
	{
		//		return;
		//		ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, 14, 14, 0, 1, 15);
		//		ScrollbarDrawScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME);
		EvtAppendEvt(SND_MGR_EVT, REC_END, 0, 0, NULL);
		return;
	}
	
	/* display position */
	VoxMemoNum2Time(++VoxMemoTime, sbuffer, FALSE);
	StringSetText(STRING_VOXMEMO_PLAY_POSTIME, sbuffer);
	StringDrawString(STRING_VOXMEMO_PLAY_POSTIME);
	
	/* display time remaining */
	VoxMemoNum2Time(--VoxMemoTime2, sbuffer, FALSE);
	/*
	StringSetText(STRING_VOXMEMO_PLAY_TTIME, sbuffer);
	StringDrawString(STRING_VOXMEMO_PLAY_TTIME);
	*/
	
	/* set the scrollbar value */
	//	ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, VoxMemoTime*30*BYTEPS/TotalLen, 29, 0, 1, 30);
	
	//	if (VoxMemoTime2 != 0)
	//		ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, VoxMemoTime, (WORD)(VoxMemoTime+VoxMemoTime2), 0, 1, (WORD)(VoxMemoTime+VoxMemoTime2+1));
	//	else
	//		ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, 14, 14, 0, 1, 15);
	
	ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, (WORD)(VoxMemoTime*60/(VoxMemoTime+VoxMemoTime2)), 60, 0, 1, 61);
	
	ScrollbarDrawScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME);
	
	return;
}


/********************************************************
* Function:	VoxMemoDisplayPauseTime
* Purpose: 	This function is called to display the timing status
*				when pause button is pressed
* Scope:		application
* Input:		Event		
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void VoxMemoDisplayPauseTime(void)
{
	BYTE		sbuffer[10], null_buf[1]={'\0'};
	static BOOLEAN	null_display = TRUE;
	
	switch(DisplayAction)
	{
	case DISPLAY_REC:
		if (null_display)
		{
			StringSetText(STRING_VOXMEMO_REC_RECTIME, null_buf);
			StringDrawString(STRING_VOXMEMO_REC_RECTIME);
			StringSetText(STRING_VOXMEMO_REC_REMTIME, null_buf);
			StringDrawString(STRING_VOXMEMO_REC_REMTIME);	
			null_display = FALSE;
		}
		else
		{
			/* display time recorded */
			VoxMemoNum2Time(VoxMemoTime, sbuffer, FALSE);
			StringSetText(STRING_VOXMEMO_REC_RECTIME, sbuffer);
			StringDrawString(STRING_VOXMEMO_REC_RECTIME);
			/* display time remaining */
			VoxMemoNum2Time(VoxMemoTime2, sbuffer, FALSE);
			StringSetText(STRING_VOXMEMO_REC_REMTIME, sbuffer);
			StringDrawString(STRING_VOXMEMO_REC_REMTIME);
			null_display = TRUE;
		}
		return;
	case DISPLAY_PLAY:
		if (null_display)
		{
			StringSetText(STRING_VOXMEMO_PLAY_POSTIME, null_buf);
			StringDrawString(STRING_VOXMEMO_PLAY_POSTIME);			
			//StringSetText(STRING_VOXMEMO_PLAY_TTIME, null_buf);
			//StringDrawString(STRING_VOXMEMO_PLAY_TTIME);
			null_display = FALSE;
		}
		else
		{
			/* display position */
			VoxMemoNum2Time(VoxMemoTime, sbuffer, FALSE);
			StringSetText(STRING_VOXMEMO_PLAY_POSTIME, sbuffer);
			StringDrawString(STRING_VOXMEMO_PLAY_POSTIME);
			/* display time remaining */
			//VoxMemoNum2Time((USHORT)(TotalLen / BYTEPS), sbuffer, FALSE);
			//StringSetText(STRING_VOXMEMO_PLAY_TTIME, sbuffer);
			//StringDrawString(STRING_VOXMEMO_PLAY_TTIME);
			null_display = TRUE;
		}
		
		return;
	}
	
	return;
}





/*****************************************************************
* Function:	VoxMemoNewRecord
* Purpose: 	This function is used to open a new record and 
*				initialize all the item displayed on the screen
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		TRUE if success
*				FALSE if the database is not found
* Comment: 	None
*****************************************************************/
BOOLEAN VoxMemoNewRecord(void)
{
	RTM			date_source;
	BYTE		sbuffer[15];
	BYTE		tbuffer[10];
	BYTE		text_ptr[1];
	USHORT		j;
	UWORD		total_rec;
	VOX_DATE	date;
	CountrySettings	country;
	
	
	strcpy(tbuffer, "0:00");
	
	if (DataTotalRecord(VoxMemo_dbid, &total_rec) != TRUE)
		return FALSE;
	if (total_rec > 98)
		return FALSE;
	
	if (DataNewRecord(VoxMemo_dbid, 0x01, VOXMEMO_NUM_FIELD, &VoxMemo_rec_id) != TRUE)
		return FALSE;
	
	RtcGetTime(&date_source);
	date.sec = (BYTE)date_source.sec;
	date.min = (BYTE)date_source.min;
	date.hr	 = (BYTE)date_source.hour;
	date.day = (BYTE)date_source.mday;
    date.mon = (BYTE)(date_source.mon+1);
	date.yr  = (BYTE)(date_source.year - SYSETUP_YEAR_OFFSET); 
	
	if (DataWriteField(VoxMemo_dbid,VoxMemo_rec_id, F_TIME_DATE, sizeof(VOX_DATE), (BYTE*)&date) != TRUE)
		return FALSE;
	
	text_ptr[0] = 0;
	if (DataWriteField(VoxMemo_dbid,VoxMemo_rec_id, F_INFO, 1, text_ptr) != TRUE)
		return FALSE;
	
	if (!SySetupGetCountrySettings(&country))
		return FALSE;
	
	/* display hour, minute */
	if (country.time_fmt ==  SYSETUP_12HR_DISPLAY)
	{
		if (date.hr == 0)
			j = sprintf((char*)sbuffer, "12:");
		else if(date.hr < 13)
			j = sprintf((char*)sbuffer, "%d:", date.hr);
		else
			j = sprintf((char*)sbuffer, "%d:", date.hr-12);
		
		if (date.min < 10)
			j += sprintf((char*)sbuffer + j, "0%d", date.min);
		else
			j += sprintf((char*)sbuffer + j, "%d", date.min);
		
		if(date.hr < 12)
			j += sprintf((char*)sbuffer + j, VOX_CHARA);
		else
			j += sprintf((char*)sbuffer + j, VOX_CHARP);
	}
	else
	{
		if (date.hr < 10)
			j = sprintf((char*)sbuffer, "0%d:", date.hr);
		else
			j = sprintf((char*)sbuffer, "%d:", date.hr);
		
		if (date.min < 10)
			j += sprintf((char*)sbuffer + j, "0%d", date.min);
		else
			j += sprintf((char*)sbuffer + j, "%d", date.min);
	}
	
	StringSetText(STRING_VOXMEMO_REC_TIME, sbuffer); 
	
	/* display month, day & year */
	switch(country.date_fmt)
	{
	case SYSETUP_YMD:
		if (date.yr < 0)
			date.yr += 100;
		if ((date.yr)%100 < 10)
			j = sprintf((char*)sbuffer, "0%d/", (date.yr)%100);
		else
			j = sprintf((char*)sbuffer, "%d/", (date.yr)%100);
			/*if (date.mon < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date.mon);
		else*/
		j += sprintf((char*)sbuffer + j, "%d/", date.mon);
		
		if (date.day < 10)
			j += sprintf((char*)sbuffer + j, "0%d", date.day);
		else
			j += sprintf((char*)sbuffer + j, "%d", date.day);
		break;
		
	case SYSETUP_DMY:
		if (date.day < 10)
			j = sprintf((char*)sbuffer, "0%d/", date.day);
		else
			j = sprintf((char*)sbuffer, "%d/", date.day);
			/*if (date.mon < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date.mon);
		else*/
		j += sprintf((char*)sbuffer + j, "%d/", date.mon);
		
		if (date.yr < 0)
			date.yr += 100;
		if ((date.yr)%100 < 10)
			j += sprintf((char*)sbuffer + j, "0%d", (date.yr)%100);
		else
			j += sprintf((char*)sbuffer + j, "%d", (date.yr)%100);
		break;
		
	default:
	/*if (date.mon < 10)
				j = sprintf((char*)sbuffer, "0%d/", date.mon);
		else*/
		j = sprintf((char*)sbuffer, "%d/", date.mon);
		
		if (date.day < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date.day);
		else
			j += sprintf((char*)sbuffer + j, "%d/", date.day);
		
		if (date.yr < 0)
			date.yr += 100;
		if ((date.yr)%100 < 10)
			j += sprintf((char*)sbuffer + j, "0%d", (date.yr)%100);
		else
			j += sprintf((char*)sbuffer + j, "%d", (date.yr)%100);
		break;
	}		
	
	StringSetText(STRING_VOXMEMO_REC_DATE, sbuffer);
	StringSetText(STRING_VOXMEMO_INFO_DATE, sbuffer);
	TextboxSetText(TEXTBOX_VOXMEMO_INFO_INFO, (BYTE*)(""));
	
	/* display time recorded */
	StringSetText(STRING_VOXMEMO_REC_RECTIME, tbuffer);
	
	/* display time remaining */
	DisplayAction = DISPLAY_REC;
	
	return TRUE;
}


/*****************************************************************
* Function:	VoxMemoNum2Time
* Purpose: 	This function is used to convert the numbering to time display
* Scope:		application
* Input:		time			input time
* Output:		*subffer		output string buffer
* Return:		None
* Comment: 	None
*****************************************************************/
void VoxMemoNum2Time(USHORT time, BYTE *sbuffer, BOOLEAN zero)
{
	USHORT	j;
	
	/* display minute */
	if (time > 59)
	{
	/*
	if (time/60 < 10)
	if (zero)
				j  = sprintf((char*)sbuffer, "0%d:", time/60);
				else
				j  = sprintf((char*)sbuffer, "%d:", time/60);
		else*/
		j  = sprintf((char*)sbuffer, "%d:", (SHORT)(time/60));
		
		/* display second */
		if (time%60 < 10)
			j += sprintf((char*)sbuffer + j, "0%d", time%60);
		else
			j += sprintf((char*)sbuffer + j, "%d", time%60);
	}
	
	/* display second if time less than 1 min */
	else
	{
		if (time < 10)
			j = sprintf((char*)sbuffer, "0:0%d", time);
		else
			j = sprintf((char*)sbuffer, "0:%d", time);
	}
	
	return;	
}

/*****************************************************************
* Function:	VoxMemoOpenRecord
* Purpose: 	This function is used to handle the voxmemo actions 
* Scope:		application
* Input:		rec_num			the selected record number
* Output:		None
* Return:		TRUE if success
*				FALSE if the database not found
* Comment: 	This function should be called in the StopApplication
*****************************************************************/
BOOLEAN VoxMemoOpenRecord(SHORT rec_num)
{
	BYTE	*item_text;
	UWORD	total_num_rec, byte_read;
	
	
	/* - Open Data Record ----------------------------*/
	if (DataTotalRecord(VoxMemo_dbid, &total_num_rec) != TRUE)
		return FALSE;
	if ((rec_num < 0 )||(rec_num+1 > total_num_rec))
		return FALSE;
	if (DataOpenRecord(VoxMemo_dbid, total_num_rec - rec_num - 1, &VoxMemo_rec_id, NULL)!=TRUE)
		return FALSE;
	if (DataFieldSize(VoxMemo_dbid, VoxMemo_rec_id, F_CODEDATA, &TotalLen) != TRUE)
		return FALSE;
	
	ListGetListItem(LIST_VOXMEMO_LIST_NUM, rec_num, &item_text);
	StringSetText(STRING_VOXMEMO_PLAY_NUM, item_text);
	
	ListGetListItem(LIST_VOXMEMO_LIST_TIME, rec_num, &item_text);
	StringSetText(STRING_VOXMEMO_PLAY_TIME, item_text);
	
	ListGetListItem(LIST_VOXMEMO_LIST_DATE, rec_num, &item_text);
	StringSetText(STRING_VOXMEMO_PLAY_DATE, item_text);
	
	//ListGetListItem(LIST_VOXMEMO_LIST_INFO, rec_num, &item_text);
	if (DataGetField(VoxMemo_dbid, VoxMemo_rec_id, F_INFO, &item_text, &byte_read) != TRUE)
		return FALSE;
	StringSetText(STRING_VOXMEMO_PLAY_INFO, item_text);
	
	DisplayAction = DISPLAY_PLAY;
	/* reset scrollbar & timer display*/
	VoxMemoPlayReset();
	
	return TRUE;	
}

/*****************************************************************
* Function:	VoxMemoAction
* Purpose: 	This function is used to handle the voxmemo actions 
* Scope:		application
* Input:		None
* 
* Output:		None
* Return:		TRUE if success
*				FALSE if the database not found
* Comment: 	This function should be called in the StopApplication
*****************************************************************/
BOOLEAN VoxMemoPlayClose(void)
{
	/* - Close Data Record */
	if (DataCloseRecord(VoxMemo_dbid, VoxMemo_rec_id) != TRUE)
		return FALSE;
	
	//	EncodataIndex = 0;
	
	return TRUE;
}

/*****************************************************************
* Function:	VoxMemoPlayReset
* Purpose: 	This function is used to reset the timer and scrollbar 
*				before playing
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
*****************************************************************/
void VoxMemoPlayReset(void)
{
	BYTE	tbuffer[10];
	BYTE	sbuffer[15];
    BYTE	object_type;
    Scrollbar *addr;
	
	tbuffer[0] = '0';
	tbuffer[1] = ':';
	tbuffer[2] = '0';
	tbuffer[3] = '0';
	tbuffer[4] = 0;
	
	//	EncodataIndex = 0;
	VoxMemoTime = 0;
	
	/* display position */
	StringSetText(STRING_VOXMEMO_PLAY_POSTIME, tbuffer);
	StringDrawString(STRING_VOXMEMO_PLAY_POSTIME);
	
	/* display total time */
	VoxMemoTime2 = (USHORT)(TotalLen / BYTEPS);
	VoxMemoNum2Time(VoxMemoTime2, sbuffer, FALSE);
	StringSetText(STRING_VOXMEMO_PLAY_TTIME, sbuffer);
	StringDrawString(STRING_VOXMEMO_PLAY_TTIME);
	
	/* reset scrollbar  */
	//	ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, 0, (WORD)(VoxMemoTime2), 0, 1, (WORD)(VoxMemoTime2+1));
	ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME, 0, 60, 0, 1, 61);
	ScrollbarDrawScrollbar(SCROLLBAR_VOXMEMO_PLAY_TIME);
	
	return;
}

/*****************************************************************
* Function:	VoxMemoRecordToList
* Purpose: 	This function is used to show the correct records to 
*				the list objects in the voice memo list page
* Scope:		application
* Input:		item_num
* Output:		*top_item_num
* Return:		TRUE				Complete
*				FALSE				Error
* Comment: 	The list object must be initialised first
*				The database must be opened first
*				The function will update the scrollbar too
*****************************************************************/
BOOLEAN VoxMemoRecordToList(SHORT item_num, SHORT *top_item_num)
{
	BOOLEAN		update = FALSE;
	BYTE		*buffer, sbuffer[16];
	USHORT		i, j;
	UWORD		byte_read, memo_num = 1, total_num_rec;
	VOX_DATE	*date_buf;
	CountrySettings	country;
	RecordID rec_id;
	
	
	if (!SySetupGetCountrySettings(&country))
		return FALSE;
	
	if (!DataFindDB(VOXDB, &VoxMemo_dbid))
		return FALSE;
	
	if (DataTotalRecord(VoxMemo_dbid, &total_num_rec) != TRUE)
		return FALSE;
	if (total_num_rec > 12)
	{
		if (item_num > (SHORT)total_num_rec - 12)
			*top_item_num = (SHORT)total_num_rec - 12;
		else
			*top_item_num = item_num;
	}
	else
		*top_item_num = -1;
	ListDeleteAllItems(LIST_VOXMEMO_LIST_NUM);
	ListDeleteAllItems(LIST_VOXMEMO_LIST_TIME);
	ListDeleteAllItems(LIST_VOXMEMO_LIST_DATE);
	ListDeleteAllItems(LIST_VOXMEMO_LIST_INFO);
	
	for (i=0; i<total_num_rec; i++)
	{
		/* Format and print various data: */
		if (memo_num < 10)
			j  = sprintf((char*)sbuffer,     "0%d:", memo_num++);
		else
			j  = sprintf((char*)sbuffer,     "%d:", memo_num++);
		ListInsertItem(LIST_VOXMEMO_LIST_NUM, i, sbuffer);
		
		if (DataOpenRecord(VoxMemo_dbid, total_num_rec-1-i, &VoxMemo_rec_id, NULL) != TRUE)
			return FALSE;
		
		
		if (DataGetField(VoxMemo_dbid, VoxMemo_rec_id, F_TIME_DATE, (BYTE**)&date_buf, &byte_read) != TRUE)
			return FALSE;
		
		if (country.time_fmt ==  SYSETUP_12HR_DISPLAY)
		{
			if (date_buf->hr == 0)
				j = sprintf((char*)sbuffer, "12:");
			else if(date_buf->hr < 13)
				j = sprintf((char*)sbuffer, "%d:", date_buf->hr);
			else
				j = sprintf((char*)sbuffer, "%d:", date_buf->hr-12);
			
			if (date_buf->min < 10)
				j += sprintf((char*)sbuffer + j, "0%d", date_buf->min);
			else
				j += sprintf((char*)sbuffer + j, "%d", date_buf->min);
			
			if(date_buf->hr < 12)
				j += sprintf((char*)sbuffer + j, VOX_CHARA);
			else
				j += sprintf((char*)sbuffer + j, VOX_CHARP);
			
		}
		else
		{
			if (date_buf->hr < 10)
				j = sprintf((char*)sbuffer, "0%d:", date_buf->hr);
			else
				j = sprintf((char*)sbuffer, "%d:", date_buf->hr);
			
			if (date_buf->min < 10)
				j += sprintf((char*)sbuffer + j, "0%d", date_buf->min);
			else
				j += sprintf((char*)sbuffer + j, "%d", date_buf->min);
		}
		
		ListInsertItem(LIST_VOXMEMO_LIST_TIME, i, sbuffer);
		
		switch(country.date_fmt)
		{
		case SYSETUP_YMD:
			if (date_buf->yr < 0)
				date_buf->yr += 100;
			if ((date_buf->yr)%100 < 10)
				j = sprintf((char*)sbuffer, "0%d/", (date_buf->yr)%100);
			else
				j = sprintf((char*)sbuffer, "%d/", (date_buf->yr)%100);
				/*if (date_buf->mon < 10)
				j += sprintf((char*)sbuffer + j, "0%d/", date_buf->mon);
			else*/
			j += sprintf((char*)sbuffer + j, "%d/", date_buf->mon);
			
			if (date_buf->day < 10)
				j += sprintf((char*)sbuffer + j, "0%d", date_buf->day);
			else
				j += sprintf((char*)sbuffer + j, "%d", date_buf->day);
			break;
			
		case SYSETUP_DMY:
			if (date_buf->day < 10)
				j = sprintf((char*)sbuffer, "0%d/", date_buf->day);
			else
				j = sprintf((char*)sbuffer, "%d/", date_buf->day);
				/*if (date_buf->mon < 10)
				j += sprintf((char*)sbuffer + j, "0%d/", date_buf->mon);
			else*/
			j += sprintf((char*)sbuffer + j, "%d/", date_buf->mon);
			
			if (date_buf->yr < 0)
				date_buf->yr += 100;
			if ((date_buf->yr)%100 < 10)
				j += sprintf((char*)sbuffer + j, "0%d", (date_buf->yr)%100);
			else
				j += sprintf((char*)sbuffer + j, "%d", (date_buf->yr)%100);
			break;
			
		default:
		/*if (date_buf->mon < 10)
		j = sprintf((char*)sbuffer, "0%d/", date_buf->mon);
			else*/
			j = sprintf((char*)sbuffer, "%d/", date_buf->mon);
			
			if (date_buf->day < 10)
				j += sprintf((char*)sbuffer + j, "0%d/", date_buf->day);
			else
				j += sprintf((char*)sbuffer + j, "%d/", date_buf->day);
			
			if (date_buf->yr < 0)
				date_buf->yr += 100;
			if ((date_buf->yr)%100 < 10)
				j += sprintf((char*)sbuffer + j, "0%d", (date_buf->yr)%100);
			else
				j += sprintf((char*)sbuffer + j, "%d", (date_buf->yr)%100);
			break;
		}		
		ListInsertItem(LIST_VOXMEMO_LIST_DATE, i, sbuffer);
		qfree(date_buf);
		
		if (DataGetField(VoxMemo_dbid, VoxMemo_rec_id, F_INFO, &buffer, &byte_read) != TRUE)
			return FALSE;
		ListInsertItem(LIST_VOXMEMO_LIST_INFO, i, buffer);
		qfree(buffer);
		
		if (DataCloseRecord(VoxMemo_dbid, VoxMemo_rec_id) != TRUE)
			return FALSE;
		
		update = TRUE;
	}
	
	if (update == TRUE)
	{
		VoxMemoListSetScrollbar();
		return TRUE;
	}
	
	return TRUE;
}

/*****************************************************************
* Function:	VoxMemoPrepareFindText
* Purpose: 	This function is called to prepare the find text to 
be displayed in Global Find
* Scope:		application/internal
* Input:		dbid
rec_id
prepare_string
* Output:		None
* Return:		None
* Comment: 	None
*****************************************************************/
BOOLEAN VoxMemoPrepareFindText(DatabaseID dbid, RecordID rec_id, UWORD rec_num, BYTE *buffer, BYTE *sbuffer)
{
	USHORT		j;
	UWORD		byte_read;
	VOX_DATE	*date_buf;
	CountrySettings	country;
	
	/* Format and print various data: */
	if (rec_num < 10)
		j  = sprintf((char*)sbuffer,     "0%d: ", rec_num);
	else
		j  = sprintf((char*)sbuffer,     "%d: ", rec_num);
	
	if (DataGetField(dbid, rec_id, F_TIME_DATE, (BYTE**)&date_buf, &byte_read) != TRUE)
		return FALSE;
	
	SySetupGetCountrySettings(&country);
	if (country.time_fmt ==  SYSETUP_12HR_DISPLAY)
	{
		if (date_buf->hr == 0)
			j += sprintf((char*)sbuffer + j, "12:");
		else if(date_buf->hr < 13)
			j += sprintf((char*)sbuffer + j, "%d:", date_buf->hr);
		else
			j += sprintf((char*)sbuffer + j, "%d:", date_buf->hr-12);
		
		if (date_buf->min < 10)
			j += sprintf((char*)sbuffer + j, "0%d ", date_buf->min);
		else
			j += sprintf((char*)sbuffer + j, "%d", date_buf->min);
		
		if(date_buf->hr < 12)
			j += sprintf((char*)sbuffer + j, VOX_CHARA1);
		else
			j += sprintf((char*)sbuffer + j, VOX_CHARP2);
		
	}
	else
	{
		if (date_buf->hr < 10)
			j += sprintf((char*)sbuffer + j, "0%d:", date_buf->hr);
		else
			j += sprintf((char*)sbuffer + j, "%d:", date_buf->hr);
		
		if (date_buf->min < 10)
			j += sprintf((char*)sbuffer + j, "0%d ", date_buf->min);
		else
			j += sprintf((char*)sbuffer + j, "%d ", date_buf->min);
	}
	
	switch(country.date_fmt)
	{
	case SYSETUP_YMD:
		if (date_buf->yr < 0)
			date_buf->yr += 100;
		if ((date_buf->yr)%100 < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", (date_buf->yr)%100);
		else
			j += sprintf((char*)sbuffer + j, "%d/", (date_buf->yr)%100);
			/*if (date_buf->mon < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date_buf->mon);
		else*/
		j += sprintf((char*)sbuffer + j, "%d/", date_buf->mon);
		
		if (date_buf->day < 10)
			j += sprintf((char*)sbuffer + j, "0%d", date_buf->day);
		else
			j += sprintf((char*)sbuffer + j, "%d", date_buf->day);
		break;
		
	case SYSETUP_DMY:
		if (date_buf->day < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date_buf->day);
		else
			j += sprintf((char*)sbuffer + j, "%d/", date_buf->day);
			/*if (date_buf->mon < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date_buf->mon);
		else*/
		j += sprintf((char*)sbuffer + j, "%d/", date_buf->mon);
		
		if (date_buf->yr < 0)
			date_buf->yr += 100;
		if ((date_buf->yr)%100 < 10)
			j += sprintf((char*)sbuffer + j, "0%d", (date_buf->yr)%100);
		else
			j += sprintf((char*)sbuffer + j, "%d", (date_buf->yr)%100);
		break;
		
	default:
	/*if (date_buf->mon < 10)
				j += sprintf((char*)sbuffer + j, "0%d/", date_buf->mon);
		else*/
		j += sprintf((char*)sbuffer + j, "%d/", date_buf->mon);
		
		if (date_buf->day < 10)
			j += sprintf((char*)sbuffer + j, "0%d/", date_buf->day);
		else
			j += sprintf((char*)sbuffer + j, "%d/", date_buf->day);
		
		if (date_buf->yr < 0)
			date_buf->yr += 100;
		if ((date_buf->yr)%100 < 10)
			j += sprintf((char*)sbuffer + j, "0%d", (date_buf->yr)%100);
		else
			j += sprintf((char*)sbuffer + j, "%d", (date_buf->yr)%100);
		break;
	}		
	
	qfree(date_buf);
	j += sprintf((char*)sbuffer + j, " %s", buffer);
	
	
	return TRUE;
}


/*****************************************************************
* Function:	VoxMemoRecClose
* Purpose: 	This function is used to handle the voxmemo actions 
* Scope:		application
* Input:		None
* 
* Output:		None
* Return:		TRUE if success
*				FALSE if the database not found
* Comment: 	This function should be called in the StopApplication
*****************************************************************/
BOOLEAN VoxMemoRecClose(void)
{
	BYTE	*text_ptr = NULL;
	Err		err;
	
	TextboxGetTextPointer(TEXTBOX_VOXMEMO_INFO_INFO, &text_ptr);
	
	err = DataWriteField(VoxMemo_dbid,VoxMemo_rec_id, F_INFO, (strlen(text_ptr)+1), text_ptr);
	if (err != 1)
	{
#ifdef DEBUG
		printf("\n DWF in VoxMemoRecClose -->> err = %d", err);
#endif		
		EvtAppendEvt(SND_MGR_EVT, LOW_MEM, 0, 0, 0);
		return FALSE;
	}
	
	/* - Close Data Record */
	err = DataCloseRecord(VoxMemo_dbid, VoxMemo_rec_id);
	if (err != 1)
	{
#ifdef DEBUG
		printf("\n DCR in VoxMemoRecClose -->> err = %d", err);
#endif		
		return FALSE;
	}
	
	return TRUE;
}

/*****************************************************************
* Function:	VoxMemoRecReset
* Purpose: 	This function is used to open a new record and 
*				initialize all the item displayed on the screen
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		TRUE if success
*				FALSE if the database is not found
* Comment: 	None
*****************************************************************/
void VoxMemoRecReset(void)
{
	BYTE		sbuffer[15];
	BYTE		tbuffer[10];
	
	strcpy(tbuffer, "0:00");	
	/* display time recorded */
	VoxMemoTime = 0;
	ScrollbarSetScrollbar(SCROLLBAR_VOXMEMO_REC, 0, 14, 0, 1, 15);
	
	StringSetText(STRING_VOXMEMO_REC_RECTIME, tbuffer);
	
	/* display time remaining */
	VoxMemoTime2 = BLOCK_SIZE * (MemoryTotalFree() - FREE_MEM_BLOCK_LIMIT) / BYTEPS - 65;
	VoxMemoNum2Time(VoxMemoTime2, sbuffer, FALSE);
	StringSetText(STRING_VOXMEMO_REC_REMTIME, sbuffer);
	
	FormSetControlGroupSelection(FORM_VOXMEMO_REC, CONTROL_VOXMEMO_REC_REC);
	
	return;
}



/*****************************************************************
* Function:	VoxMemoRenameTitle
* Purpose: 	This function is used to handle the voxmemo rename 
title actions 
* Scope:		application
* Input:		None
* 
* Output:		None
* Return:		TRUE if success
*				FALSE if the database not found
* Comment: 	None
*****************************************************************/
BOOLEAN VoxMemoRenameTitle(void)
{
	BYTE	*textbox_text, *string_text;
	
	StringGetText(STRING_VOXMEMO_PLAY_INFO, &string_text);
	TextboxGetTextPointer(TEXTBOX_VOXMEMO_DIALOG_EDTITLE, &textbox_text);
	if (!strcmp(string_text, textbox_text))
		return TRUE;
	
	StringSetText(STRING_VOXMEMO_PLAY_INFO, textbox_text);
	if (DataWriteField(VoxMemo_dbid,VoxMemo_rec_id, F_INFO, (strlen(textbox_text)+1), textbox_text) != TRUE)
	{
		EvtAppendEvt(SND_MGR_EVT, LOW_MEM, 0, 0, 0);
		return FALSE;
	}
	/* - Close Data Record */
	
	return TRUE;
}



/*****************************************************************
* Function:	VoxMemoCheckRecordWithSound
* Purpose: 	This function is used to check the record with sound 
or not
* Scope:		application
* Input:		dbid						DatabaseID
rec_id						Record ID
field_num					Field number
* Output:		None
* Return:		TRUE if the record with sound
*				FALSE if otherwise
* Comment: 	None
*****************************************************************/
BOOLEAN VoxMemoCheckRecordWithSound(DatabaseID dbid, RecordID rec_id, USHORT field_num)
{
	UWORD field_size;
	
	if (DataFieldSize(dbid, rec_id, field_num, &field_size) != TRUE)
		return FALSE;
	
	if (field_size > BYTEPS)
		return TRUE;
	else
		return FALSE;
}
