// steadyhand.com asset allocator
// Neil Jensen, August 2011
// TODO: too much hardcoding... use more loops

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

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

AssetCalculator.prototype.initialize = function () {

	// initialize or reset the data
	this.starting_assets = 20000;

	// array of fund data, including asset allocation, starting assets, and fee ('simple')
	this.funds = new Array();
	this.funds['savings'] = { 'can':0 , 'us':0, 'overseas':0, 'fi':100, 'amount': this.starting_assets, 'simple':0.65 };
	this.funds['income'] = { 'can':25 , 'us':0, 'overseas':0, 'fi':75,'amount': this.starting_assets, 'simple':1.04 };
	this.funds['equity'] = { 'can':60 , 'us':30, 'overseas':10, 'fi':0,'amount': this.starting_assets, 'simple':1.42 };
	this.funds['global'] = { 'can':0 , 'us':35, 'overseas':65, 'fi':0,'amount': this.starting_assets, 'simple':1.78 };
	this.funds['smallcap'] = { 'can':80 , 'us':20, 'overseas':0, 'fi':0,'amount': this.starting_assets, 'simple':1.78 };
	
	// 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 );    
	
	
	// array of asset classes and total dollars in that class
	this.asset_classes = new Array();
	this.asset_classes['can_equities'] = 0;
	this.asset_classes['us_equities'] = 0;
	this.asset_classes['int_equities'] = 0;
	this.asset_classes['fi'] = 0;
	
	for (var asset in this.asset_classes) {
		connect(asset + '_other', "onkeyup", this.updateAllocation);
	}
		
	//populate fund asset allocation table with data
	for( var fund in this.funds ) {
		$(fund + '_can').innerHTML = this.funds[fund].can;
		$(fund + '_us').innerHTML = this.funds[fund].us;
		$(fund + '_overseas').innerHTML = this.funds[fund].overseas;
		$(fund + '_fi').innerHTML = this.funds[fund].fi;
		$(fund).value = this.funds[fund].amount;
		
		//connect events for data entry
		connect(fund,"onkeyup", this.updateAllocation);
	}
			
	// portfolios makeup
	this.portfolios = new Array();
	this.portfolios['aggressive'] = {'savings':0, 'income':0, 'equity':40, 'global':40, 'smallcap':20 }; 
	this.portfolios['growth'] = {'savings':0, 'income':20, 'equity':32, 'global':32, 'smallcap':16 };
	this.portfolios['balanced_equity'] = {'savings':0, 'income':40, 'equity':24, 'global':24, 'smallcap':12 };
	this.portfolios['balanced_income'] = {'savings':0, 'income':66, 'equity':14, 'global':13, 'smallcap':7 };
	this.portfolios['income'] = {'savings':20, 'income':70, 'equity':5, 'global':5, 'smallcap':0 };
	
	//populate portfolios table with data
	for( var portfolio in this.portfolios ) {
		$(portfolio + '_savings').innerHTML = this.portfolios[portfolio].savings + '%';
		$(portfolio + '_income').innerHTML = this.portfolios[portfolio].income  + '%';
		$(portfolio + '_equity').innerHTML = this.portfolios[portfolio].equity  + '%';
		$(portfolio + '_global').innerHTML = this.portfolios[portfolio].global  + '%';
		$(portfolio + '_smallcap').innerHTML = this.portfolios[portfolio].smallcap  + '%';
	}

    connect("aggressive_portfolio", "onclick", partial(this.useModelPortfolio, "aggressive"));
    connect("growth_portfolio", "onclick", partial(this.useModelPortfolio, "growth"));
    connect("balanced_equity_portfolio", "onclick", partial(this.useModelPortfolio, "balanced_equity"));
    connect("balanced_income_portfolio", "onclick", partial(this.useModelPortfolio, "balanced_income"));
    connect("income_portfolio", "onclick", partial(this.useModelPortfolio, "income"));
    
    connect("other_investment_txt", "onclick",partial(this.toggleElement,"other_investments"));

    // create the piechart
    var dt = new google.visualization.DataTable();   
    dt.addColumn('string');          
    dt.addColumn('number');  
    dt.addRows(4);

    dt.setCell(0, 0,'CDN Equities');
    dt.setCell(1, 0,'US Equities');
    dt.setCell(2, 0,'Int. Equities');
    dt.setCell(3, 0,'Fixed Income');

    dt.setCell(0, 1,33);
    dt.setCell(1, 1,17);
    dt.setCell(2, 1,15);
    dt.setCell(3, 1,35);
    self.dt = dt;

    self.chartoptions =  {width: 331, 
                          height: 155, 
                          chartArea: {left:0,top:20, width:"100%",height:"95%"},  
                          legendTextStyle: {fontName:'Helvetica',fontSize:11},  
                          colors: ['#d12421', '#00b052', '#57b5e0', '#fcd647'],
                          pieSliceText: 'none',  
                          legend: 'left',
                          is3D: true};

    self.view = new google.visualization.PieChart(document.getElementById('chart1'));
    self.view.draw(dt, self.chartoptions);

    this.updateAllocation();
};


// change asset allocation of funds... not used currently
AssetCalculator.prototype.editFundAllocation = function( edit_fund ){
	
	var asset_classes = ['can','us', 'overseas', 'fi'];
	
	if( $(edit_fund + '_allocation').innerHTML != 'save' ) {
		forEach( asset_classes, 
			function(asset_class) {
				 var input = INPUT( {"type":"text", "value":$(edit_fund + '_' + asset_class).innerHTML, "size":"6", "id": edit_fund + '_' + asset_class } );
				swapDOM($(edit_fund + '_' + asset_class), input);
		});
		$(edit_fund + '_allocation').innerHTML = 'save';
	
	} else {
		// make sure we add up to 100%
		var total = 0;
		forEach( asset_classes, 
			function(asset_class) {
				total = total + parseInt($(edit_fund + '_' + asset_class).value);
		});
	
		// update the object, change the table, and the recalculate
		if(total == 100) {	
			forEach( asset_classes, 
				function(asset_class) {				
					ac.funds[edit_fund][asset_class] = parseInt($(edit_fund + '_' + asset_class).value);
					
					var display = SPAN({"id": edit_fund + '_' + asset_class}, $(edit_fund + '_' + asset_class).value); 
					swapDOM($(edit_fund + '_' + asset_class), display);
			});
			$(edit_fund + '_allocation').innerHTML = 'edit';	
			this.updateAllocation();
		} else {
			alert('asset allocation must add up to 100%');
		}
	}
	
	return false;	
};

AssetCalculator.prototype.toggleElement = function( toggle_element ){
	toggle($(toggle_element),"appear");
        //showElement($(toggle_element));
};


AssetCalculator.prototype.useModelPortfolio = function( portfolio ) {

        var pa = 0;

        if(parseInt($('portfolio_amount').value) > 0){
            pa = parseInt($('portfolio_amount').value);
        } else {
            pa = 100000;
        }

	$('savings').value = (this.portfolios[portfolio].savings/100 * pa).toFixed(0);
	$('income').value = (this.portfolios[portfolio].income/100 * pa).toFixed(0);
	$('equity').value = (this.portfolios[portfolio].equity/100 * pa).toFixed(0);
	$('global').value = (this.portfolios[portfolio].global/100 * pa).toFixed(0);
	$('smallcap').value = (this.portfolios[portfolio].smallcap/100 * pa).toFixed(0);

  new Highlight($('dyn_piechrt'),{duration : 1.0,endcolor :"#FFFFFF" });
	this.updateAllocation();
	
};


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


AssetCalculator.prototype.calculateFee = function(total) {

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

	// calculate the weighted average fee
	var fee_total = 0;
	for( var fund in this.funds ) {
		var weighting = this.funds[fund].amount/total;
		
		var rebate_fee = (this.funds[fund].simple * weighted_fee/100 );
		fee_total = fee_total + rebate_fee*weighting;
	}
	
  return fee_total.toFixed(2);

};


AssetCalculator.prototype.updateAllocation = function() {
	
	// total assets held
	var total = 0;

	// update 'other assets' table with total other assets
	var other_total = 0;
	for( var asset_class in this.asset_classes ) {
            if(parseInt($(asset_class + '_other').value) > 0){
			this.asset_classes[asset_class] = parseInt($(asset_class + '_other').value);
		} else {
			this.asset_classes[asset_class] = 0;
		}
		other_total = other_total + this.asset_classes[asset_class];
	}
 	$('other_total').innerHTML = this.dollarFormatter(other_total);	
 	
 	// update fund object and determine total steadyhand assets 
 	var steadyhand_total = 0;
 	var querystring_keys = new Array();
	var querystring_values = new Array();
	for( var fund in this.funds ) {
		if(parseInt($(fund).value) > 0){
			this.funds[fund].amount = parseInt($(fund).value);
		} else {
			this.funds[fund].amount = 0;
		}
		steadyhand_total = steadyhand_total + this.funds[fund].amount;
		querystring_keys.push(fund);
		querystring_values.push(this.funds[fund].amount);
	}
 	$('steadyhand_total').innerHTML = this.dollarFormatter(steadyhand_total);
  //$('portfolio_amount').value = this.dollarFormatter(steadyhand_total); 
  $('portfolio_amount').value = steadyhand_total; 

        // determine and display fee (with rebates)
        var fee = this.calculateFee(steadyhand_total);
        $('fee_amount').innerHTML = fee;

 	// update the link to the fee calculator page
 	$('fee_url').href = '/education/fee_calculator/?' + queryString(querystring_keys, querystring_values) + "#title";

 	// now that we know the steadyhand_total, determine steadyhand portfolio percentages
 	for( var fund in this.funds ) {
		$(fund + '_%').innerHTML = (100*this.funds[fund].amount/steadyhand_total).toFixed(1);
	}
 	
 	// loop through the amount in each steadyhand fund to determine the steadyhand asset totals
    var can_equities = 0;
    var us_equities = 0;
    var int_equities = 0;
    var fi = 0;

	var can_equities_percent = 0;
    var us_equities_percent = 0;
    var int_equities_percent = 0;
    var fi_percent = 0;

	for( var fund in this.funds ) {
		can_equities = can_equities + this.funds[fund].amount * (this.funds[fund].can/100);
		us_equities = us_equities + this.funds[fund].amount * (this.funds[fund].us/100);
		int_equities = int_equities + this.funds[fund].amount * (this.funds[fund].overseas/100);
		fi = fi + this.funds[fund].amount * (this.funds[fund].fi/100);
	}
	// draw steadyhand portfolio asset mix chart
	can_equities_percent = Math.round(can_equities / steadyhand_total * 100);
	us_equities_percent = Math.round(us_equities / steadyhand_total * 100);
	int_equities_percent = Math.round(int_equities / steadyhand_total * 100);
	fi_percent = Math.round(fi / steadyhand_total * 100);
	// uncomment this and the corresponding flash chart on the page to show the Steadyhand asset mix
	//so.call('updateChart', can_equities_percent, us_equities_percent, int_equities_percent, fi_percent);


 	// now calculate the total dollar amount in each asset category, adding the other assets 
    can_equities = can_equities + this.asset_classes['can_equities'];
    us_equities = us_equities + this.asset_classes['us_equities'];
    int_equities = int_equities + this.asset_classes['int_equities'];
    fi = fi + this.asset_classes['fi'];

	total = can_equities + us_equities + int_equities + fi;
	
	// now that we know the total, determine other holding percentages
 	//for( var asset_class in this.asset_classes ) {
	//	$(asset_class + '_other_%').innerHTML = (100*this.asset_classes[asset_class]/total).toFixed(1);
	//}

	// overall portfolio asset mix chart
	can_equities_percent = Math.round(can_equities / total * 100);
	us_equities_percent = Math.round(us_equities / total * 100);
	int_equities_percent = Math.round(int_equities / total * 100);
	fi_percent = Math.round(fi / total * 100);	

        // redraw the chart
        self.dt.setCell(0, 0,can_equities_percent + '% CDN Equities');
        self.dt.setCell(1, 0,us_equities_percent + '% US Equities');
        self.dt.setCell(2, 0,int_equities_percent + '% Int. Equities');
        self.dt.setCell(3, 0,fi_percent + '% Fixed Income');
        
        self.dt.setCell(0, 1,can_equities_percent);
        self.dt.setCell(1, 1,us_equities_percent);
        self.dt.setCell(2, 1,int_equities_percent);
        self.dt.setCell(3, 1,fi_percent);

        self.view.draw(self.dt, self.chartoptions);
}


google.load("visualization", "1", {packages:["corechart"]});
ac = new AssetCalculator();
addLoadEvent(ac.initialize);



