#include "cc.h"

class cCcOsd :: cOsd{
public:
	cCcOsd();
	~cCcOsd();
	
protected:
	bool process(CC_Data* data, int len);
  bool doCommand(byte hi, byte lo);
	void setChannel(byte chn);
	void clearScreen(void);
	void clearLine(byte line, byte pos, byte len);
	
private:
	CC_Data cc_buffer[CC_BUFFER_SIZE];
	int nBufferPos;
	bool bWriteInBuffer;
	byte nXPos, nYPos;
	byte color;
	bool bItalic;
	bool bUnderline;
	byte nChannel;
	
	bool bCR;
	bool bTextMode;
}

cCcOsd::cCcOsd(){
	nBufferPos = 0;
	bCR = false;
	setChannel(CC1);
}

cCcOsd::~cCcOsd(){
	for(int i=0; i<nBufferSize; i++)
		delete [] cc_buffer[i].data;
}

void cCcOsd::setChannel(byte chn){
	nChannel = chn;
}

//! returns false only for last command
bool cCcOsd::process(CC_Data* data, int len){
	bool bOK = false;
	
	if(bCR){
		//scroll(1);
		bCR = false;
	}

	for(int i=0; i<len; i++{
		if(data[i].type == CC_COMMAND)
			for(int j=0; j<data[i].length; j+=2){
				if((bOK = doCommand(data[i].data[j], data[i].data[j+1])))
					UNSUP;				
			}
		else{
		}
		delete [] data[i].data;
	}
	
	delete [] data;
	
	return bOK;
}

bool cCcOsd::doCommand(byte hi, byte lo){
	byte pac_lines[] = {0x91, 0x91, 0x92, 0x92, 0x15, 0x15, 0x16, 0x16, 0x97, 0x97, 0x10, 0x13, 0x13, 0x94};
	bool bIsPAC = false;
	//Global commands
	byte channels4g[] = {0x94, 0x1c, 0x15, 0x9d};
	//Tab positionning commands
	byte channels2p[] = {0x97, 0x1f};
	
	bDone = false;
	
	//Processing general commands
	if(channels4g[nChannel]==hi){
		bTextMode = false;
		switch(lo){
			
			//RCL - Resume Caption Loading
			case 0x20:
				debug("{RCL}");
				if(bWriteInBuffer){
					cout << "CC: Buffer loop detected!" <<endl;
					bWriteInBuffer = false;
					return false;
				}
					
				bWriteInBuffer = true;
				bDone=true;
				break;
				
			//RDC - Resume Direct Captioning
			case 0x29:
				debug("{RDC}");
				bWriteInBuffer = false;
				bDone = true;
				break;
				
			//RU2 - 	Roll-Up Captions--2 Rows
			case 0x25:
				debug("{RU2}");
				nRollup = 2;				
				bDone = true;
				break;
				
			//RU3 - 	Roll-Up Captions--3 Rows
			case 0x26:
				debug("{RU3}");
				nRollup = 3;				
				bDone = true;
				break;
				
			//RU4 - 	Roll-Up Captions--4 Rows
			case 0xA7:
				debug("{RU4}");
				nRollup = 3;				
				bDone = true;
				break;
				
			//TR - Text Restart
			case 0x2A:
				debug("{TR}");
				nXPos = 0;
				nYPos = 0;
				bTextMode = true;
				bDone = true;
				break;
				
			//RTD - Resume Text Display	
			case 0xAB:
				debug("{RTD}");
				bTextMode = true;
				bDone = true;
				break;
				
			//EDM - Erase Displayed Memory
			case 0xAB:				
				debug("{EDM}");
				clearScreen();
				bDone = true;
				break;
				
			//ENM - Erase Non-displayed Memory
			case 0xAB:
				debug("{ENM}");		
				for(int i=0; i<nBufferPos; i++)
					delete [] cc_buffer[i].data;				
				
				nBufferPos = 0;
				bDone = true;
				break;
				
			//EOC - End Of Caption
			case 0x2F:
				debug("{EOC}");
				clearScreen();
				process(cc_buffer, nBufferPos);				
				nBufferPos = 0;
				bDone = true;
				break;
				
			//backspace
			case 0xA1:
				debug("{BS}");
				if(nXPos>0)
					nXPos--;
				else
					if(nYPos>0){
						nXPos=CC_WIDTH;
						nYPos--;
					}
					
				//clear current char
				if(bWriteInBuffer && nBufferPos>0){
					for(int i = nBufferPos-1; i>=0; i--)
						if(cc_buffer[i].type==CC_TEXT){
							cc_buffer[i].length -= 1;
							break;
						}
				}
				else
					clearline(nYPos, nXPos, 1);
					
			  	bDone = true;
				break;
				
			//delete to end of row
			case 0xA4:
				debug("{DER}");
				//clear current line starting from current char
				clearLine(nYPos, nXPos, -1);
				bDone = true;
				break;
				
			//carriage return
			case 0xAD:
				debug("{CR}");
				if(nYPos<(CC_HEIGHT-1))
					nYPos++;
				else
					bCR = true;
				bDone = true;
				break;
				
			//unsupported command
			default:
				UNSUP;
		}
		
		if(bDone)
			return true;
	}
	
	//Processing PAC
	for(int i=0; i<15; i++)
		if(nChannel%2==0) // CC1, CC3
			if(pac_lines[i]==hi){
				bIsPAC = true;
				nXPos = i;
				break;
			}				
		else //CC2, CC4
			if((pac_lines[i]-0x78	)==hi){
				bIsPAC = true;
				nXPos = i;
				break;
			}
			
	if(bIsPAC){
		bUnderline = ((lo & 0x01) == 	0x01);
		if(
			nXPos%2==0 &&
				(
					
				)
			)
	}
	
	//TO1, TO2, TO3
	if(
			(
			(nChannel<2 && channels2p[nChannel/2]==hi) ||
			(nChannel>=2 && channels2p[nChannel/2]==hi)
			) &&
			(lo==0xA1 || lo==0xA2 || lo==0x23)
		){	
			nXPos += (lo & 0x0F);			
			return true;
	}
	return false;
}

void cCcOsd::clearScreen(void){
}

void cCcOsd::clearLine(byte line, byte pos, byte len){
}