// Pelle's Harmonograph v1.1
// COPYRIGHT Per Swantesson 2010
//
// This application is not open source. 
// Please contact me at www.swantesson.com/contact.html 

var xscale,yscale,xoff,yoff,xfreq,yfreq,loop,damp;
var currentPreset = 1;
var canvas, ctx;
var presets = new Array();
var isIE = !jQuery.support.leadingWhitespace;
var dragX,dragY;
var zoomingInProgress = 0;
var createPresetCounter = 1;

presets.push(new preset(1000,100,750,1000,100,400,1,4,1,1.019,20000,2,100,1));
presets.push(new preset(1000,100,750,1000,100,400,1,4.02,1,1.01,30000,2,100,2));
presets.push(new preset(1000,100,750,1000,500,400,1,2.015,1,1.019,20000,2,100,10));
presets.push(new preset(1360,240,1456,720,136,399,1.0001,2.0001,0.9999,4.0005,100000,1,19.5,1));
presets.push(new preset(1000,100,750,1000,200,400,1,2.01,1,1.01,200000,4,100,1));
presets.push(new preset(2031,233,462,2031,233,186,1,9.01,1,1.,130000,1,95,.8));
presets.push(new preset(200,30,750,200,30,300,1.,2.02,1,3.006,300000,5,100,0.1));
presets.push(new preset(200,100,700,200,50,300,1,4.02,1,1.01,30000,2,100,0.6));
presets.push(new preset(831,95,664,831,95,525,1,4.01,1,1.01,80000,2,100,3.5));
presets.push(new preset(450,100,750,300,50,300,1,2,1.003,2,300000,4,100,0.1));
presets.push(new preset(6407,587,-4400,2635,587,291,1.00,7,1,4.0,100000,1,10,1));
presets.push(new preset(2440,2440,1560,2440,702,-473,1.001,1,1,1,200000,1,51,1.5));
presets.push(new preset(1700,300,750,900,170,1100,1,2,1,4,100000,1,100,1));
presets.push(new preset(1089,114,896,452,114,528,1.005,2,1,4.02,70000,1,15,0.7));
presets.push(new preset(255,16,824,255,16,394,2,4.05,2.008,10,200000,1,15,0.6));
presets.push(new preset(1000,100,750,1000,500,400,1,2.015,1,1.019,20000,2,100,0.8));
presets.push(new preset(1700,300,750,900,170,1100,1,2,1,4.04,10000,1,100,2));
presets.push(new preset(76,320,678,76,76,261,1,0.12501,1,0.250001,400000,2,8,0.4));
presets.push(new preset(1300,150,1200,1300,150,800,1,4.02,1,1.01,40000,2,100,3.5));
presets.push(new preset(1000,100,750,1000,200,400,1,2.01,1,1.01,90000,3,100,1));
presets.push(new preset(2031,233,896,2031,233,312,1,8.995,1,1.,530000,10,100,.7));
presets.push(new preset(450,50,750,190,50,300,1,2,1,4.04,50000,2,100,1));
presets.push(new preset(600,0,750,550,0,400,1,0,1,0,4000,3,100,35));
presets.push(new preset(250,50,750,200,100,300,1.0001,2.005,1,3.003,500000,5,100,0.06));
presets.push(new preset(400,0,750,250,20,300,1,2,1,4.02,90000,4,100,0.5));
presets.push(new preset(1095,117,750,456,117,233,1,2,1,3.5,200000,2,70,0.8));
presets.push(new preset(949,136,750,949,136,300,1,2.02,1,3.006,500000,100,200,0.05));
/*

Pretty presets that require much more CPU than the standard ones.
To DO:
-Progress indicator
-Progressive drawing
-Disable drag and drop event while calculating
-Chrome has a limitation on number of iterations

presets.push(new preset(7740,880,5623,7740,2028,-3267,1,8.9952,1,2.001,1530000,10,100,1.5));
presets.push(new preset(947,471,129,947,233,68,1,4.004,1,1.001,3000000,60,100,0.05));
presets.push(new preset(1183,588,1429,1183,291,-71,1,5.001,1,1.00,1500000,20,100,0.04));
presets.push(new preset(940,468,1647,940,227,-121,1,5.001,1,1.00,7000000,20,30,0.025));
presets.push(new preset(940,468,1429,940,227,64,1,5.001,1,1.00,9000000,20,30,0.03));
presets.push(new preset(1171,578,1412,1171,277,-33,1,5.001,1,1.00,19000000,20,80,0.01));
presets.push(new preset(1171,578,1689,1171,277,-105,1,5.001,1,1.00,19000000,20,80,0.01));
presets.push(new preset(1461,720,2021,1461,344,456,1,5.0015,1,1.00,19000000,30,80,0.015));
presets.push(new preset(1460,720,1924,1460,343,165,1,5.0015,1,1.00,19000000,30,24,0.015));
presets.push(new preset(933,460,1362,933,218,-161,1,5.0015,1,1.00,19000000,40,24,0.015));
*/

$(document).ready(function() {
	if(isIE){return}

	$("body").append("<canvas id='canvas' style='position:absolute;top:0px;left:0px;'></canvas>");
	$("body").append("<scale min='1' max='10' orient='vertical'/>");
	canvas = document.getElementById("canvas");
	setCanvasSize();
	ctx = canvas.getContext("2d");
	$(window).resize(function(){
		setCanvasSize();
		refresh();
	});
	drawPreset();
	$("#canvas").draggable({
		stop: function(event, ui) {

			// Get dropped position.
			var Stoppos = $(this).position();
			var xSetting = document.getElementById("xoffset");
			var ySetting = document.getElementById("yoffset");
			xSetting.value = parseInt(xSetting.value) + Stoppos.left;
			ySetting.value = parseInt(ySetting.value) + Stoppos.top;
			$("#canvas").css({left: 0, top: 0});
			refresh();
		}
	}).mousewheel(function(event, delta) {
		$(".splash").fadeOut("fast");
		$("#startHere").fadeOut("fast");
		console.log(delta);
		var xscaleSetting = document.getElementById("xscale");
		var yscaleSetting = document.getElementById("yscale");
		var xscale2Setting = document.getElementById("xscale2");
		var yscale2Setting = document.getElementById("yscale2");
		
		if (delta < 0){
			// Zoom out
			console.log(delta);
			xscaleSetting.value = parseInt(xscaleSetting.value * .80);
			yscaleSetting.value = parseInt(yscaleSetting.value * .80);
			xscale2Setting.value = parseInt(xscale2Setting.value * .80);
			yscale2Setting.value = parseInt(yscale2Setting.value * .80);
			refresh();
		}
		if (delta > 0){
			// Zoom in
			xscaleSetting.value = parseInt(xscaleSetting.value * 1.25);
			yscaleSetting.value = parseInt(yscaleSetting.value * 1.25);
			xscale2Setting.value = parseInt(xscale2Setting.value * 1.25);
			yscale2Setting.value = parseInt(yscale2Setting.value * 1.25);
			refresh();
		}
	});

	setTimeout(function(){
		$("#startHere").fadeIn("slow");
	},1000)
});

function updateSettings(){
	xscale= document.getElementById("xscale").value;
	yscale= document.getElementById("yscale").value;
	xscale2= document.getElementById("xscale2").value;
	yscale2= document.getElementById("yscale2").value;
	xoff= document.getElementById("xoffset").value;
	yoff= document.getElementById("yoffset").value;
	xfreq= document.getElementById("xfreq").value;
	yfreq= document.getElementById("yfreq").value;
	xfreq2= document.getElementById("xfreq2").value;
	yfreq2= document.getElementById("yfreq2").value;
	loop= document.getElementById("loop").value;
	damp= document.getElementById("damp").value;
	quality= document.getElementById("quality").value;
	thickness = document.getElementById("thickness").value;
	completeness= document.getElementById("completeness").value;
	ctx.lineWidth=thickness;
}

function setCanvasSize(){
	var myHeight = $(window).height();
	if (myHeight<550){
		myHeight=550;
	}
	$("#canvas").attr("width", $(window).width()).attr("height",myHeight);
}

function refresh(){
	updateSettings();
	draw();
	$(".splash").fadeOut("fast");
	$("#startHere").fadeOut("fast");
}

function draw() {
	if(isIE){return}
	ctx.clearRect(0,0,2400,2000);
	ctx.lineWidth=thickness;
	//ctx.strokeStyle='#9db4b9';
	ctx.beginPath();
	var startValue= 1+(loop-(loop*completeness/100));
	ctx.moveTo(getX(90+startValue),getY(startValue));

	starttime=new Date();
	for (var a=1+(loop-(loop*completeness/100));a<loop ;a=a+parseInt(quality) ){
		ctx.lineTo(getX(a+90),getY(a));
	}
	ctx.stroke();
	endtime=new Date();
	totaltime=starttime-endtime;
	console.log(getAllSettings());
}

function drawPreset(){
	if(isIE){return}
	selectedPreset	= presets[currentPreset];
	xscale		= selectedPreset.xscale;
	xscale2		= selectedPreset.xscale2;
	xoff		= selectedPreset.xoff;
	yscale		= selectedPreset.yscale;
	yscale2		= selectedPreset.yscale2;
	yoff		= selectedPreset.yoff;
	xfreq		= selectedPreset.xfreq;
	xfreq2		= selectedPreset.xfreq2;
	yfreq		= selectedPreset.yfreq;
	yfreq2		= selectedPreset.yfreq2;
	loop		= selectedPreset.loop;
	quality		= selectedPreset.quality;
	thickness	= selectedPreset.thickness;
	completeness= selectedPreset.completeness;

	document.getElementById("xscale").value = xscale;
	document.getElementById("yscale").value = yscale;
	document.getElementById("xscale2").value = xscale2;
	document.getElementById("yscale2").value = yscale2;
	document.getElementById("xoffset").value = xoff;
	document.getElementById("yoffset").value = yoff;
	document.getElementById("xfreq").value = xfreq;
	document.getElementById("yfreq").value = yfreq;
	document.getElementById("xfreq2").value = xfreq2;
	document.getElementById("yfreq2").value = yfreq2;
	document.getElementById("loop").value = loop;
	document.getElementById("damp").value = damp;
	document.getElementById("quality").value = quality;
	document.getElementById("thickness").value = thickness;
	document.getElementById("completeness").value = completeness;

	draw();
}

function getY(a){
	return ((dampen(a,loop))*(sin(a*yfreq)*yscale+sin(a*yfreq2)*yscale2)+parseInt(yoff));
}

function getX(a){
	return ((dampen(a,loop))*(sin(a*xfreq)*xscale+sin(a*xfreq2)*xscale2)+parseInt(xoff));
}

function sin(a){
	return Math.sin(getRadian(a));
}

function cos(a){
	return Math.cos(getRadian(a));
}

function getRadian(deg) {
	// return deg in radians
	return Math.PI * deg / 180	;
}

function dampen(currentStep,totalsteps){
	//damp = sin(90-(90/totalsteps*currentStep));// Dämpar mot ytterkanterna
	damp = cos(90/totalsteps*currentStep)-1;// Dämpar mot mitten
	return damp;
}

function preset(a,b,c,d,e,f,g,h,i,j,k,l,m,n){
	this.xscale = a;
	this.xscale2 = b;
	this.xoff = c;
	this.yscale = d;
	this.yscale2 = e;
	this.yoff = f;
	this.xfreq = g;
	this.xfreq2 = h;
	this.yfreq = i;
	this.yfreq2 = j;
	this.loop = k;
	this.quality = l;
	this.completeness = m;
	this.thickness = n;
	return this;
}

function increasePreset(){
	$(".splash").fadeOut("fast");
	$("#startHere").fadeOut("fast");
	if(currentPreset==presets.length-1){
		currentPreset=0;
	}
	currentPreset++;
	document.getElementById("currentPreset").innerHTML=currentPreset;
	drawPreset();
}

function decreasePreset(){
	$(".splash").fadeOut("fast");
	$("#startHere").fadeOut("fast");
	if(currentPreset==1){
		currentPreset=presets.length;
	}
	currentPreset--;
	document.getElementById("currentPreset").innerHTML=currentPreset;
	drawPreset();
}

function getAllSettings(){
	var result = xscale+","+xscale2+","+xoff+","+yscale+","+yscale2+","+yoff+","+xfreq+","+xfreq2+","+yfreq+","+yfreq2+","+loop+","+quality+","+completeness+","+thickness;
	return result;
}
