#include  "include_c.h" 

/* Main function is "_tWinMain" */


errnum_t  GetTextFromClipboard(void);
errnum_t  SetTextToClipboard(void);


 
/***********************************************************************
  <<< [_tWinMain] >>> 
************************************************************************/
int APIENTRY  _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine, int       nCmdShow )
{
	errnum_t  e;
	TCHAR     command_name[40];

//Err2_setBreakErrID( 1 );
	Globals_init_const();
	e= Globals_init(); IF(e)goto fin;

	e= GetCommandLineUnnamed( 1, command_name, sizeof( command_name ) ); IF(e)goto fin;
	if ( _tcscmp( command_name, _T("GetTextFromClipboard") ) == 0 )
		{ e= GetTextFromClipboard(); IF(e)goto fin; }
	else if ( _tcscmp( command_name, _T("SetTextToClipboard") ) == 0 )
		{ e= SetTextToClipboard(); IF(e)goto fin; }
	else
		{ ASSERT_R( false, goto err ); }

	e=0;
fin:
	e= Globals_finish( e );
	IfErrThenBreak();
	if ( _CrtDumpMemoryLeaks() )  DebugBreak();
	return  e;

err:  e = E_Others;  goto fin;
}


 
/***********************************************************************
  <<< [GetTextFromClipboard] >>> 
************************************************************************/
errnum_t  GetTextFromClipboard()
{
	errnum_t  e;
	BOOL      b;
	HGLOBAL   data = NULL;
	DWORD     size;
	DWORD     nz_size;  /* without '\0' */
	DWORD     n;
	TCHAR*    str = NULL;
	TCHAR*    z_str;
	FILE*     file = NULL;
	TCHAR     out_path[MAX_PATH*2];
	errno_t   en;
	TCHAR     byte_order_mark = _T('\xFEFF');


	e= GetCommandLineNamed( _T("Out"), false, out_path, sizeof(out_path) ); IF(e)goto fin;
	e= AppKey_newWritable( NULL, NULL, out_path, NULL ); IF(e)goto fin;

	b= OpenClipboard( NULL ); IF(!b)goto err;
	data = GetClipboardData( CF_UNICODETEXT ); IF(data==NULL)goto err_nf;
	size = GlobalSize( data );
	str = (TCHAR*)GlobalLock( data ); IF(str==NULL)goto err;

	// Sometimes size > _tcslen( str )
	z_str = _tcschr( str, _T('\0') );
	if ( (char*) z_str + sizeof(TCHAR) - (char*) str < (int) size ) {
		size = (char*) z_str + sizeof(TCHAR) - (char*) str;
	}

	nz_size = size - sizeof(TCHAR);

	en = _tfopen_s( &file, out_path, _T("wb") );  IF(en) goto err_no;
	n = fwrite( &byte_order_mark, 1,sizeof(TCHAR), file ); IF(ferror(file))goto err_no;
		IF( n != sizeof(TCHAR) )goto err_no;
	n = fwrite( str, 1,nz_size, file ); IF(ferror(file))goto err_no;
		IF( n != nz_size )goto err_no;

	e=0;
fin:
	e= FileT_close( file, e );
	e= AppKey_finishGlobal( e );
	if ( data != NULL )  GlobalUnlock( data );
	CloseClipboard();
	return  e;

err:     e = E_Others;  goto fin;
err_no:  e = E_Errno;  goto fin;
err_nf:  e = E_NotFoundSymbol;  goto fin;
}


 
/***********************************************************************
  <<< [FileT_getSize] >>> 
************************************************************************/
errnum_t  FileT_getSize( const TCHAR* Path, size_t* out_Size )
{
	errnum_t  e;
	DWORD     size;
	DWORD     size_high;
	HANDLE    file = INVALID_HANDLE_VALUE;

	file = CreateFile( Path, GENERIC_READ, FILE_SHARE_READ,
	                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
		IF(file == INVALID_HANDLE_VALUE) goto err;

	size = GetFileSize( file, &size_high ); IF(size==-1)goto err;
	IF( size_high != 0 )goto err_fa;
	*out_Size = size;

	e=0;
fin:
	CloseHandle( file );
	return  e;

err:     e = E_Others;    goto fin;
err_fa:  e = E_FewArray;  goto fin;
}


 
/***********************************************************************
  <<< [SetTextToClipboard] >>> 
************************************************************************/
errnum_t  SetTextToClipboard()
{
	errnum_t  e;
	FILE*     file = NULL;
	HGLOBAL   data = NULL;
	bool      is_data_lock = false;
	bool      is_set = false;
	size_t    size;
	size_t    max_size;
	TCHAR*    str = NULL;
	TCHAR*    str_next;
	TCHAR*    str2;
	TCHAR     in_path[MAX_PATH*2];

	e= GetCommandLineNamed( _T("In"), false, in_path, sizeof(in_path) ); IF(e)goto fin;


	/* Allocate "str" */
	e= FileT_getSize( in_path, &max_size ); IF(e)goto fin;
	max_size *= sizeof(TCHAR) * 2;  /* 2 is \n -> \r\n */
	size = 0;
	str = (TCHAR*) malloc( max_size ); IF(str==NULL)goto err_fm;
	str_next = str;


	/* Read from "in_path" to "str" */
	e= FileT_openForRead( &file, in_path ); IF(e)goto fin;
	for (;;) {
		_fgetts( str_next, ( max_size - size ) / sizeof(TCHAR),  file );
		if ( str_next[0] == _T('\0') )  break;  /* EOF (because no '\n') */
		str_next = _tcschr( str_next, _T('\0') );
		if ( *( str_next - 1 ) == _T('\n') ) {
			*( str_next - 1 ) = _T('\r');
			*( str_next     ) = _T('\n');
			*( str_next + 1 ) = _T('\0');
			str_next += 1;
		}
		size = (int8_t*) str_next - (int8_t*) str;
		if ( feof( file ) )  break;
	}
	e= FileT_close( file, e );  file = NULL;
	size += sizeof(TCHAR);  /* for '\0' */


	/* Set "data" from "str" */
	data = GlobalAlloc( GMEM_DDESHARE, size ); IF(data==NULL)goto err_fm;
	is_data_lock = true;
	str2 = (TCHAR*) GlobalLock( data );
	memcpy( str2, str, size );
	GlobalUnlock( data );
	is_data_lock = false;


	/* Set to clipboard */
	if ( OpenClipboard( NULL ) ) {
		EmptyClipboard();
		SetClipboardData( CF_UNICODETEXT, data );
		CloseClipboard();
		is_set = true;
	}

	e=0;
fin:
	if ( str != NULL )  free( str );
	if ( is_data_lock )  IF( ! GlobalUnlock( data ) &&!e) e=E_Others;
	if ( data != NULL && ! is_set )  IF( GlobalFree( data ) != NULL &&!e) e=E_Others;
	e= FileT_close( file, e );
	return  e;

err_fm:  e = E_FewMemory;  goto fin;
}


 
