//if (window == window.parent || window.parent.location.href.indexOf('damninteresting.com') == -1) {
//	this.location = "http://www.damninteresting.com/space-radio-more-static-less-talk";
//}

var equation = new Equation();
var mouseDocX = 0;
var bodyPaddingLeft = 60;
var slideStepSize = 10;
var slideAnimDelay = 3;
var sliderBgWidth = 720;

function Equation () {
	this.sliders = [];
	this.presets = [];
	this.presetsSections = [];

	this.addSlider = function (name, min, max, decimals, labelStops, isPercentage, logarithmBase) {
		this.sliders.push(new HorizontalSlider(this, name, min, max, decimals, labelStops, isPercentage, logarithmBase));
	};
	
	this.addPresets = function (equationPresets) {
		var section = null;
		this.presets.push(equationPresets);
		equationPresets.equation = this;
		
		section = this.getPresetsSection(equationPresets.category);
		equationPresets.spawnOptionRowInside(section.listDiv);		
	};

	this.loadPresets = function (equationPresets) {
		for (var i=0; i < this.sliders.length; i++) {
			this.sliders[i].setValuePreset(equationPresets.values[i]);
		}
		hidePresetsMenu();
	};
	
	this.stopAllSliders = function () {
		for (var i=0; i < this.sliders.length; i++) {
			this.sliders[i].stop();
		}
	};

	this.getPresetsSection = function (name) {
		if (!this.presetsSections[name]) {
			this.presetsSections[name] = new EquationPresetsCategory(name);
		}
		return this.presetsSections[name];
	};

	this.compute = function () {
		var total = this.sliders[0].getCalcValue();
		var displayTotal = '';
		for (var i=1; i < this.sliders.length; i++) {
			total*= this.sliders[i].getCalcValue();
		}		
		displayTotal = addCommas(Math.round(total * 10)/10);

		if (displayTotal.indexOf(".") == -1) {
			displayTotal+= ".0";
		}	
		return displayTotal;
	};
	
	
	this.showTextOnly = function () {
		var text = '<pre>';
		var sliders = $('sliders');
		var equation = $('equation');
		var textOnly = $('textOnlyValues');

		text+= "New Milky Way stars per year = " + this.sliders[0].value + "\n";
		text+= "Proportion of stars which have planets = " + this.sliders[1].value + "%\n";
		text+= "Average number of life-compatible satellites = " + this.sliders[2].value + "\n";
		text+= "Percentage of planets where life does appear = " + this.sliders[3].value + "%\n";
		text+= "Percentage where intelligent life evolves = " + this.sliders[4].value + "%\n";
		text+= "Percentage of civilizations which send signals into space = " + this.sliders[5].value + "%\n";
		text+= "Average years that civilizations will send signals = " + this.sliders[6].value + "\n\n";

		text+= "Average civilizations in our galaxy = " + this.compute() + "\n</pre>";

		textOnly.innerHTML = text;
		equation.style.display = 'none';
		sliders.style.display = 'none';
		textOnly.parentNode.style.display = 'block';
	};

	this.showSliders = function () {
		var sliders = $('sliders');
		var equation = $('equation');
		var textOnly = $('textOnlyValues');

		equation.style.display = 'none';
		sliders.style.display = 'block';
		textOnly.parentNode.style.display = 'none';	
	};

	this.showEquation = function () {
		var sliders = $('sliders');
		var equation = $('equation');
		var textOnly = $('textOnlyValues');

		equation.style.display = 'block';
		sliders.style.display = 'none';
		textOnly.parentNode.style.display = 'none';		
	};
}

/*
	Sagan
	400 billion stars
	25% have planets
	2 per system can support life
	50% life does arise
	10% get intelligence
	10% get technical

	1/100,000,000 of planet lifetime sending signals = 10
		30
	or 1/100 = millions
*/

function HorizontalSlider (equation, name, min, max, decimals, labelStops, isPercentage, logarithmBase) {
	
	this.equation = equation;
	this.name = name;
	this.min = min;
	this.max = max;
	this.decimals = decimals;
	this.labelStops = labelStops;
	this.isPercentage = isPercentage;
	this.logarithmBase = logarithmBase;
	this.value = this.min;
	this.currentX = 0;
	this.interval = null;
	this.div;
	this.resultBox;
	this.labelFreq = 0;
	this.width = 0;
	this.sectionWidth = 0;

	
	this.drawInside = function (elementId) {
		var e = $(elementId);
		var that = this;
		var labelCounter = 0;
		
		this.div = document.createElement('div');
		this.div.setAttribute('id', this.name + "Slider");
		this.div.className = 'hSlider';
		this.resultBox = document.createElement('div');
		this.resultBox.setAttribute('id', this.name + "Result");
		this.resultBox.className = 'hSliderResult';
		
		e.appendChild(this.div);
		this.div.appendChild(this.resultBox);
		
		if (this.logarithmBase) {
			for (var i=this.min; i <= this.max; i*=this.logarithmBase) {
				var temp = document.createElement('div');
				var width = this.div.offsetWidth/this.labelStops;
				temp.className = 'hSliderScaleSection';
				temp.style.width = width + "px"; 

				if (i >= 1000000000) {
					temp.innerHTML = (i/1000000000) + 'bil';
				}
				else if (i >= 1000000) {
					temp.innerHTML = (i/1000000) + 'mil';
				}
				else if (i >= 1000) {
					temp.innerHTML = (i/1000) + 'k';
				}
				else {
					temp.innerHTML = i;	
				}
				this.div.appendChild(temp);
				temp.style.left = ((labelCounter * width) - width/2) + "px";
				labelCounter++;
			}		
		}
		else {
			labelFreq = (this.max - this.min) / this.labelStops;
		
			for (var i=this.min; i <= this.max; i+=labelFreq) {
				var temp = document.createElement('div');
				var width = this.div.offsetWidth/this.labelStops;
				temp.className = 'hSliderScaleSection';
				temp.style.width = width + "px"; 

				temp.innerHTML = i;	

				if (this.isPercentage) {
					temp.innerHTML+= '%';
				}
				this.div.appendChild(temp);
				temp.style.left = (((i/labelFreq) * width) - width/2) + "px";
			}
		}
		
		this.div.onmousedown = function (ev) {
			ev = (ev || window.event);
			that.equation.stopAllSliders();
			that.interval = setInterval(function () { that.setValueMouse(mouseDocX); }, 10);
			return false;
		};
		
		this.div.onmouseup = function () {
			that.equation.stopAllSliders();	
		};
		
		e.onselectstart = function() {return false;}
		
		this.width = this.div.offsetWidth;
		this.sectionWidth = Math.round(this.width/this.labelStops);		
		
		this.setValuePreset(0);
	};
	
	
	this.setValueMouse = function (mouseDocX) {
		var x = mouseDocX - this.div.offsetLeft - bodyPaddingLeft;
		
		if (x < 0) {
			x = 0;	
		}
		if (x > this.width) {
			x = this.width;
		}
		
		//get the value that corresponds to the mouse location
		
		this.setValueByX(x);
	};

	
	this.setValueByX = function (x) {
		if (x == this.width) {
			this.setValue(this.max);
		}
		else if (this.logarithmBase) {
			var base = Math.pow(this.logarithmBase, Math.floor(x/this.sectionWidth));
			var nextBase = base * this.logarithmBase;
			var diff = nextBase - base;
			var sectionValue = diff * ((x % this.sectionWidth) / this.sectionWidth);
			
			this.setValue(base + sectionValue);
		}
		else {
			this.setValue((this.min + ((x/this.width) * this.max)));
		}
		this.moveToX(x);	
	};
	
	
	this.setValuePreset = function (value) {
		if (this.logarithmBase) {
			var section = 0;
			var pos = this.min;
			var x = 0;
			var sectionPixelVal = 0;
			var diff = 0;

			for (; pos < value; pos*=this.logarithmBase) {
				x+=this.sectionWidth;
			}
			
			if (value >= this.logarithmBase) {
				diff = (Math.pow(pos, this.logarithmBase)) - pos;
			}
			else {
				diff = this.logarithmBase;
			}
			sectionPixelVal = diff / this.sectionWidth;
		
			x+= Math.round((value - pos) / sectionPixelVal);
			
			this.slideTo(value, x);
		}
		else {
			var pixelVal = (this.max - this.min)/this.width;
			this.slideTo(value, value/pixelVal);
		}
	};
	
	
	this.moveToX = function (x) {
		x = Math.round(x);
	
		var backgroundX = x - Math.ceil(sliderBgWidth/2);
		var resultBoxX = x - this.resultBox.offsetWidth/2;

		this.resultBox.style.left = resultBoxX + "px";
		this.div.style.backgroundPosition = backgroundX + 'px 0px';
		
		this.currentX = x;
	};
	
	
	this.slideTo = function (value, x) {
		x = Math.round(x);
	
		var diff = x - this.currentX;
		var direction = (diff > 0) ? 1 : -1;
		
		diff*= direction; //make sure it's a positive number
		
		//console.log(x + " | " + this.currentX + " | " + diff + " | " + direction);
		
		if (diff > slideStepSize * 2) {
			var slideQueue = new tools.Queue(this.name + '_slideQueue', true);
			
			for (; diff > 0; diff-=slideStepSize) {
				slideQueue.push(
					function (slider, newX) {
						slider.setValueByX(newX);
					},
					[this, x - (diff * direction)],
					slideAnimDelay
				);
			}
			slideQueue.push(
				function (slider, newX) {
					slider.setValue(value);
					slider.moveToX(newX);
				},
				[this, x],
				slideAnimDelay
			);			
		}
		else {
			this.setValue(value);
			this.moveToX(x);
		}
	};
	
	
	this.setValue = function (value) {
		var actualValue = value;
		this.value = value = "" + limitDecimals(value, this.decimals) + "";		
		
		if (parseFloat(value) == 0 && actualValue == 0.000001) {
			//deal with special case for rare earth's 0.000001
			this.value = value = "" + limitDecimals(actualValue, 6) + "";	
		}
		if (value.indexOf(".") == -1) {
			value+= ".0";
		}
		
		this.resultBox.innerHTML = addCommas(value);

		$('drakeTotal').innerHTML = this.equation.compute();	
	};
	
	
	this.getCalcValue = function () {
		if (this.isPercentage) {
			return this.value/100;	
		}
		return this.value;
	};
	
	
	this.stop = function () {
		clearInterval(this.interval);
	};
}


function EquationPresets () { //category, label, value, value, value...
	
	var that = this; //used for lambda stuff
	
	this.values = [];
	
	for (var i=0; i < arguments.length; i++) {
		this.values.push(arguments[i]);
	}

	this.optionRowEl = null;	
	this.equation = null;
	this.category = this.values.shift();
	this.label = this.values.shift();
	
	
	this.spawnOptionRowInside = function (el) {
		var container = $(el);
		var row = container.create('div','presetRow');
		var equation = this.equation;
		
		row.innerHTML = this.label;
		row.onclick = function () {
			equation.loadPresets(that);
		};
		
		this.optionRowEl = row;
	};
	
	this.isCurrent = function () {
		for (var i=0; i < this.values.length; i++) {
			//console.log(this.equation.sliders[i].value) + " ~ " + this.values[i];
			if (parseFloat(this.equation.sliders[i].value) != this.values[i]) {
				return false;
			}
		}
		return true;
	};
	
}


function EquationPresetsCategory (name) {
	var container = $('presets');

	this.name = name;
	this.div = container.create('div','presetsSection');	
	this.titleDiv = this.div.create('div','presetsSectionTitle');	
	this.listDiv = this.div.create('div');	
	
	this.titleDiv.innerHTML = this.name;
}


function updateMousePos (ev) {
	if (window.event) {
		mouseDocX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
	}
	else {
		mouseDocX = ev.pageX;
	}
	
}

function getWindowWidth () {
	if (window.innerWidth) {
		return window.innerWidth;
	}
	else if (doc.body && doc.body.clientWidth) {
		return doc.body.clientWidth;
	}
	else if (doc.docElement && doc.docElement.clientWidth) {
		return doc.docElement.clientWidth;
	}
	return 0;
}

function addCommas (nStr)	{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}		

function togglePresetsMenu (ev) {
	var menu = $('presets');
	browser.stopEvent(ev);
	
	if (menu.style.display == 'block') {
		hidePresetsMenu();
	}	
	else {
		showPresetsMenu();
	}
	//menu.css.toggle('display','block','none');
}


function showPresetsMenu () {
	for (var i=0; i < equation.presets.length; i++) {
		if (equation.presets[i].isCurrent()) {
			equation.presets[i].optionRowEl.css.addClass('selected');
		}
		else {
			equation.presets[i].optionRowEl.css.removeClass('selected');
		}
	}
	$('presets').style.display = 'block';
}


function hidePresetsMenu () {
	$('presets').style.display = 'none';
}





function limitDecimals (number, decimals) {
	var multiplier = Math.pow(10, decimals);
	return Math.round(number * multiplier)/multiplier;
}

function init () {

	equation.addSlider("stars", 0,      10, 1, 5, false, false);
	equation.addSlider("pws",   0,     100, 1, 4, true,  false);
	equation.addSlider("lsp",   0,      10, 1, 5, false, false);
	equation.addSlider("lhp",   0,     100, 1, 4, true,  false);
	equation.addSlider("ilp",   0,     100, 1, 4, true,  false);
	equation.addSlider("isc",   0,     100, 1, 4, true,  false);
	equation.addSlider("isd",   1, 1000000, 0, 6, false, 10);	

	equation.sliders[0].drawInside("sl1");
	equation.sliders[1].drawInside("sl2");
	equation.sliders[2].drawInside("sl3");
	equation.sliders[3].drawInside("sl4");
	equation.sliders[4].drawInside("sl5");
	equation.sliders[5].drawInside("sl6");
	equation.sliders[6].drawInside("sl7");

	equation.addPresets(new EquationPresets('General', "Minimum Values", 0,0,0,0,0,0,1));
	equation.addPresets(new EquationPresets('General', "Maximum Values", 10,100,10,100,100,100,1000000));
	//equation.addPresets(new EquationPresets("Carl Sagan's Estimates", 12,25,2,50,10,10,40000000)); //he used a different version of the equation that doesn't transfer... gah!
	//equation.addPresets(new EquationPresets("Carl Sagan's Estimates", 12,25,2,50,10,10,40));
	equation.addPresets(new EquationPresets('Frank Drake',"Frank Drake's 1961 Estimates", 10,50,2,100,1,1,10000));
	equation.addPresets(new EquationPresets('Frank Drake',"Frank Drake's 2004 Estimates", 5,50,2,100,20,100,10000));
	equation.addPresets(new EquationPresets('Other', "Author's Estimates", 6,62.5,0.5,89.5,1,50,5000));
	equation.addPresets(new EquationPresets('Other', "Conservative Estimates", 7,30,2,33,1,1,10000));
	equation.addPresets(new EquationPresets('Other', "\"Rare Earth\" Estimates", 6,50,0.000001,33,1,1,10000));

	equation.loadPresets(equation.presets[5]);
	
	if (document.addEventListener) {
		document.addEventListener('mouseup', function () { equation.stopAllSliders(); }, false);
		document.addEventListener('mousemove', updateMousePos, false);
	}
	else if (document.attachEvent) {
		document.documentElement.attachEvent('onmouseup', function () { equation.stopAllSliders(); });
		document.documentElement.attachEvent('onmousemove', updateMousePos);
	}	
}





