#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "text_oem.h"
#include "thr_func.h"

BOOL thr_CallBackFunc2(LDDMC_OLEERR* OleErr)
{
	printf("This OleErr is level %d\n",OleErr->LevNum);
	printf("This OleErr's code is %d\n",OleErr->ErrCode);
	printf("This OleErr's Engine is %s\n",OleErr->DtctResult);
	if (OleErr->ErrCode) return DMC_TRUE; // 2007/05/24 by show
	return DMC_FALSE;
}

RESULT_TYPE CALLING thr_GetText(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetText_V3( pData->appfile, pData->txtfile, &(pData->textInfo) );
	if( iRet == 0 ) {
		printf("GetText from %s to %s succeeded.\n", pData->appfile, pData->txtfile);
	}
	else {
		printf("GetText from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetText_V4(void *arg)
{
	INT iRet=0;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetText_V4( pData->appfile, pData->txtfile, &(pData->textInfo_V4),(DMC_OLEERR_CALLBACK)thr_CallBackFunc2);
	if( iRet == 0 ) {
		printf("GetText_V4 from %s to %s succeeded.\n", pData->appfile, pData->txtfile);
	}
	else {
		printf("GetText_V4 from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}


RESULT_TYPE CALLING thr_GetTextStream_V4(void *arg)
{
	INT iRet=0;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= ToStreamDmc( pData->appfile, pData->txtfile, &(pData->textInfo_V4));

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetPageText(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetPageText_V3( pData->appfile, pData->txtfile, &(pData->textInfo), &(pData->pages) );
	if( iRet == 0 ) {
		printf("GetPageText from %s to %s succeeded, total pages: %d.\n", pData->appfile, pData->txtfile, pData->pages);
	}
	else {
		printf("GetPageText from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}


RESULT_TYPE CALLING thr_GetPageTextStream_V4(void *arg)
{
	INT iRet=0;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= ToPageStreamDmc( pData->appfile, pData->txtfile, &(pData->textInfo_V4), &(pData->pages));

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}


RESULT_TYPE CALLING thr_GetPageText_V4(void *arg)
{
	INT iRet=0;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetPageText_V4( pData->appfile, pData->txtfile, &(pData->textInfo_V4), &(pData->pages),(DMC_OLEERR_CALLBACK)thr_CallBackFunc2 );
	if( iRet == 0 ) {
		printf("GetPageText_V4 from %s to %s succeeded, total pages: %d.\n", pData->appfile, pData->txtfile, pData->pages);
	}
	else {
		printf("GetPageText_V4 from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}


RESULT_TYPE CALLING thr_GetProperty(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	if (((iRet = DMC_GetProperty_V3( pData->appfile, &(pData->textInfo), &(pData->property))) == 0) &&
		((iRet = WritePropertyToFile((char*)pData->txtfile, &(pData->property), pData->textInfo.GroupName)) == DMC_TRUE)) {
		printf("GetProperty from %s succeeded.\n", pData->appfile);
		iRet = 0;
	}
	else {
		printf("GetProperty from %s failed, error code: %d\n", pData->appfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetProperty_V4(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	if (((iRet = DMC_GetProperty_V4( pData->appfile, &(pData->textInfo_V4), &(pData->property))) == 0) &&
		((iRet = WritePropertyToFile((char*)pData->txtfile, &(pData->property), pData->textInfo_V4.GroupName)) == DMC_TRUE)) {
		printf("GetProperty_V4 from %s succeeded.\n", pData->appfile);
		iRet = 0;
	}
	else {
		printf("GetProperty_V4 from %s failed, error code: %d\n", pData->appfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetPwdText(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetPwdText_V3( pData->appfile, pData->txtfile, &(pData->textInfo),(unsigned char *)pData->password );
	if( iRet == 0 ) {
		printf("GetPwdText from %s to %s succeeded.\n", pData->appfile, pData->txtfile);
	}
	else {
		printf("GetPwdText from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetPwdText_V4(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetPwdText_V4( pData->appfile, pData->txtfile, &(pData->textInfo_V4),(unsigned char *)pData->password,(DMC_OLEERR_CALLBACK)thr_CallBackFunc2  );
	if( iRet == 0 ) {
		printf("GetPwdText_V4 from %s to %s succeeded.\n", pData->appfile, pData->txtfile);
	}
	else {
		printf("GetPwdText_V4 from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetPwdPageText(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetPwdPageText_V3( pData->appfile, pData->txtfile, &(pData->textInfo), &(pData->pages),(unsigned char *)pData->password );
	if( iRet == 0 ) {
		printf("GetPwdPageText from %s to %s succeeded, total pages: %d.\n", pData->appfile, pData->txtfile, pData->pages);
	}
	else {
		printf("GetPwdPageText from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetPwdPageText_V4(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	iRet= DMC_GetPwdPageText_V4( pData->appfile, pData->txtfile, &(pData->textInfo_V4), &(pData->pages),(unsigned char *)pData->password,(DMC_OLEERR_CALLBACK)thr_CallBackFunc2  );
	if( iRet == 0 ) {
		printf("GetPwdPageText_V4 from %s to %s succeeded, total pages: %d.\n", pData->appfile, pData->txtfile, pData->pages);
	}
	else {
		printf("GetPwdPageText_V4 from %s to %s failed, error code: %d\n", pData->appfile, pData->txtfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}


RESULT_TYPE CALLING thr_GetPwdProperty(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	if (((iRet = DMC_GetPwdProperty_V3( pData->appfile, &(pData->textInfo), &(pData->property), (unsigned char *)pData->password)) == 0) &&
		((iRet = WritePropertyToFile((char*)pData->txtfile, &(pData->property), pData->textInfo.GroupName)) == DMC_TRUE)) {
		printf("GetPwdProperty from %s succeeded.\n", pData->appfile);
		iRet = 0;
	}
	else {
		printf("GetPwdProperty from %s failed, error code: %d\n", pData->appfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

RESULT_TYPE CALLING thr_GetPwdProperty_V4(void *arg)
{
	INT iRet;
	THR_DATA *pData = (THR_DATA *)arg;
#if defined DMC_WIN
	if( !pData ) return -1;
#else
	if( !pData ) return NULL;
#endif // #if defined DMC_WIN

	if (((iRet = DMC_GetPwdProperty_V4( pData->appfile, &(pData->textInfo_V4), &(pData->property), (unsigned char *)pData->password)) == 0) &&
		((iRet = WritePropertyToFile((char*)pData->txtfile, &(pData->property), pData->textInfo_V4.GroupName)) == DMC_TRUE)) {
		printf("GetPwdProperty_V4 from %s succeeded.\n", pData->appfile);
		iRet = 0;
	}
	else {
		printf("GetPwdProperty_V4 from %s failed, error code: %d\n", pData->appfile, iRet);
	}

#if defined DMC_WIN
	return iRet;
#else
	return NULL;
#endif // #if defined DMC_WIN
}

static int CutZero( const char* str, int nlen,Byte* GroupName )
{
	int i=0;
	Byte  dw=0;
	Word  dw1=0;
	DWord dw2=0;

	if(!strcmp((const char*)GroupName,"ISO-10646-UCS-2") || !strcmp((const char*)GroupName,"UTF-16") ){
		for(i=0; i<nlen; i+=2) {
			dw1= *(Word*)(str+i);
			if( dw1 == 0 ) break;
		}
	}
	else if(!strcmp((const char*)GroupName,"ISO-10646-UCS-4")){
		for(i=0; i<nlen; i+=4) {
			dw2= *(DWord*)(str+i);
			if( dw2 == 0 ) break;
		}
	}
	else{
		for(i=0; i<nlen; i+=1) {
			dw= *(str+i);
			if( dw == 0 ) break;
		}
	}

	return i;
}

static void WriteFileString( FILE* fp, const char* str, int nlen,Byte* GroupName )
{
	int n= CutZero(str, nlen,GroupName);
	if( n>0 ) 
		fwrite(str,1,n,fp);
	else 
		fwrite("\0",1,1,fp);
}

static int APP_FileTellSize( FILE* file )
{
	int fSize = 0;
	int fCur = 0;

	fCur = ftell(file);
	if(fCur < 0) return -1;
	fseek(file, 0, SEEK_END);
	fSize = ftell( file );
	if(fSize < 0) return -1;
	fseek( file, fCur, SEEK_SET);
	return fSize;
}


int WritePropertyToFile(const char* filename, DMC_PROPERTY* pProp,Byte* GroupName)
{
	int filesize=0;
	FILE* fp= fopen(filename,"wb");
	if(!fp) {
		printf("can't open %s\n",filename);
		return FileCantOpen;
	}

	WriteFileString(fp, pProp->title,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->author,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->keyword,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->subject,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->comment,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->manager,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->company,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->category,		MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->createdate,		MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->revision,		MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->lastrevisor,		MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->revisioncount,	MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->lastprintdate,	MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->edittime,		MAXDATABUF,GroupName);
	/*WriteFileString(fp, pProp->lastrevidate,	MAXDATABUF);*/
	WriteFileString(fp, pProp->creator,			MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->producer,		MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->encryptionflag,	32,GroupName);
	/*WriteFileString(fp, pProp->operat,			MAXCHARBUF);*/
	WriteFileString(fp, pProp->slides,			MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->paragraphs,		MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->bytes,			MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->notes,			MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->presentation,	MAXCHARBUF,GroupName);
	WriteFileString(fp, pProp->doctype,			MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->lastsavetime,	MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->owner,			MAXDATABUF,GroupName);
	
	/* word perfect */
	WriteFileString(fp, pProp->abstract, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->account, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->address, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->attachments, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->authorization, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->bill_to, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->blind_copy, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->carbon_copy, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->checked_by, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->client, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->department, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->descriptive_name, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->descriptive_type, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->destination, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->disposition, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->division, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->document_number, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->editor, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->forward_to, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->group, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->language, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->mail_stop, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->matter, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->office, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->project, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->publisher, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->purpose, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->received_from, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->recorded_by, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->recorded_date, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->reference, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->revision_date, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->revision_notes, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->section, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->security, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->source, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->status, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->telephone_number, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->typist, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->version_date, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->version_notes, MAXDATABUF,GroupName);
	WriteFileString(fp, pProp->version_number, MAXDATABUF,GroupName);

	filesize=APP_FileTellSize(fp);
	if(filesize<0){
		return OtherProblems;
	}
	else if(filesize==0){
		if(fp){
			fclose(fp);
			remove(filename);
		}
		return NoTextStringFound;
	}
	if(fp){
		fclose(fp);
	}
	return DMC_TRUE;
}
