#include "stdafx.h"
#include "EnhancedBookImporter.h"
#include "BookDal.h"
#include "BookInfo.h"
#include "NoteDao.h"
#include "PDFNoteInfo.h"
#include "XZip\XUnzip.h"
#include "StringOp.h"
#include "GlobalData.h"

CEnhancedBookImporter::CEnhancedBookImporter(void)
{
}


CEnhancedBookImporter::~CEnhancedBookImporter(void)
{
}


int CEnhancedBookImporter::Init(TCHAR* lpszDBName, TCHAR* lpszResourcePath)
{
	if (lpszDBName == NULL || lpszResourcePath == NULL)
		return -1;

	_tcscpy(m_lpszDBName, lpszDBName);
	_tcscpy(m_lpszRootPath, lpszResourcePath);

//	_tcscpy(CSqlLiteHelper::path, m_lpszDBName);

	return 0;
}

int CEnhancedBookImporter::ImportBook(TCHAR* lpszBookName, TCHAR* bookId)
{
	//Comment By Ray 2018-06-19
	//�����鼮(��ѹ��������Դ)
	m_log.EnableWriteLog(FALSE);

	m_log.WriteLog(_T("Import Book : %s, id = %s"), lpszBookName, bookId);

	TCHAR lpszBookPath[MAX_PATH] = {0};
	_tcscpy(lpszBookPath, m_lpszRootPath);
	_tcscpy(m_lpszBookId, bookId);
	_tcscat(lpszBookPath, _T("source\\public\\"));
	_tcscat(lpszBookPath, m_lpszBookId);
	_tcscat(lpszBookPath, _T("\\"));

	if (UnzipOneDczBook(lpszBookName, bookId))
	{
		//Modify By Ray 2018-08-09
		//if (ImportOneBook(lpszBookPath))

			return 1;
	}
	else
	{
		DeleteDirectory(lpszBookPath);
		return 0;
	}

	return 0;
}

BOOL CEnhancedBookImporter::UnzipOneDczBook(TCHAR* lpszBookName, TCHAR* bookId)
{
	TCHAR sDrive[_MAX_DRIVE];
	TCHAR sDir[_MAX_DIR];
	TCHAR sFilename[_MAX_FNAME];
	TCHAR sExt[_MAX_EXT];
	_tsplitpath_s(lpszBookName, sDrive, sDir, sFilename, sExt);

	char* ss = m_log.Unicode2Ansi(lpszBookName);
	//	m_Log.WriteLogA("UnzipOneDczBook %s Start!", ss);
	//m_Log.WriteLog(_T("UnzipOneDczBook %s Start!"), strBookName);

	//	TCHAR id[10] = {0};
	//	_tcscpy(m_lpszBookId, GetBookIdByName(sFilename));

	m_log.WriteLog(_T("bookId is : %s"), m_lpszBookId);

	if (m_lpszBookId == NULL)
	{
		m_log.WriteLog(_T("can't find the book info %s"), sFilename);
		return FALSE;
	}

// 	if (IsBookHasImported(m_lpszBookId))
// 	{
// 		m_log.WriteLog(_T("this book has already imported in DB!"));
// 		return FALSE;
// 	}
	//	_tcscpy(id, m_strBookNameID);
	_tcscpy(m_lpszFileName, sFilename);

	TCHAR lpszBookPath[MAX_PATH] = {0};
	_tcscpy(lpszBookPath, m_lpszRootPath);
	_tcscat(lpszBookPath, _T("source\\public\\"));
	_tcscat(lpszBookPath, bookId);
	//_tcscat(lpszBookPath, _T("\\"));

	m_log.WriteLog(_T("the resource path is : %s"), lpszBookPath);

	HANDLE hFind;
	WIN32_FIND_DATA wfd;

//	hFind = FindFirstFile(lpszBookPath, &wfd);
// 	if (INVALID_HANDLE_VALUE != hFind)
// 	{
// 		FindClose(hFind);
// 		if (!DeleteDirectory(lpszBookPath))
// 		{
// 			int error = GetLastError();
// 			m_log.WriteLog(_T("Delete Directory %s Failed!"), lpszBookPath);
// 			return FALSE;
// 		}
// 	}    

	_tcscat(lpszBookPath, _T("\\"));

	m_log.WriteLog(lpszBookPath);
	//CreateAllDirectory(lpszBookPath);
	int error = GetLastError();
	SetCurrentDirectory(lpszBookPath);

	BOOL bUnzip = TRUE;
	HZIP hZip = 
		OpenZip(const_cast<void*>(reinterpret_cast<const void*>(static_cast<LPCTSTR>(lpszBookName))), 0, ZIP_FILENAME);
	 error = GetLastError();
	if (hZip != NULL)
	{
		ZIPENTRYW ze;
		ZRESULT zr = GetZipItemW(hZip, -1, &ze);
		
		if (zr == ZR_OK)
		{
			int iItems = ze.index;
			for (int i = 0; i < iItems; i++)
			{
				if (g_bExit)
					break;
				TCHAR name[MAX_PATH] = {0};
				zr = GetZipItemW(hZip, i, &ze);
				if (zr != ZR_OK)
				{
					bUnzip = FALSE;
					break;
				}
				zr = UnzipItem(hZip, i, ze.name, 0, ZIP_FILENAME);
				if (zr != ZR_OK)
				{
					bUnzip = FALSE;
					break;
				}
			}
		}
		else
		{
			bUnzip = FALSE;
		}

		CloseZip(hZip);
	}
	else
	{
		bUnzip = FALSE;
	}

	if (!bUnzip)
	{
		 error = GetLastError();
		CString strMsg = _T("");
		strMsg.Format(_T("Import Book:%s Failed!"), sFilename);
		m_log.WriteLog(strMsg);
		//		MessageBox(NULL, strMsg, _T(""), MB_OK);
	}

	m_log.WriteLog(_T("UnzipOneDczBook End!"));

	return bUnzip;
}

PDFNoteType CEnhancedBookImporter::GetNoteType(wchar_t* resType)
{
	PDFNoteType iNoteType = NoteNone;

	iNoteType = NoteFile;


	return iNoteType;
}

CString CEnhancedBookImporter::GetSrcPath(CString strManifestName)
{
	m_log.WriteLog(_T("get src path start!"));
	CString path = _T("");
	int pos = -1;
	pos = strManifestName.Find(_T("\\resources\\books\\MyResources\\"));
	m_log.WriteLog(_T("the pos of manifest is %d"), pos);
	if (pos != -1)
	{
		CString strPath = strManifestName.Right(strManifestName.GetLength() - pos);
		m_log.WriteLog(_T("the strpath is %s"), strPath);
		pos = strPath.ReverseFind(_T('\\'));
		m_log.WriteLog(_T("the pos of strPath is %d"), pos);
		if (pos != -1)
		{
			path = strPath.Left(pos);
			m_log.WriteLog(_T("the path is : %s"), path);
			path += _T("\\attachments\\");
		}
	}

	// 	TCHAR sPath[MAX_PATH] = {0};
	// 	_tcscpy(sPath, path.GetBuffer(path.GetLength()));
	// 	path.ReleaseBuffer();
	m_log.WriteLog(_T("get src path end!"));

	return path;
}



BOOL CEnhancedBookImporter::GetRegionIdByAttchmentIdInRelations(int attachmentId, std::vector<BookModel::Relation> &relations, std::vector<int> &RegionIds)
{
	BOOL bFind = FALSE;
	int regionId = -1;
	std::vector<BookModel::Relation>::iterator iter;
	for (iter = relations.begin(); iter != relations.end(); iter++)
	{
		int objectId = iter->objectId;
		if (objectId == attachmentId)
		{
			RegionIds.push_back(iter->regionId);
			bFind = TRUE;
		}
	}

	return bFind;
}

BOOL CEnhancedBookImporter::GetRegionInfoByRegionIdInRegions(int regionId, int& pageNo, POINT& pt, std::vector<BookModel::Region> &regions)
{
	std::vector<BookModel::Region>::iterator iter;
	for (iter = regions.begin(); iter != regions.end(); iter++)
	{
		if (iter->id == regionId)
		{
			pageNo = iter->pageNo;
			pt.x = iter->loc.x;
			pt.y = iter->loc.y;

			return TRUE;
		}
	}

	return FALSE;
}

std::vector<textbook_catalogInfo> CEnhancedBookImporter::TestBook(CString bookId)
{
	/*std::vector<BookModel::item> items;
	std::wstring wstr = L"D:\\contents.xml";
	BookModel::ParseItemXmlFile(Util::Text::StringOp::ToUTF8(wstr), items);
	return items;*/

	std::vector<textbook_catalogInfo> infos;
	CCatalogDao catalogDao;
	catalogDao.GetCatalogInfoByParentId(infos, bookId, 0);
	return infos;
}

void CEnhancedBookImporter::InsertDB(BookModel::item *pItem, int parentId)
{
	std::vector<BookModel::item>::iterator iterItem;
	for(iterItem = pItem->item_.begin(); iterItem != pItem->item_.end(); iterItem++)
	{
		textbook_catalogInfo catalogInfo;
		catalogInfo.bookId = m_lpszBookId;
		catalogInfo.startPage = iterItem->start_page;
		catalogInfo.endPage = iterItem->end_page;
		catalogInfo.parentId = parentId;
		catalogInfo.orderNo = 0;
		
		CFunction function;
		catalogInfo.catalogName = function.AsciiToUnicode(iterItem->unit_name.c_str());

		CCatalogDao catalogDao;
		long id = catalogDao.AddNoteInfo(catalogInfo, TRUE);

		iterItem->catalogId = id;
		InsertDB(&(*iterItem), id);
	}
}

long CEnhancedBookImporter::FindCalalogId(std::vector<BookModel::item>& items, int attchmentId)
{
	std::vector<BookModel::item>::iterator iterItem;
	for(iterItem = items.begin(); iterItem != items.end(); iterItem++)
	{	
		std::vector<int>::iterator iterId;
		for(iterId = iterItem->attachmentId.begin(); iterId != iterItem->attachmentId.end(); iterId++)
		{
			if(attchmentId == *iterId)
				return iterItem->catalogId;
		}

		int ret = FindCalalogId(iterItem->item_, attchmentId);
		if(ret != -1)
			return ret;
	}
	
	return -1;
}

BOOL CEnhancedBookImporter::ImportOneBook(TCHAR* lpszPath)
{
	//Comment By Ray 2018-06-19
	//�����鼮
	m_log.WriteLog(_T("ImportOneBook Start %s"), lpszPath);

	int iPdfId = 0;

	TCHAR lpszManFileName[MAX_PATH] = {0};
	TCHAR lpszRegFileName[MAX_PATH] = {0};
	TCHAR lpszRelFileName[MAX_PATH] = {0};
	TCHAR lpszCotFileName[MAX_PATH] = {0};
	_tcscpy(lpszManFileName, lpszPath);
	_tcscat(lpszManFileName, MANIFANST);
	_tcscpy(lpszRegFileName, lpszPath);
	_tcscat(lpszRegFileName, REGIONS);
	_tcscpy(lpszRelFileName, lpszPath);
	_tcscat(lpszRelFileName, RELATIONS);
	_tcscpy(lpszCotFileName, lpszPath);
	_tcscat(lpszCotFileName, CONTENTS);

	TCHAR lpszPdfFileName[MAX_PATH] = {0};
	_tcscpy(lpszPdfFileName, lpszPath);
	_tcscat(lpszPdfFileName, m_lpszFileName);
	_tcscat(lpszPdfFileName, _T(".pdf"));

	//Mark By Ray 2018-06-19
	//Ŀ¼����Դ�Ķ�ȡ��ʽ�ı�
/*	Model model;
	FILE* file;
	file = _tfopen(lpszManFileName, _T("r"));
	if (file != NULL)
	{
		Model::ParseXmlFile(file, &model);
		fclose(file);
	}

	std::vector<BookModel::Region> regions;
	std::wstring wstr = lpszRegFileName;
	BookModel::ParseRegionXmlFile(Util::Text::StringOp::ToUTF8(wstr), regions);

	std::vector<BookModel::Relation> relations;
	wstr = lpszRelFileName;
	BookModel::ParseRelationXmlFile(Util::Text::StringOp::ToUTF8(wstr), relations);

	std::vector<BookModel::item> items;
	wstr = lpszCotFileName;
	BookModel::ParseItemXmlFile(Util::Text::StringOp::ToUTF8(wstr), items);
	*/
    //Add By Ray 2018-06-19
	//Ŀ¼����--Jason
	Model model;
	std::vector<BookModel::item> items;
	std::vector<BookModel::Region> regions;
	std::vector<BookModel::Relation> relations;


	//���
	std::vector<BookModel::item>::iterator iterItem;
	for (iterItem = items.begin(); iterItem != items.end(); iterItem++)
	{
		//Ŀ¼
		textbook_catalogInfo catalogInfo;
		catalogInfo.bookId = m_lpszBookId;
		catalogInfo.startPage = iterItem->start_page;
		catalogInfo.endPage = iterItem->end_page;
		catalogInfo.parentId = 0;
		catalogInfo.orderNo = 0;
		
		CFunction function;
		catalogInfo.catalogName = function.AsciiToUnicode(iterItem->unit_name.c_str());

		CCatalogDao catalogDao;
		long id = catalogDao.AddNoteInfo(catalogInfo, TRUE);

		iterItem->catalogId = id;
		InsertDB(&(*iterItem), id);
	}

	//�����ʼ�
	std::vector<Model::Base>::iterator iter;
	for (iter = model.attachments.begin(); iter != model.attachments.end(); iter++)
	{
		if (g_bExit)
			break;
		//		m_log.WriteLog(_T("attachment %d"), iPdfId);
		CPDFNoteInfo* pPdfNoteInfo = new CPDFNoteInfo;
		pPdfNoteInfo->bookId      = m_lpszBookId;
		pPdfNoteInfo->pdfNoteType = 
			GetNoteType(const_cast<wchar_t *>(Util::Text::StringOp::ToUnicode(iter->srctype.ToString()).c_str()));
		pPdfNoteInfo->content = Util::Text::StringOp::FromUTF8(iter->name).c_str();

		CString strDate;
		SYSTEMTIME tm;
		GetLocalTime(&tm);
		strDate.Format(_T("%d-%d-%d"), tm.wYear, tm.wMonth, tm.wDay);
		pPdfNoteInfo->updateTime = strDate;

		pPdfNoteInfo->contentStartPos = _T("");
		pPdfNoteInfo->lineColor       = 0;
		pPdfNoteInfo->lineType        = LineNone;
		pPdfNoteInfo->lineWidth       = 0;
		//		pPdfNoteInfo->pageHight       = -1;
		pPdfNoteInfo->userName        = _T("");


		std::vector<CLabelInfo*> lableInfos;
		pPdfNoteInfo->lableInfos = lableInfos;

		TCHAR path[MAX_PATH] = {0};
		wmemset(path, 0, MAX_PATH);
		m_log.WriteLog(_T("the lpszManfileName is : %s"), lpszManFileName);
		CString srcPath = GetSrcPath(lpszManFileName);
		m_log.WriteLog(_T("src path is : %s"), srcPath);
		_tcscpy(path, GetSrcPath(lpszManFileName));

		//		m_log.WriteLog(_T("iter src is : %s"), Util::Text::StringOp::FromUTF8(iter->src.c_str()));

		//		wmemset(path, 0, MAX_PATH);
		//		_tcscpy(path, lpszPath);
		_tcscat(path, Util::Text::StringOp::FromUTF8(iter->src).c_str());
		//CString strpath;
		//strpath.Format(_T("%s"),path);

		m_log.WriteLog(_T("import source path is : %s"), path);

		pPdfNoteInfo->SetNoteTextByString(path);
		pPdfNoteInfo->noteOrigin = ORIGIN_SYSTEM;

		std::vector<int> RegionIds;
		BOOL bFind = GetRegionIdByAttchmentIdInRelations(iter->id, relations, RegionIds);
		if (bFind)
		{
			std::vector<int>::iterator it;
			for (it = RegionIds.begin(); it != RegionIds.end(); it++)
			{
				if (g_bExit) break;

				iPdfId++;
				pPdfNoteInfo->pdfId       = iPdfId;
				int pageNo = 0;
				POINT pt = {0};
				BOOL bReg = GetRegionInfoByRegionIdInRegions(*it, pageNo, pt, regions);
				if (bReg)
				{
					pPdfNoteInfo->pageIndex = pageNo;

					CString strPoint;
					strPoint.Format(_T("%d,%d"), pt.x, pt.y);
					pPdfNoteInfo->coord = strPoint;

					std::map<int, std::pair<int, int>>::iterator it = model.main.pageSizes.find(pageNo);
					std::pair<int, int> pr = it->second;
					pPdfNoteInfo->pageWidth = pr.first;
					pPdfNoteInfo->pageHeight = pr.second;
				}

				int catalogId = FindCalalogId(items, iter->id);
				pPdfNoteInfo->noteCatalog.Format(_T("%d"), catalogId);

				CNoteDao noteDao;
				noteDao.AddNoteInfo(*pPdfNoteInfo, TRUE);
			}			
		}



		if (pPdfNoteInfo != NULL)
		{
			delete pPdfNoteInfo;
			pPdfNoteInfo = NULL;
		}
	}

	TCHAR bookPath[MAX_PATH] = {0};
	_tcscpy(bookPath, m_lpszRootPath);
	_tcscat(bookPath, _T("resources\\books\\"));
	_tcscat(bookPath, m_lpszFileName);
	_tcscat(bookPath, _T(".pdf"));

	MoveFile(lpszPdfFileName, bookPath);


	DeleteFileByName(lpszManFileName);
	DeleteFileByName(lpszRegFileName);
	DeleteFileByName(lpszRelFileName);
	DeleteFileByName(lpszCotFileName);
	DeleteFileByName(lpszPdfFileName);

	m_log.WriteLog(_T("ImportOneBook End"));


	return TRUE;
}

BOOL CEnhancedBookImporter::DeleteFileByName(CString strFileName)
{
	DWORD fileAttributes = GetFileAttributes(strFileName);
	fileAttributes &= ~FILE_ATTRIBUTE_READONLY;
	SetFileAttributes(strFileName, fileAttributes);
	::DeleteFile(strFileName);

	return TRUE;
}

TCHAR* CEnhancedBookImporter::GetBookIdByName(wchar_t* name)
{
#ifdef IMPORT_VERSION_PC
	CString strName = _T("resources\\books\\");
#elif defined IMPORT_VERSION_ANDROID
	CString strName = _T("resources/books/");
#endif

	TCHAR lpszName[MAX_PATH] = {0};

	_tcscpy(lpszName, _T("resources\\books\\"));
	_tcscat(lpszName, name);
	_tcscat(lpszName, _T(".pdf"));


	CBookDal bookDal;
	CBookInfo bookInfo = bookDal.GetBookInfosByBookTextPath(lpszName);

	return (LPTSTR)(LPCTSTR)bookInfo.bookId;
}

BOOL CEnhancedBookImporter::IsBookHasImported(TCHAR* lpszBookID)
{
	CNoteDao noteDao;
	std::vector<CPDFNoteInfo*> NoteInfos;
	noteDao.GetNoteInfosByBookId(lpszBookID, NoteInfos);
	if (NoteInfos.size() > 0)
	{
		std::vector<CPDFNoteInfo*>::iterator iter;
		for (iter = NoteInfos.begin(); iter != NoteInfos.end(); iter++)
		{
			if (NULL != *iter)
			{
				delete *iter;
				*iter = NULL;
			}
		}
		NoteInfos.clear();
		return TRUE;
	}
	return FALSE;
}

BOOL CEnhancedBookImporter::DeleteDirectory(TCHAR* lpszDir)
{
	CFileFind finder;
	TCHAR lpszDirectory[MAX_PATH] = {0};
	_tcscpy(lpszDirectory, lpszDir);
	_tcscat(lpszDirectory, _T("\\*.*"));

	BOOL IsFinded=(BOOL)finder.FindFile(lpszDirectory);
	while(IsFinded)
	{
		IsFinded=(BOOL)finder.FindNextFile();
		if(finder.IsDirectory())
		{
			if(!finder.IsDots())
			{
				CString strPath = finder.GetFilePath();
				DeleteDirectory((LPTSTR)(LPCTSTR)strPath);
			}
		}
		else
		{
			CString str = finder.GetFilePath();
			DWORD fileAttributes = GetFileAttributes(str);
			fileAttributes &= ~FILE_ATTRIBUTE_READONLY;
			SetFileAttributes(str, fileAttributes);
			SetFileAttributes(finder.GetFilePath(), FILE_ATTRIBUTE_NORMAL);
			BOOL bDelete = ::DeleteFile(str);
			if (!bDelete)
			{
				return FALSE;
			}
		}
	}

	return TRUE;
}

void CEnhancedBookImporter::CreateAllDirectory(TCHAR* lpszPath)
{
	CFileFind aFinder;
	CString csTemp;
	int rootLength = _tcslen(m_lpszRootPath);
	int nPos,nStartPos = rootLength;
	CString strPath(lpszPath);
	do
	{
		nPos = strPath.Find(L"\\", nStartPos + 1);
		if( nPos != -1)
		{
			CString csCur = strPath.Mid(0, nPos);
			CreateDirectory(csCur, NULL);
		}
		else
		{
			CreateDirectory(strPath, NULL);
		}
		nStartPos = nPos + 1;
	}while(nPos != -1);
}