// - - - - - - - - - - - -
// Adapted from PEAR Math_Finance by AF
// Same interface as Excel financial functions.
// - - - - - - - - - - - -

// note that all these functions which use 'type' 
//  default it to 1, because that's all I ever seem to use


// Returns the effective interest rate given the nominal rate and the number of compounding payments per year
// Excel equivalent: EFFECT

// nominal_rate: float - Nominal interest rate
// npery: int - Number of compounding payments per year
// return float

function effectiveRate(nominal_rate, npery) {
	npery = parseInt(npery);
	if (npery < 0) {
		myOnLog('Number of compounding payments per year is not positive');
		return false;
	}
	var effect = Math.pow((1 + nominal_rate / npery), npery) - 1;
	return effect;
}


// Returns the nominal interest rate given the effective rate and the number of compounding payments per year
// Excel equivalent: NOMINAL

function nominalRate(effect_rate, npery) {
	npery = parseInt(npery);
	if (npery < 0) {
		myOnLog('Number of compounding payments per year is not positive');
		return false;
	}
	var nominal = npery * (Math.pow(effect_rate + 1, 1/npery) - 1);
	return nominal;
}




// Returns the Present Value of a cash flow with constant payments and interest rate (annuities)
// Excel equivalent: PV

// rate: float - Interest rate per period 
// nper: int   - Number of periods
// pmt:  float - Periodic payment (annuity)
// fv:   float - Future Value
// type: int   - Payment type: 0 (default) = at the end of each period, 1 = beginning

// return float

function presentValue(rate, nper, pmt, fv, type) {
	
	if (typeof fv   == 'undefined') fv   = 0;
	if (typeof type == 'undefined' || (type != 0 && type != 1)) type = 1;
	
	nper = parseInt(nper);
	
	var pv;
	if (rate != 0) {
		pv = (-pmt * ((1 + rate) * type) * ((Math.pow(1 + rate, nper) - 1) / rate) - fv) / Math.pow(1 + rate, nper);
	} else {
		pv = -fv - pmt * nper;
	}
	return pv;
}


// Returns the Future Value of a cash flow with constant payments and interest rate (annuities)
// Excel equivalent: FV

function futureValue(rate, nper, pmt, pv, type) {
	
	if (typeof pv   == 'undefined') pv   = 0;
	if (typeof type == 'undefined' || (type != 0 && type != 1)) type = 1;
	
	var fv;
	if (rate != 0) {
		fv = -pv * Math.pow(1 + rate, nper) - pmt * ((1 + rate) * type) * (Math.pow(1 + rate, nper) - 1) / rate;
	} else {
		fv = (-pv - pmt) * nper;
	}
	return fv;
}



// Returns the constant payment (annuity) for a cash flow with a constant interest rate
// Excel equivalent: PMT

function payment(rate, nper, pv, fv, type) {

	if (typeof fv   == 'undefined') fv   = 0;
	if (typeof type == 'undefined' || (type != 0 && type != 1)) type = 1;

	var pmt;
	if (rate) {
		pmt = (-fv - pv * Math.pow(1 + rate, nper)) / ((1 + rate) * type) / ((Math.pow(1 + rate, nper) - 1) / rate);
	} else {
		pmt = (-pv - fv) / nper;
	}
	return pmt;
}



// Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate
// Excel equivalent: NPER

function periods(rate, pmt, pv, fv, type) {

	if (typeof fv   == 'undefined') fv   = 0;
	if (typeof type == 'undefined' || (type != 0 && type != 1)) type = 1;

	var nper;
	
	if (rate) {
		if (pmt == 0 && pv == 0) {
			myOnLog("Payment and Present Value can't be both zero when the rate is not zero");
			return false;
		}
		nper = Math.log((pmt * ((1 + rate) * type) / rate - fv) / (pv + pmt * ((1 + rate) * type) / rate)) / Math.log(1 + rate);
	
	} else {
		if (pmt == 0) {
			myOnLog("Rate and Payment can't be both zero");
			return false;
		}
		nper = (-pv - fv) / pmt;
	}
	return nper;
}




// Returns the periodic interest rate for a cash flow with constant periodic payments (annuities)
// Excel equivalent: RATE

// ok, guys... gotta bring the server into play here
// this function is pretty useless outside this calculator,
//  so it's been pulled out of the general-purpose ax_finance.js script

function rate(nper, pmt, pv, fv, type, guess) {
	
	if (typeof fv   == 'undefined') fv   = 0;
	if (typeof type == 'undefined' || (type != 0 && type != 1)) type = 1;
	if (typeof guess == 'undefined') guess = 0.01;
	
	var params;
	params  = '?f=rate';
	params += '&nper='  + nper;
	params += '&pmt='   + pmt;
	params += '&pv='    + pv;
	params += '&fv='    + fv;
	params += '&type='  + type;
	params += '&guess=' + guess;

	myOnLog('rate params: ' + params);

	var x = new ajax();
	x.onComplete = getFin;
	x.submit('_fin.php' + params);
}


// callback for rate()
//  (should allow defining callback for this func!)

function getFin(txt, xml) {
	myOnLog(txt);
	
	var resObj;
	
	if (txt.substring(0,2) != '{ ') {
		myOnLog('problems calling external finance calculator');
		return;
	}
	
	eval('resObj = ' + txt + ';');
	with (resObj) {
		if (err != 0) {
			myOnLog(msg);
		
		} else {
			myOnLog('calc ' + res['param'] + ' = ' + res['value']);
			c3solve(res['f'], res['value']);
		}
	}
}



