/*
steps to convert obj-c to javascript
1. Replace "- \(void\)(.*?) {" with "function \1(hg) {"
2. Replace "&hg" with "hg"
3. Replace "float s\[2\] = \{(.*?)\};" with "var s = [\1];"
*/


var hgs;

function fingerGesture() {
	this.x = new Array();
	this.y = new Array();
	this.cpx = new Array();
	this.cpy = new Array();
	this.t = new Array();
	this.len = 0.0;
	this.pressed = 0;
	this.type = 0;
}

function handGesture(id, f, bz) {
	this.fg = new Array();
	for (var i=0; i<10; i++) {
		this.fg[i] = new fingerGesture();
	}
	this.n = 0;
	this.t = 0;
	this.type = 0;
	this.counter = 0;
	this.id = id;
	this.needsRefresh = true;

	if (bz !== undefined) {
		this.lastI = 0;
		this.accumT = 0.0;
		this.accumLen = 0.0;
		this.lastX = 0.0;
		this.lastY = 0.0;
		this.on = 0;
	
		document.getElementById(id).hg=this;
		$("#"+id).mouseover(
			function() {
				this.hg.counter = 0;
				this.hg.lastI = 0;
				this.hg.on = 1;
				this.hg.needsRefresh = true;
			}
		);
		$("#"+id).mouseout(
			function() {
				this.hg.on = 0;
				this.hg.needsRefresh = true;
			}
		);
	}
	f(this);
	
}


function init() {
	hgs = new Array();
	
	if (document.getElementById("nextprev") != null) { //Magic Mouse
		hgs.push(new handGesture("nextprev", createMMNextPreviousTab));
		hgs.push(new handGesture("openlinkinnewtab", createMMMiddleClick));
		hgs.push(new handGesture("selecttababovecursor", createMMOneFixRightTap));
		hgs.push(new handGesture("close", createMMMiddleFixIndexSlideLeft));
		hgs.push(new handGesture("refresh", createMMMiddleFixIndexSlideRight));
		hgs.push(new handGesture("showdesktop", createMMThreeSwipeUp));
		hgs.push(new handGesture("expose", createMMThreeSwipeDown));
		hgs.push(new handGesture("minimize", createMMIndexFixMiddleSlideLeft));
		hgs.push(new handGesture("zoom", createMMIndexFixMiddleSlideRight));
		hgs.push(new handGesture("moveresize", createMMVShape));
		hgs.push(new handGesture("changespaces", createMMChangeSpaces));
		hgs.push(new handGesture("quicktabswitching", createMMQuickTabSwitching));
	} else if (document.getElementById("nextprev2") != null) { //Trackpad
		hgs.push(new handGesture("nextprev2", createNextPreviousTab));
		hgs.push(new handGesture("openlinkinnewtab2", createThreeFingerTap));
		hgs.push(new handGesture("close2", createOneFixTwoSlideDown));
		hgs.push(new handGesture("openclose2", createOneFixTwoSlideUp));
		hgs.push(new handGesture("quit2", createOneFixPressTwoSlideDown));
		hgs.push(new handGesture("refresh2", createTwoFixOneDoubleTap));
		hgs.push(new handGesture("minimize2", createIndexToPinky));
		hgs.push(new handGesture("zoom2", createPinkyToIndex));
		hgs.push(new handGesture("moveresize2", createMoveResize));
		hgs.push(new handGesture("changespaces2", createChangeSpaces));
	} else { //Characters
		hgs.push(new handGesture("c_a",createA,1));
		hgs.push(new handGesture("c_b",createB,1));
		hgs.push(new handGesture("c_c",createC,1));
		hgs.push(new handGesture("c_d",createD,1));
		hgs.push(new handGesture("c_e",createE,1));
		hgs.push(new handGesture("c_f",createF,1));
		hgs.push(new handGesture("c_g",createG,1));
		hgs.push(new handGesture("c_h",createH,1));
		hgs.push(new handGesture("c_i",createI,1));
		hgs.push(new handGesture("c_j",createJ,1));
		hgs.push(new handGesture("c_k",createK,1));
		hgs.push(new handGesture("c_l",createL,1));
		hgs.push(new handGesture("c_m",createM,1));
		hgs.push(new handGesture("c_n",createN,1));
		hgs.push(new handGesture("c_o",createO,1));
		hgs.push(new handGesture("c_p",createP,1));
		hgs.push(new handGesture("c_q",createQ,1));
		hgs.push(new handGesture("c_r",createR,1));
		hgs.push(new handGesture("c_s",createS,1));
		hgs.push(new handGesture("c_t",createT,1));
		hgs.push(new handGesture("c_u",createU,1));
		hgs.push(new handGesture("c_v",createV,1));
		hgs.push(new handGesture("c_w",createW,1));
		hgs.push(new handGesture("c_x",createX,1));
		hgs.push(new handGesture("c_y",createY,1));
		hgs.push(new handGesture("c_z",createZ,1));
		hgs.push(new handGesture("c_up",createUp,1));
		hgs.push(new handGesture("c_sup",createSUp,1));
		hgs.push(new handGesture("c_sdown",createSDown,1));
		hgs.push(new handGesture("c_left",createLeft,1));
		hgs.push(new handGesture("c_right",createRight,1));
	}

	setInterval(draw, 35);
	//setInterval(draw, 2000);
}



function draw() {
	var hgIndex;
	for (hgIndex in hgs) {
		var hg = hgs[hgIndex];
		
		if (hg.type==0 || (hg.type==1 && hg.on)) {
			hg.needsRefresh = true;
		}
		if (!hg.needsRefresh) continue;
		hg.needsRefresh = false;
	
		var canvas = document.getElementById(hg.id);
		if(canvas) {
			var w = canvas.width;
			var h = canvas.height;

			var ctx = canvas.getContext("2d");
			ctx.clearRect(0, 0, 248, 184);
	
			var time = hg.counter*0.04;
			var x,y;
			
			var min = hg.type==0?11:9;
			
			if (hg.type) {
				ctx.lineJoin = 'round';
				ctx.lineCap = 'round';
				
				if (!hg.on) {
					ctx.lineWidth = 7;
					ctx.strokeStyle = "rgba(200, 106, 110, 1)";
					ctx.beginPath(); 
					ctx.arc(hg.fg[0].x[0]*w,h-(hg.fg[0].y[0]*h),11,0,Math.PI*2,true);
					ctx.stroke();
				}
				
				ctx.beginPath();
				ctx.moveTo(hg.fg[0].x[0]*w, h-hg.fg[0].y[0]*h);
				for(var i=0;i<hg.n;i++) {
					ctx.bezierCurveTo(
						hg.fg[i].cpx[0]*w,
						h-hg.fg[i].cpy[0]*h,
						hg.fg[i].cpx[1]*w,
						h-hg.fg[i].cpy[1]*h,
						hg.fg[i].x[1]*w,
						h-hg.fg[i].y[1]*h);
				}
				ctx.lineWidth = 9;
				ctx.strokeStyle = "rgba(100, 100, 100, 1)";
				ctx.stroke();
			}
			
			if (hg.type==1 && !hg.on) continue;
			
			ctx.fillStyle = "rgba(184, 106, 110, 1)";
			ctx.strokeStyle = "rgba(184, 106, 110, 1)";
			
			for(var i=0;i<hg.n;i++) {
				var tmp = 1;
				if(hg.fg[i].t[2]!=-1 && time >= hg.fg[i].t[2] && time <= hg.fg[i].t[0]) {
					x = hg.fg[i].x[0];
					y = hg.fg[i].y[0];
				} else if(hg.fg[i].t[3]!=-1 && time >= hg.fg[i].t[1] && time <= hg.fg[i].t[3]) {
					x = hg.fg[i].x[1];
					y = hg.fg[i].y[1];
				} else if(hg.fg[i].t[0] <= time && hg.fg[i].t[1] >= time) {
					if (hg.fg[i].type == 0) {
						var t = (time - hg.fg[i].t[0]) / (hg.fg[i].t[1]-hg.fg[i].t[0]);
						t = (1-Math.sin(Math.PI/2+t*Math.PI))/2;
						x = hg.fg[i].x[1]*t + hg.fg[i].x[0]*(1-t);
						y = hg.fg[i].y[1]*t + hg.fg[i].y[0]*(1-t);
					} else {
						var realT = (time - hg.fg[i].t[0]) / (hg.fg[i].t[1]-hg.fg[i].t[0]);
		
						if (i+1 != hg.lastI) {
							hg.accumLen = 0.0;
							hg.accumT = 0.0;
							x = hg.fg[i].x[0];
							y = hg.fg[i].y[0];
							hg.lastX = x;
							hg.lastY = y;
							hg.lastI = i+1;
						}
		
						while (hg.accumLen/hg.fg[i].len < realT) {
							var t = hg.accumT;
							x = (1-t)*(1-t)*(1-t)*hg.fg[i].x[0] + 3*(1-t)*(1-t)*t*hg.fg[i].cpx[0] + 3*(1-t)*t*t*hg.fg[i].cpx[1] + t*t*t*hg.fg[i].x[1];
							y = (1-t)*(1-t)*(1-t)*hg.fg[i].y[0] + 3*(1-t)*(1-t)*t*hg.fg[i].cpy[0] + 3*(1-t)*t*t*hg.fg[i].cpy[1] + t*t*t*hg.fg[i].y[1];
							
							var dx=hg.lastX-x, dy=hg.lastY-y;
							var len=Math.sqrt(dx*dx+dy*dy);
							hg.accumLen += len;
							hg.lastX = x;
							hg.lastY = y;
							hg.accumT += 0.01;
						}
					}
				} else
					tmp = 0;
				if(tmp) {
					
					x *= w;
					y *= h;
					if (hg.type==0) y+=10;

					y = h-y;
					
					if (hg.fg[i].pressed) {
						ctx.lineWidth = 2;
						ctx.beginPath();
						ctx.arc(x, y, min+3, 0, Math.PI*2, true);
						ctx.stroke();
					}
				
					if (hg.fg[i].type == 0) {
						ctx.beginPath();
						ctx.arc(x, y, min, 0, Math.PI*2, true);
						ctx.fill();
					} else {
						ctx.beginPath();
						ctx.arc(x-25, y, min, 0, Math.PI*2, true);
						ctx.fill();
						ctx.beginPath();
						ctx.arc(x+25, y, min, 0, Math.PI*2, true);
						ctx.fill();
					}
				}
			}
			hg.counter ++;
			if(time >= hg.t) {
				hg.counter = 0;
				hg.lastI = 0;
			}
		}
	}
}

function setFG(out, x1, y1, x2, y2, t1, t2) {
	out.x[0] = x1;
	out.y[0] = y1;
	out.x[1] = x2;
	out.y[1] = y2;
	out.t[0] = t1*2;
	out.t[1] = t2*2;
	
	out.t[2] = out.t[3] = -1;
	out.pressed = 0;
	out.s = "";
}

function setFG2(out, x1, y1, x2, y2, t0, t1, t2, t3) {
	setFG(out, x1, y1, x2, y2, t0, t1);
	out.t[2] = t2*2;
	out.t[3] = t3*2;
}

function setFGx(out, x1, y1, x2, y2, t1, t2) {
	setFG(out, x1, y1, x2, y2, t1, t2);
	out.pressed = 1;
}

function setFGs(out, x1, y1, x2, y2, t1, t2) {
	setFG(out, x1, y1, x2, y2, t1, t2);
	out.s = 1;
}



function createThreeFingerTap(hg) {
	hg.n = 9;
	hg.t = 3.8*2;
	setFG(hg.fg[0], 0.36, 0.5,  0.36, 0.5, 0.25, 0.4);
	setFG(hg.fg[1], 0.50, 0.53, 0.50, 0.53, 0.25, 0.4);
	setFG(hg.fg[2], 0.64, 0.51, 0.64, 0.51, 0.25, 0.4);
	
	setFG(hg.fg[3], 0.36, 0.5,  0.36, 0.5, 1, 1.9);
	setFG(hg.fg[4], 0.50, 0.53, 0.50, 0.53, 1.5, 1.65);
	setFG(hg.fg[5], 0.64, 0.51, 0.64, 0.51, 1.5, 1.65);
	
	setFG(hg.fg[6], 0.36, 0.5,  0.36, 0.5, 3, 3.15);
	setFG(hg.fg[7], 0.50, 0.53, 0.50, 0.53, 2.5, 3.5);
	setFG(hg.fg[8], 0.64, 0.51, 0.64, 0.51, 3, 3.15);
}

function createOneFixTwoSlideUp(hg) {
	hg.n = 3;
	hg.t = 1.1*2;
	setFG(hg.fg[0], 0.36, 0.5, 0.36, 0.5, 0, 1.1);
	setFG2(hg.fg[1], 0.50, 0.41,  0.50, 0.62, 0.4, 0.8, 0.33, 1);
	setFG2(hg.fg[2], 0.64, 0.38, 0.64, 0.6, 0.4, 0.8, 0.33, 1);
}

function createOneFixTwoSlideDown(hg) {
	hg.n = 3;
	hg.t = 1.1*2;
	setFG(hg.fg[0], 0.36, 0.5,  0.36, 0.5, 0, 1.1);
	setFG2(hg.fg[1], 0.50, 0.62,  0.50, 0.41, 0.4, 0.8, 0.33, 1);
	setFG2(hg.fg[2], 0.64, 0.60, 0.64, 0.38, 0.4, 0.8, 0.33, 1);
}

function createOneFixPressTwoSlideUp(hg) {
	hg.n = 3;
	hg.t = 1.1*2;
	setFGx(hg.fg[0], 0.36, 0.5, 0.36, 0.5, 0, 1.1);
	setFG2(hg.fg[1], 0.50, 0.5, 0.50, 0.63, 0.4, 0.8, 0.33, 1);
	setFG2(hg.fg[2], 0.64, 0.5, 0.64, 0.61, 0.4, 0.8, 0.33, 1);
}

function createOneFixPressTwoSlideDown(hg) {
	hg.n = 3;
	hg.t = 1.1*2;
	setFGx(hg.fg[0], 0.36, 0.5,  0.36, 0.5, 0, 1.1);
	setFG2(hg.fg[1], 0.50, 0.62,  0.50, 0.41, 0.4, 0.8, 0.33, 1);
	setFG2(hg.fg[2], 0.64, 0.60, 0.64, 0.38, 0.4, 0.8, 0.33, 1);
}

function createOneFixThreeSlide(hg) {
	hg.n = 4;
	hg.t = 1.1*2;
	setFG(hg.fg[0], 0.29, 0.5,  0.29, 0.5, 0, 1.1);
	setFG2(hg.fg[1], 0.43, 0.65,  0.43, 0.53, 0.4, 0.8, 0.33, 1);
	setFG2(hg.fg[2], 0.57, 0.63, 0.57, 0.53, 0.4, 0.8, 0.33, 1);
	setFG2(hg.fg[3], 0.71, 0.60, 0.71, 0.53, 0.4, 0.8, 0.33, 1);
}

function createIndexToPinky(hg) {
	hg.n = 4;
	hg.t = 1*2;
	var s = [0, 0.15];
	setFG(hg.fg[0], s[0]+0.29, s[1]+0.3, s[0]+0.29, s[1]+0.3, 0, 0.4);
	setFG(hg.fg[1], s[0]+0.43, s[1]+0.36, s[0]+0.43, s[1]+0.36, 0.1, 0.4);
	setFG(hg.fg[2], s[0]+0.57, s[1]+0.335, s[0]+0.57, s[1]+0.335, 0.2, 0.4);
	setFG(hg.fg[3], s[0]+0.71, s[1]+0.28, s[0]+0.71, s[1]+0.28, 0.3, 0.4);
}
function createPinkyToIndex(hg) {
	hg.n = 4;
	hg.t = 1*2;
	var s = [0, 0.15];
	setFG(hg.fg[0], s[0]+0.29, s[1]+0.3, s[0]+0.29, s[1]+0.3, 0.3, 0.4);
	setFG(hg.fg[1], s[0]+0.43, s[1]+0.36, s[0]+0.43, s[1]+0.36, 0.2, 0.4);
	setFG(hg.fg[2], s[0]+0.57, s[1]+0.335, s[0]+0.57, s[1]+0.335, 0.1, 0.4);
	setFG(hg.fg[3], s[0]+0.71, s[1]+0.28, s[0]+0.71, s[1]+0.28, 0, 0.4);
}


function createOneFixLeftTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	var s = [0, 0];
	setFG(hg.fg[0], s[0]+0.36, s[1]+0.49, s[0]+0.36, s[1]+0.49, 0.3, 0.3+0.15);
	setFG(hg.fg[1], s[0]+0.50, s[1]+0.5, s[0]+0.50, s[1]+0.5, 0, 1.0);
}
function createOneFixRightTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	var s = [0, 0];
	setFG(hg.fg[0], s[0]+0.50, s[1]+0.5, s[0]+0.50, s[1]+0.5, 0, 1.0);
	setFG(hg.fg[1], s[0]+0.64, s[1]+0.49, s[0]+0.64, s[1]+0.49, 0.3, 0.3+0.15);
}
function createMoveResize(hg) {
	hg.n = 4;
	hg.t = 3*2;
	var s = [0, 0];
	setFG(hg.fg[0], s[0]+0.43, s[1]+0.5,  s[0]+0.43, s[1]+0.5, 0, 3);
	setFG2(hg.fg[1], s[0]+0.57, s[1]+0.57,  s[0]+0.57, s[1]+0.43, 0.4, 0.8, 0.33, 1);
	setFG(hg.fg[2], s[0]+0.57, s[1]+0.5,  s[0]+0.57, s[1]+0.5, 1.5, 1.65);
	setFG2(hg.fg[3], s[0]+0.57, s[1]+0.43,  s[0]+0.57, s[1]+0.57, 2.15, 2.55, 2.08, 2.75 );
}

function createChangeSpaces(hg) {
	hg.n = 6;
	hg.t = 4*2;
	setFG(hg.fg[0], 0.50, 0.5, 0.50, 0.5, 0, 4);
	setFG(hg.fg[1], 0.64, 0.49, 0.64, 0.49, 0, 4);
	
	setFG2(hg.fg[2], 0.36, 0.45, 0.36, 0.53, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[3], 0.36, 0.53, 0.36, 0.45, 0.5+1, 0.75+1, 0.46+1, 0.83+1);
	setFG2(hg.fg[4], 0.36, 0.48, 0.31, 0.48, 0.5+2, 0.75+2, 0.46+2, 0.83+2);
	setFG2(hg.fg[5], 0.31, 0.48, 0.36, 0.48, 0.5+3, 0.75+3, 0.46+3, 0.83+3);	
	/*
	setFG2(hg.fg[2], 0.25, 0.5, 0.25, 0.5, 0.5, 0.75, 0.46, 0.86);
	setFG2(hg.fg[3], 0.25, 0.5, 0.25, 0.5, 0.5+1, 0.75+1, 0.46+1, 0.86+1);
	setFG2(hg.fg[4], 0.28, 0.5, 0.22, 0.5, 0.5+2, 0.75+2, 0.46+2, 0.86+2);
	setFG2(hg.fg[5], 0.22, 0.5, 0.28, 0.5, 0.5+3, 0.75+3, 0.46+3, 0.86+3);*/
}
function createTwoFixOneSlideUp(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.5, 0.50, 0.5, 0, 4);
	setFG(hg.fg[1], 0.64, 0.49, 0.64, 0.49, 0, 4);
	
	setFG2(hg.fg[2], 0.36, 0.45, 0.36, 0.53, 0.5, 0.75, 0.46, 0.83);
}

function createTwoFixOneSlideDown(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.5, 0.50, 0.5, 0, 4);
	setFG(hg.fg[1], 0.64, 0.49, 0.64, 0.49, 0, 4);
	
	setFG2(hg.fg[2], 0.36, 0.53, 0.36, 0.45, 0.5, 0.75, 0.46, 0.83);
}

function createTwoFixOneSlideLeft(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.5, 0.50, 0.5, 0, 4);
	setFG(hg.fg[1], 0.64, 0.49, 0.64, 0.49, 0, 4);
	
	setFG2(hg.fg[2], 0.36, 0.48, 0.31, 0.48, 0.5, 0.75, 0.46, 0.83);
}

function createTwoFixOneSlideRight(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.5, 0.50, 0.5, 0, 4);
	setFG(hg.fg[1], 0.64, 0.49, 0.64, 0.49, 0, 4);
	
	setFG2(hg.fg[2], 0.31, 0.48, 0.36, 0.48, 0.5, 0.75, 0.46, 0.83);
}

function createTwoFixOneDoubleTap(hg) {
	hg.n = 4;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.53, 0.50, 0.53, 0, 1);
	setFG(hg.fg[1], 0.64, 0.51, 0.64, 0.51, 0, 1);
	
	setFG(hg.fg[2], 0.36, 0.5,  0.36, 0.5, 0.5, 0.6);
	setFG(hg.fg[3], 0.36, 0.5,  0.36, 0.5, 0.7, 0.8);
}

function createThreeSwipeUp(hg) {
	hg.n = 3;
	hg.t = 1*2;
	setFG2(hg.fg[0], 0.36, 0.43, 0.36, 0.57, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[1], 0.50, 0.46, 0.50, 0.60, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[2], 0.64, 0.43, 0.64, 0.57, 0.5, 0.75, 0.46, 0.83);
}

function createThreeSwipeDown(hg) {
	hg.n = 3;
	hg.t = 1*2;
	setFG2(hg.fg[0], 0.36, 0.57, 0.36, 0.43, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[1], 0.50, 0.60, 0.50, 0.46, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[2], 0.64, 0.57, 0.64, 0.43, 0.5, 0.75, 0.46, 0.83);
}


function createMiddleFixIndexNearTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 1.0);
}

function createMiddleFixIndexFarTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.25, 0.75, 0.25, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 1.0);
}

function createIndexFixMiddleNearTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.25, 0.75, 0.25, 0.75, 0, 1.0);
}

function createIndexFixMiddleFarTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.75, 0.75, 0.75, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.25, 0.75, 0.25, 0.75, 0, 1.0);
}

function createMiddleFixIndexNearTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 1.0);
}

function createMiddleFixIndexFarTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.25, 0.75, 0.25, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 1.0);
}

function createIndexFixMiddleNearTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.25, 0.75, 0.25, 0.75, 0, 1.0);
}

function createIndexFixMiddleFarTap(hg) {
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.75, 0.75, 0.75, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.25, 0.75, 0.25, 0.75, 0, 1.0);
}

function createMMOneFixLeftTap(hg) { //TODO: fix
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.30, 0.75, 0.30, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.70, 0.75, 0.70, 0.75, 0, 1.0);
}
function createMMOneFixRightTap(hg) { //TODO: fix
	hg.n = 2;
	hg.t = 0.6*2;
	setFG(hg.fg[0], 0.30, 0.75, 0.30, 0.75, 0, 1.0);
	setFG(hg.fg[1], 0.70, 0.75, 0.70, 0.75, 0.3, 0.3+0.15);
}

function createMMMiddleFixIndexSlideLeft(hg) {
	
	hg.n = 2;
	hg.t = 1*2;
	setFG(hg.fg[0], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[1], 0.36, 0.75, 0.25, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMMiddleFixIndexSlideRight(hg) {
	hg.n = 2;
	hg.t = 1*2;
	setFG(hg.fg[0], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[1], 0.25, 0.75, 0.36, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMIndexFixMiddleSlideLeft(hg) {
	hg.n = 2;
	hg.t = 1*2;
	setFG(hg.fg[0], 0.30, 0.75, 0.30, 0.75, 0, 4);
	setFG2(hg.fg[1], 0.75, 0.75, 0.64, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMIndexFixMiddleSlideRight(hg) {
	hg.n = 2;
	hg.t = 1*2;
	setFG(hg.fg[0], 0.30, 0.75, 0.30, 0.75, 0, 4);
	setFG2(hg.fg[1], 0.64, 0.75, 0.75, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMThreeSwipeLeft(hg) {
	hg.n = 3;
	hg.t = 1*2;
	setFG2(hg.fg[0], 0.30, 0.75, 0.15, 0.75, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[1], 0.55, 0.75, 0.40, 0.75, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[2], 0.80, 0.75, 0.65, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMThreeSwipeRight(hg) {
	hg.n = 3;
	hg.t = 1*2;
	setFG2(hg.fg[0], 0.20, 0.75, 0.35, 0.75, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[1], 0.45, 0.75, 0.60, 0.75, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[2], 0.70, 0.75, 0.85, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMThreeSwipeUp(hg) {
	hg.n = 3;
	hg.t = 1*2;
	setFG2(hg.fg[0], 0.25, 0.75, 0.25, 0.83, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[1], 0.50, 0.75, 0.50, 0.83, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[2], 0.75, 0.75, 0.75, 0.83, 0.5, 0.75, 0.46, 0.83);
}

function createMMThreeSwipeDown(hg) {
	hg.n = 3;
	hg.t = 1*2;
	setFG2(hg.fg[0], 0.25, 0.75, 0.25, 0.67, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[1], 0.50, 0.75, 0.50, 0.67, 0.5, 0.75, 0.46, 0.83);
	setFG2(hg.fg[2], 0.75, 0.75, 0.75, 0.67, 0.5, 0.75, 0.46, 0.83);
}

function createMMVShape(hg) {
	hg.n = 2;
	hg.t = 1.3*2;
	var s = [0, 0];
	
	setFG(hg.fg[0], s[0]+0.15, s[1]+0.84, s[0]+0.15, s[1]+0.84, 0.3, 0.9);
	setFG(hg.fg[1], s[0]+0.87, s[1]+0.84, s[0]+0.87, s[1]+0.84, 0.3, 1.3);
}

function createMMTwoFingerTap(hg) {
	hg.n = 2;
	hg.t = 0.7*2;
	var s = [0, 0.25];
	setFG(hg.fg[0], s[0]+0.30, s[1]+0.5, s[0]+0.30, s[1]+0.5, 0.25, 0.4);
	setFG(hg.fg[1], s[0]+0.70, s[1]+0.5, s[0]+0.70, s[1]+0.5, 0.25, 0.4);
	
}

function createMMThreeFingerTap(hg) { //TODO: sure??
	hg.n = 9;
	hg.t = 3.8*2;
	var s = [0, 0.25];
	setFG(hg.fg[0], s[0]+0.30, s[1]+0.5,  s[0]+0.30, s[1]+0.5, 0.25, 0.4);
	setFG(hg.fg[1], s[0]+0.50, s[1]+0.53, s[0]+0.50, s[1]+0.53, 0.25, 0.4);
	setFG(hg.fg[2], s[0]+0.70, s[1]+0.51, s[0]+0.70, s[1]+0.51, 0.25, 0.4);
	
	setFG(hg.fg[3], s[0]+0.30, s[1]+0.5,  s[0]+0.30, s[1]+0.5, 1, 1.9);
	setFG(hg.fg[4], s[0]+0.50, s[1]+0.53, s[0]+0.50, s[1]+0.53, 1.5, 1.65);
	setFG(hg.fg[5], s[0]+0.70, s[1]+0.51, s[0]+0.70, s[1]+0.51, 1.5, 1.65);
	
	setFG(hg.fg[6], s[0]+0.30, s[1]+0.5,  s[0]+0.30, s[1]+0.5, 3, 3.15);
	setFG(hg.fg[7], s[0]+0.50, s[1]+0.53, s[0]+0.50, s[1]+0.53, 2.5, 3.5);
	setFG(hg.fg[8], s[0]+0.70, s[1]+0.51, s[0]+0.70, s[1]+0.51, 3, 3.15);
}


function createMMThumb(hg) {
	hg.n = 1;
	hg.t = 0.7*2;
	setFG(hg.fg[0], 0.15, 0.55, 0.15, 0.55, 0, 1.0);
}

function createMMMiddleClick(hg) {
	hg.n = 3;
	hg.t = 0.7*2;
	setFG(hg.fg[0], 0.75, 0.79, 0.75, 0.79, 0, 1.0);
	setFG(hg.fg[1], 0.5, 0.72, 0.5, 0.72, 0, 1.0);
	setFGx(hg.fg[2], 0.5, 0.72, 0.5, 0.72, 0.25, 0.4);
}

function createMMTwoFixOneSlideUp(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0, 4);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[2], 0.25, 0.75, 0.25, 0.82, 0.5, 0.75, 0.46, 0.83);
}

function createMMTwoFixOneSlideDown(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0, 4);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[2], 0.25, 0.75, 0.25, 0.68, 0.5, 0.75, 0.46, 0.83);
}

function createMMTwoFixOneSlideLeft(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0, 4);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[2], 0.25, 0.75, 0.18, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createMMTwoFixOneSlideRight(hg) {
	hg.n = 3;
	hg.t = 1*2;
	
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0, 4);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[2], 0.25, 0.75, 0.32, 0.75, 0.5, 0.75, 0.46, 0.83);
}

function createNextPreviousTab(hg) {
	hg.n = 3;
	hg.t = 1.3*2;
	var s = [0, 0];
	setFG(hg.fg[0], s[0]+0.32, s[1]+0.49, s[0]+0.32, s[1]+0.49, 0.95, 0.95+0.15);
	setFG(hg.fg[1], s[0]+0.50, s[1]+0.5, s[0]+0.50, s[1]+0.5, 0, 1.4);
	setFG(hg.fg[2], s[0]+0.68, s[1]+0.49, s[0]+0.68, s[1]+0.49, 0.3, 0.3+0.15);
}

//------------------------------------------------------

function createMMNextPreviousTab(hg) {
	hg.n = 3;
	hg.t = 1.3*2;
	setFG(hg.fg[0], 0.30, 0.75, 0.30, 0.75, 0.3, 0.3+0.15);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 2.0);
	setFG(hg.fg[2], 0.50, 0.75, 0.50, 0.75, 0.95, 0.95+0.15);
}


function createMMChangeSpaces(hg) {
	hg.n = 6;
	hg.t = 4*2;
	setFG(hg.fg[0], 0.50, 0.75, 0.50, 0.75, 0, 4);
	setFG(hg.fg[1], 0.75, 0.75, 0.75, 0.75, 0, 4);
	setFG2(hg.fg[2], 0.25, 0.72, 0.25, 0.78, 0.5, 0.75, 0.46, 0.86);
	setFG2(hg.fg[3], 0.25, 0.78, 0.25, 0.72, 0.5+1, 0.75+1, 0.46+1, 0.86+1);
	setFG2(hg.fg[4], 0.28, 0.75, 0.22, 0.75, 0.5+2, 0.75+2, 0.46+2, 0.86+2);
	setFG2(hg.fg[5], 0.22, 0.75, 0.28, 0.75, 0.5+3, 0.75+3, 0.46+3, 0.86+3);
}

function createMMQuickTabSwitching(hg) {
	hg.n = 1;
	hg.t = 1.2*2;
	setFG(hg.fg[0], 0.15, 0.55, 0.15, 0.55, 0.5, 1.2);
}

//-------------

function bezier(hg, a, n) {
	hg.n = n;
	//hg.t = 0.6*2;
	//setFG(&hg.fg[0], 0.75, 0.75, 0.75, 0.75, 0.3, 0.3+0.15);
	//setFG(&hg.fg[1], 0.25, 0.75, 0.25, 0.75, 0, 1.0);
	
	var i;
	var accumT=0.0;
	for (i=0; i<n; i++) {
		hg.fg[i].x[0] = a[i*8 + 0]*0.4 + 0.3;
		hg.fg[i].y[0] = a[i*8 + 1]*0.5 + 0.25;
		hg.fg[i].cpx[0] = a[i*8 + 2]*0.4 + 0.3;
		hg.fg[i].cpy[0] = a[i*8 + 3]*0.5 + 0.25;
		hg.fg[i].cpx[1] = a[i*8 + 4]*0.4 + 0.3;
		hg.fg[i].cpy[1] = a[i*8 + 5]*0.5 + 0.25;
		hg.fg[i].x[1] = a[i*8 + 6]*0.4 + 0.3;
		hg.fg[i].y[1] = a[i*8 + 7]*0.5 + 0.25;
		
		
		var len=0.0;
		var t=0.0;
		var x,y,lastX,lastY;
		while (t < 1.0) {
			x = (1-t)*(1-t)*(1-t)*hg.fg[i].x[0] + 3*(1-t)*(1-t)*t*hg.fg[i].cpx[0] + 3*(1-t)*t*t*hg.fg[i].cpx[1] + t*t*t*hg.fg[i].x[1];
			y = (1-t)*(1-t)*(1-t)*hg.fg[i].y[0] + 3*(1-t)*(1-t)*t*hg.fg[i].cpy[0] + 3*(1-t)*t*t*hg.fg[i].cpy[1] + t*t*t*hg.fg[i].y[1];
			if (t==0) {
				lastX = x;
				lastY = y;
			}
			var dx=lastX-x, dy=lastY-y;
			len+=Math.sqrt(dx*dx+dy*dy);
			t+=0.01;
			lastX = x;
			lastY = y;
		}
		
		hg.fg[i].t[0] = accumT;
		hg.fg[i].t[1] = accumT + len*1.7;
		hg.fg[i].len = len;
		accumT += len*1.7;
		hg.fg[i].t[2] = hg.fg[i].t[3] = -1;
		hg.fg[i].type = 1;
	}
	hg.fg[n-1].t[2] = hg.fg[n-1].t[0];
	hg.fg[n-1].t[3] = hg.fg[n-1].t[1]+0.3;
	hg.t = accumT + 1.0;
	hg.type = 1;
}




function createA(hg) {
	var a = [0.13,0.01,0.13,0.01,0.5,1.0,0.52,1.0,0.52,1.0,0.52,1.0,0.87,0.0,0.87,0.0];
	bezier(hg,a,2);
}
function createB(hg) { //TODO:
	var a = [0.23,0.01,0.23,0.01,0.24,0.99,0.23,1.0,
			0.23,1.0,0.97,1.0,0.73,0.52,0.38,0.51,
			0.38,0.51,1.17,0.49,0.74,0.0,0.37,0.01];
	bezier(hg,a,3);
}
function createC(hg) {
	var a = [0.85,0.9,-0.13,1.41,-0.11,-0.41,0.83,0.1];
	bezier(hg,a,1);
}
function createD(hg) { //TODO:
	var a = [0.16,0.0,0.16,0.0,0.16,0.99,0.17,0.99,
			0.17,0.99,1.06,0.98,1.15,0.0,0.30,0.0];
	bezier(hg,a,2);
}
function createE(hg) {
	var a = [0.73,0.98,0.07,1.1,0.11,0.49,0.63,0.5,0.63,0.5,0.04,0.5,0.11,-0.15,0.71,0.04];
	bezier(hg,a,2);
}
function createF(hg) {
	var a = [0.82,1.0,0.82,1.0,0.21,1.0,0.21,1.0,0.21,1.0,0.21,1.0,0.21,-0.01,0.21,-0.01];
	bezier(hg,a,2);
}
function createG(hg) { //TODO: sync with quartzview.m
	var a = [0.81,0.86,0.51,1.15,0.09,0.91,0.1,0.45,
			0.1,0.45,0.09,-0.08,0.87,-0.18,0.87,0.45,
			0.87,0.45,0.87,0.45,0.4,0.45,0.4,0.45];
	bezier(hg,a,3);
}
function createH(hg) {
	var a = [0.19,0.99,0.19,0.99,0.19,0.0,0.19,0.0,0.19,0.0,0.22,0.79,0.83,0.65,0.82,0.0];
	bezier(hg,a,2);
}
function createI(hg) {
	var a = [0.48,0.99,0.48,0.99,0.48,0.0,0.48,0.0];
	bezier(hg,a,1);
}
function createJ(hg) { //TODO:
	var a = [0.67,0.99,0.67,0.99,0.67,0.33,0.67,0.33,0.67,0.33,0.66,-0.22,0.31,0.08,0.26,0.28];
	bezier(hg,a,2);
}
function createK(hg) {
	var a = [0.82,1.0,0.82,1.0,0.17,0.0,0.17,0.0,0.17,0.0,0.17,0.0,0.17,1.0,0.17,1.0,0.17,1.0,0.17,1.0,0.86,0.01,0.86,0.01];
	bezier(hg,a,3);
}
function createL(hg) {
	var a = [0.2,0.99,0.2,0.99,0.2,0.0,0.2,0.0,0.2,0.0,0.2,0.0,0.83,0.0,0.83,0.0];
	bezier(hg,a,2);
}
function createM(hg) {
	var a = [0.01,0.01,0.01,0.01,0.01,0.99,0.01,0.99,0.01,0.99,0.01,0.99,0.51,0.0,0.51,0.0,0.51,0.0,0.51,0.0,0.99,1.0,0.99,1.0,0.99,1.0,0.99,1.0,0.99,0.0,0.99,0.0];
	bezier(hg,a,4);
}
function createN(hg) {
	var a = [0.16,0.01,0.16,0.01,0.17,1.0,0.17,1.0,0.17,1.0,0.17,1.0,0.84,0.02,0.84,0.02,0.84,0.02,0.84,0.02,0.84,1.0,0.84,1.0];
	bezier(hg,a,3);
}
function createO(hg) { //TODO:
	var a = [0.44,0.99,-0.08,0.95,-0.01,0.02,0.5,0.01,0.5,0.01,1.01,0.03,1.09,0.99,0.58,0.99];
	bezier(hg,a,2);
}
function createP(hg) { //TODO:
	var a = [0.24,0.01,0.24,0.01,0.24,0.99,0.24,0.99,
			0.24,0.99,1.12,1.0,0.81,0.49,0.38,0.48];
	bezier(hg,a,2);
}
function createQ(hg) { //TODO:
	var a = [0.41,0.99,-0.01,0.98,0.0,0.01,0.5,0.02,
			0.5,0.02,0.99,0.02,1.03,0.97,0.58,0.99,
			0.58,0.99,0.43,0.98,0.75,0.1,0.83,0.06];
	bezier(hg,a,3);
}
function createR(hg) { //TODO:
	var a = [0.25,0.0,0.25,0.0,0.24,1.0,0.25,1.0,
			0.25,1.0,0.98,1.0,0.93,0.47,0.38,0.49,
			0.38,0.49,0.38,0.48,0.8,0.01,0.8,0.01];
	bezier(hg,a,3);
}
function createS(hg) {
	var a = [0.74,0.92,0.26,1.2,-0.01,0.57,0.47,0.51,0.47,0.51,1.05,0.45,0.74,-0.3,0.21,0.16];
	bezier(hg,a,2);
}
function createT(hg) {
	var a = [0.17,1.0,0.17,1.0,0.81,0.99,0.81,0.99,0.81,0.99,0.81,0.99,0.81,0.0,0.81,0.0];
	bezier(hg,a,2);
}
function createU(hg) { //TODO: sync with quartzview.m
	var a = [0.16,1.0,0.16,1.0,0.16,0.4,0.16,0.4,
			0.16,0.4,0.16,-0.11,0.83,-0.11,0.83,0.4,
			0.83,0.4,0.83,0.4,0.83,1.0,0.83,1.0];
	bezier(hg,a,3);
}
function createV(hg) {
	var a = [0.14,1.0,0.14,1.0,0.52,0.01,0.53,0.01,0.53,0.01,0.52,0.0,0.85,1.0,0.85,1.0];
	bezier(hg,a,2);
}
function createW(hg) {
	var a = [0.01,0.99,0.01,0.99,0.22,0.0,0.22,0.0,0.22,0.0,0.22,0.0,0.49,1.0,0.49,1.0,0.49,1.0,0.49,1.0,0.77,0.0,0.77,0.0,0.77,0.0,0.77,0.0,0.99,1.0,0.99,1.0];
	bezier(hg,a,4);
}
function createX(hg) {
	var a = [0.13,0.01,0.13,0.01,0.85,1.0,0.85,1.0,0.85,1.0,0.85,1.0,0.13,1.0,0.13,1.0,0.13,1.0,0.13,1.0,0.84,0.01,0.84,0.01];
	bezier(hg,a,3);
}
function createY(hg) {
	var a = [0.16,1.0,0.18,0.34,0.8,0.33,0.85,1.0,0.85,1.0,0.85,1.0,0.78,0.01,0.33,0.02];
	bezier(hg,a,2);
}
function createZ(hg) {
	var a = [0.15,0.99,0.15,0.99,0.86,0.99,0.86,0.99,0.86,0.99,0.86,0.99,0.16,0.01,0.16,0.01,0.16,0.01,0.16,0.01,0.83,0.01,0.83,0.01];
	bezier(hg,a,3);
}


function createLeft(hg) {
	var a = [0.2,0.5,0.2,0.5,0.83,0.5,0.83,0.5];
	bezier(hg,a,1);
}
function createRight(hg) {
	var a = [0.83,0.5,0.83,0.5,0.2,0.5,0.2,0.5];
	bezier(hg,a,1);
}
function createUp(hg) {
	var a = [0.5,0.2,0.5,0.2,0.5,0.83,0.5,0.83];
	bezier(hg,a,1);
}
function createDown(hg) {
	var a = [0.5,0.83,0.5,0.83,0.5,0.2,0.5,0.2];
	bezier(hg,a,1);}
function createRightLeft(hg) {
	var a = [0.83,0.5,0.83,0.5,0.2,0.5,0.2,0.5,0.2,0.5,0.2,0.5,0.83,0.5,0.83,0.5];
	bezier(hg,a,2);
}
function createLeftRight(hg) {
	var a = [0.2,0.5,0.2,0.5,0.83,0.5,0.83,0.5,0.83,0.5,0.83,0.5,0.2,0.5,0.2,0.5];
	bezier(hg,a,2);
}
function createUpRight(hg) {
	var a = [0.21,-0.01,0.21,-0.01,0.21,1.0,0.21,1.0,0.21,1.0,0.21,1.0,0.82,1.0,0.82,1.0];
	bezier(hg,a,2);
}
function createUpLeft(hg) {
	var a = [0.81,0.0,0.81,0.0,0.81,0.99,0.81,0.99,0.81,0.99,0.81,0.99,0.17,1.0,0.17,1.0];
	bezier(hg,a,2);
}
function createRightUp(hg) {
	var a = [0.17,0,0.17,0,0.81,0,0.81,0,0.81,0.0,0.81,0.0,0.81,0.99,0.81,0.99];
	bezier(hg,a,2);
}
function createLeftUp(hg) {
	var a = [0.83,0.0,0.83,0.0,0.2,0.0,0.2,0.0,0.2,0.0,0.2,0.0,0.2,0.99,0.2,0.99];
	bezier(hg,a,2);
}
function createSUp(hg) {
	var a = [0.2,0.2,0.2,0.2,0.7,0.7,0.7,0.7];
	bezier(hg,a,1);
}
function createSDown(hg) {
	var a = [0.7,0.7,0.7,0.7,0.2,0.2,0.2,0.2];
	bezier(hg,a,1);
}
function createBSUp(hg) {
	var a = [0.7,0.2,0.7,0.2,0.2,0.7,0.2,0.7];
	bezier(hg,a,1);
}
function createBSDown(hg) {
	var a = [0.2,0.7,0.2,0.7,0.7,0.2,0.7,0.2];
	bezier(hg,a,1);
}
