#define	STRICT
#include	<windows.h>
#include	<windowsx.h>
#include	<commctrl.h>
#include	<tchar.h>
#include	"kctrl.h"
#include	"controls.h"
#include	"resource.h"
#include	"appmain.h"
#include	"appsub.h"
#include	"diatrain.h"

TCHAR		MessageBuf[ 512 ] ;

BOOL	FileOpenDlg( HINSTANCE hInst, HWND hWnd, LPTSTR buf, DWORD size ) ;
#ifdef	_WIN32_WCE
BOOL	AlarmDialogExec( HINSTANCE hInst, HWND hWnd, LPWORD pMinute, PEG_USER_NOTIFICATION *pPUN, LPCSTR pArrival ) ;
#endif	/* _WIN32_WCE */
BOOL	SetupDialogExec( HINSTANCE hInst, HWND hWnd, LPTSTR path, LPDWORD val ) ;
extern	BOOL	g_bNarrow ;

WORD
get_now()
{
	SYSTEMTIME	st ;

	GetLocalTime( &st ) ;
	return st.wHour * 60 + st.wMinute ;
}

/*-------------------------------------------------------------------------*
 * DiaApp
 *-------------------------------------------------------------------------*/
DiaApp::DiaApp()
{
	m_pMainWnd = 0 ;
	m_pListArea = new ListArea() ;
	m_pHeaderArea = new HeaderArea() ;
	m_pDateArea = new DateArea() ;
	m_path[0] = 0 ;
	m_fNeedData = TRUE ;
	m_pTtable = new TimeTableInfo() ;
#ifdef	_WIN32_WCE
	_tcscpy( m_sWave, TEXT("alarm1.wav") ) ;
	memset( &m_Notify, 0, sizeof m_Notify ) ;
	m_Notify.ActionFlags = PUN_DIALOG ;
	m_Notify.pwszSound = m_sWave ;
#endif	/* _WIN32_WCE */
	m_sEditor[0] = 0 ;
	m_dInterval = 10 ;
}

DiaApp::~DiaApp()
{
	delete m_pTtable ;
	delete m_pDateArea ;
	delete m_pHeaderArea ;
	delete m_pListArea ;
}

BOOL
DiaApp::Create( HINSTANCE hInstance )
{
	m_hInst = hInstance ;

	if ( !BigListRegisterClass( m_hInst ) ) {
		return FALSE ;
	}
	if ( !LabelRegisterClass( m_hInst ) ) {
		return FALSE ;
	}
	if ( !MainWindow::RegisterClass( m_hInst ) ) {
		return FALSE ;
	}

	/* レジストリの設定を読み込む */
	GetReg() ;

#ifdef	_WIN32_WCE
	m_hAccl = LoadAccelerators( m_hInst,
								MAKEINTRESOURCE(IDR_ACCELERATOR1) ) ;
#else	/* _WIN32_WCE */
	m_hAccl = LoadAccelerators( GetModuleHandle(NULL),
								MAKEINTRESOURCE(IDR_ACCELERATOR1) ) ;

#endif	/* _WIN32_WCE */

	m_pMainWnd = new MainWindow( this ) ;
	if ( !m_pMainWnd ) {
		return FALSE ;
	}
	if ( !m_pMainWnd->Create() ) {
		return FALSE ;
	}
	/* データを初期化する */
	m_fNeedData = !FileTableInfo::read_nextfmt( m_path ) ;
	m_fTitle = TRUE ;
	m_pListArea->SetProc( FileTableInfo::list_proc ) ;
	if ( m_fNeedData ) {
		/* ファイルの読み込みに失敗したらファイルオープンダイアログを出す */
		PostMessage( m_pMainWnd->get_hwnd(), WM_COMMAND, IDM_OPEN, 0 ) ;
	}
	/* 画面を前面にする */
	SetForegroundWindow( m_pMainWnd->get_hwnd() ) ;
	return TRUE ;
}

int
DiaApp::Run()
{
	MSG		msg ;

	while ( GetMessage( &msg, NULL, 0, 0 ) ) {
		if ( !TranslateAccelerator( m_pMainWnd->get_hwnd(), m_hAccl, &msg ) ) {
			TranslateMessage( &msg ) ;
		}
		DispatchMessage( &msg ) ;
	}
	return msg.wParam ;
}

/*
 * テーブルファイルを読み込む
 */
BOOL
DiaApp::OpenTableFile( HWND hWnd, BOOL fReread, LPBOOL pfQuit )
{
	TCHAR	path[ MAX_PATH ] ;

	_tcscpy( path, m_path ) ;
	while ( 1 ) {
		if ( !fReread && !FileOpenDlg( m_hInst, hWnd, path, sizeof path ) ) {
			*pfQuit = m_fNeedData ;
			return FALSE ;
		}
		fReread = FALSE ;
		m_fNeedData = !FileTableInfo::read_nextfmt( path ) ;
		if ( !m_fNeedData ) {
			_tcscpy( m_path, path ) ;
			return TRUE ;
		}
	}
}

/*
 * NextTrain形式のデータを読み込む
 */
BOOL
DiaApp::LoadFromNextTrain( LPCTSTR fn )
{
	CurList.clear() ;
	if ( !m_pTtable->read( fn ) ) {
		return FALSE ;
	}
	CurHour = HOUR_NOW ;
	m_pTtable->pickup( &CurList, get_now(), CurHour ) ;
	return TRUE ;
}

/*
 * 一覧の更新を行う
 */
void
DiaApp::SetupList() const
{
	m_pListArea->SetProc( list_proc ) ;
}

/*
 * 時刻表一覧の内容を更新し表示も更新する
 */
BOOL
DiaApp::Refresh()
{
	WORD		now ;
	DWORD		ret, index ;

	/* タイマーの処理を開始する */
	SetTimer( m_pMainWnd->get_hwnd(), TRUE, TRUE ) ;
	now = get_now() ;
	if ( CurBase == now ) {
		return TRUE ;
	}
	CurBase = now ;
	get_date()->Refresh() ;
	if ( m_fTitle || CurHour != HOUR_NOW ) {
		/* 現在表示ではない場合 */
		return FALSE ;
	}
	if ( CurList.count() ) {
		/* リストに項目がある場合 */
		ret = m_pTtable->delete_until_now( &CurList, CurBase ) ;
		if ( ret ) {
			index = m_pListArea->GetCurSel() ;
			m_pListArea->SetProc( list_proc ) ;
			index = index >= ret ? index - ret : 0 ;
			m_pListArea->SetCurSel( index ) ;
		}
	} else {
		/* リストが空の場合 */
		m_pTtable->pickup( &CurList, CurBase, CurHour ) ;
	}
	::InvalidateRect( m_pListArea->get_hwnd(), NULL, TRUE ) ;
	return TRUE ;
}

/*
 * 現在時刻の一覧に戻る
 */
BOOL
DiaApp::Home()
{
	WORD	now ;

	/* タイマーの処理を開始する */
	SetTimer( m_pMainWnd->get_hwnd(), TRUE, TRUE ) ;
	/* 現在時刻表示にする */
	CurHour = HOUR_NOW ;
	now = get_now() ;
	m_pTtable->pickup( &CurList, now, CurHour ) ;
	if ( CurBase != now ) {
		/* 現在時刻を表示する */
		CurBase = now ;
		get_date()->Refresh() ;
	}
	return TRUE ;
}

/*
 * 前の一覧に移動する
 */
BOOL
DiaApp::Prev()
{
	WORD			now ;
	BYTE			hour, max ;
	BOOL			fCheck = FALSE ;

	if ( CurHour == HOUR_ALL ) {
		return FALSE ;
	}
	now = get_now() ;
	hour = m_pTtable->get_hour( (BYTE) (now / 60) ) ;
	max = m_pTtable->get_maxhour() ;
	if ( CurHour == HOUR_NOW ) {
		CurHour = hour ;
	} else {
		CurHour = CurHour ? CurHour - 1 : max ;
		fCheck = TRUE ;
	}
	for ( int i = 0 ; i < 25 ; i ++ ) {
		if ( fCheck && CurHour == hour ) {
			break ;
		}
		fCheck = TRUE ;
		if ( m_pTtable->pickup( &CurList, now, CurHour ) ) {
			return TRUE ;
		}
		CurHour = CurHour ? CurHour - 1 : max ;
	}
	CurHour = HOUR_NOW ;
	m_pTtable->pickup( &CurList, now, CurHour ) ;
	return TRUE ;
}

/*
 * 次の一覧に移動する
 */
BOOL
DiaApp::Next()
{
	WORD			now ;
	BYTE			max, hour ;

	if ( CurHour == HOUR_ALL ) {
		return FALSE ;
	}
	now = get_now() ;
	hour = m_pTtable->get_hour( (BYTE) (now / 60) ) ;
	max = m_pTtable->get_maxhour() ;
	if ( CurHour == hour ) {
		CurHour = HOUR_NOW ;
		m_pTtable->pickup( &CurList, now, CurHour ) ;
		return TRUE ;
	} else if ( CurHour == HOUR_NOW ) {
		CurHour = hour ;
	}
	for ( int i = 0 ; i < 25 ; i ++ ) {
		CurHour = CurHour + 1 <= max ? CurHour + 1 : 0 ;
		if ( m_pTtable->pickup( &CurList, now, CurHour ) ) {
			return TRUE ;
		} else if ( CurHour == hour ) {
			break ;
		}
	}
	CurHour = HOUR_NOW ;
	m_pTtable->pickup( &CurList, now, CurHour ) ;
	return TRUE ;
}

/*
 * タイトル表示から時刻表に移る
 */
BOOL
DiaApp::EnterContent()
{
	TCHAR	path[ MAX_PATH ], *ptr ;

	/* 時刻表ファイルのファイル名を作成する */
	m_dTitleIndex = m_pListArea->GetCurSel() ;
	_tcscpy( path, get_path() ) ;
	if ( ptr = _tcsrchr( path, TEXT('\\') ) ) {
		ptr ++ ;
	} else {
		ptr = path ;
	}
	_tcscpy( ptr, FileTableInfo::get_path( m_dTitleIndex ) ) ;
	/* 時刻表ファイルを読み込む */
	if ( !LoadFromNextTrain( path ) ) {
		m_fTitle = TRUE ;
		return FALSE ;
	}
	/* ヘッダー文字列を設定する */
	sjis2unicode( (LPBYTE) FileTableInfo::get_detail( m_dTitleIndex ), path, sizeof path ) ;
	m_pHeaderArea->SetText( path ) ;
	/* 一覧の設定を行う */
	SetupList() ;
	/* キーボードマスクを設定する */
	m_pListArea->SetKeyMask( FALSE ) ;
	m_fTitle = FALSE ;
	return TRUE ;
}

/*
 * 時刻表からタイトル表示に移る
 */
BOOL
DiaApp::EnterTitle()
{
	/* ヘッダー文字列を設定する */
	m_pHeaderArea->SetText( TEXT("") ) ;
	/* リスト用プロシージャを設定する */
	m_pListArea->SetProc( FileTableInfo::list_proc ) ;
	/* 選択行を設定する */
	m_pListArea->SetCurSel( m_dTitleIndex ) ;
	/* キーボードマスクを設定する */
	m_pListArea->SetKeyMask( TRUE ) ;
	m_fTitle = TRUE ;
	return TRUE ;
}

/*
 * アラームの設定を行う
 */
BOOL
DiaApp::SetAlarm()
{
	MinInfo	*cur ;
	int		index ;
	WORD	dept_time = 0 ;

	index = m_pListArea->GetCurSel() ;
	/* 現在選択中の分情報を得る */
	cur = GetMinInfo( index ) ;
	if ( cur == NULL ) {
		return FALSE ;
	}
	/* 出発時刻を求める */
	dept_time = cur->get_hour() * 60 + cur->get_min() ;
#ifdef	_WIN32_WCE
	WORD			wMinute, diff ;
	SYSTEMTIME		time ;
	TCHAR			buf[ 256 ] ;
	CHAR			sjis[ 256 ] ;

	wMinute = dept_time ;
	cur->make_str_for_message( sjis ) ;
	if ( !AlarmDialogExec( m_hInst, m_pMainWnd->get_hwnd(), &wMinute, &m_Notify, sjis ) ) {
		return FALSE ;
	}
	diff = dept_time - wMinute ;
	GetLocalTime( &time ) ;
	wMinute %= 24 * 60 ;
	if ( wMinute < time.wHour * 60 + time.wMinute ) {
		time.wDay ++ ;
	}
	time.wHour   = wMinute / 60 ;
	time.wMinute = wMinute % 60 ;
	time.wSecond = 0 ;
	time.wMilliseconds = 0 ;

	m_Notify.ActionFlags |= PUN_DIALOG|PUN_REPEAT ;
	m_Notify.pwszDialogTitle = szTitleName ;
	if ( GetKLocale() == LOCALE_JAPAN ) {
		char	sjis[ 256 ], *ptr = sjis ;

		strcpy( ptr, FileTableInfo::get_detail( m_dTitleIndex ) ) ;
		ptr += strlen( ptr ) ;
		*ptr++ = '\r' ;
		*ptr++ = '\n' ;
		cur->make_str_on_alarm( ptr ) ;
		ptr += strlen( ptr ) ;
		strcpy( ptr, "\r\n\r\n上記の予定" ) ;
		ptr += strlen( ptr ) ;
		if ( diff ) {
			strcpy( ptr, "の " ) ;
			ptr += 3 ;
			if ( diff >= 60 ) {
				*ptr++ = (diff / 60) + '0' ;
				strcpy( ptr, "時間" ), ptr += 4 ;
				diff %= 60 ;
			}
			if ( diff ) {
				*ptr++ = (diff / 10) + '0' ;
				*ptr++ = (diff % 10) + '0' ;
				strcpy( ptr, "分" ) ;
				ptr += 2 ;
			}
			strcpy( ptr, "前です" ) ;
		} else {
			strcpy( ptr, "時刻です" ) ;
			ptr += strlen( ptr ) ;
		}
		sjis2unicode( (LPBYTE) sjis, buf, sizeof buf ) ;
	} else {
		wsprintf( buf, TEXT("It is [%d] minutes before [%02d:%02d] departure."),
				  diff, dept_time / 60, dept_time % 60 ) ;
	}
	m_Notify.pwszDialogText = buf ;
	m_Notify.dwReserved = 0 ;
	PegSetUserNotification( 0, AppName, &time,
							&m_Notify ) ;
#endif	/* _WIN32_WCE */
	return TRUE ;
}

#ifdef	_WIN32_WCE
/*
 * アラームから起動された場合の処理
 */
BOOL
DiaApp::HandleAlarm()
{
	HWND	hWnd ;

	PegHandleAppNotifications( AppName ) ;
	hWnd = FindWindow( szTitleName, NULL ) ;
	if ( hWnd == NULL ) {
		return FALSE ;
	}
	SetForegroundWindow( hWnd ) ;
	return TRUE ;
}
#endif	/* _WIN32_WCE */

/*
 * セットアップダイアログを出して各種の設定を行う
 */
BOOL
DiaApp::Setup( HWND hWnd )
{
	return SetupDialogExec( m_hInst, hWnd, m_sEditor, &m_dInterval ) ;
}

/*
 * エディターを起動する 
 */
BOOL
DiaApp::ExecuteEditor( BOOL fTable )
{
	BOOL		ret ;
	TCHAR		cmdline[ MAX_PATH ], *ptr ;

	if ( !m_sEditor[0] ) {
		/* エディターが設定されていない場合 */
		return FALSE ;
	}
	ptr = cmdline ;
	if ( fTable ) {
		if ( m_fTitle ) {
			m_dTitleIndex = m_pListArea->GetCurSel() ;
		}
		_tcscpy( ptr, get_path() ) ;
		if ( ptr = _tcsrchr( ptr, TEXT('\\') ) ) {
			ptr ++ ;
		} else {
			ptr = cmdline ;
		}
		_tcscpy( ptr, FileTableInfo::get_path( m_dTitleIndex ) ) ;
	} else {
		_tcscpy( ptr, m_path ) ;
	}
	if ( GetFileAttributes( cmdline ) == 0xFFFFFFFF ) {
		/* 指定ファイルが見つからない場合 */
		return FALSE ;
	}
	PROCESS_INFORMATION	pi ;
	memset( &pi, 0, sizeof pi ) ;
#ifdef	_WIN32_WCE
	ret = CreateProcess( m_sEditor, cmdline,
						 NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi ) ;
#else	/* _WIN32_WCE */
	STARTUPINFO	si ;
	memset( &si, 0, sizeof si ) ;
	si.cb = sizeof si ;
	ret = CreateProcess( m_sEditor, (LPTSTR) cmdline,
						 NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ;
#endif	/* _WIN32_WCE */
	if ( !ret ) {
		return FALSE ;
	}
	CloseHandle( pi.hProcess ) ;
	CloseHandle( pi.hThread ) ;
	return TRUE ;
}

/*
 * タイマーの処理を開始する
 */
void
DiaApp::SetTimer( HWND hWnd, BOOL fKill, BOOL fSet ) const
{
	if ( fKill ^ fSet ) {
		if ( fKill ) {
			::KillTimer( hWnd, IDC_TIMER_REFRESH ) ;
		}
		if ( fSet ) {
			::SetTimer( hWnd, IDC_TIMER_REFRESH, m_dInterval * 1000, NULL ) ;
		}
	}
}

#define		REG_SUBKEY		TEXT("Software\\Gawaro\\DIATRAIN")
#define		VAR_FILENAME	TEXT("Filename")
#define		VAR_ALARMACT	TEXT("AlarmAct")
#define		VAR_ALARMWAV	TEXT("AlarmWav")
#define		VAR_EDITOR		TEXT("Editor")
#define		VAR_INTERVAL	TEXT("Interval")

/*
 * レジストリからの情報取得
 */
BOOL
DiaApp::GetReg()
{
	HKEY	hk ;
	LONG	lret ;
	LPTSTR	name ;
	LPBYTE	lpData ;
	DWORD	dwType, cbData, dwData ;

	/* レジストリキーをオープンする */
	lret = RegOpenKeyEx( HKEY_CURRENT_USER,
						 REG_SUBKEY,
						 0,
						 KEY_QUERY_VALUE,
						 &hk ) ;
	if ( lret != ERROR_SUCCESS ) {
		return FALSE ;
	}
	/* データファイル名 */
	name = VAR_FILENAME ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_path ;
	cbData = sizeof m_path ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
#ifdef	_WIN32_WCE
	/* アラームフラグ */
	name = VAR_ALARMACT ;
	dwType = REG_DWORD ;
	lpData = (LPBYTE) &dwData ;
	cbData = sizeof (DWORD) ;
	if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
		m_Notify.ActionFlags = dwData ;
	}
	/* WAVファイル名 */
	name = VAR_ALARMWAV ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_sWave ;
	cbData = sizeof m_sWave ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
#endif	/* _WIN32_WCE */
	/* エディターパス名 */
	name = VAR_EDITOR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_sEditor ;
	cbData = sizeof m_sEditor ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	/* Timer間隔 */
	name = VAR_INTERVAL ;
	dwType = REG_DWORD ;
	lpData = (LPBYTE) &dwData ;
	cbData = sizeof (DWORD) ;
	if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
		m_dInterval = dwData ;
	}
	/* レジストリをクローズする */
	RegCloseKey( hk ) ;
	return TRUE ;
}

/*
 * レジストリへの情報設定
 */
BOOL
DiaApp::SetReg() const
{
	HKEY	hk ;
	LONG	lret ;
	LPTSTR	name ;
	LPBYTE	lpData ;
	DWORD	ret, dwType, cbData, dwData ;

	/* レジストリキーを作成する */
	lret = RegCreateKeyEx( HKEY_CURRENT_USER, REG_SUBKEY, 0, TEXT(""), 0,
#ifdef	_WIN32_WCE
						   0,
#else	/* _WIN32_WCE */
						   KEY_ALL_ACCESS,
#endif	/* _WIN32_WCE */
						   NULL, &hk, &ret ) ;
	if ( lret != ERROR_SUCCESS ) {
		return FALSE ;
	}
	/* データファイル名 */
	name = VAR_FILENAME ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_path ;
	cbData = (_tcslen(m_path) + 1) * sizeof (*m_path) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
#ifdef	_WIN32_WCE
	/* アラームフラグ */
	name = VAR_ALARMACT ;
	dwType = REG_DWORD ;
	dwData = m_Notify.ActionFlags ;
	lpData = (LPBYTE) &dwData ;
	cbData = sizeof (DWORD) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* WAVファイル名 */
	name = VAR_ALARMWAV ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_sWave ;
	cbData = (_tcslen(m_sWave) + 1) * sizeof (*m_sWave) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
#endif	/* _WIN32_WCE */
	/* エディターパス名 */
	name = VAR_EDITOR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_sEditor ;
	cbData = (_tcslen(m_sEditor) + 1) * sizeof (*m_sEditor) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* Timer間隔 */
	name = VAR_INTERVAL ;
	dwType = REG_DWORD ;
	dwData = m_dInterval ;
	lpData = (LPBYTE) &dwData ;
	cbData = sizeof (DWORD) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* レジストリをクローズする */
	RegCloseKey( hk ) ;
	return TRUE ;
}

/*
 * レジストリ情報削除
 */
void
DiaApp::DeleteReg() const
{
	RegDeleteKey( HKEY_CURRENT_USER, REG_SUBKEY ) ;
}

BYTE	DiaApp::CurHour = 0 ;	/* 表示中の時間 */
List	DiaApp::CurList ;		/* 表示中の分リスト */
WORD	DiaApp::CurBase = 0 ;	/* 基準となる現在時刻 */

int
DiaApp::list_proc( int index, const BYTE **ptr, int *len )
{
	WORD			now ;
	LPSTR			text ;
	char			buf[ 10 ] ;
	static	BYTE	tmpbuf[ 256 ] ;

	now = get_now() ;
	if ( index < 0 ) {
		return CurList.count() ;
	} else if ( index >= (int) CurList.count() ) {
		return -1 ;
	}
	Iterator	l( CurList, index ) ;
	MinInfo		*cur = (MinInfo*) l() ;
	if ( g_bNarrow ) {
#if 1
		text = "" ;
#else
		text = "     " ;
		if ( CurHour == HOUR_NOW ) {
			switch ( index ) {
			case 0:		text = "今度 " ;	break ;
			case 1:		text = " 次  " ;	break ;
			case 2:		text = "     " ;	break ;
			}
		} else if ( CurHour != HOUR_ALL ) {
			if ( !index ) {
				buf[0] = (char) (CurHour / 10) + '0' ;
				buf[1] = (char) (CurHour % 10) + '0' ;
				strcpy( &buf[2], "時 " ) ;
				text = buf ;
			}
		}
#endif
	} else {
		text = "        " ;
		if ( CurHour == HOUR_NOW ) {
			switch ( index ) {
			case 0:		text = "こんど  " ;	break ;
			case 1:		text = "つ  ぎ  " ;	break ;
			case 2:		text = "その次  " ;	break ;
			}
		} else if ( CurHour != HOUR_ALL ) {
			if ( !index ) {
				buf[0] = (char) (CurHour / 10) + '0' ;
				buf[1] = (char) (CurHour % 10) + '0' ;
				strcpy( &buf[2], "時台  " ) ;
				text = buf ;
			}
		}
	}
	strcpy( (LPSTR) tmpbuf, text ) ;
	text = (LPSTR) &tmpbuf[ strlen( (LPSTR) tmpbuf ) ] ;
	if ( CurHour == HOUR_NOW ) {
		cur->make_str_on_now( text, now ) ;
	} else {
		cur->make_str_normal( text ) ;
	}
	*ptr = tmpbuf ;
	*len = strlen( (LPSTR) *ptr ) ;
	return 0 ;
}

MinInfo*
DiaApp::GetMinInfo( int index )
{
	Iterator	l( CurList, index ) ;
	return (MinInfo*) l() ;
}
