#include <fstream>
#include <memory>
#include <string>

// Loads image from file
int rtf_load_image(char* image, int width, int height)
{
	// Set error flag
	int error = RTF_SUCCESS;

	// Check image type
	bool err = false;
	if ( strstr(image,".bmp") == NULL )
	{
		if ( strstr(image,".jpg") == NULL )
		{
			if (strstr(image,".gif") == NULL )
				err = true;
		}
	}

	// If valid image type
	if ( err == false )
	{
		// Free IPicture object
		if ( rtfPicture != NULL )
		{
			rtfPicture->Release();
			rtfPicture = NULL;
		}

		::std::ifstream ifs( image, ::std::ios::binary );
		ifs.seekg( 0, ::std::ios::end );
		::std::size_t sz( ifs.tellg() );
		ifs.seekg( 0, ::std::ios::beg );
		::std::unique_ptr<char[]> buf( new char[sz] );
		ifs.read( &buf[0], sz );
		ifs.close();
		/*
		::std::ofstream ofs( ::std::string( image ) + "t", ::std::ios::binary );
		ofs.write( &buf[0], sz );
		ofs.close();
		*/

		// Read image file
		//int imageFile = _open( image, _O_RDONLY | _O_BINARY );
		//struct _stat st;
		//_fstat( imageFile, &st );
		//DWORD nSize = st.st_size;
		//BYTE* pBuff = new BYTE[nSize];
		//_read( imageFile, pBuff, nSize );
		// Alocate memory for image data
		HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sz);
		void* pData = GlobalLock(hGlobal);
		memcpy(pData, &buf[0], sz);
		GlobalUnlock(hGlobal);
		// Load image using OLE
		IStream* pStream = NULL;
		if ( CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK )
		{
			HRESULT hr;
			if ((hr = OleLoadPicture( pStream, sz, FALSE, IID_IPicture, (LPVOID *)&rtfPicture)) != S_OK)
				error = RTF_IMAGE_ERROR;

			pStream->Release();
		}
		//delete []pBuff;
		//_close(imageFile);

		// If image is loaded
		if ( rtfPicture != NULL )
		{
			class DC {
			public:
				operator HDC() const {
					return this->_dc;
				}
				~DC() {
					::ReleaseDC( ::GetDesktopWindow(), this->_dc );
				}
				DC()
					: _dc( ::GetDC( ::GetDesktopWindow() ) )
				{}
			protected:
				HDC _dc;
			};

			DC dc;
			// Calculate image size
			long hmWidth;
			long hmHeight;
			rtfPicture->get_Width(&hmWidth);
			rtfPicture->get_Height(&hmHeight);
			int nWidth	= MulDiv( hmWidth, GetDeviceCaps( dc,LOGPIXELSX), 2540 );
			int nHeight	= MulDiv( hmHeight, GetDeviceCaps( dc,LOGPIXELSY), 2540 );

			// Create metafile;
			HDC hdcMeta = CreateMetaFile(NULL);

			// Render picture to metafile
			rtfPicture->Render( hdcMeta, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, NULL );

			// Close metafile
			HMETAFILE hmf = CloseMetaFile(hdcMeta);

			// Get metafile data
			UINT size = GetMetaFileBitsEx( hmf, 0, NULL );
			BYTE* buffer = new BYTE[size];
			GetMetaFileBitsEx( hmf, size, buffer );
			DeleteMetaFile(hmf);

			// Convert metafile binary data to hexadecimal
			char* str = rtf_bin_hex_convert( buffer, size );
			delete []buffer;

			// Format picture paragraph
			RTF_PARAGRAPH_FORMAT* pf = rtf_get_paragraphformat();
			pf->paragraphText = "";
			rtf_write_paragraphformat();

			// Writes RTF picture data
			char rtfText[1024];
			sprintf( rtfText, "\n{\\pict\\wmetafile8\\picwgoal%d\\pichgoal%d\\picscalex%d\\picscaley%d\n", hmWidth, hmHeight, width, height );
			if ( fwrite( rtfText, 1, strlen(rtfText), rtfFile ) < strlen(rtfText) )
				error = RTF_IMAGE_ERROR;
			fwrite( str, 1, 2*size, rtfFile );
			strcpy( rtfText, "}" );
			fwrite( rtfText, 1, strlen(rtfText), rtfFile );
		}
	}
	else
	{
		// Writes RTF picture data
		char rtfText[1024];
		strcpy( rtfText, "\n\\par\\pard *** Error! Wrong image format ***\\par" );
		fwrite( rtfText, 1, strlen(rtfText), rtfFile );
	}

	// Return error flag
	return error;
}

void main()
{
	rtf_open( "R:\\rtf\\rtf\\test.rtf" );
	
	rtf_load_image( "R:\\rtf\\rtf\\123.bmp", 32, 32 );

	rtf_close();
}