/* 	Parallax Calculator
	v 0.9
	William Schurman
	http://wschurman.com/adc
	Equations: L. Smallwood, D. Katz, M. Richmond.
*/

function Observatory(oname,lat,longi,erad) {

	this.oname = oname;
	this.longitude = longi; //stored as degree
	this.latitude = lat; //stored as degree
	this.earth_rad = erad;
	var loc = new Array(3);

	this.setLoc = function(locx) {
		this.loc = locx;
	}
	this.getLoc = function() {
		return this.loc;
	}
	this.getRad = function() {
		return this.earth_rad;
	}
	this.getLat = function() {
		return deg2rad(this.latitude); //returns radians
	}
	this.getLong = function() {
		return deg2rad(this.longitude); //returns radians
	}
}

/*
Calculates the dot product of two arrays, arr1 and arr2
Does not need any modification.
*/
function calc_dot_product(arr1, arr2) {
	if(arr1.length != arr2.length) return false;

	var al = arr1.length;
	var total = 0;

	for(var i=0; i<al; i++) {
		total+=(arr1[i]*arr2[i]);
	}
	return total;
}

//Simple math functions
function deg2rad(deg) {
	return deg * (Math.PI/180);
}
function arcsec2rad(as) {
	return deg2rad((as/3600));
}
function rad2deg(rad) {
	return rad * (180/Math.PI);
}
function hour2rad(hour) {
	var result = hour*15; //degrees
	return deg2rad(result);
}
function rnd(num) {
	var result = Math.round(num*10)/10;
	return result;
}

//for remembering the observatory values
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}
function eraseCookie(name) {
	createCookie(name,"",-1);
}

/* START Calculation Functions */
function calc_magnitude(arr) {
	var al = arr.length;
	var total = 0;

	for(var i=0; i<al; i++) {
		total+=arr[i]*arr[i];
	}
	total = Math.sqrt(Math.abs(total));
	return total;
}

function loc_observ_1(obs1, obs2) { //obs1.getLoc()
	var loc = new Array(3);
	loc[0] = (obs1.getRad()*Math.cos(obs1.getLat())); //Re*cos(latx)
	loc[1] = 0;
	loc[2] = (obs1.getRad()*Math.sin(obs1.getLat())); //Re*sin(latx)
	return loc;
}
function loc_observ_2(obs1, obs2) { //obs2.getLoc()
	var loc = new Array(3);
	loc[0] = (obs2.getRad()*Math.cos(obs2.getLat())*Math.cos(obs1.getLong()-obs2.getLong())); //Re*cos(laty)*cos(b); b=longx-longy
	loc[1] = (obs2.getRad()*Math.cos(obs2.getLat())*Math.sin(obs1.getLong()-obs2.getLong()));
	loc[2] = (obs1.getRad()*Math.sin(obs2.getLat()));
	return loc;
}
function calc_chord(obs1, obs2) { //already has earth rad because the C vector is just the differences. See souce sheet.
	var c = new Array(3);
	c[0] = (obs1.getLoc()[0]-obs2.getLoc()[0]); //differences of vectors
	c[1] = (obs1.getLoc()[1]-obs2.getLoc()[1]);
	c[2] = (obs1.getLoc()[2]-obs2.getLoc()[2]);
	return c;
}
function calc_ast_vector() {
	var v = new Array(3);
	var dec = $("#obs1-dec").val();
	var hour = $("#obs1-hour").val();

	//make compatible w/ functions
	dec = deg2rad(dec);
	hour = deg2rad(hour); //may need to multiply by 15 if entered value is in hours not degrees

	v[0] = (Math.cos(hour)*Math.cos(dec));
	v[1] = (Math.sin(hour)*Math.cos(dec));
	v[2] = (Math.sin(dec));
	return v;
}
function calc_chord_ast_angle(c, v) { //c=chord dist, v=unit ast vector
	var dp = calc_dot_product(c,v);
	var mag = calc_magnitude(c);
	var angle = ((dp)/(mag));
	angle = Math.acos(angle);
	return angle; //in radians
}
function calc_dist_to_ast(parallax_ang, base_mag) {
	var dist = base_mag;
	dist /= (2*Math.tan(arcsec2rad(parallax_ang/2))); //need to confirm this line
	return dist;
}
/*END Calculation Functions */

$(document).ready(function(){
	
	var read = readCookie("adc-last");
	if(read) {
		var rarr = read.split(":");
		$("#obs1-lat").val(rarr[0]);
		$("#obs1-long").val(rarr[1]);
		$("#obs2-lat").val(rarr[2]);
		$("#obs2-long").val(rarr[3]);
	}
	
	var height = $("#main").height();
	
	$("form").submit(function(){
		
		var cokie = $("#obs1-lat").val()+":"+$("#obs1-long").val()+":"+$("#obs2-lat").val()+":"+$("#obs2-long").val();
		createCookie("adc-last", cokie, 30);
		
		//create observatories
		var observatory1 = new Observatory("1", $("#obs1-lat").val(), $("#obs1-long").val(), $("#e-rad").val());
		var observatory2 = new Observatory("2", $("#obs2-lat").val(), $("#obs2-long").val(), $("#e-rad").val());

		//set locations
		observatory1.setLoc(loc_observ_1(observatory1, observatory2));
		observatory2.setLoc(loc_observ_2(observatory1, observatory2));

		//calculate chord distance between observatories
		var chord_dist = new Array(3);
		chord_dist = calc_chord(observatory1, observatory2);

		//calculate the asteroid verctor from the first observatory
		var ast_obs1_vector = new Array(3);
		ast_obs1_vector = calc_ast_vector();
		
		var chord_ast_angle = calc_chord_ast_angle(chord_dist, ast_obs1_vector);

		var baseline_magnitude = (calc_magnitude(chord_dist)*Math.sin(chord_ast_angle));

		var dist_to_asteriod = calc_dist_to_ast($("#e-par").val(), baseline_magnitude);

		//create the resulting HTML
		var result_html = 
		"<h3>Distance to Asteroid: "+rnd(dist_to_asteriod)+" km</h3>"+
		"Observatory 1: ["+
		rnd(observatory1.getLoc()[0])+", "+rnd(observatory1.getLoc()[1])+", "+rnd(observatory1.getLoc()[2])+"]<br />"+
		"Observatory 2: ["+
		rnd(observatory2.getLoc()[0])+", "+rnd(observatory2.getLoc()[1])+", "+rnd(observatory2.getLoc()[2])+"]<br />"+
		"Result Chord Distance: ["+
		rnd(chord_dist[0])+", "+rnd(chord_dist[1])+", "+rnd(chord_dist[2])+"]<br />"+
		"Asteroid Unit Vector: ["+
		rnd(ast_obs1_vector[0])+", "+rnd(ast_obs1_vector[1])+", "+rnd(ast_obs1_vector[2])+"] Mag: "+calc_magnitude(ast_obs1_vector)+"<br />"+
		"Chord Asteroid Angle: "+rnd(rad2deg(chord_ast_angle))+"°<br />"+
		"Baseline Magnitude: "+rnd(baseline_magnitude);
		
		//cool effects
		if(!$("#result-data").hasClass("slid")) {
			$("#main").animate({height: height+165}, 500);
		}
		
		$("#result-data").html(result_html);
		$("#result-data").addClass("slid");

		return false;
	});
});

