
#ifndef WORD_DOCUMENT_H_
#define WORD_DOCUMENT_H_


typedef struct
{
	string		strBaseStyle;
	
	bool		bFontBold;
	bool		bItalic;
	int			nFontColor;
	int			nFontSize;
}DOC_STYLE;

class BaseDocument
{
public:
	virtual bool SetDebugMode(bool bDebugMode=true) {return false;}
	
	virtual bool OpenDoc(LPCSTR lpcszFile=NULL) {return false;}
	virtual bool OpenTemplate(LPCSTR lpcszTemplate) {return false;}
	virtual bool SaveDoc(LPCSTR lpcszFileName) {return false;}
	/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
	//virtual bool CloseDoc() {return false;}
	virtual bool CloseDoc(bool bSaveChange = false) {return false;}
	/// end XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
	virtual bool CloseAllDoc() {return false;}
	
	virtual bool IsValid() {return false;}
	
	virtual bool AddString(const string& str, LPCSTR lpcszTable=NULL, LPCSTR lpcszBookMark=NULL, LPCSTR lpcszStyle=NULL) {return false;}
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//virtual bool AddRichText(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark=NULL, LPCSTR lpcszStyle=NULL) {return false;}
	virtual bool AddRichText(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark=NULL, LPCSTR lpcszStyle=NULL, bool bIsTable = true) {return false;}
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	virtual bool FillTable(const vector<string>& vsVals, int nCols, int& nTableIndex, LPCSTR lpcszTableBookMark=NULL, int nNumHeaderLine=0, LPCSTR lpcszCellBookMark=NULL) {return false;}
	virtual bool SplitTableCell(int nTableIndex=0, int nRow=0, int nCol=-1, int nCols=-1, LPCSTR lpcszTableBookMark=NULL, const vector<string>& vsVals=NULL, int nValCols=0, LPCSTR lpcszNewTableName=NULL, LPCSTR lpcszCellBookMark=NULL) {return false;}

	/// ----AW 11/03/05 ADD_HELP_SCREEN_SHOT
	virtual bool AddImage(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark =NULL) {return false;}
	virtual bool GetImageFile(vector<char>& vcDoc) { return false; }
	string SetFileName(LPCSTR lpcszFileName) { m_strFileName = lpcszFileName; return m_strFileName; }
	/// ---- END ADD_HELP_SCREEN_SHOT
	virtual bool SplitCellTwoRows(LPCSTR lpcszCellBookMark = NULL, LPCSTR lpcszNewCellName = NULL){return false;} ///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//use book mark to search
	virtual bool GetString(LPCSTR lpcszBookMark, string& str, bool bTableString=true){return false;}
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//virtual bool GetRichText(LPCSTR lpcszBookMark, vector<char>& vcDoc){return false;}
	virtual bool GetRichText(LPCSTR lpcszBookMark, vector<char>& vcDoc, bool bIsTable = true){return false;} //Table is true, Cell is false;
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	virtual bool DeleteSection(LPCSTR lpcszBookMark) {return false;}
	virtual	bool CreateStyle(LPCSTR lpcszStyleName, DOC_STYLE& Style){return false;}
	virtual bool SetFontColor(int nColorRGB){return false;}
	
protected:
	/// ----AW 11/03/05 ADD_HELP_SCREEN_SHOT
	string		m_strFileName;    // current file name of the file being processed.
	/// END 11/03/05 ADD_HELP_SCREEN_SHOT
	
};

///////////////////////////////////////////////////////////////////////////
/////////////////////			WordDocument		///////////////////////
///////////////////////////////////////////////////////////////////////////

/// YuI 01/31/06 DOCUMENT_FUNCTIONS_SHOULD_DEAL_WITH_TREE_ONLY
//	bool create_xf_document(BaseDocument& oDoc, XFunction& xf, TreeNode& trXF, const string& strStoredFolder, int nLang, DWORD dwOptions=0);
//	bool update_xf_by_document(BaseDocument& oDoc, XFunction& xf, TreeNode& trXF, const string& strDocFile, int nLang, DWORD dwOptions=0);
bool create_xf_document(BaseDocument& oDoc, TreeNode& trXF, const string& strStoredFolder, int nLang, DWORD dwOptions=0, BOOL bInternal = FALSE);
bool update_xf_by_document(BaseDocument& oDoc, TreeNode& trXF, const string& strDocFile, int nLang, DWORD dwOptions=0);
/// end DOCUMENT_FUNCTIONS_SHOULD_DEAL_WITH_TREE_ONLY
//---The following bookmark should be created in template file with same name
//book mark
#define STR_XF_BOOKMARK_TITLE						"xf_title"
#define STR_XF_BOOKMARK_CATEGORY					"xf_category"  ///Iris 06/28/06 ADD_CATEGORY
#define STR_XF_BOOKMARK_DESCTIP						"xf_description"
#define STR_XF_BOOKMARK_SYNTAX						"xf_syntax"
#define STR_XF_BOOKMARK_VARIABLES					"xf_variables"
#define STR_XF_BOOKMARK_BRIEF_INFO					"xf_briefinfo"
#define STR_XF_BOOKMARK_ADDITIONAL_INFO				"xf_additionalinfo" /// Hong 09/03/07 QA80-9548 v8.0694 NEW_TABLE_ADDITIONAL_INFO_FOR_ORIGINPRO_ONLY
#define STR_XF_BOOKMARK_SUMMARY						"xf_summary"
#define STR_XF_BOOKMARK_EXAMPLE						"xf_example"
#define STR_XF_BOOKMARK_REF							"xf_reference"
#define STR_XF_BOOKMARK_ALGORITHM					"xf_algorithm"
#define STR_XF_BOOKMARK_SEEALSO						"xf_seealso"
#define STR_XF_BOOKMARK_MODIFICATION_LOG			"xf_modificationlog" /// Iris 10/09/05 ADD_MODIFICATION_LOG
#define STR_XF_BOOKMARK_RELATED_XF					"xf_relatedXF" //---CPY 10/25/05 ADD_RELATED_XF_NODE_FOR_XF_DOC
#define STR_XF_BOOKMARK_PARAMETERS					"xf_parameters" ///DSC 10/27/05 ADD_PARAMETERS_NODE_TO_XFT
#define STR_XF_BOOKMARK_ERRMSG						"xf_errmessage"
#define STR_XF_BOOKMARK_SCREENSHOT					"xf_screenshot" /// ----AW 11/03/05 ADD_HELP_SCREEN_SHOT
#define STR_XF_BOOKMARK_MENU_INFO					"xf_menuinfo"
#define	STR_XF_BOOKMARK_LT_SCRIPT_EXAMPLE			"xf_script_example"	///---Joseph 04/26/07 QA70-9678 ADD_SCRIPT_EXAMPLE_NODE

#define STR_XFV_BOOKMARK_TABLE_CELL					"xfv_cell"
#define STR_XFV_BOOKMARK_LIST_CELL					"xfv_cell_list"
#define STR_XF_ERRMSG_TABLE_CELL					"xf_errmsg_cell"
///---
#define STR_XFV_STYLE_GRID_TABLE					"Table Grid"

#define STR_XFV_OPTIONLIST							"Option list"
#define STR_TEMP_IAMGE_FILE							"c:\\junk.jpg"	/// ----AW 11/03/05 ADD_HELP_SCREEN_SHOT
#define STR_IMAGE_FILE_EXT							".jpg"	/// ----AW 11/03/05 ADD_HELP_SCREEN_SHOT
///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
#define STR_TREENODE								_L("TreeNode")
/// Hong 08/29/07 QA80-0548 v8.0691 MORE_BETTER_STRING_FOR_REFER_MORE_DETAIL
//#define	STR_VARIABLES								_L("Variables")
#define	STR_VAR_SEE_MORE_DETAIL								_L("See more details in Description table")
/// end MORE_BETTER_STRING_FOR_REFER_MORE_DETAIL

#define _GET_NODE_VAR_DESPTION(_STR)				_STR = _STR + "_list";				
///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
enum {
	XF2DOC_CLEAR_EMPTY 	= 0x0001,
	XF2DOC_EDITING_DOC 	= 0x0002,
	XF2DOC_DEBUG_MODE	= 0x0004,
	XF2DOC_PARTIAL_CONTENT	= 0x0008, /// Hong 23/05/08 QA80-11565 DOC2XF_ALLOW_SKIP_CONTENTS_LIKE_PARAMETERS
	
	XF2DOC_LAST_ENTRY
};
#define NUM_VARS_COLS									4
#define NUM_VAR_COMBOLIST_COLS							2
#define NUM_ERRMSG_TABLE_COLS							2


// Word constants
#define wdGoToTable					2
#define wdGoToNext					2
#define wdGoToSection				0
#define wdGoToBookmark				-1
#define wdEndOfDocument				-1

#define wdCell						12
#define wdLine						5
#define wdParagraph					4
#define wdCharacter					1
#define wdExtend					1
#define wdRowHeightAtLeast			1

#define wdPreferredWidthPoints		3
#define wdAdjustNone				0
#define wdPasteDefault				0
#define wdSingleCellTable			6

#define wdColorBlue					16711680
#define wdColorDarkBlue				8388608
#define wdColorBlack				0
#define wdColorRed					255

#define wdStyleTypeParagraph		1
#define wdDoNotSaveChanges			0
#define wdSaveChanges 				-1	/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO

//the following function need try/catch to implement
//All operation is to current active document
class WordDocument : public BaseDocument
{
public:
	WordDocument(bool bWordVisible=true);
	~WordDocument();
	
	//virtual
	bool IsValid();
	bool SetDebugMode(bool bDebugMode=true);
	
	bool OpenDoc(LPCSTR lpcszFile=NULL);	//NULL to open an empty one
	bool OpenTemplate(LPCSTR lpcszTemplate);
	bool SaveDoc(LPCSTR lpcszFileName);
	/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
	//bool CloseDoc();
	bool CloseDoc(bool bSaveChange = false);
	/// end XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
	
	bool AddString(const string& str, LPCSTR lpcszTable=NULL, LPCSTR lpcszBookMark=NULL, LPCSTR lpcszStyle=NULL);
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//bool AddRichText(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark=NULL, LPCSTR lpcszStyle=NULL);
	bool AddRichText(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark=NULL, LPCSTR lpcszStyle=NULL, bool bIsTable = true);
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	bool FillTable(const vector<string>& vsVals, int nCols, int& nTableIndex, LPCSTR lpcszTableBookMark=NULL, int nNumHeaderLine=0, LPCSTR lpcszCellBookMark=NULL);
	//use book mark to search
	bool GetString(LPCSTR lpcszBookMark, string& str, bool bTableString=true);
	bool CleanString(LPCSTR lpcszBookMark, bool bTableString=true); /// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//bool GetRichText(LPCSTR lpcszBookMark, vector<char>& vcDoc);
	bool GetRichText(LPCSTR lpcszBookMark, vector<char>& vcDoc, bool IsTable = true); 
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	bool CreateStyle(LPCSTR lpcszStyleName, DOC_STYLE& Style);
	
	bool CloseAllDoc();
	bool SetFontColor(int nColorRGB);
		
protected:
	bool AddBookMark(LPCSTR lpcszBookMark);
	bool AddText(string strText, LPCSTR lpcszBookMark = NULL);
	
	//use book mark to search table
	string GetTableText(LPCSTR lpcszTableBookMark);	
	bool CleanTableText(LPCSTR lpcszTableBookMark); /// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO

	bool SetStyle(LPCSTR lpcszStyleName);
	bool GetTable(LPCSTR lpcszBookMark, Object& oWordTable);
	
	bool putCursorToEnd();
	bool addEditingTable(LPCSTR lpcszBookMark, LPCSTR lpcszTableName, LPCSTR lpcszStyleName);
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//bool doc2ActiveWord(vector<char>& vcDoc, LPCSTR lpcszStyleName=NULL);	//doc to dummy file, then insert dummy file to curent active word document
	bool doc2ActiveWord(vector<char>& vcDoc, LPCSTR lpcszStyleName=NULL, bool IsTable = true);	//doc to dummy file, then insert dummy file to curent active word document
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	/// ----AW 10/03/05 ADD_HELP_SCREEN_SHOT
	bool InsertImage(vector<char>& vcDoc);
	bool GetImageFile(vector<char>& vcDoc);
	/// END ADD_HELP_SCREEN_SHOT
	
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//string copyTableTextToDummyFile(LPCSTR lpcszTableBookMark);
	string copyTableTextToDummyFile(LPCSTR lpcszTableBookMark, bool bIsTable = true);
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	
	string getDocString(LPCSTR lpcszText);
	string getTemporaryDocFile();
	int findPrefixTabNumber(const string& str);
	int findEndEnterNumber(const string& str);
	
protected:
	Object				m_oWord;	//word application
	Object				m_oActiveDoc;
	
	bool				m_bVisible;
private:
};

//better put this in .c/.cpp file
//for help text
static bool _save_doc(LPCSTR lpcszFile, const vector<char>& vcDoc)
{
	file ff;
	if(ff.Open(lpcszFile, file::modeWrite | file::shareExclusive | file::modeCreate))
	{
		int nSize = vcDoc.GetSize();
		void* lp = (char*)vcDoc;
		ff.Write(lp, nSize); 
		ff.Flush();
		ff.Close();
		//printf("success in writing into %s, size = %d\n", lpcszFile, nSize);
		return true;
	}
	return false;
}
static bool _load_doc(LPCSTR lpcszFile, vector<char>& vcDoc)
{
	file docFile;

	// open the source file for reading
	bool bOK = docFile.Open(lpcszFile, file::modeRead | file::shareDenyWrite);
	
	if(!bOK)
	{
		string strErr = "failed to open the source file: ";
		strErr += lpcszFile;
		/// Iris 1/16/05 OUTPUT_DEBUG_ERR_MESSAGE
		//out_str(strErr);   /// AW 10/03/05 it is better add filename here.
		//return false;
		return error_report(strErr);
		///End OUTPUT_DEBUG_ERR_MESSAGE
	}
	DWORD dwSize = docFile.GetLength();
	vcDoc.SetSize(dwSize);
	LPSTR lpstr = vcDoc;
	docFile.Read(lpstr, dwSize);
	docFile.Close();
	//printf("success in reading %s, size = %d\n", lpcszFile, dwSize);
	return true;
}

WordDocument::WordDocument(bool bVisible)
{
	string str;
	str="/*******************************/\n\n";
	str+="Strongly recommend you close Word \nbefore running this application.\n\n";
	str+="/*******************************/\n\n\n";
	printf("%s", str);
	
	try
	{
		m_oWord = CreateObject("word.application");
	}
	catch(int nError)
	{
	}
	if(m_oWord)
	{
		m_oWord.Visible = bVisible;
		m_bVisible = bVisible;
	}
	else
		printf("Word not install in this computer.\nPlease install Word first.");
}
WordDocument::~WordDocument()
{
	if(m_oActiveDoc)
	{
		m_oActiveDoc.Close();
		m_oActiveDoc = NULL;
	}
	
	if(m_oWord)
	{
		//m_oWord.ScreenUpdating = true;
		SetDebugMode(true);	//debug mode all is visible
		m_oWord.Quit();
	}
	m_oWord=NULL;
}
bool WordDocument::IsValid()
{
	if(m_oWord)
		return true;
	return false;
}
bool WordDocument::SetDebugMode(bool bDebugMode)
{
	bool bVisible = bDebugMode;
	try
	{
		//m_oWord.Visible = bVisible;
		if(!bDebugMode)
		{
			m_oWord.ScreenUpdating=false;		//set un-visible will speed-up the running
			//m_oWord.DisplayStatusBar=false;		//Lock status bar	//error, already fail here
			m_oWord.StatusBar="Quick running mode, please wait for this ending...";
		}
		else	//debug mode
		{
			m_oWord.DisplayStatusBar=true;		//restore status bar
			m_oWord.ScreenUpdating=true;		//must store this after execution
		}
	}
	catch(int nErr)
	{
		return false;
	}
	return true;
}

bool WordDocument::OpenDoc(LPCSTR lpcszFile)
{
	string strFile(lpcszFile);
	try
	{
		if(strFile.IsEmpty())
			m_oActiveDoc = m_oWord.Documents.Add();	// Add a blank document
		else
			m_oActiveDoc = m_oWord.Documents.Open(strFile);
	}
	catch(int nError)
	{
		return false;
	}
	return true;
}
bool WordDocument::OpenTemplate(LPCSTR lpcszTemplate)
{
	string str(lpcszTemplate);
	try
	{
		m_oActiveDoc = m_oWord.Documents.Add(Template:=str);
	}
	catch(int nErr)
	{
		return false;
	}
	if(!m_oActiveDoc)
	{
		printf("Fail to open template: %s\n", str);
		return false;
	}
	return true;
}
bool WordDocument::SaveDoc(LPCSTR lpcszFileName)
{
	try
	{
		m_oActiveDoc.SaveAs(lpcszFileName);
	}
	catch(int nError)
	{
		 return false;
	}
	return true;
}
//need to get the current active index to m_nActive after close window
/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
//bool WordDocument::CloseDoc()
bool WordDocument::CloseDoc(bool bSaveChange) // false
/// end XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
{
	try
	{
		if(m_oActiveDoc)
		{
			/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
			if ( bSaveChange )
				m_oActiveDoc.Close(SaveChange:=wdSaveChanges);
			else
			/// end XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
			m_oActiveDoc.Close();
			m_oActiveDoc=NULL;
		}
		m_oActiveDoc = m_oWord.ActiveDocument;
	}
	catch(int nError)
	{
		 return false;
	}
	return true;
}
bool WordDocument::AddString(const string& str, LPCSTR lpcszTable, LPCSTR lpcszBookMark, LPCSTR lpcszStyle) //=NULL, NULL, NULL
{
	if(lpcszTable != NULL)
		addEditingTable(lpcszBookMark, lpcszTable, lpcszStyle);
	else	//else style for text
		SetStyle(lpcszStyle);
	return AddText(str, lpcszBookMark);
}
///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
//bool WordDocument::AddRichText(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark, LPCSTR lpcszStyle) //=NULL, NULL
bool WordDocument::AddRichText(const vector<char>& vcDoc, LPCSTR lpcszTable, LPCSTR lpcszBookMark, LPCSTR lpcszStyle, bool bIsTable) //=NULL, NULL
///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
{
	SetStyle(lpcszStyle);
	if(bIsTable)  ///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
		addEditingTable(lpcszBookMark, lpcszTable, lpcszStyle);
	bool bRet = doc2ActiveWord(vcDoc, lpcszStyle);
	putCursorToEnd();
	return bRet;
}
bool WordDocument::FillTable(const vector<string>& vsVals, int nCols, int& nTableIndex, LPCSTR lpcszTableBookMark, int nNumHeaderLine, LPCSTR lpcszCellBookMark)
{
	string strCellBookMark(lpcszCellBookMark);
	
	Object oWordTable;
	//start from the first cell of table if bookmark not specify
	if(NULL!=lpcszTableBookMark && !GetTable(lpcszTableBookMark, oWordTable))
		return false;
	
	bool bRet=true;
	//enlarge table by vsVals
	try
	{
		//posotin cursor in the begin edit cell
		if(0 < nNumHeaderLine)
			m_oWord.Selection.MoveRight(Unit:=wdCell, Count:=nNumHeaderLine*nCols);	//to the edit cell, skip header
		
		for(int ii=0; ii<vsVals.GetSize(); ii++)
		{
			if(0!=ii)
				m_oWord.Selection.MoveRight(Unit:=wdCell);
			if(!strCellBookMark.IsEmpty())
				AddBookMark(strCellBookMark+(string)(ii+1));
			m_oWord.Selection.TypeText(vsVals[ii]);
		}
	}
	catch(int nError)
	{
		error_report("Fail to put value inside tables.");
		bRet = false;
	}
	putCursorToEnd();
	return bRet;
}
bool WordDocument::GetString(LPCSTR lpcszBookMark, string& str, bool bTableString) //=true
{
	if(bTableString)
	{
		str = GetTableText(lpcszBookMark);
	}
	else	//add if needed
	{
		return false;
	}
	return true;
}

/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
bool WordDocument::CleanString(LPCSTR lpcszBookMark, bool bTableString) //=true
{
	if(bTableString)
	{
		return CleanTableText(lpcszBookMark);
	}
	else	//add if needed
	{
		return false;
	}
	
	return true;
}
/// end XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO

///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
//bool WordDocument::GetRichText(LPCSTR lpcszBookMark, vector<char>& vcDoc)
bool WordDocument::GetRichText(LPCSTR lpcszBookMark, vector<char>& vcDoc, bool bIsTable)
///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
{
	string strTempDoc;
	strTempDoc = copyTableTextToDummyFile(lpcszBookMark, bIsTable);
	
	if(strTempDoc.IsFile())
	{
		_load_doc(strTempDoc, vcDoc);	//load string from dummy file(temporary file)
		DeleteFile(strTempDoc);
		return true;
	}
	return false;
}

bool WordDocument::CloseAllDoc()
{
	try
	{
		for( int ii = 0; ii < m_oWord.Documents.Count; ii++ )
			//CloseDoc(ii);
			m_oWord.Documents.Item(ii).Close();
	}
	catch(int nError)
	{
		return false;
	}
	return true;
}

bool WordDocument::AddBookMark(LPCSTR lpcszBookMark)
{
	string str(lpcszBookMark);
	if(str.IsEmpty())
		return false;
	bool bRet=true;
	try
	{
		if(m_oActiveDoc.Bookmarks.Exists(str))
		{
			///if bookmark exist, goto bookmark
			m_oWord.Selection.GoTo(What:= wdGoToBookmark, Name:=str);
			bRet = false;
		}
		else
			m_oActiveDoc.Bookmarks.Add(str);
	}
	catch(int nError)
	{
		return false;
	}
	return bRet;
}
bool WordDocument::AddText(string strText, LPCSTR lpcszBookMark)
{
	// Add text
	try
	{
		AddBookMark(lpcszBookMark);
		m_oWord.Selection.TypeText(strText);
		
		putCursorToEnd();
	}
	catch(int nError)
	{
		return false;
	}
	return true;
}
bool WordDocument::SetFontColor(int nColorRGB)
{
	try
	{
		m_oWord.Selection.Font.Color = nColorRGB;
	}
	catch(int nError)
	{
		return false;
	}
	return true;
}

//use book mark to search table
string WordDocument::GetTableText(LPCSTR lpcszTableBookMark)
{
	string strText;
	int nEndEnter;
	Object oWordTable;
	if(!GetTable(lpcszTableBookMark, oWordTable))
	{
		return "";
	}
	
	try
	{
		m_oWord.Selection.SelectCell();
		
		strText = m_oWord.Selection.Text;
		strText = getDocString(strText);
	}
	catch(int nErr)
	{}
	return strText;
}

/// Hong 09/25/07 v8.0708 XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO
bool WordDocument::CleanTableText(LPCSTR lpcszTableBookMark)
{
	string strText;
	int nEndEnter;
	Object oWordTable;
	if(!GetTable(lpcszTableBookMark, oWordTable))
	{
		return false;
	}
	
	try
	{
		m_oWord.Selection.SelectCell();
		m_oWord.Selection.Delete();
	}
	catch(int nErr)
	{
		return false;
	}
	return true;
}
/// end XFDOC_REDUCE_SIZE_BY_REMOVE_NONGUI_HELP_INFO

//return style name
bool WordDocument::CreateStyle(LPCSTR lpcszStyleName, DOC_STYLE& FontStyle)
{
	int nn;
	Object oWordStyle;
	try
	{
		oWordStyle = m_oActiveDoc.Styles.Add(Name:=lpcszStyleName, Type:=wdStyleTypeParagraph);
		oWordStyle.AutomaticallyUpdate = false;
		
		if(!FontStyle.strBaseStyle.IsEmpty())
			oWordStyle.BaseStyle = FontStyle.strBaseStyle;
		oWordStyle.Font.Bold = FontStyle.bFontBold;
		oWordStyle.Font.Italic = FontStyle.bItalic;
		
		//keep old settings
		nn=FontStyle.nFontColor;
		if(-1 < nn)
			oWordStyle.Font.Color = nn;
		nn=FontStyle.nFontSize;
		if(0 < nn)
		oWordStyle.Font.Size = nn;
		
		//more style settings will be later
	}
	catch(int nError)
	{
		printf("Err create word style %s: %d\n", lpcszStyleName, nError);
		return false;
	}
	return true;
}
bool WordDocument::SetStyle(LPCSTR lpcszStyleName)
{
	if(NULL == lpcszStyleName) return false;
	try
	{
		m_oWord.Selection.Style = m_oActiveDoc.Styles(lpcszStyleName);
	}
	catch(int nError)
	{
		printf("Err set word style %s: %d\n", lpcszStyleName, nError);
		return false;
	}
	return true;
}
bool WordDocument::addEditingTable(LPCSTR lpcszBookMark, LPCSTR lpcszTableName, LPCSTR lpcszStyleName)
{
	if(!AddBookMark(lpcszBookMark))
		return false;	//
	
	// Add text as table name
	string strTableName(lpcszTableName);
	strTableName += "\r\n";
	if( ! AddText(strTableName) )
		return false;
	
	int nNumTab=findPrefixTabNumber(strTableName);
	double dTabSize = m_oActiveDoc.DefaultTabStop;
	// Add 1x1 table
	Object oWordTable;
	try
	{
		oWordTable = m_oActiveDoc.Tables.Add( m_oActiveDoc.Bookmarks.Item("\endofdoc").Range, 1, 1, 0, 2);		
		
		oWordTable.Rows.SetLeftIndent(LeftIndent:=dTabSize * nNumTab, RulerStyle:= wdAdjustNone);
	}
	catch(int nError)
	{
		return false;
	}
	
	// Position cursor at the edited cell
	try
	{
		oWordTable.Cell(Row := 1, Column := 1).Select();
	}
	catch(int nError)
	{
		error_report("Fail to position cursor at the edit cell");
		return true;
	}
	
	SetStyle(lpcszStyleName);
	return true;
}

//doc to dummy file, then insert dummy file to curent active word document
///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
//bool WordDocument::doc2ActiveWord(vector<char>& vcDoc, LPCSTR lpcszStyleName)
bool WordDocument::doc2ActiveWord(vector<char>& vcDoc, LPCSTR lpcszStyleName, bool bIsTable)
///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
{
	string strTempDoc = getTemporaryDocFile();
	
	bool bRet = _save_doc(strTempDoc, vcDoc);
	if(!bRet)
		return error_report("Fail to save document to RTF file");
	
	try
	{
		m_oWord.Selection.InsertFile(strTempDoc);
		m_oWord.Selection.TypeBackspace();	///DG 9/2/05 : remove new junk line
		///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
		//if(NULL != lpcszStyleName)
		if(bIsTable && NULL != lpcszStyleName) 
		///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
		{
			//set text color
			m_oWord.Selection.Tables(1).Select();
			SetStyle(lpcszStyleName);
		}
	}
	catch(int nError)
	{
		bRet=false;
	}
	DeleteFile(strTempDoc);
	return bRet;
}

/// ----AW 11/03/05 ADD_HELP_SCREEN_SHOT
bool WordDocument::InsertImage(vector<char>& vcDoc)
{
	string strImgFileName;
	if ( m_strFileName.IsEmpty() )
	{
		ASSERT(FALSE);
		strImgFileName = STR_TEMP_IAMGE_FILE;
	}
	else
	{
		strImgFileName = m_strFileName + STR_IMAGE_FILE_EXT	
	}
	bool bRet = _save_doc(strImgFileName, vcDoc);
	if(!bRet)
		return error_report("Fail to save temp image file");
	try
	{
		m_oWord.Selection.InlineShapes.AddPicture(FileName:=strImgFileName,LinkToFile:=1, SaveWithDocument:=1);
		m_oWord.Selection.TypeBackspace();	///DG 9/2/05 : remove new junk line
	}
	catch(int nError)
	{
		bRet=false;
	}
	//DeleteFile(strImgFileName);
	return bRet;
}
bool WordDocument::GetImageFile(vector<char>& vcDoc)
{
	string strImgName = m_strFileName + STR_IMAGE_FILE_EXT;
	return _load_doc(strImgName, vcDoc);
}

/// ----END ADD_HELP_SCREEN_SHOT
///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
//string WordDocument::copyTableTextToDummyFile(LPCSTR lpcszTableBookMark)
string WordDocument::copyTableTextToDummyFile(LPCSTR lpcszTableBookMark, bool bIsTable)
///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
{
	string strTempDoc;
	strTempDoc=getTemporaryDocFile();
	
	Object oWordTempDOC, oWordTable;
	
	//Goto table
	///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	//if(!GetTable(lpcszTableBookMark, oWordTable))
	if(bIsTable && !GetTable(lpcszTableBookMark, oWordTable))
	///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
	{
		return "";
	}
	
	bool bRet = true;
	try
	{
		//select table text
		///Joseph 11/30/06	SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
		//oWordTable.Select();
		//m_oWord.Selection.Tables(1).Select();
		if(bIsTable)
		{
			oWordTable.Select();
			m_oWord.Selection.Tables(1).Select();
		}
		else
		{
			m_oWord.Selection.GoTo(What:= wdGoToBookmark, Name:=lpcszTableBookMark);
			m_oWord.Selection.SelectCell();
		}
		///End SPLITE_TABLE_CELL_FOR_TREENODE_VARIABLE
		//Copy selected text
		m_oWord.Selection.Copy();
		
		//open a temporary Doc file
		oWordTempDOC = m_oWord.Documents.Add();
		
		//paste
		m_oWord.Selection.PasteAndFormat(wdPasteDefault);	//DOC_WDSINGLECELL_TABLE);
		
		//avoid pop-up dialog to ask clear clipboard, copy simple text("\n" at the end) to clean clipboard
		m_oWord.Selection.MoveRight(Unit:=wdCharacter, Count:=1, Extend:=wdExtend);
		m_oWord.Selection.Copy();
		
		//save and close
		oWordTempDOC.SaveAs(strTempDoc);
		oWordTempDOC.Close();
	}
	catch(int nError)
	{
		out_str("Fail to read table");
		return "";
	}
	return strTempDoc;
}
string WordDocument::getDocString(LPCSTR lpcszText)
{
	//format text to be oc string: trim junk character
	string strText(lpcszText);
	strText=strText.Left(strText.GetLength()-2);	//strangely, at the end of this text, it's '\a\a'
	
	///DG 9/2/05 : REMOVE_JUNK_WRAP_LINE_CHAR : trim junk '\n' in the end
	int nEndEnter=findEndEnterNumber(strText);
	if(2 < nEndEnter)	//if more, keep one
		nEndEnter--;
	strText=strText.Left(strText.GetLength()-nEndEnter);
	///end REMOVE_JUNK_WRAP_LINE_CHAR
	return strText;
}
string WordDocument::getTemporaryDocFile()
{
	//get a temporary rtf file to do rtf convertion
	string strPrefix, strTempRTF;
	strPrefix=okutil_get_origin_path(ORIGIN_PATH_USER, "OCTemp\\")+"XFDocTemporary";
	int nFile=0;
	strTempRTF=strPrefix+".doc";
	while(strTempRTF.IsFile())
	{
		nFile++;
		strTempRTF=strPrefix+(string)nFile+".doc";
	}
	return strTempRTF;
}
int WordDocument::findPrefixTabNumber(const string& str)
{
	return find_prefix_char_number(str, '\t');
}
int WordDocument::findEndEnterNumber(const string& str)
{
	return find_end_char_number(str, '\n');
}
bool WordDocument::putCursorToEnd()
{
	try
	{
		// Position cursor at end of doc
		m_oWord.Selection.GoTo(What:= wdGoToBookmark, Name:="\endofdoc");
	}
	catch(int nErro)
	{
		return false;
	}
	return true;
}
bool WordDocument::GetTable(LPCSTR lpcszBookMark, Object& oWordTable)
{
	string strTableBookMark(lpcszBookMark);
	try
	{
		//Goto table
		m_oWord.Selection.GoTo(What := wdGoToBookmark, Name:=strTableBookMark);
		oWordTable = m_oWord.Selection.GoTo(What := wdGoToTable, Which := wdGoToNext);
		oWordTable.Select();
	}
	catch(int nError)
	{
		printf("Fail to find table: %s\n", strTableBookMark);
		return false;
	}
	return true;
}

bool display_xf_help(const BaseDocument& oDoc, const string& strXFName, const int& nlanguage);




#endif //WORD_DOCUMENT_H_