#include <Platform_Lib/SubtitleParser/TEXTSUBParser.h>
#include <Application/AppClass/SetupClass.h>
// Resource Manager
#include <Utility/ResourceMgr/resource.h>

#include <Platform_Lib/FontRenderer/render.h>
#include <string.h>
#include <stdlib.h>

#ifndef IS_SET
    #define IS_SET(x,y)     ((x) & (y))
    #define ClearFlag(x,y)  ((x) &= ~(y))
    #define SetFlag(x,y)    ((x) |= (y))
#endif

//#define DEBUGPRINT
#ifdef DEBUGPRINT
#define DBGPRINT(fmt,args...)  printf(fmt,## args)
#else 
#define DBGPRINT(fmt,args...) 
#endif

bool TEXTSUBParser :: Open(char *filename) {
	char textBuffer[TEXTSUB_BUFFER_LENGTH];
	fp = fopen(filename, "rb");
	if(fp == NULL) {
		SetFlag(m_state, TEXTSUB_PARSER_STATE_FAIL);
		return false;
	}

	m_state = 0;
	
//	memset(start_smi_data, 0, sizeof(start_smi_data));
//	memset(stop_smi_data, 0, sizeof(stop_smi_data));
	startTimeMs = 0;
	stopTimeMs = 0;
	startframe = 0;
	stopframe = 0;
	lastSeekTimeMs = -1;
	
	//get subtitle charset_encoding
	switch((SetupClass::GetInstance())->GetTextSubtitleEncoding()){
		case TEXT_ENCODING_UTF8:
			charset_encoding = UTF8;
			break;
		case TEXT_ENCODING_GBK:
			charset_encoding = DBCS_GBK;
			break;
		case TEXT_ENCODING_BIG5:
			charset_encoding = DBCS_BIG5;
			break;
		default:
			charset_encoding = UTF8;
	}
	//charset_encoding = DBCS_BIG5;
	//omit UTF BOM
	unsigned char tmp[3];
	if (charset_encoding == UTF8){
			if(!fread(tmp,3,1,fp)){
				SetFlag(m_state, TEXTSUB_PARSER_STATE_FAIL);
				return false;
			}
			if((tmp[0]==0xef)&&(tmp[1]==0xbb)&&(tmp[2]==0xbf))
				;
			else //file do not have UTF8 BOM
				rewind(fp);
	}
	//find the auccurate fps int the header			
	do {
			if(fgets(textBuffer, TEXTSUB_BUFFER_LENGTH, fp) == NULL) /* eof/error */
				return false;
			if(sscanf(textBuffer, "{%d}{%d}", &startframe,&stopframe) == 2)
				break;
			} while(1);

	if(startframe != stopframe){
		printf("no fps informmation in the textsub\n");
		accurate_fps =	-1;	//-1 means no fps information in textsub
		fps_multiplier = 1;
		fseek(fp, -strlen(textBuffer), SEEK_CUR);
		return true;
	}
	char *p;
	char *tmpstr;
	//find the second occurrence of the '}'
	p = strchr(textBuffer,'}');
	if(p!=NULL)
	p = strchr(p+1,'}');
			
	//get the fps string
	if(strlen(p+1) <= TEXTSUB_BUFFER_LENGTH)
		strcpy(current_text,p+1);		

	//accurate_fps = atof(current_text);
	//mips toolchain can not support float 
	//so process the float to int 
        p = current_text;
	
	printf(">>>>>>>>>>>>>>>>>text = %s\n>>>>>>>>>>>>>>>>>",p);
        tmpstr = strchr(p,'.');
	//fps is interger
	if(tmpstr ==NULL){
		accurate_fps = atol(p);
		fps_multiplier = 1;
		return true;
	}
	//fps is float
        if(tmpstr != strrchr(p,'.')){
                printf("error11111111111111\n");
        	return false;
        }

        fps_multiplier = 0;
        int i=0;
        while(p != tmpstr){
                if((*p<'0')||(*p>'9')){
                        printf("error2222222222222222\n");
                        return false ;
                }
                textBuffer[i++]=*(p++);
        }
        p = tmpstr+1;
        while((*p !='\0')&&(*p != '\r')&&(*p != '\n')){
         if((*p<'0')||(*p>'9')){
                        printf("error333333333333333\n");
                        return false ;
                }
                textBuffer[i++]=*(p++);
		fps_multiplier += 1;
        }

        textBuffer[i]='\0';
			
	accurate_fps = atol(textBuffer);
	i =1;
	while(fps_multiplier > 0){
		i = i*10;
		fps_multiplier --;
	}	
	fps_multiplier = i;
	
	printf("########################### accurate fps = %f ,multiplier = %d ############################\n",accurate_fps,fps_multiplier);


	return true;
}

bool TEXTSUBParser :: Close() {
	if(fp != NULL)
		fclose(fp);
	return true;
}



void TEXTSUBParser :: ProcessText( char * text) {
//	FontRenderer *pFont;
	int offset;
	char tmpbuf[1024];
	char *tmp = tmpbuf;//output buf
//	(ResourceMgr::GetInstance())->GetFontRenderer(FONT_FREETYPE, FONT_STYLE_CJK, FONT_SIZE_CUSTOM, &pFont);
	if(charset_encoding == UTF8){
		while(*text != '\0'){
			FontRenderer::get_char_code(text, UTF8, &offset);
	//		if(offset != 1){ // not single byte charset
			if((offset != 1)&&(offset <= 4)&&(offset >= 2)){ // not single byte charset
				strncpy(tmp, text,offset); //just copy to output buf
				text += offset;
				tmp += offset;
			}	
			else{
				if(*text == '|'){ //treat '|' as "\r\n"
					text += 1;
					*tmp = '\r';
					*(tmp+1) = '\n';
					tmp += 2;
				}
				else
					*(tmp++) = *(text++);
			}
		}
		*tmp = '\0';
	}
	else{//BIG5 or GBK
		while(*text != '\0'){
			if(*text < 0 ){//not single byte charset
				strncpy(tmp, text,2); //just copy to output buf
				text += 2;
				tmp += 2;
			}
			else{
				if(*text == '|'){ //treat '|' as "\r\n"
					text += 1;
					*tmp = '\r';
					*(tmp+1) = '\n';
					tmp += 2;
				}
				else
					*(tmp++) = *(text++);
			}
				
		}
		*tmp = '\0';
	}

	strcpy(current_text,tmpbuf);
}



int TEXTSUBParser :: GetSubtitle(int timeMs, SUBTITLE_STYLE_SHEET *stylesheet, char **text,float fps) {
	char textBuffer[TEXTSUB_BUFFER_LENGTH];

	lastSeekTimeMs = -1; // not seek but sequential read
	
	if(IS_SET(m_state, TEXTSUB_PARSER_STATE_FAIL))
		return -1;


	if((accurate_fps == -1)&&(fps_multiplier ==1))//if no fps information in textsub,use video fps
	{				
		printf("#########################use video fps %f\n",fps);
		accurate_fps = fps;
		fps_multiplier =1;
	}
	



	/* style sheet initialization */
	stylesheet->type = PLAIN;

	/* check current one */
		/* (1) [SUB_TIME START] <NAVTIME> [SUB_TIME STOP] */
	if(timeMs >= startTimeMs && timeMs < stopTimeMs) {
		*text = current_text;
		return(stopTimeMs - timeMs);
	}
		/* (2) <NAVTIME> [SUB_TIME START] [SUB_TIME STOP] */
	else if(timeMs <= startTimeMs)
		return SubtitleSeek(timeMs, stylesheet, text,fps);

		/* (3) [SUB_TIME START] [SUB_TIME STOP] <NAVTIME> */
	while(stopTimeMs == 0 || timeMs >= stopTimeMs) {
			//find line start with '{'
			do {
			if(fgets(textBuffer, TEXTSUB_BUFFER_LENGTH, fp) == NULL) /* eof/error */
				return -1;
			if(sscanf(textBuffer, "{%d}{%d}", &startframe,&stopframe) == 2)
				break;
			} while(1);
	/*
			//get Start and end frame num
			if(sscanf(textBuffer, "{%d}{%d}", &startframe,&stopframe) != 2) {
			SetFlag(m_state, TEXTSUB_PARSER_STATE_ERROR);
			return -1;
			}
	*/		
			startTimeMs = (int)(startframe *1000ULL *fps_multiplier /accurate_fps);//fps;
			stopTimeMs = (int) (stopframe * 1000ULL *fps_multiplier /accurate_fps);//fps;
		//	printf("###########get Subtitle:%d %d\n",startTimeMs,stopTimeMs);
			char *tmp;
			//find the second occurrence of the '}'
			tmp = strchr(textBuffer,'}');
			if(tmp!=NULL)
				tmp = strchr(tmp+1,'}');
			
			//get subtitle text
			if(strlen(tmp+1) <= TEXTSUB_BUFFER_LENGTH)
				strcpy(current_text,tmp+1);
		}
	
		//format current_text		
		ProcessText(current_text);
		
	 	if(timeMs >= startTimeMs && timeMs < stopTimeMs) {
			*text = current_text;
			return(stopTimeMs - timeMs);
		}
		else
			return -1;
}


int TEXTSUBParser :: SubtitleSeek(int timeMs, SUBTITLE_STYLE_SHEET *stylesheet, char **text,float fps) {
	char textBuffer[TEXTSUB_BUFFER_LENGTH];

	ClearFlag(m_state, TEXTSUB_PARSER_STATE_ERROR);

	/* redundant seek eliminiation */
		/* [last seek] [target] [stopTimeMs] */
	#if 0
	if(lastSeekTimeMs != -1 && timeMs > lastSeekTimeMs && timeMs < stopTimeMs) {
		lastSeekTimeMs = timeMs;
		return -1;
	}
	lastSeekTimeMs = timeMs;
	#endif

	if((accurate_fps == -1)&&(fps_multiplier ==1))//if no fps information in textsub,use video fps
	{				
		printf("#########################use video fps %f\n",fps);
		accurate_fps = fps;
		fps_multiplier =1;
	}

	

	/* style sheet initialization */
	stylesheet->type = PLAIN;

	/* rewind */
	rewind(fp);

	startTimeMs = 0;
	stopTimeMs = 0;
	
	while(stopTimeMs == 0 || timeMs >= stopTimeMs) {
			//find line start with '{'
			do {
			if(fgets(textBuffer, TEXTSUB_BUFFER_LENGTH, fp) == NULL) /* eof/error */
				return -1;
			if(sscanf(textBuffer, "{%d}{%d}", &startframe,&stopframe) == 2)
				break;
			} while(1);
	/*
			//get Start and end frame num
			if(sscanf(textBuffer, "{%d}{%d}", &startframe,&stopframe) != 2) {
			SetFlag(m_state, TEXTSUB_PARSER_STATE_ERROR);
			return -1;
			}
	*/		
			
			startTimeMs = (int)(startframe *1000ULL *fps_multiplier /accurate_fps);//fps;
			stopTimeMs = (int) (stopframe * 1000ULL *fps_multiplier /accurate_fps);//fps;
			//printf("###########Seek Subtitle:%d %d\n",startTimeMs,stopTimeMs);
			
			char *tmp;
			//find the second occurrence of the '}'
			tmp = strchr(textBuffer,'}');
			if(tmp!=NULL)
				tmp = strchr(tmp+1,'}');
			
			//get subtitle text
			if(strlen(tmp+1) <= TEXTSUB_BUFFER_LENGTH)
				strcpy(current_text,tmp+1);
		}
	
		//format current_text		
		ProcessText(current_text);
		
	 	if(timeMs >= startTimeMs && timeMs < stopTimeMs) {
			*text = current_text;
			return(stopTimeMs - timeMs);
		}
		else
			return -1;
}

