function checkNumeric(value){
	var anum=/^[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$/
   if (anum.test(value)) {
   	return true;
   } else {
     return false;
   }
}

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;
}

var STTGraph = {
  init : function(dataTable){
	STTGraph.width = 530;
	STTGraph.height = 300;
	STTGraph.roicolour = "#0054a4";
	STTGraph.netcolour = "#9be";
	
	$("#graph").empty();
	
	STTGraph.graph = Raphael("graph", STTGraph.width, STTGraph.height+20);
	STTGraph.scalefactor = 100000; // Approximate Max Dollar Amount
	STTGraph.labelunit = 10000; // Dollar amount per label line

	for(var label = STTGraph.scalefactor; label > 0; label -= STTGraph.labelunit) {
		var c = "#ccc";
		var labely = Math.floor(STTGraph.height*label/STTGraph.scalefactor);
		STTGraph.graph.path({stroke: c}).moveTo(0, labely).lineTo(STTGraph.width,labely);
		if(label%(STTGraph.labelunit*2)>0) {
			STTGraph.graph.text(40, labely-12, "$"+(STTGraph.scalefactor-label)).attr({"fill":"#ddd","font-size":"14px"});
		}
	}
	
	STTGraph.roipoints = new Array();
	STTGraph.dataTable = dataTable;	 
    STTGraph.startPath();
    STTGraph.updateGraph();
	
  },
  startPath : function() {
  	if(STTGraph.roi) { STTGraph.roi.remove(); }
  	if(STTGraph.net) { STTGraph.net.remove(); }
	
	for(point in STTGraph.roipoints) {
		STTGraph.roipoints[point].remove();
	}
  
  	var init_roi = Math.floor(this.dataTable['roi'][0] * STTGraph.height);
 	var init_net = Math.floor(this.dataTable['net'][0] * STTGraph.height);

	STTGraph.showLegend();

    STTGraph.roi = STTGraph.graph.path({
        stroke: STTGraph.roicolour,
        "stroke-width": 5, 
        "fill-opacity": 0
    }).moveTo(20, STTGraph.height-init_roi);
	
	STTGraph.net = STTGraph.graph.path({
        stroke: STTGraph.netcolour,
        "stroke-width": 3, 
        "fill-opacity": 0		
	}).moveTo(20, STTGraph.height-init_net);
  },
  showLegend : function() {
	STTGraph.graph.rect(80,2,190,160,15).attr({"fill":"#fff","stroke":"#ddd","stroke-width":"2px"});
	
	STTGraph.graph.path({ // Thick line in legend
        stroke: STTGraph.roicolour,
        "stroke-width": 5, 
        "fill-opacity": 0
    }).moveTo(100, 82).lineTo(135, 82); 
    
    STTGraph.graph.circle(130,82,7).attr({"stroke": STTGraph.roicolour, "stroke-width": 4, "fill": "#fff"});
    
    STTGraph.graph.path({ // Thin line in legend
        stroke: STTGraph.netcolour,
        "stroke-width": 3, 
        "fill-opacity": 0
    }).moveTo(100, 37).lineTo(135, 37);
    
    STTGraph.graph.text(199, 34, "Savings without\nInterest").attr({"fill":"#555","font-size":"14px"});
    STTGraph.graph.text(199, 79, "Savings with\nInterest").attr({"fill":"#555","font-size":"14px"});
    
    STTGraph.graph.text(175, 125, "Hover over circles to see\nsavings at points in time").attr({"fill":"#555","font-size":"14px"});
  },
  updateGraph : function() { // Writes the stuff.
    while(STTGraph.updates++ < 20) {    
	  var yearstep = 20+Math.floor(STTGraph.updates*((STTGraph.width-40)/20));
	  
      var roi = STTGraph.height - Math.floor(this.dataTable['roi'][STTGraph.updates*12] * STTGraph.height / STTGraph.scalefactor);
      STTGraph.roi.lineTo(yearstep, roi);    
	  
	  if(STTGraph.updates%2 <=0) {
	  	var point = STTGraph.graph.circle(yearstep,roi,7);
		point.attr({"stroke": STTGraph.roicolour, "stroke-width": 4, "fill": "#fff"});
		
		var makepoint = function(point, x, y, year, amount, STTGraph) {
			var allthings = new Array();
		
			var magnetx = 0;
			var magnety = 0;
			
			var bubblex = Math.floor((magnetx*2+x)/3);
			var bubbley = Math.floor((magnety*3+y)/4);
			
			var width = 180;
			var height = 115;
			
			var bubble_cx = bubblex + width/2;
			var bubble_cy = bubbley + height/2;
			
			var aPointx = Math.floor((x*9 + bubble_cx)/10);
			var aPointy = Math.floor((y*9 + bubble_cy)/10);
			
			var aStartx = bubble_cx - 20;
			var aStarty = bubble_cy + 20;
			
			var aEndx = bubble_cx + 20;
			var aEndy = bubble_cy - 20;
			
			var arrow = STTGraph.graph.path({
				stroke: "#ddd",
				"stroke-width": 0, 
				"fill": "#ddd"		
			}).moveTo(aStartx, aStarty).lineTo(aPointx, aPointy).lineTo(aEndx, aEndy).andClose();
			
			allthings.push(arrow);
			
			var rect = STTGraph.graph.rect(bubblex,bubbley,width,height,20);
			rect.attr({"stroke-width":8,"stroke":"#05a","fill":"#fff"});
			
			allthings.push(rect);
			
			var text_x = bubblex+3;
			text_x = text_x+"px";
			
			var text_y = bubbley+15;
			text_y = text_y+"px";
			
			amount = Math.round(amount*100)/100;

			var monthly_investment = $("span.monthly").text();
			var annualrate = $("span.annualrate").text();
			
			var text2 = $("<div class=\"bubble\"><p>After <span class=\"year\">"+year+"</span> years, you'll have <br/><span class=\"roi\">$"+addCommas(amount)+"</span><br/> dollars saved.</p></div>").appendTo("#graph");
			
			
			
			text2.css({"position":"absolute","top":text_y,"left":text_x,"width":(width-8)+"px"});
			
			allthings.push(text2);
			
			for(x in allthings) {
				allthings[x].hide();
			}

			$(point.node).hover(function() {
				point.animate({"stroke-width": 7}, 100);
				for(x in allthings) {
					allthings[x].show();
				}
			},function() {
				point.animate({"stroke-width": 4}, 100);
				for(x in allthings) {
					allthings[x].hide();
				}
			});
		}
		
		makepoint(point, yearstep, roi, STTGraph.updates, this.dataTable['roi'][STTGraph.updates*12], STTGraph);
		
		STTGraph.roipoints[STTGraph.updates] = point
		
	  }
	  
	  var net = STTGraph.height - Math.floor(this.dataTable['net'][STTGraph.updates*12] * STTGraph.height / STTGraph.scalefactor);
      STTGraph.net.lineTo(yearstep, net);  
    }

  },
  updates : 0
}

function runCalculations() {
	var monthly_investment = $("span.monthly").text();
	var annualrate = $("span.annualrate").text();
	
	if(!checkNumeric(monthly_investment) || !checkNumeric(annualrate)) {
		return false;
	}
	
	var time = 0;
	var roi=new Array();
	var net=new Array();

	monthly_investment = parseFloat(monthly_investment);
	annualrate = parseFloat(annualrate);
	var monthrate = Math.pow((1+annualrate/100),(1/12));
	var roi_now = 0;
	var net_now = 0;
	roi.push(0);
	net.push(0);
	
	while(time++ <= 240) {
		net_now += monthly_investment;
		roi_now = roi_now*monthrate + monthly_investment;
		roi.push(roi_now);
		net.push(net_now);
	}

	var result = new Array();
	result['roi'] = roi;
	result['net'] = net;
	
	$("#final_roi").text("$"+addCommas(Math.round(roi[240])));
	$("#final_interest").text("$"+addCommas(Math.round(roi[240]-net[240])));
	
	
	return result;
}

function changeValue(spanobj, miniform) {
	var newvalue = $(miniform).find("#miniform").attr("value");
	
	if(checkNumeric(newvalue) && $(spanobj).text()!=newvalue) {
		$(spanobj).text(newvalue);
		refreshGraph();			
	}
	
	$(spanobj).show();
	$(miniform).remove();
}

function editInPlace(spanobj) {

	var value = $(spanobj).text();
	var miniform = jQuery('<span id="bounds"><input id="miniform" type="text" value="'+value+'" maxlength="7"><span id="submit">&#10004;</span><span id="cancel">&#10008;</span></span>');
	miniform.mouseInside = true;
	
	$(miniform).mouseover(function() {
		miniform.mouseInside = true;
	}).mouseout(function() {
		miniform.mouseInside = false;
	});
	
	var form = $(spanobj).after(miniform);
	
	$(miniform).find("#miniform").focus().blur(function() {
		if(!miniform.mouseInside) {
			changeValue(spanobj, miniform);
		}
	}).keypress(function (e) {
		var code = (e.keyCode ? e.keyCode : e.which);
		
		if (code == 13) {
			changeValue(spanobj, miniform);
		} else {
			if (code == 27) {
				$(miniform).remove();
				$(spanobj).show();
			}
		}
	});	
	
	$(miniform).find("#submit").click(function() {
		changeValue(spanobj, miniform);
	});
	
	$(miniform).find("#cancel").bind("click", function(e) {
		$(miniform).remove();
		$(spanobj).show();
	});

	$(spanobj).hide();
}

function refreshGraph() {	
	var newData = runCalculations();
	if(newData) {
		STTGraph.updates = 0;
		STTGraph.breakup = false;
		STTGraph.dataTable = newData;
		STTGraph.startPath();
		STTGraph.updateGraph();
	}
}

// Load jQuery
google.load("jquery", "1.3");
google.setOnLoadCallback(function() {	
	var dataTable = runCalculations();
	STTGraph.init(dataTable);
	
	$("span.variable").click(function(){
		editInPlace(this);
	}).hover(function() {
		$(this).css({"border-color":"#99f #99f #ff4 #99f"});
	}, function() {
		$(this).css({"border-color":"#ddd #ddd #ff4 #ddd"});
	});
});
