#define	STRICT
#include	<windows.h>
#include	<windowsx.h>
#include	<commctrl.h>
#include	<tchar.h>
#include	"tools.h"
#include	"kctrl.h"
#include	"kedit.h"
#include	"resource.h"
#include	"appmain.h"
#include	"dialog.h"

TCHAR	MessageBuf[ 512 ] ;
TCHAR	g_szPathname[ MAX_PATH ] = TEXT("") ;
TCHAR	g_szInitDir[ MAX_PATH ] = TEXT("\\") ;

#define		GawaroBaseKey	TEXT("Software\\Gawaro")
#define		VAR_FEPNAME		TEXT("FepName")
#define		VAR_FEPPROGRAM	TEXT("FepProgram")
#define		VAR_TTFONT0		TEXT("TTFont0")
#define		VAR_FONTHEIGHT0	TEXT("FontHeight0")
#define		VAR_FONTWIDTH0	TEXT("FontWidth0")
#define		VAR_INITDIR		TEXT("InitDir")

TCHAR	g_szFontName0[ MAX_PATH ] = TEXT("CEFONT") ;
DWORD	g_dwFontW0 = 6 ;
DWORD	g_dwFontH0 = 12 ;

class MainWindow : public Window {
private:
	MainApp		*m_pApp ;			/* アプリケーションへのポインタ */
	HICON		m_hIcon ;			/* アプリアイコンのハンドル */
	BOOL		m_fUninstall ;		/* アンインストールフラグ */
	HWND		m_hWndCB ;

public:
	MainWindow( MainApp *app ) ;

	BOOL	Create() ;
	DWORD	CreateCommandBar() ;

	void	WMCreate( HWND hWnd ) ;

	void	WMDestroy() ;
	LRESULT	WMCommand( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp ) ;
	void	WMNotify( HWND hWnd, int idCtrl, LPNMHDR pnmh ) ;
	BOOL	WMClose() ;

	void	WMSetFocus() ;

	BOOL	CheckClose( HWND hWnd ) ;
	BOOL	SaveToFile( HWND hWnd, BOOL fSaveAs = FALSE ) ;
	void	SetTitle() const ;

	static	BOOL	RegisterClass( HINSTANCE hInst ) ;
	static	LPCTSTR	GetClassName() { return TEXT("MINIPAD") ; }
} ;

class MainApp ;

/*
 * 入力領域
 */
class EditArea {
private:
	HWND	m_hWnd ;		/* 対応するウィンドウハンドル */
	HFONT	m_hFont ;		/* フォントのハンドル */

public:
	EditArea() ;
	~EditArea() ;

	HWND	get_hwnd() const { return m_hWnd ; }
	HWND	Create( HINSTANCE hInst, HWND hWndParent, DWORD x, DWORD y, DWORD w, DWORD h, WORD id ) ;
	BOOL	Load( LPCTSTR fn ) ;
	BOOL	Save( LPCTSTR fn ) ;
	void	ClearAll() const ;
	inline void	Undo() const ;
	inline void	Cut() const ;
	inline void	Copy() const ;
	inline void	Paste() const ;
	inline void	SelectAll() const ;
	BOOL	GetModify() const ;
	void	SetModify( BOOL flag ) const ;

	void	SetFocus() const { ::SetFocus( m_hWnd ) ; }
} ;

/*-------------------------------------------------------------------------*
 * MainApp
 *-------------------------------------------------------------------------*/
MainApp::MainApp()
{
	m_pMainWnd = 0 ;
	m_pEditArea = 0 ;
}

MainApp::~MainApp()
{
}

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

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

#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 */

	GetReg() ;

	m_pMainWnd = new MainWindow( this ) ;
	m_pEditArea = new EditArea() ;
	if ( !m_pMainWnd || !m_pEditArea ) {
		return FALSE ;
	}
	if ( !m_pMainWnd->Create() ) {
		delete m_pMainWnd ;
		return FALSE ;
	}

	if ( g_szArgs && *g_szArgs ) {
		_tcscpy( g_szPathname, g_szArgs ) ;
		PostMessage( m_pMainWnd->get_hwnd(), WM_COMMAND, IDM_RELOAD, 0 ) ;
	}

	return TRUE ;
}

int
MainApp::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
MainApp::GetReg()
{
	HKEY	hk ;
	LONG	lret ;
	LPCTSTR	name ;
	LPBYTE	lpData ;
	TCHAR	sValue[ 256 ] ;
	DWORD	dwType, cbData, dwValue ;

	/* レジストリキーをオープンする */
	lret = RegOpenKeyEx( HKEY_CURRENT_USER, GawaroBaseKey, 0,
						 KEY_QUERY_VALUE, &hk ) ;
	if ( lret == ERROR_SUCCESS ) {
		/* FepName */
		name = VAR_FEPNAME ;
		dwType = REG_SZ ;
		lpData = (LPBYTE) sValue ;
		cbData = sizeof sValue ;
		if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
			_tcscpy( g_szFepName, sValue ) ;
		}
		/* FepProgram */
		name = VAR_FEPPROGRAM ;
		dwType = REG_SZ ;
		lpData = (LPBYTE) sValue ;
		cbData = sizeof sValue ;
		if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
			_tcscpy( g_szFepProgram, sValue ) ;
		}
		/* レジストリクローズ */
		RegCloseKey( hk ) ;
	}
	wsprintf( sValue, TEXT("%s\\%s"), GawaroBaseKey, szTitleName ) ;
	/* レジストリキーをオープンする */
	lret = RegOpenKeyEx( HKEY_CURRENT_USER, sValue, 0,
						 KEY_QUERY_VALUE, &hk ) ;
	if ( lret == ERROR_SUCCESS ) {
		/* TTFont0 */
		name = VAR_TTFONT0 ;
		dwType = REG_SZ ;
		lpData = (LPBYTE) sValue ;
		cbData = sizeof sValue ;
		if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
			_tcscpy( g_szFontName0, sValue ) ;
		}
		/* FontWidth0 */
		name = VAR_FONTWIDTH0 ;
		dwType = REG_DWORD ;
		lpData = (LPBYTE) &dwValue ;
		cbData = sizeof dwValue ;
		if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
			g_dwFontW0 = dwValue ;
		}
		/* FontHeight0 */
		name = VAR_FONTHEIGHT0 ;
		dwType = REG_DWORD ;
		lpData = (LPBYTE) &dwValue ;
		cbData = sizeof dwValue ;
		if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
			g_dwFontH0 = dwValue ;
		}
		/* InitDir */
		name = VAR_INITDIR ;
		dwType = REG_SZ ;
		lpData = (LPBYTE) sValue ;
		cbData = sizeof sValue ;
		if ( RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) == ERROR_SUCCESS ) {
			_tcscpy( g_szInitDir, sValue ) ;
		}
		/* レジストリクローズ */
		RegCloseKey( hk ) ;
	}
	return TRUE ;
}

void
MainApp::SetReg() const
{
	HKEY	hk ;
	LONG	lret ;
	LPTSTR	name ;
	LPBYTE	lpData ;
	TCHAR	sValue[ 256 ] ;
	DWORD	dwType, cbData, dwValue, ret ;

	/* キー名称を作成する */
	wsprintf( sValue, TEXT("%s\\%s"), GawaroBaseKey, szTitleName ) ;
	/* レジストリキーを作成する */
	lret = RegCreateKeyEx( HKEY_CURRENT_USER, sValue, 0, TEXT(""), 0,
#ifdef	_WIN32_WCE
						   0,
#else	/* _WIN32_WCE */
						   KEY_ALL_ACCESS,
#endif	/* _WIN32_WCE */
						   NULL, &hk, &ret ) ;
	if ( lret == ERROR_SUCCESS ) {
		/* TTFont0 */
		name = VAR_TTFONT0 ;
		dwType = REG_SZ ;
		lpData = (LPBYTE) g_szFontName0 ;
		cbData = (_tcslen(g_szFontName0) + 1) * sizeof (*g_szFontName0) ;
		RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
		/* FontWidth0 */
		name = VAR_FONTWIDTH0 ;
		dwType = REG_DWORD ;
		dwValue = g_dwFontW0 ;
		lpData = (LPBYTE) &dwValue ;
		cbData = sizeof dwValue ;
		RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
		/* FontHeight0 */
		name = VAR_FONTHEIGHT0 ;
		dwType = REG_DWORD ;
		dwValue = g_dwFontH0 ;
		lpData = (LPBYTE) &dwValue ;
		cbData = sizeof dwValue ;
		RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
		/* InitDir */
		name = VAR_INITDIR ;
		dwType = REG_SZ ;
		lpData = (LPBYTE) g_szInitDir ;
		cbData = (_tcslen(g_szInitDir) + 1) * sizeof (*g_szInitDir) ;
		RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
		/* レジストリクローズ */
		RegCloseKey( hk ) ;
	}
}

void
MainApp::DeleteReg() const
{
	TCHAR	sValue[ 256 ] ;

	wsprintf( sValue, TEXT("%s\\%s"), GawaroBaseKey, szTitleName ) ;
	RegDeleteKey( HKEY_CURRENT_USER, sValue ) ;
}

/*-------------------------------------------------------------------------*
 * MainWindow
 *-------------------------------------------------------------------------*/
MainWindow::MainWindow( MainApp *pApp )
{
	m_pApp = pApp ;
	m_hIcon = 0 ;
	m_fUninstall = FALSE ;
}

void
MainWindow::WMCreate( HWND hWnd )
{
	RECT		rect ;
	DWORD		height = 2, tw, h, th ;
	HINSTANCE	hInst = m_pApp->get_inst() ;

	m_hWnd = hWnd ;
	/* アイコンを作成しタスクバーに登録する */
	m_hIcon = (HICON) LoadImage( m_pApp->get_inst(), MAKEINTRESOURCE(IDI_APPICON),
								 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ) ;
	if ( m_hIcon ) {
		SendMessage( hWnd, WM_SETICON, FALSE, (LPARAM) m_hIcon ) ;
	}

	/* コマンドバーを追加する */
	height += CreateCommandBar() ;
	/* 表示領域を求める */
	GetClientRect( m_hWnd, &rect ) ;
	rect.right -= 2 ;
	rect.top += height ;
	rect.bottom -= 2 ;
#ifdef	_WIN32_WCE
	tw = GetSystemMetrics( SM_CXSCREEN ) ;
	th = GetSystemMetrics( SM_CYSCREEN ) ;
#else	/* _WIN32_WCE */
	tw = 480 ;
	th = 240 ;
#endif	/* _WIN32_WCE */
	h = height + 2 ;
	/* 一覧表示領域を作成する */
	m_pApp->get_edit()->Create( hInst, m_hWnd, 2, h, tw - 8, th - h - 35,
								IDC_EDIT ) ;
}

void
MainWindow::WMDestroy()
{
	if ( m_hIcon ) {
		::DeleteObject( m_hIcon ) ;
		m_hIcon = 0 ;
	}
	PostQuitMessage( 0 ) ;
}

LRESULT
MainWindow::WMCommand( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	BOOL	fDelete ;
	WORD	notifyCode = HIWORD(wParam), cmd = LOWORD(wParam) ;

	switch ( cmd ) {
	case IDM_EXIT:
		SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
		break ;
	case IDM_NEW:
		if ( !CheckClose( hWnd ) ) {
			break ;
		}
		m_pApp->get_edit()->ClearAll() ;
		*g_szPathname = 0 ;
		SetTitle() ;
		break ;
	case IDM_OPEN:
		if ( !CheckClose( hWnd ) ) {
			break ;
		}
		if ( !FileOpenDlg( m_pApp->get_inst(), hWnd, g_szPathname, sizeof g_szPathname / sizeof *g_szPathname ) ) {
			break ;
		}
		if ( !m_pApp->get_edit()->Load( g_szPathname ) ) {
			*g_szPathname = 0 ;
		}
		SetTitle() ;
		break ;
	case IDM_RELOAD:
		if ( !CheckClose( hWnd ) ) {
			break ;
		}
		if ( *g_szPathname ) {
			if ( !m_pApp->get_edit()->Load( g_szPathname ) ) {
				*g_szPathname = 0 ;
			}
		} else {
			m_pApp->get_edit()->ClearAll() ;
		}
		SetTitle() ;
		break ;
	case IDM_SAVE:
		SaveToFile( hWnd ) ;
		SetTitle() ;
		break ;
	case IDM_SAVEAS:
		SaveToFile( hWnd, TRUE ) ;
		SetTitle() ;
		break ;
	case IDM_UNDO:
		m_pApp->get_edit()->Undo() ;
		break ;
	case IDM_CUT:
		m_pApp->get_edit()->Cut() ;
		break ;
	case IDM_COPY:
		m_pApp->get_edit()->Copy() ;
		break ;
	case IDM_PASTE:
		m_pApp->get_edit()->Paste() ;
		break ;
	case IDM_SELECTALL:
		m_pApp->get_edit()->SelectAll() ;
		break ;
	case IDM_ABOUT:
		if ( AboutDialogExec( m_pApp->get_inst(), hWnd, &fDelete ) && fDelete ) {
			m_fUninstall = TRUE ;
			SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
		}
		break ;
	}
	return 0 ;
}

void
MainWindow::WMNotify( HWND hWnd, int idCtrl, LPNMHDR pnmh )
{
}

void
MainWindow::WMSetFocus()
{
	m_pApp->get_edit()->SetFocus() ;
}

BOOL
MainWindow::WMClose()
{
	if ( !CheckClose( m_hWnd ) ) {
		return TRUE ;
	}
	if ( m_fUninstall ) {
		m_pApp->DeleteReg() ;
	} else {
		m_pApp->SetReg() ;
	}
	return FALSE ;
}

BOOL
MainWindow::CheckClose( HWND hWnd )
{
	DWORD	ret ;
	TCHAR	buf[ MAX_PATH ] ;

	if ( m_pApp->get_edit()->GetModify() ) {
		wsprintf( buf, TEXT("Save changes To '%s'?"), g_szPathname ) ;
		ret = MessageBox( hWnd, buf, szTitleName, MB_YESNOCANCEL|MB_ICONQUESTION ) ;
		if ( ret == IDCANCEL ) {
			return FALSE ;
		} else if ( ret == IDYES ) {
			return SaveToFile( hWnd ) ;
		}
	}
	return TRUE ;
}

BOOL
MainWindow::SaveToFile( HWND hWnd, BOOL fSaveAs )
{
	DWORD	ret ;
	TCHAR	buf[ MAX_PATH ] ;

	if ( !*g_szPathname || fSaveAs ) {
		if ( !FileSaveDlg( m_pApp->get_inst(), hWnd, buf, sizeof buf / sizeof *buf ) ) {
			return FALSE ;
		}
		ret = GetFileAttributes( buf ) ;
		if ( ret != 0xFFFFFFFF ) {
			wsprintf( MessageBuf, TEXT("'%s':\r\nThis file already exists. Replace existing file?"), buf ) ;
			if ( MessageBox( hWnd, MessageBuf, TEXT("Save As"), MB_YESNO|MB_ICONQUESTION ) != IDYES ) {
				return FALSE ;
			}
		}
		_tcscpy( g_szPathname, buf ) ;
	}
	return m_pApp->get_edit()->Save( g_szPathname ) ;
}

void
MainWindow::SetTitle() const
{
	LPCTSTR	title = szTitleName ;

	if ( *g_szPathname ) {
		title = _tcsrchr( g_szPathname, TEXT('\\') ) ;
		if ( title ) {
			title ++ ;
		} else {
			title = g_szPathname ;
		}
	}
	SetWindowText( m_hWnd, title ) ;
}

BOOL
MainWindow::Create()
{
	HWND	hWnd = CreateWindowEx( 0,
						GetClassName(),
						szTitleName,
						WS_BORDER,
#ifdef	_WIN32_WCE
						0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
#else	/* _WIN32_WCE */
						0, 0, 480, 240,
#endif	/* _WIN32_WCE */
						NULL,
						NULL,
						m_pApp->get_inst(),
						this ) ;
	if ( hWnd == 0 ) {
		return FALSE ;
	}
	ShowWindow( hWnd, SW_SHOW ) ;
    UpdateWindow( hWnd ) ;
    return TRUE ;
}

DWORD
MainWindow::CreateCommandBar()
{
	HINSTANCE	hInst = m_pApp->get_inst() ;

#ifdef	_WIN32_WCE
	static TBBUTTON	tbButton[] = {
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, -1},
		{STD_FILENEW,    IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, -1},
		{STD_FILEOPEN,   IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{STD_FILESAVE,   IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, -1},
		{STD_CUT,        IDM_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0},
		{STD_COPY,       IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{STD_PASTE,      IDM_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
	} ;

	m_hWndCB = CommandBar_Create( hInst, m_hWnd, 0 ) ;
	CommandBar_InsertMenubar( m_hWndCB, hInst, IDR_MAIN_MENU, 0 ) ;
	CommandBar_AddBitmap( m_hWndCB, HINST_COMMCTRL, IDB_STD_SMALL_COLOR, 15, 0, 0 ) ;
	CommandBar_AddButtons( m_hWndCB, sizeof(tbButton) / sizeof(*tbButton), tbButton ) ;
	CommandBar_AddAdornments( m_hWndCB, 0, 0 ) ;
	return CommandBar_Height( m_hWndCB ) ;
#else	/* _WIN32_WCE */
	return 0 ;
#endif	/* _WIN32_WCE */
}

BOOL
MainWindow::RegisterClass( HINSTANCE hInst )
{
	WNDCLASS	wc ;

	wc.style         = NULL ;
	wc.lpfnWndProc   = (WNDPROC) WndProc ;
	wc.cbClsExtra    = 0 ;
	wc.cbWndExtra    = 4 ;
	wc.hInstance     = hInst ;
	wc.hIcon         = NULL ;
	wc.hCursor       = NULL ;
	wc.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
#ifdef	_WIN32_WCE
	wc.lpszMenuName  = 0 ;
#else	/* _WIN32_WCE */
	wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAIN_MENU) ;
#endif	/* _WIN32_WCE */
	wc.lpszClassName = 	GetClassName() ;
	return ::RegisterClass( &wc ) ;
}

/*-------------------------------------------------------------------------*
 * EditArea
 *-------------------------------------------------------------------------*/
EditArea::EditArea()
{
	LOGFONT	LF_MSG ;

	memset( &LF_MSG, 0, sizeof LF_MSG ) ;
	LF_MSG.lfHeight = g_dwFontH0 ;
	LF_MSG.lfWidth = g_dwFontW0 ;
	LF_MSG.lfWeight = 0x190 ;
	LF_MSG.lfClipPrecision = 0x02 ;
	LF_MSG.lfQuality = 0x01 ;
	LF_MSG.lfPitchAndFamily = 0x02 ;
	_tcscpy( LF_MSG.lfFaceName, g_szFontName0 ) ;
	m_hFont = CreateFontIndirect( &LF_MSG ) ;
}

EditArea::~EditArea()
{
	DeleteObject( m_hFont ) ;
}

/*
 * ウィンドウを作成する
 */
HWND
EditArea::Create( HINSTANCE hInst, HWND hWndParent, DWORD x, DWORD y, DWORD w, DWORD h, WORD id )
{
	m_hWnd = CreateWindowEx( 0,
					TEXT("EDIT"),
					TEXT(""),
					WS_VISIBLE|WS_CHILD|WS_VSCROLL|
					WS_BORDER|ES_MULTILINE|ES_WANTRETURN,
					x, y, w, h,
					hWndParent,
					(HMENU) id,
					hInst,
					NULL ) ;
	SubclassToKEdit( m_hWnd ) ;
	SendMessage( m_hWnd, WM_SETFONT, (WPARAM) m_hFont, (LPARAM) TRUE ) ;
	return m_hWnd ;
}

#define		MAX_SJIS	512
#define		MAX_UNICODE	(512*sizeof (TCHAR))

CHAR	g_szSjis[ MAX_SJIS ] ;
TCHAR	g_szUnicode[ MAX_UNICODE ] ;

DWORD
Convert( LPTSTR dst )
{
	LPSTR	ptr ;
	DWORD	result = 0 ;
	int		c, sjisLen, len ;

	ptr = g_szSjis, sjisLen = 0 ;
	while ( (c = Fgetc()) != -1 ) {
		if ( c == '\r' ) {
			continue ;
		} else if ( c == '\n' ) {
			*ptr = 0 ;
			ptr = g_szSjis, sjisLen = 0 ;
			sjis2unicode( (LPBYTE) g_szSjis, g_szUnicode, MAX_UNICODE - 4 ) ;
			len = _tcslen( g_szUnicode ) ;
			if ( dst ) {
				_tcscpy( dst, g_szUnicode ) ;
				_tcscpy( &dst[ len ], TEXT("\r\n") ) ;
				dst += len + 2 ;
			}
			result += len + 2 ;
		} else if ( sjisLen < MAX_SJIS - 1 ) {
			*ptr++ = (CHAR) c ;
			sjisLen ++ ;
		}
	}
	if ( ptr != g_szSjis ) {
		*ptr = 0 ;
		sjis2unicode( (LPBYTE) g_szSjis, g_szUnicode, MAX_UNICODE ) ;
		len = _tcslen( g_szUnicode ) ;
		if ( dst ) {
			_tcscpy( dst, g_szUnicode ) ;
		}
		result += len ;
	}
	return result + 1 ;
}

BOOL
EditArea::Load( LPCTSTR fn )
{
	DWORD		len ;
	LPTSTR		ptr ;

	if ( !Fopen( fn, TEXT("rb") ) ) {
		return FALSE ;
	}
	SetCursor( (HCURSOR) IDC_WAIT ) ;

	len = Convert( 0 ) ;
	ptr = (LPTSTR) LocalAlloc( LMEM_FIXED, len * sizeof (TCHAR) ) ;
	if ( !ptr ) {
		goto error ;
	}
	Fseek( 0, 0 ) ;
	Convert( ptr ) ;
	Fclose() ;
	SetWindowText( m_hWnd, ptr ) ;
	LocalFree( (HLOCAL) ptr ) ;

	SetCursor( NULL ) ;
	SetModify( FALSE ) ;
	return TRUE ;

error:
	Fclose() ;
	SetCursor( NULL ) ;
	return FALSE ;
}

BOOL
EditArea::Save( LPCTSTR fn )
{
	LPSTR		ptr ;
	int			i, lines, size ;

	SetCursor( (HCURSOR) IDC_WAIT ) ;
	if ( !Fopen( fn, TEXT("wb") ) ) {
		goto error ;
	}
	lines = SendMessage( m_hWnd, EM_GETLINECOUNT, 0, 0 ) ;
	for ( i = 0 ; i < lines ; i ++ ) {
		memset( g_szUnicode, 0, MAX_UNICODE ) ;
		*g_szUnicode = (MAX_UNICODE / sizeof (TCHAR)) - 2 ;
		SendMessage( m_hWnd, EM_GETLINE, (WPARAM) i, (LPARAM) g_szUnicode ) ;
		if ( i ) {
			g_szSjis[0] = '\r' ;
			g_szSjis[1] = '\n' ;
			ptr = &g_szSjis[2] ;
			size = MAX_SJIS - 2 ;
		} else {
			ptr = g_szSjis ;
			size = MAX_SJIS ;
		}
		unicode2sjis( g_szUnicode, (LPBYTE) ptr, size ) ;
		Fputs( g_szSjis ) ;
	}
	Fclose() ;
	SetCursor( NULL ) ;
	SetModify( FALSE ) ;
	return TRUE ;

error:
	SetCursor( NULL ) ;
	return FALSE ;
}

void
EditArea::ClearAll() const
{
	SetWindowText( m_hWnd, TEXT("") ) ;
	SetModify( FALSE ) ;
}

void
EditArea::Undo() const
{
	SendMessage( m_hWnd, WM_UNDO, 0, 0 ) ;
}

void
EditArea::Cut() const
{
	SendMessage( m_hWnd, WM_CUT, 0, 0 ) ;
}

void
EditArea::Copy() const
{
	SendMessage( m_hWnd, WM_COPY, 0, 0 ) ;
}

void
EditArea::Paste() const
{
	SendMessage( m_hWnd, WM_PASTE, 0, 0 ) ;
}

void
EditArea::SelectAll() const
{
	SendMessage( m_hWnd, EM_SETSEL, 0, (LPARAM) -1 ) ;
}

BOOL
EditArea::GetModify() const
{
	return SendMessage( m_hWnd, EM_GETMODIFY, 0, 0 ) ;
}

void
EditArea::SetModify( BOOL flag ) const
{
	SendMessage( m_hWnd, EM_SETMODIFY, (WPARAM) flag, 0 ) ;
}
