#include "timeStroke.h"

//-----------------------------------------
timeStroke::timeStroke(){

	//XML.setVerbose(true);

	memset(name, 0, 128);	
	reset();
}

//-----------------------------------------
void timeStroke::setName(char * _name){
	//strip out the .mov
	
	int index = 0;
	sprintf(name, "%s", _name);
}

//-----------------------------------------
void timeStroke::reset(){
	for (int i = 0; i < MAX_NUM_TIME_STROKE; i++){
		pts[i].t = -1;
		pts[i].x = 0;
		pts[i].y = 0;
		ref[i] = 0;
	}
	
	//get rid of the xml data for this 
	//point
	//XML.clearTagContents(name);
	
	nPts		= 0;
	startSide	= 0;
	endSide		= 0;	
	startSide	= 0;
	startPct	= 0;
	endPct		= 0;
	width		= 0;
	height		= 0;
}

//-----------------------------------------
static void catmullRom(timePt p1, timePt p2, timePt p3, timePt p4, float t, float *x, float *y){
	float t1, t2, t3;

	t1 = (1-t)*(1-t);
	t2 = t*t;
	t3 = t*t*t;
	 
	*x = (-t*t1*p1.x + (2-5*t2+3*t3)*p2.x + t*(1+4*t-3*t2)*p3.x - t2*(1-t)*p4.x)/2;
	*y = (-t*t1*p1.y + (2-5*t2+3*t3)*p2.y + t*(1+4*t-3*t2)*p3.y - t2*(1-t)*p4.y)/2;
}

//-----------------------------------------
void timeStroke::setDimensions(int w, int h){
	width  = w;
	height = h;
}

//-----------------------------------------
void timeStroke::draw(float time, int currPosition){
	
	int w = 640;
	int h = 480;
	
	ofSetColor(0x00FF00);
	
		if(startSide == 0)ofRect(0, 0, w, 2);
		else
		if(startSide == 1)ofRect(w, 0, 2, h);
		else
		if(startSide == 2)ofRect(0, h, w, 2);
		else
		if(startSide == 3)ofRect(0, 0, 2, h);
	
	ofSetColor(0xFF0000);
	
		if(endSide == 0)ofRect(0, -2, w, 2);
		else
		if(endSide == 1)ofRect(w+2, 0, 2, h);
		else
		if(endSide == 2)ofRect(0, h+2, w, 2);
		else
		if(endSide == 3)ofRect(-2, 0, 2, h);			

	ofSetColor(0xFFFFFF);

	glLogicOp(GL_INVERT);
	glEnable(GL_COLOR_LOGIC_OP);
	
	glBegin(GL_LINE_STRIP);
		for (int i = 0; i < MAX_NUM_TIME_STROKE; i++){
		
			//we don't want to draw points not set
			if(pts[i].t == -1) continue;
			
			if (pts[i].t < time+0.01f && pts[i].t >= 0){
				//our current drawing position.
				glVertex2f(pts[i].x, pts[i].y);
			}
		}
	glEnd();
	
	ofFill();
	if (pts[currPosition].t >= 0){
			ofCircle(pts[currPosition].x, pts[currPosition].y, 3);
	}
	
	glLogicOp(GL_CLEAR);
	glDisable(GL_COLOR_LOGIC_OP);
	
		
}

void timeStroke::loadSettings(char * fileName){

	XML.initFromFile(fileName, "PARAMS");
	XML.getValue("name", name);
	XML.getValue("nPts", &nPts);
	XML.getValue("width", &width);
	XML.getValue("height", &height);
	XML.getValue("startSide", &startSide);
	XML.getValue("endSide", &endSide);
	XML.getValue("startPct", &startPct);
	XML.getValue("endPct", &endPct);

	char tmpStr[50];
	for (int i = 0; i < nPts; i++){
		
		memset(tmpStr, 0, 50);
		sprintf(tmpStr,"pts%i:x", i);
		XML.getValue(tmpStr, &pts[i].x);

		memset(tmpStr, 0, 50);
		sprintf(tmpStr,"pts%i:y", i);
		XML.getValue(tmpStr, &pts[i].y);

		memset(tmpStr, 0, 50);
		sprintf(tmpStr,"pts%i:t", i);
		XML.getValue(tmpStr, &pts[i].t);

	}

}

//-----------------------------------------
void timeStroke::saveSettings(char * fileName)
{

	ofXML XMLout;				// new xml, because using the old object was a problem....
	XMLout.init("PARAMS");
	
	startPct = 1.0;
	endPct   = 0.0;
	
	//Find the first and last frame based on the movie's pct
	for (int i = 0; i < MAX_NUM_TIME_STROKE; i++){	
		if(pts[i].t == -1) continue;
		
		if(pts[i].t < startPct) startPct = pts[i].t;
		if(pts[i].t > endPct) endPct = pts[i].t;
	}	
	
	XMLout.setValue("name", name);
	XMLout.setValue("nPts", nPts);
	XMLout.setValue("width", width);
	XMLout.setValue("height", height);
	XMLout.setValue("startSide", startSide);
	XMLout.setValue("endSide", endSide);
	XMLout.setValue("startPct", startPct);
	XMLout.setValue("endPct", endPct);
	
	int counter = 0;	// <--- so that in the input, the # of points comes out in order, 0,1,2,3....
	
	char tmpStr[50];
	for (int i = 0; i < MAX_NUM_TIME_STROKE; i++){
		
		if(pts[i].t == -1) continue;
		
		memset(tmpStr, 0, 50);
		sprintf(tmpStr,"pts%i:x", counter);
		XMLout.setValue(tmpStr, pts[i].x);

		memset(tmpStr, 0, 50);
		sprintf(tmpStr,"pts%i:y", counter);
		XMLout.setValue(tmpStr, pts[i].y);

		memset(tmpStr, 0, 50);
		sprintf(tmpStr,"pts%i:t", counter);
		XMLout.setValue(tmpStr, pts[i].t);
		
		counter++;

	}
	
	XMLout.saveFile(fileName);
}

//-----------------------------------------
ofVec3f	timeStroke::getPointForPct(float pct){
	ofVec3f ret;
	ret.set(-1,-1,-1);
	for(int i = 0; i < nPts; i++){
		if ( (pts[i].t < (pct+0.01f)) && (pts[i].t >= 0) ){
			
			ret.set(pts[i].x, pts[i].y, 0);
		}
	}
	
	return ret;
}

//-----------------------------------------
float timeStroke::getStartingAngle(){
	ofVec3f pta;
	ofVec3f ptb;
	pta.set(pts[0].x, pts[0].y,0);
	ptb.set(pts[1].x, pts[1].y,0);
	ofVec3f diff = ptb - pta;
	return atan2(diff.y, diff.x);
}

//-----------------------------------------
ofVec3f timeStroke::getStartingPoint(){
	return ofVec3f(pts[0].x, pts[0].y,0);
}
		

//-----------------------------------------
void timeStroke::addPt(int whichPt, float x, float y, float t){
	
	if(pts[whichPt].t == -1) nPts++;
	
	pts[whichPt].x		= x;
	pts[whichPt].y		= y;
	pts[whichPt].t		= t;
}

//-----------------------------------------
void timeStroke::removePt(int whichPt){
	
	if(pts[whichPt].t != -1) nPts--;

	pts[whichPt].x		= 0;
	pts[whichPt].y		= 0;
	pts[whichPt].t		= -1;
		
	char tmpStr[50];
	memset(tmpStr, 0, 50);
	sprintf(tmpStr,"%s:pts%i", name, whichPt);
	//XML.removeTag(tmpStr);
}