/**
 * Author:	Jose Miguel Cotrino Benavides
 * Date:	17.01.2010
 * License:	Creative Commons 3.0 (Attribution-Noncommercial)
 * 		http://creativecommons.org/licenses/by-nc/3.0/
 */
var angle = [0.0,0.0,0.0];
var color = ["red", "green", "blue"];
var frequency = [0.005, 0.01, 0.025];
var fundamental = 1;
var amplitude = [50, 25, 10];
var speed = 50;
var last = [null, null, null, null];
var clockWidth = 500.0;
var clockHeight = 150.0;
var signalWidth = 1500.0;
var signalHeight = 300.0;
var j = 0;
var pause = 1;
var ctx = null;

function fundfreq_init(){
	setFundamentalFrequency();
	controls();
	clock();
	cleanSignalView();
	setInterval(run,speed);
}

function run() {
	if( pause == 0 ) {
		clock();
		signals();
		j++;
		if( j > signalWidth ) {
			j=0;
			cleanSignalView();
		}
	}
}

function restart() {
	for(var i=0; i<angle.length; i++) {
		angle[i] = 0;
		last[i] = null;
		frequency[i] = parseFloat(document.getElementById('freq'+i).value);
		amplitude[i] = parseInt(document.getElementById('ampl'+i).value);
	}
	last[angle.length] = null;
	j = 0;
	setFundamentalFrequency();
	controls();
	cleanSignalView();
}

function cleanSignalView() {
	ctx = document.getElementById('canvas2').getContext('2d');
	ctx.save();
	ctx.clearRect(0,0,signalWidth,signalHeight);
	ctx.strokeStyle = "gray";
	ctx.globalAlpha = 0.3;
	ctx.beginPath();
	ctx.moveTo(0,signalHeight/2);
	ctx.lineTo(signalWidth,signalHeight/2);
	ctx.stroke();
	for(var i=0; i<angle.length; i++) {
		ctx.lineWidth = 1;
		ctx.strokeStyle = color[i];
		ctx.beginPath();
		ctx.moveTo(1/frequency[i],0);
		ctx.lineTo(1/frequency[i],signalHeight);
		ctx.stroke();
	}
	// fundamental frequency
	ctx.strokeStyle = "black";
	ctx.beginPath();
	ctx.moveTo(1/fundamental,0);
	ctx.lineTo(1/fundamental,signalHeight);
	ctx.stroke();
	ctx.restore();
}

function example() {
	k = document.getElementById('example').selectedIndex;
	// f0 = 0.005
	if( k==0 ) {
		frequency[0]=0.005;
		frequency[1]=0.01;
		frequency[2]=0.025;
	}
	// f0 = 0.005
	else if( k==1 ) {
		frequency[0]=0.01;
		frequency[1]=0.02;
		frequency[2]=0.035;
	}
	// f0 = 0.02
	else if( k==2 ) {
		frequency[0]=0.02;
		frequency[1]=0.04;
		frequency[2]=0.06;
	}
	// f0 = 0.006
	else if( k==3 ) {
		frequency[0]=0.012;
		frequency[1]=0.06;
		frequency[2]=0.09;
	}
	// f0 = 0.01
	else if( k==4 ) {
		frequency[0]=0.02;
		frequency[1]=0.021;
		frequency[2]=0.023;
	}
	// f0 = 0.01
	else if( k==5 ) {
		frequency[0]=0.01;
		frequency[1]=0.021;
		frequency[2]=0.023;
	}
	for(var i=0; i<angle.length; i++) {
		document.getElementById('freq'+i).value = frequency[i];
	}
	restart();
}

function controls() {
	var text = "<input type='button' style='color:white; background: #0000aa;' value='Play/pause' onClick='togglePause();'/>"+
		"<input type='button' style='color:white; background: #aa0000;' value='Restart' onClick='restart();'/>";
	text += " Examples: <select id='example' onChange='example();'><option>1) f0 = 0.005</option>"+
		"<option>2) f0 = 0.005</option><option>3) f0 = 0.02</option><option>4) f0 = 0.006</option>"+
		"<option>5) f0 = 0.001</option><option>6) f0 = 0.001</option></select>";
	text += "<br/><table><tr>";
	for(var i=0; i<angle.length; i++) {
		text += "<td>Freq"+(i+1)+":</td><td><input type='textfield' id='freq"+i+"' value='"+frequency[i]+"' size='5'/></td>";
	}
	text += "</tr><tr>";
	for(var i=0; i<angle.length; i++) {
		text += "<td>Ampl"+(i+1)+":</td><td><input type='textfield' id='ampl"+i+"' value='"+amplitude[i]+"' size='2'/></td>";
	}
	text += "</tr></table>Fundamental frequency: "+fundamental+"<br/>";
	text += "<canvas id='canvas' width='"+clockWidth+"' height='"+clockHeight+"'></canvas><br/>"+
		"<div style='width:500px; overflow:scroll;'>"+
		"<canvas id='canvas2' style='border: solid 1px gray;' width='"+signalWidth+"' height='"+signalHeight+"'></canvas>"+
		"</div>";

	document.getElementById('controls').innerHTML = text;
}

function setFundamentalFrequency() {
	var T = 1;
	var max = null;
	var f = new Array();
	for(var i=0; i<angle.length; i++) {
		f[i] = Math.round(frequency[i]*100000);
		if( f[i] > max ) {
			max = Math.round(f[i]);
		}
	}
	for(var p=max; p>0; p--) {
		var valid = true;
		for(var i=0; i<angle.length; i++) {
			if( f[i]%p != 0 ) {
				valid = false;
			}
		}
		if( valid == true ) {
			T = p;
			break;
		}
	}
	fundamental = T/100000;
}

function signals() {
	ctx = document.getElementById('canvas2').getContext('2d');
	ctx.save();
	ctx.translate(0,signalHeight/2);
	ctx.lineWidth = 1;
	for(var i=0; i < angle.length; i++) {
	  drawSignal(i);
	}
	drawSumma();
	ctx.restore();
}

function drawSignal(i) {
	ctx.strokeStyle = color[i];
	ctx.beginPath();
	var point = amplitude[i] * Math.cos(2*Math.PI * angle[i]); // + k/20);
	ctx.moveTo(j,point);
	if( last[i] != null ) {
		ctx.lineTo(j,last[i]);
	}
	last[i] = point;
	ctx.stroke();
}

function drawSumma() {
	ctx.strokeStyle = "black";
	ctx.lineWidth = 3;
	ctx.beginPath();
	var point = 0;
	for(var i=0; i<angle.length; i++) {
		point += last[i];
	}
	ctx.moveTo(j,point);
	if( last[angle.length] != null ) {
		ctx.lineTo(j,last[angle.length]);
	}
	last[angle.length] = point;
	ctx.stroke();
}

function drawHands(i) {
	ctx.save();
	ctx.strokeStyle = color[i];
	ctx.lineCap = "round";
	ctx.lineWidth = 8;
	ctx.rotate( 2*Math.PI * angle[i] )
	ctx.beginPath();
	ctx.moveTo(0,0);
	ctx.lineTo(clockHeight/3,0);
	ctx.stroke();
	ctx.restore();
}

function clock(){
	ctx = document.getElementById('canvas').getContext('2d');
	ctx.save();
	ctx.clearRect(0,0,clockWidth,clockHeight);
	ctx.translate(clockWidth/2,clockHeight/2);
	ctx.rotate(-Math.PI/2);
	ctx.strokeStyle = "black";
	ctx.fillStyle = "white";
	ctx.lineWidth = 4;

	// Hour marks
	ctx.save();
	ctx.lineWidth = 4;
	for (var i=0;i<12;i++){
		ctx.beginPath();
		ctx.rotate(Math.PI/6);
		ctx.moveTo(clockHeight/3,0);
		ctx.lineTo(clockHeight/3+clockHeight/15,0);
		ctx.stroke();
	}
	ctx.restore();

	// Minute marks
	ctx.save();
	ctx.lineWidth = 2;
	for (var i=0;i<60;i++){
		if (i%5!=0) {
			ctx.beginPath();
			ctx.moveTo(clockHeight/3+clockHeight/15,0);
			ctx.lineTo(clockHeight/3+clockHeight/30,0);
			ctx.stroke();
		}
		ctx.rotate(Math.PI/30);
	}
	ctx.restore();
  
	for(var i=0; i<angle.length; i++) {	
		drawHands(i);
		angle[i] += frequency[i];
		/*document.getElementById('angle'+i).value = angle[i];*/
	}

	ctx.strokeStyle = "blue";
	ctx.beginPath();
	ctx.arc(0,0,clockHeight/2.3,0,Math.PI*2,true); // Outer circle
	ctx.stroke();

	ctx.restore();
}

function togglePause() {
	if( pause == 0 ) {
		pause = 1;
	} else {
		pause = 0;
	}
}


