/*
*  Finance Calculator with Adjustable APR
*
* Author: Marlon King <marlon.king@gforces.co.uk>
*
* Notes: For use without APR being adjustable, pass in a fixed interest rate
*/



function updateResultsFromApr( price, rate, adjustableApr ){

	//reset values before starting
	var totalPrice          = price; //passed in from php page
	var deposit             = 0;     //selectable
	var loanPeriod          = 0;     //selectable in years
	var monthlyPayments     = 0;
	var creditAmount        = 0;
	var interestPayable     = 0;
	var totalAmountPayable  = 0;
	var apr                 = 0;
	var totalNumberOfMonths = 0;
	var interestRate        = rate;  //ie 12.2


	//retrieve inputed values

	deposit             = parseInt( $('input_deposit').value );
	loanPeriod          = parseInt( $('input_loanPeriod').value );
	//apr_selected        = parseFloat( $('input_apr').value )/100;

	if ( deposit > 0 && loanPeriod > 0 ) {

		//calculate all
		creditAmount        = (totalPrice - deposit);
		creditAmountIni     = (totalPrice - deposit); //without 165 added
		totalNumberOfMonths = loanPeriod * 12;
		interestRate        = interestRate / 100;
		monthlyPayments     = creditAmount / totalNumberOfMonths;


		//creditAmount = creditAmount + 165;

    	interestPayable      = ( creditAmount * interestRate) * loanPeriod ;
    	totalAmountPayable   = ( creditAmount + interestPayable );
    	monthlyPayments      = ( totalAmountPayable / totalNumberOfMonths );

		apr = calculateAPR( creditAmountIni, totalNumberOfMonths, monthlyPayments );

    	interestPayable    = ((monthlyPayments * totalNumberOfMonths)) - creditAmountIni;
		totalAmountPayable = ((monthlyPayments * totalNumberOfMonths) + (deposit));



		//display results
		//$('totalPrice').innerHTML         = '<strong>£' + addCommas(Math.round(totalPrice * 100 ) / 100 ) + '</strong>';
		$('creditAmount').innerHTML       = '£' + addCommas(Math.round(creditAmountIni * 100 ) / 100 );
		$('interestPayable').innerHTML    = '£' + addCommas(Math.round( interestPayable  * 100 ) / 100 );
		$('monthlyPayments').innerHTML    = '£' + addCommas(Math.round( monthlyPayments * 100 ) / 100 );
		$('totalAmountPayable').innerHTML = '£' + addCommas(Math.round( totalAmountPayable * 100 ) / 100);

		if ( adjustableApr == true ){

			apr = reverseCalculateAPR( creditAmountIni, totalNumberOfMonths, totalAmountPayable, apr_selected, deposit );

		}else{

			$('apr').innerHTML                =  Math.round( parseFloat( apr ) * 10 ) / 10 + '%';
		}

	}else if ( deposit >= 0 ){

		creditAmount        = (totalPrice - deposit);
		$('creditAmount').innerHTML       = '£' + addCommas(Math.round( creditAmount * 100 ) / 100);

	}
}


function calculateLoanFromAPR( apr, totalNumberOfMonths, monthlyPayments ) {

    var loan = 0;

    for( time = 1; time <= totalNumberOfMonths; time++ ) {

        payment = monthlyPayments;

        //payment += ( time == totalNumberOfMonths ) ? 45 : 0;//final sum added on to final payment - REMOVE AS NECESSARY

        interest = ( payment / ( Math.pow( 1 + apr, time / 12 ) ) );

        loan +=interest;

        //alert('debug ' + time + ' - loan: ' + loan + ', payment: ' + payment + ', period: ' + time  + ' PV: ' + interest );
    }

    return loan;

}



function calculateAPR( creditAmount, totalNumberOfMonths, monthlyPayments ) {

    //alert( creditAmount + ' - ' + totalNumberOfMonths + ' - ' + monthlyPayments );

    minApr = 0;
    minAprCalculatedLoan = calculateLoanFromAPR( minApr, totalNumberOfMonths, monthlyPayments );
    maxApr = 1;
    maxAprCalculatedLoan = calculateLoanFromAPR( maxApr, totalNumberOfMonths, monthlyPayments );

    time_to_live = 200;

    target_amount = creditAmount;

    do {
        midApr = ( ( maxApr - minApr ) / 2 ) + minApr;
        midAprCalculatedLoan = calculateLoanFromAPR( midApr, totalNumberOfMonths, monthlyPayments );

        if( target_amount < midAprCalculatedLoan ) {

            minApr = midApr;

        } else if( target_amount > midAprCalculatedLoan ) {

            maxApr = midApr;
        }

        difference = Math.abs(midAprCalculatedLoan - target_amount);

        //alert('debug - apr: ' + midApr + ', ' + midAprCalculatedLoan + ' < ' + target_amount + ', loan difference: ' + difference + ', loan: ' + creditAmount );

    } while ( (midAprCalculatedLoan < target_amount || difference > 0.001) && time_to_live-- > 0 );

    if( time_to_live < 0 ) {

        return "NAN";

    } else {

        return midApr * 100;

    }

}

//change the month payment
function reverseCalculateAPR( creditAmount, totalNumberOfMonths, monthlyPayments, newApr, deposit ) {

  	 var loan   = 0;
  	 //var adjust = 0;

   	payment = creditAmount/totalNumberOfMonths;

	for( time = 1; time <= totalNumberOfMonths; time++ ) {

		interest = ( payment * ( Math.pow( 1 + newApr, time / 12 ) ) );


		loan +=interest;
		//alert ( "interest: " +  interest );
		//adjust += ( time / 12 );
	}

	//alert ( 'Adjust: ' + adjust );

	//alert ('loan2: ' + loan);
	//alert ('monthly payment' + ( loan / (totalNumberOfMonths )) );


	monthlyPayments        = ( loan / ( totalNumberOfMonths ) );
	loan                   = monthlyPayments * totalNumberOfMonths;
	var newInterest        = loan - creditAmount;
	var totalAmountPayable = ( loan + deposit);

   	//display results
   	$('interestPayable').innerHTML    = '£' + addCommas(Math.round( newInterest  * 100 ) / 100 );
   	$('monthlyPayments').innerHTML    = '£' + addCommas(Math.round( monthlyPayments * 100 ) / 100 );
   	$('totalAmountPayable').innerHTML = '£' + addCommas(Math.round( totalAmountPayable * 100 ) / 100);
  	// $('apr').innerHTML                =  Math.round( parseFloat( (newApr*100)) * 10 ) / 10 + '%';


}




function addCommas(nStr)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	if ( x.length > 1 ){
		theDec = x[1];
		theDec = ( theDec.length == 1 )? x[1] + '0' : theDec;
		x2 = '.' + theDec;
	}else{
		x2 = '';
	}
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}