#include "StdAfx.h"
#include "ExportEngine.h"
#include "gdiplus.h"
#include "MSWord.h"
#include "Function.h"
#include "NoteDao.h"
#include "MyReader-DUI-MFC.h"

CExportEngine::CExportEngine(void)
{
	m_pExportEdit = NULL;
	m_strPath = _T("");
}

CExportEngine::~CExportEngine(void)
{
}

BOOL CExportEngine::ExportWordFiles(std::vector<CPDFNoteInfo*> const& notes,
									std::wstring const& wordFilename,
									CRichEditUI* pEdit)
{

	return TRUE;
}

BOOL CExportEngine::ExportPowerPointFiles(std::vector<CPDFNoteInfo*> &notes,
										  std::wstring const& wsFileName,
										  CRichEditUI* pEdit)
{
	CMSPowerPoint m_msPowerPoint;

	CString strFileName(wsFileName.c_str());
	m_strPath = theApp.GetBookTmpDir();//GetCurrentPath();

	m_pExportEdit = pEdit;

	if (notes.size() <= 0)
		return FALSE;


	return TRUE;
}

static DWORD CALLBACK MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	/*NoteText *pstr = (NoteText*)dwCookie;
	if(pstr->noteText!=NULL)
	{
	*pcb=pstr->noteLength;
	memcpy(pbBuff, pstr, *pcb );
	}*/
	CFile* pFile = (CFile*) dwCookie;
	*pcb = pFile->Read(pbBuff, cb);
	return 0;
}

CString CExportEngine::GetPlainTextFromRTFText(std::string noteText)
{
	CString fileName=theApp.GetBookTmpDir()+_T("note.rtf");
	CFile cFile(fileName, CFile::modeCreate|CFile::modeWrite);
	cFile.Write(noteText.c_str(),noteText.length());
	cFile.Close();
	cFile.Open(fileName,CFile::modeRead);
	EDITSTREAM es;
	es.dwError = 0;
	es.pfnCallback = MyStreamInCallback;
	es.dwCookie = (DWORD_PTR) &cFile;
	m_pExportEdit->StreamIn(SF_RTF,es);
	cFile.Close();

	CString str = m_pExportEdit->GetText();

	return str;

	/*
	if (noteText.length() == 0)
	return FALSE;

	std::string sTempRTF = "temp.rtf";
	CFile file;
	BOOL bOpen = file.Open(_T("temp.rtf"), CFile::modeCreate | CFile::modeReadWrite);
	if (bOpen)
	{
	int len = noteText.length();
	file.Write(noteText.c_str(), len);

	LPCTSTR strText;
	CMSWord* pMsWord = new CMSWord();
	pMsWord->OpenDocument(_T("temp.rtf"), false);
	pMsWord->GetSelectionText(strText);
	}
	*/
}

BOOL CExportEngine::RemoveImagesFromNoteText(std::string& noteText)
{
	if (noteText.length() == 0)
		return FALSE;
	int count = Replace_all(noteText, "\r\n", "");

	while (true)
	{
		int start = noteText.find("pict");
		if (start == -1)
			break;

		int end = noteText.find("}", start);
		if (end != 1)
		{
			noteText.erase(start - 2, end - start + 3);
		}
	}

	/*
	std::vector<std::pair<int, int>>::reverse_iterator iter;
	for (iter = posImages.rbegin(); iter != posImages.rend(); iter++)
	{
	int iStartPos = iter->first;
	int iLength   = iter->second;

	std::string str3 = noteText.erase(iStartPos, iLength);

	noteText = str3;
	}
	*/

	return TRUE;
}

int CExportEngine::GetImageDataFromNote(CPDFNoteInfo* noteInfo, std::vector<ImageInRTF*>& TempImages)
{
	ULONG_PTR gdiplusToken;
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	int count = 0;
	BOOL bHaveImage = FALSE;
	//Mark By Ray 
// 	std::string sImage = noteInfo->noteText;
// 	//	std::vector<string> images;
// 	while (true)
// 	{
// 		int index = sImage.find("pichgoal");
// 		if (index == -1)
// 			break;
// 
// 		count++;
// 		ImageInRTF* image = new ImageInRTF;
// 		CString strName = GetTempImageNameByIndex(count);
// 		image->strTempImage = strName;
// 
// 		int iPos = sImage.find("pict");
// 		if (iPos != -1)
// 		{
// 			int iPosW = sImage.find("picw", iPos);
// 			int iPosH = sImage.find("pich", iPos);
// 			std::string sWidth = sImage.substr(iPosW + 4, 4);
// 			std::string sHeight = sImage.substr(iPosH + 4, 4);
// 
// 			image->iWidth  = atoi(sWidth.c_str()) / 26;
// 			image->iHeight = atoi(sHeight.c_str()) / 26;
// 			m_Log.WriteLog(_T("the image size is : width = %d", height = %d), image->iWidth, image->iHeight);
// 		}
// 
// 		bHaveImage = TRUE;
// 		sImage = sImage.substr(index + 8, sImage.length() - index - 8);
// 
// 		index = sImage.find("\r\n");
// 		if (index != -1)
// 			sImage = sImage.substr(index, sImage.length() - index);
// 
// 		index = sImage.find("}");
// 		if (index != -1)
// 		{
// 			std::string str = sImage.substr(0, index);
// 			int count = Replace_all(str, "\r\n", "");
// 			image->sImageData = str;
// 			TempImages.push_back(image);
// 			sImage = sImage.substr(index + 1, sImage.length() - index);
// 		}
// 	}
// 
// 	if (!bHaveImage)
// 	{
// 		if (gdiplusToken)
// 			Gdiplus::GdiplusShutdown(gdiplusToken);
// 
// 		return 0;
// 	}
// 
// 	int index = 1;
// 	int length = 0;
// 	unsigned char* buffer = NULL;
// 	std::vector<ImageInRTF*>::iterator iter;
// 	for (iter = TempImages.begin(); iter != TempImages.end(); iter++)
// 	{
// 		length = ((*iter)->sImageData).length() / 2;
// 		buffer = new unsigned char[length + 1];
// 		memset(buffer, 0, length + 1);
// 		std::string sImage = (*iter)->sImageData;
// 		for (int i = 0; i < length; i++)
// 		{
// 			std::string bt;
// 			bt = sImage.substr(i * 2, 2);
// 			char hex[5] = {0};
// 			strcpy(hex, bt.c_str());
// 			int value = HexToDecimal(hex);
// 			buffer[i] = value;
// 		}
// 
// 		CHAR *acTemp;
// 		int iLen = sizeof(buffer);
// 		acTemp = (CHAR *) GlobalAlloc (GMEM_FIXED, length);
// 		memcpy (acTemp, buffer, length);
// 		IStream* pStream = NULL;
// 		::CreateStreamOnHGlobal(acTemp, TRUE, &pStream);
// 
// 		Image* image = Image::FromStream(pStream, FALSE);
// 		CLSID clsid;
// 		GetEncoderClsid(_T("image/bmp"), &clsid);
// 
// 		//		CString strName = GetTempImageNameByIndex(index);
// 		Status st = image->Save((*iter)->strTempImage, &clsid, NULL);
// 		index++;
// 
// 		if (st != Ok)
// 			return 0;
// 	}
// 
// 	if (gdiplusToken)
// 		Gdiplus::GdiplusShutdown(gdiplusToken);

	return count;
}

CString CExportEngine::GetTempImageNameByIndex(int index)
{
	CString strName = _T("");
	strName.Format(_T("Sample%d"), index);
	strName += _T(".bmp");

	return (m_strPath + strName);
}

int CExportEngine::HexToDecimal(char* strHex)
{
	ULONG lValue;//4 BYTE
	sscanf(strHex,"%X",&lValue);
	return lValue;
}

unsigned char CExportEngine::ASCI_16(unsigned char a)
{
	unsigned char b;
	if (a >= 0x30 && a <= 0x39)
		b = a - 0x30;
	else if (a >= 0x41 && a <= 0x46)
		b = a - 0x41 + 10;
	else if (a >= 0x61 && a <= 0x66)
		b = a - 0x61 + 10;
	return b;
}

int byte2hex(const unsigned char *input, unsigned long inlen, unsigned char *output, unsigned long *outlen)
{
	const char *num = "0123456789ABCDEF";
	unsigned long i = 0;
	unsigned char *p = output;
	if (*outlen < inlen * 2)
	{
		*outlen = inlen * 2;
		return -1;
	}
	for (i=0; i<inlen; ++i)
	{
		*p++ = num[input[i] >> 4];
		*p++ = num[input[i] & 0x0F];
	}
	*outlen = p - output;
	return 0;
}

int CExportEngine::Replace_all(std::string& str,  const std::string& pattern,  const std::string& newpat)
{
	int count = 0;
	const size_t nsize = newpat.size();
	const size_t psize = pattern.size();

	for(size_t pos = str.find(pattern, 0); pos != std::string::npos; pos = str.find(pattern,pos + nsize))
	{
		str.replace(pos, psize, newpat);
		count++;
	}

	return count;
}

int CExportEngine::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	UINT  num = 0;          // number of image encoders
	UINT  size = 0;         // size of the image encoder array in bytes

	ImageCodecInfo* pImageCodecInfo = NULL;

	GetImageEncodersSize(&num, &size);
	if(size == 0)
		return -1;  // Failure

	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
	if(pImageCodecInfo == NULL)
		return -1;  // Failure

	GetImageEncoders(num, size, pImageCodecInfo);

	for(UINT j = 0; j < num; ++j)
	{
		if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;  // Success
		}
	}

	free(pImageCodecInfo);
	return -1;  // Failure
}

wchar_t* CExportEngine::Ansi2Unicode(const char* szAnsi)
{
	if (szAnsi == NULL)
		return NULL;

	int wcsLen = ::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), NULL, 0);
	wchar_t* wszString = new wchar_t[wcsLen+1];
	if (wszString == NULL)
		return NULL;
	::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), wszString, wcsLen);
	wszString[wcsLen] = L'/0';
	return wszString;
}

char* CExportEngine::Unicode2Ansi(const wchar_t* wszString)
{
	if (wszString == NULL)
		return NULL;

	int ansiLen = ::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
	char* szAnsi = new char[ansiLen + 1];
	if (szAnsi == NULL)
		return NULL;
	::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), szAnsi, ansiLen, NULL, NULL);
	szAnsi[ansiLen] = '/0';
	return szAnsi;
}

/*CString CExportEngine::GetCurrentPath()
{
TCHAR path[MAX_PATH] = {0};
TCHAR * lpPart[MAX_PATH]={NULL};
TCHAR buffer[MAX_PATH];
GetModuleFileName(NULL, buffer, MAX_PATH);
DWORD retval = GetFullPathName(buffer, MAX_PATH, path, lpPart);
(_tcsrchr(path, _T('\\')))[1] = 0;

return (CString)path;
}*/