
var StartingCostEstimator = Class.create({
	initialize: function(elContainer, options) {
		this.container = $(elContainer);		
		this.options = {
			width : 400			
		}
		Object.extend(this.options, options || { });
		
		this.mainRow = new CalcLine({
			title: 'Total Start-up Requirements',
			type: 'static',
			useCurrency: true			
		});				
		// First row
		var line = new CalcLine({
			title: "Initial expenses",
			description: "Legal costs, stationery, sales literature, etc.",
			type: "static",
			useCurrency: true
		});
		line.addSubline({ title: "Legal", value: 300 });
		line.addSubline({ title: "Office Supplies", value: 200 });
		line.addSubline({ title: "Office Equipment", value: 800 });
		line.addSubline({ title: "Design", value: 50 });
		line.addSubline({ title: "Brochures", value: 200 });
		line.addSubline({ title: "Website", value: 300 });
		line.addSubline({ title: "Other", value: 650 });		
		this.mainRow.addSubline(line);				
		
		// Second row
		line = new CalcLine({ title: "Money in the bank as reserve for losses", type: "static", useCurrency: true });
		line.addSubline({ title: "Estimate monthly payroll during your start-up period", value: 2000 });
		line.addSubline({ title: "Estimate your monthly rent during the start-up period", value: 500 });
		line.addSubline({ title: "Estimate other regular monthly expenses you need to allow for during start-up", value: 250 });
		line.addSubline({ title: "Total monthly running spending during start-up", operation: 'sum_all', type: 'static', useCurrency: true });
		line.addSubline({ 
			title: "How many months of spending do want to keep in reserve",
			value: 6,
			type: 'slider',
			sliderOptions: { range: $R(0,12), step: 1, incriment: 1, values:[0,1,2,3,4,5,6,7,8,9,10,11,12]},
			useCurrency: false,
			operation: 'mul'
		});
		this.mainRow.addSubline(line);
		
		// Third row
		this.mainRow.addSubline(new CalcLine({ title: "Start-up Inventory", description: "If required", value: 300 }));
		// Forth row 
		this.mainRow.addSubline(new CalcLine({ 
			title: "Other current assets", 
			description: "leasehold improvements, fixtures, signage, etc.",
			value: 700
		}));
		// Fifth row
		this.mainRow.addSubline(new CalcLine({ 
			title: "Long term or fixed assets",
			description: "land, plant, equipment, etc.",
			value: 0
		}));
		
		//draw
		this._render();
	},
	_render: function() {
		if (!this.mainRow.sub.length) return;
		var tbody = new Element('tbody');
		this.container.update(new Element('table',{'cellpadding': '0', 'cellspacing': '0', 'class': 'app-calc-container'}).insert(tbody));
		this.mainRow.sub.each(function (line) {
			var tr = new Element('tr');
			var td = new Element('td', {'valing' : 'top'});
			var h = new Element('div').update(line.title + ":");
			
			var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
			td.insert(h); td.insert(d); tr.insert(td);

			td = new Element('td', {'valing' : 'top'});
			var el = line.genHtml();
			if (line.sub.length) {
				line.element.addClassName('app-complex');
				line.element.observe('click', function(ev) { 
					this.popup();
				}.bind(line));
			}
			td.insert(el);
			tr.insert(td);
			tbody.insert(tr);
			if (line.type == 'slider') line.initSlider();
		}.bind(this));
		var td = new Element('td', {'colspan' : '2'});		
		tbody.insert(new Element('tr').insert(td));		
		td.update(new Element('hr').setStyle({'width' : '90%'}));
		
		td = new Element('td');
		tbody.insert(new Element('tr').insert(new Element('td')).insert(td));		
		td.update(this.mainRow.genHtml());
	}
});

// ######################################
var ConversionRate = new Class.create({
	initialize: function(elContainer, options) {
		this.container = $(elContainer);		
		this.options = {
			width : 400			
		}
		Object.extend(this.options, options || { });
		//hidden
		this.mainRow = new CalcLine({ title: 'Total', type: 'static' });
		//part I
		// 0
		this.mainRow.addSubline({ 
			title: "Website Visitors",
			description: "over a certain time period",
			value: 1000			
		});
		// 1
		this.mainRow.addSubline({ 
			title: "Average Order Amount",
			value: 50,
			fixed_s: 2
		});
		// 2
		this.mainRow.addSubline({ 
			title: "Total Orders",
			value: 20
		});
		//part II
		// 3
		this.mainRow.addSubline({
			title: "Current Conversion Rate",
			type: 'static',
			fixed_s: 2,
			end_with: '%',
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[2].value / this.src.sub[0].value)*100;
			}
		});
		// 4
		this.mainRow.addSubline({
			title: "Current Total Sales",
			type: 'static',
			useCurrency: true,
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[2].value * this.src.sub[1].value);
			}			
		});
		// 5
		this.mainRow.addSubline({
			title: "Current Sales per Visitor",
			type: 'static',
			useCurrency: true,
			fixed_s: 2,
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[2].value * this.src.sub[1].value)/this.src.sub[0].value;
			}			
		});
		//part III
		// 6
		var v = [];
		for (i = 0; i<= 250; i++) v.push(i/10);		
		this.mainRow.addSubline({
			title: "New Conversion Rate",
			type: 'slider',
			fixed_s: 1,
			sliderOptions: { range: $R(0,25), step: 0.1, incriment: 0.1, values: v},
			end_with: '%'			
		});
		// 7
		this.mainRow.addSubline({
			title: "New Total Orders",
			type: 'static',
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[0].value * this.src.sub[6].value)/100;
			}					
		});
		// 8
		this.mainRow.addSubline({
			title: "New Total Sales",
			type: 'static',
			useCurrency: true,
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[7].value * this.src.sub[1].value);
			}			
		});
		// 9
		this.mainRow.addSubline({
			title: "New Sales per Visitor",
			type: 'static',
			useCurrency: true,
			fixed_s: 2,
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[8].value / this.src.sub[0].value);
			}			

		});
		
		this._render();
	},
	_render: function () {
		if (!this.mainRow.sub.length) return;
		var w_tbody = new Element('tbody');
		this.container.update(new Element('table',{'cellpadding': '0', 'cellspacing': '0', 'class': 'app-calc-container'}).insert(w_tbody));
		//part 1 // empty
		//part 2 // part 3
		var w_tr = new Element('tr');
		var w_td = new Element('td');
		w_tr.insert(w_td);
		w_tr.insert(new Element('td').update('&nbsp;'));
		w_tbody.insert(w_tr);
		
		var i;
		// first 3 elements
		var tbody = new Element('tbody');
		w_td.insert(new Element('table',{'cellpadding': '0', 'cellspacing': '0'}).insert(tbody));		
		for (i = 0; i < 3; i++) {
			var line = this.mainRow.sub[i];
			var tr = new Element('tr');
			var td = new Element('td', {'valign' : 'top'});
			var h = new Element('div').update(line.title + ":");			
			var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
			td.insert(h); td.insert(d); tr.insert(td);
			td = new Element('td', {'valing' : 'top'});
			var el = line.genHtml();
			td.insert(el);
			tr.insert(td);			
			tr.insert(new Element('td', {'colspan' : '3'}).update('&nbsp;'));
			tbody.insert(tr);
			if (line.type == 'slider') line.initSlider();			
		}
		
		w_tr = new Element('tr');
		w_td = new Element('td');
		w_tr.insert(w_td);	
		w_tbody.insert(w_tr);

		tbody = new Element('tbody');
		w_td.insert(new Element('table',{'cellpadding': '0', 'cellspacing': '0'}).insert(tbody));		
		for (i = 3; i < 6; i++) {
			var line = this.mainRow.sub[i];
			var tr = new Element('tr');
			var td = new Element('td', {'valign' : 'top'});
			var h = new Element('div').update(line.title + ":");			
			var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
			td.insert(h); td.insert(d); tr.insert(td);
			td = new Element('td', {'valing' : 'top'});
			var el = line.genHtml();
			td.insert(el);
			tr.insert(td);			
			tr.insert(new Element('td', {'colspan' : '3'}).update('&nbsp;'));
			tbody.insert(tr);
			if (line.type == 'slider') line.initSlider();
		}
		
		w_td = new Element('td');
		w_tr.insert(w_td);	
		tbody = new Element('tbody');
		w_td.insert(new Element('table',{'cellpadding': '0', 'cellspacing': '0'}).insert(tbody));		
		for (i = 6; i < this.mainRow.sub.length; i++) {
			var line = this.mainRow.sub[i];
			var tr = new Element('tr');
			var td = new Element('td', {'valign' : 'top'});
			var h = new Element('div').update(line.title + ":");			
			var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
			td.insert(h); td.insert(d); tr.insert(td);
			td = new Element('td', {'valing' : 'top'});
			var el = line.genHtml();
			td.insert(el);
			tr.insert(td);			
			tr.insert(new Element('td', {'colspan' : '3'}).update('&nbsp;'));
			tbody.insert(tr);
			if (line.type == 'slider') line.initSlider();
		}
	}
});
// ######################################
var PpcRoiCalc = new Class.create({
	initialize: function(elContainer, options) {
		this.container = $(elContainer);		
		this.options = {
			width : 400			
		}
		Object.extend(this.options, options || { });
		//hidden
		this.mainRow = new CalcLine({ title: 'Total', type: 'static' });
		// part I
		// 0
		this.mainRow.addSubline({ 
			title: "Clicks Purchased",
			value: 5000
		});
		// 1
		this.mainRow.addSubline({ 
			title: "Cost-per-click",
			value: 1.2,
			fixed_s: 2
		});
		// 2
		var v = [];
		for (i = 0; i<= 1000; i++) v.push(i/10);		
		this.mainRow.addSubline({
			title: "Conversion Rate",
			description: "What % of responders will buy?",
			type: 'slider',
			fixed_s: 1,
			value: 2,
			sliderOptions: { range: $R(0,100), step: 0.1, incriment: 0.1, values: v},
			end_with: '%'			
		});		
		// 3
		this.mainRow.addSubline({ 
			title: "Average Buyer Purchase",
			description: "How much will buyers spend?",
			value: 100
		});
		// Part II
		// 4
		this.mainRow.addSubline({
			title: "Total Compaign Cost",
			type: 'static',
			useCurrency: true,
			fixed_s: 2,
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[0].value * this.src.sub[1].value);
			}			
		});
		// 5
		this.mainRow.addSubline({
			title: "# of Responders",
			type: 'static',			
			operation: 'custom',
			customCalc: function () {
				return this.src.sub[0].value;
			}			
		});
		// 6
		this.mainRow.addSubline({
			title: "# of Buyers",
			type: 'static',				
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[0].value * this.src.sub[2].value)/100;
			}			
		});
		// 7
		this.mainRow.addSubline({
			title: "Revenue Generated",
			type: 'static',
			useCurrency: true,
			fixed_s: 2,
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[0].value * this.src.sub[3].value * this.src.sub[2].value)/100;
			}			
		});
		// 8
		this.mainRow.addSubline({
			title: "Profit",
			type: 'static',
			useCurrency: true,
			fixed_s: 2,
			operation: 'custom',
			customCalc: function () {
				var ret = (this.src.sub[0].value * this.src.sub[3].value * this.src.sub[2].value)/100;
				ret -= (this.src.sub[0].value * this.src.sub[1].value);
				return ret;
			}			
		});
		// 9
		this.mainRow.addSubline({
			title: "Cost per Responder",
			type: 'static',				
			operation: 'custom',
			useCurrency: true,
			fixed_s: 2,
			customCalc: function () {
				return this.src.sub[1].value;
			}			
		});
		// 10
		this.mainRow.addSubline({
			title: "Cost per Buyer",
			type: 'static',
			useCurrency: true,
			fixed_s: 2,	
			operation: 'custom',
			customCalc: function () {
				return (this.src.sub[1].value * 100)/this.src.sub[2].value;
			}			
		});
		
		this._render();
	},
	_render: function () {
		if (!this.mainRow.sub.length) return;
		var w_tbody = new Element('tbody');
		this.container.update(new Element('table',{'cellpadding': '0', 'cellspacing': '0', 'class': 'app-calc-container'}).insert(w_tbody));
		var w_tr, w_td;
		
		w_tr = new Element('tr');
		w_td = new Element('td', {'valign' : 'top', 'colspan' : '5'});
		w_tr.insert(w_td);w_tbody.insert(w_tr);
		tbody = new Element('tbody');
		w_td.insert(new Element('table',{'cellpadding': '0', 'cellspacing': '0'}).insert(tbody));		
		for (i = 4; i < this.mainRow.sub.length; i++) {
			var line = this.mainRow.sub[i];
			var tr = new Element('tr');
			var td = new Element('td', {'valign' : 'top'});
			var h = new Element('div').update(line.title + ":");			
			var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
			td.insert(h); td.insert(d); tr.insert(td);
			td = new Element('td', {'valing' : 'top'});
			var el = line.genHtml();
			td.insert(el);
			tr.insert(td);			
			tr.insert(new Element('td', {'colspan' : '3'}).update('&nbsp;'));
			tbody.insert(tr);
			if (line.type == 'slider') line.initSlider();
		}
			
		
		w_tr = new Element('tr');
		w_td = new Element('td', {'valign' : 'top'});		
		var line = this.mainRow.sub[0];
		var h = new Element('div').update(line.title + ":");
		var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
		w_td.insert(h); w_td.insert(d); w_tr.insert(w_td);
		w_td = new Element('td', {'valing' : 'top'});
		var el = line.genHtml();
		w_td.insert(el); w_tr.insert(w_td);		
		w_tr.insert(new Element('td', {'width' : '20'}).update('&nbsp;'));		
		//slider
		w_td = new Element('td', {'valign' : 'top'});		
		line = this.mainRow.sub[2];
		h = new Element('div').update(line.title + ":");
		d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
		w_td.insert(h); w_td.insert(d); w_tr.insert(w_td);
		w_td = new Element('td', {'valing' : 'top'});
		var el = line.genHtml();
		w_td.insert(el); w_tr.insert(w_td);		
		w_tbody.insert(w_tr);
		line.initSlider();		
		
		w_tr = new Element('tr');
		w_td = new Element('td', {'valign' : 'top'});		
		line = this.mainRow.sub[1];
		h = new Element('div').update(line.title + ":");
		d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
		w_td.insert(h); w_td.insert(d); w_tr.insert(w_td);
		w_td = new Element('td', {'valing' : 'top'});
		var el = line.genHtml();
		w_td.insert(el); w_tr.insert(w_td);
		w_tr.insert(new Element('td', {'width' : '20'}).update('&nbsp;'));		
		w_td = new Element('td', {'valign' : 'top'});		
		line = this.mainRow.sub[3];
		h = new Element('div').update(line.title + ":");
		d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
		w_td.insert(h); w_td.insert(d); w_tr.insert(w_td);
		w_td = new Element('td', {'valing' : 'top'});
		var el = line.genHtml();
		w_td.insert(el); w_tr.insert(w_td);		
		w_tbody.insert(w_tr);
	}
});
// ######################################
var CalcLine = Class.create({
	initialize: function (obj) {
		
		this.title = obj.title || "New Line";
		this.description = obj.description || "";
		this.type = obj.type || 'text'; // static - text, text - input type text, slider - script aculo slider
		if (Prototype.Browser.IE && this.type == 'slider') { this.type = "text"; this._c_type = 'slider'; }
		
		this.useCurrency = !obj.useCurrency ? false : true; 
		this.currency = obj.currency || "$";
		var value = obj.value || 0;
		this.operation = obj.operation || 'add'; // can be 'add' or 'mul', 'sum_all'
		this.customCalc = ( (this.operation=='custom') && obj.customCalc) || Prototype.emptyFunction;		
		
		this.end_with = obj.end_with || '';
		this.fixed_s = parseInt(obj.fixed_s || '0');
		
		this.sub = []; // sublines
		
		this.setValue(value);
		this.element = null;
		this._popup = null;
		this._slider = null;
		this._sliderOptions = obj.sliderOptions || {};
		
	},
	addSubline: function(obj, pos) {		
		if (typeof obj.initialize != 'function') obj = new CalcLine(obj);
		obj.src = this;
		this.sub.push(obj);		
		if (pos === 0 || pos) {
			var tmp = this.sub[pos];
			this.sub[pos] = this.sub.last();
			this.sub[this.sub.length - 1] = tmp;
		}
		this.recalculate();
	},
	recalculate: function() {
		 // sum all lines with operation 'add'
		var arr1 = this.sub.findAll(function(line) { 
			return line.operation == 'add';  
		});
		var newValue = arr1.inject(0, function(tot, line) {
			return tot + parseFloat(line.value);
		});

		var arr2 = this.sub.findAll(function(line){ 
			return line.operation == 'sum_all'; 
		});
		arr2.each(function(line) {
			if (newValue != line.value) line.setValue(newValue, false);
		});
		var arr3 = this.sub.findAll(function(line) {
			return line.operation == 'custom';
		});
		arr3.each(function(line) {
			line.setValue(line.customCalc(), false);
		});
		if ((arr2.length || arr3.length) && this.src) this.src.recalculate();

		newValue = this.sub.findAll(function(line){
			return line.operation == 'mul';
		}).inject(newValue, function(tot,line){			
			return newValue * parseFloat(line.value);
		});
		if (newValue != this.value) this.setValue(newValue);
		if(this.element) this.updateHtml();			
	},
	setValue: function (nv, tt_inv) {		
		if (nv == this.value) return;
		if (typeof tt_inv == 'undefined') tt_inv = true;
		nv = parseFloat(nv);
		nv = nv.toFixed(this.fixed_s);
		this.value = nv;		
		if(this.element) this.updateHtml();
		if (this.src && tt_inv) this.src.recalculate();				
	},
	initSlider: function () {		
		if (this.type != 'slider') return;
		if (!this._slider) {			
			$(this.element.childNodes[0]).identify();
			this.element.identify();
			var handles = [$(this.element.childNodes[0])]		
			
			this._slider = new Control.Slider(handles, this.element.identify(), this._sliderOptions);
			var div = new Element('div');
			this.element.insert({'after': div});
			div.setStyle({'width': '100%', textAlign: 'center', paddingTop: '4px'}).update('&nbsp;')
			this._slider.options.onChange = function (value) {
				this.setValue(value);
				this.element.next(0).update((this.useCurrency ? this.currency : "") + this.value + this.end_with);				
			}.bind(this);
			this._slider.setValue(this.value);
		}		
	},
	genHtml: function () {
		switch (this.type) {
			case 'static' : 				 
				this.element = new Element('div');				
				break;
			case 'text':
				this.element = new Element('input');
				this.element.observe('change', function(ev) {
					this.setValue(ev.element().value);
				}.bind(this));
				break;
			case 'slider':
				this.element = new Element('div');
				this.element.setStyle({
					'width': '200px',					
					'height': '5px',
					backgroundColor : '#adc8ef'
				});
				var handl = new Element('div').setStyle({
					'width': '15px',					
					'height': '25px'
				}).update(new Element('img',{'src': 'res/img/arr.gif'}));
				this.element.insert(handl);										
				break;			
		}
		this.updateHtml();
		return this.element;
	},
	updateHtml: function() {
		switch (this.type) {
			case 'static':
				this.element.update((this.useCurrency ? this.currency : "") + this.value + this.end_with);
				break;
			case 'text':
				this.element.value = this.value;
				break;
			case 'slider':				
				break;
		}
	},
	popup: function () {
		if (!this._popup) {
			var container = this.element.up('table').up(0);
			var tbody = new Element('tbody');
			this._popup = new Element('table', {'cellpadding': '0', 'cellspacing': '0', 'class': 'app-calc-container'}).insert(tbody);
			this._popup.hide();
			container.insert(this._popup);
			
			this.sub.each(function (line) {
				var tr = new Element('tr');
				var td = new Element('td', {'valing' : 'top'});
				var h = new Element('div').update(line.title + ":");
				var d = new Element('div').update( line.description ? '(' + line.description + ')' : "");
				td.insert(h); td.insert(d); tr.insert(td);
				
				td = new Element('td', {'valing' : 'top'});
				var el = line.genHtml();
				td.insert(el);
				tr.insert(td);
				tbody.insert(tr);
				if (line.type == 'slider') line.initSlider();
			});			
		}		
		if(this._popup.visible()) {			
			if (typeof Effect == 'undefined') this._popup.hide();
			else this._popup.fade({duration: 1});
		} else {			
			this.src.sub.each(function(line){ if (line._popup && line._popup.visible()) line._popup.hide(); });
			if (typeof Effect == 'undefined') this._popup.show();
			else this._popup.appear({duration: 1});
		}
	}
})
