// steadyhand.com fee calculator
// Neil Jensen, May 2008
// TODO: way, way too much hardcoding... use more loops

/////////////////////////// Fee Calculator ///////////////////////////////////

FeeCalculator = function () {
    bindMethods(this);
};

FeeCalculator.prototype.initialize = function () {

  default_assets = 0;
  
  // check the querystring for asset sizes or use defaults
  var args = parseQueryString(window.location.search);
  if( isEmpty(keys(args))){
  	default_assets = 30000;
  };
  
  if (isUndefinedOrNull(args.savings)) { 
  	var savings_starting_assets = default_assets;
  } else {
  	var savings_starting_assets = args.savings
  };
    if (isUndefinedOrNull(args.income)) { 
  	var income_starting_assets = default_assets;
  } else {
  	var income_starting_assets = args.income
  };
    if (isUndefinedOrNull(args.equity)) { 
  	var equity_starting_assets = default_assets;
  } else {
  	var equity_starting_assets = args.equity
  };
    if (isUndefinedOrNull(args.global)) { 
  	var global_starting_assets = default_assets;
  } else {
  	var global_starting_assets = args.global
  };
   if (isUndefinedOrNull(args.smallcap)) { 
  	var smallcap_starting_assets = default_assets;
  } else {
  	var smallcap_starting_assets = args.smallcap
  };
  

	// initialize or reset the data
	var no_year_discount = "0";
	var five_year_discount = "7"; //in percent
	var ten_year_discount = "14";	
	
	// draw the select box... do this so we can easily reset
	var newSelect = SELECT({"name":"select_years", "id":"select_years"}, OPTION({"value":no_year_discount, "selected":"selected"},"less than 5"), OPTION({"value":five_year_discount},"between 5 and 10"), OPTION({"value":ten_year_discount},"10 or more")); 
	swapDOM( $('select_years'), newSelect );
	connect($('select_years'),'onchange', this.updateTotal);	


	// fees
	this.funds = new Array();
	this.funds['savings'] = { 'simple':0.65 , 'category':1.01, 'amount': savings_starting_assets};
	this.funds['income'] = { 'simple':1.00 , 'category':2.09, 'amount': income_starting_assets};
	this.funds['equity'] = { 'simple':1.35 , 'category':2.67, 'amount': equity_starting_assets};
	this.funds['global'] = { 'simple':1.70 , 'category':2.74, 'amount': global_starting_assets};
	this.funds['smallcap'] = { 'simple':1.70 , 'category':2.59, 'amount': smallcap_starting_assets};
	
	//populate table with data
	for( var fund in this.funds ) {
		$(fund + '_fee').innerHTML = this.funds[fund].simple.toFixed(2);
		$(fund + '_fee_rebate').innerHTML = this.funds[fund].simple.toFixed(2);
		$(fund + '_cat_fee').innerHTML = this.funds[fund].category.toFixed(2);
		$(fund).value = this.funds[fund].amount;
		
		//connect events for data entry
		connect(fund,"onkeyup", this.updateTotal);
	}

    // initialize rebate levels
    // first $100k @ 100%, next $150k at 80%, next $200k at 70%, rest at %60%
    this.rebates = new Array();
    this.rebates[0] = new Array( 100000, 100 );
    this.rebates[1] = new Array( 150000, 80 );
    this.rebates[2] = new Array( 250000, 70 );
    this.rebates[3] = new Array( 0, 60 );    
        
    
    // initialize chart
	// custom styles 
    var steadyHexColor = MochiKit.Color.Color.fromHexString("#7daecb");
	var steadyStyle = {
	    "axisLineWidth": 1.0,
    	"axisLabelColor": Color.grayColor(),
    	"axisLineColor": Color.fromHexString('#cccccc'),
		"axisLabelFontSize": 11,
		"axisLabelWidth": 60,
    	"padding": {top: 5, bottom: 10, left: 20, right: 0},
	    "colorScheme": PlotKit.Base.palette(steadyHexColor),
        "backgroundColor": PlotKit.Base.baseColors()[0].lighterColorWithLevel(1),
		"drawYAxis": true
	};
	
	this.layout = new PlotKit.Layout("bar", {"xTicks": [{v:0, label:"Category Average"}, {v:1, label:"Steadyhand"}]});
  	this.plotter = new PlotKit.SweetCanvasRenderer($('graph'), this.layout, steadyStyle);

	this.updateTotal();
};

// format numbers
FeeCalculator.prototype.dollarFormatter = numberFormatter("-###,###");

FeeCalculator.prototype.updateTotal = function() {
     
  	//populate fund object with data
	var total = 0;
	for( var fund in this.funds ) {
		var i = 0;
		if (!isNaN(parseInt($(fund).value,10) )) i = parseInt($(fund).value,10);
		this.funds[fund].amount = i;
		total = total + i;
	}
 	 		
	// determine the weighted fee with the rebates
	var weighted_fee = 100;
	var incremental_assets = total; // the incremental amount to apply the fee to
	
	// TODO: clean this up and turn into a loop
	if (incremental_assets > this.rebates[0][0]) {
		weighted_fee = this.rebates[0][1] * (this.rebates[0][0]/total);	
	} else {
		weighted_fee = this.rebates[0][1] * (incremental_assets/total);
		incremental_assets = 0;
	}

	incremental_assets = incremental_assets - this.rebates[0][0];
	if (incremental_assets > this.rebates[1][0]) {
		weighted_fee = weighted_fee + this.rebates[1][1] * (this.rebates[1][0]/total); 
	} else if (incremental_assets > 0) {
		weighted_fee = weighted_fee + this.rebates[1][1] * (incremental_assets/total);
		incremental_assets = 0;
	}
	
	incremental_assets = incremental_assets - this.rebates[1][0];
	if (incremental_assets > this.rebates[2][0]) {
		weighted_fee = weighted_fee + this.rebates[2][1] * (this.rebates[2][0]/total); 
	} else if (incremental_assets > 0) {
		weighted_fee = weighted_fee + this.rebates[2][1] * (incremental_assets/total);
		incremental_assets = 0;
	}

	incremental_assets = incremental_assets - this.rebates[2][0];
	if (incremental_assets > 0) {
		weighted_fee = weighted_fee + this.rebates[3][1] * (incremental_assets/total);
		incremental_assets = 0;
	}

	// apply the tenure rebates
	weighted_fee = weighted_fee * (1 - parseInt($('select_years').value)/100);

	// calculate the weighted averages and totals
	var simple_total = 0;
	var rebate_total = 0;
	var average_total = 0;
	var total_dollars_saved = 0;
	for( var fund in this.funds ) {
		var weighting = this.funds[fund].amount/total;
	
		// simple fees
		simple_total = simple_total + this.funds[fund].simple * weighting;
	
		// rebates
		var rebate_fee = (this.funds[fund].simple * weighted_fee/100 );
		$(fund + '_fee_rebate').innerHTML = rebate_fee.toFixed(2);
		rebate_total = rebate_total + rebate_fee*weighting;
		
		// category average fees
		average_total = average_total + this.funds[fund].category * weighting;
		
		// actual dollars saved
		var dollars = (this.funds[fund].category - rebate_fee)/100 * this.funds[fund].amount;
		$(fund + '_dollars_saved').innerHTML = dollars.toFixed(0);
		total_dollars_saved = total_dollars_saved + dollars;
	}
	
	// update totals on the table
	$('total').innerHTML = this.dollarFormatter(total);
	$('simple_total').innerHTML = simple_total.toFixed(2);
	$('rebate_total').innerHTML = rebate_total.toFixed(2);
	$('average_total').innerHTML = average_total.toFixed(2);
	$('total_dollars_saved').innerHTML = this.dollarFormatter(total_dollars_saved.toFixed(0));

	$('rebate_percent').innerHTML = (100 - weighted_fee).toFixed(2);
	
	// render the updated chart
	this.layout.addDataset("fee", [[0, average_total.toFixed(2)], [1, rebate_total.toFixed(2)] ]);
	this.layout.evaluate();
 	this.plotter.clear();
 	this.plotter.render();
	
};


fc = new FeeCalculator();
addLoadEvent(fc.initialize);



