


STEPS="Steps";
BANDS="Bands";
// Enumerated constants.
// Use == or != to test variables for equality with them.


        /**
	  * models a basic credit-like scheme a.la. Family Credit/WFTC/Rent rebates
	  * 
	  * @param level maximum amount
	  * @param threshold max withdrawn above this level of income
	  * @param taper withdrawn at this rate (&gt;0 &lt;1.0)
	  * @param income income level
	  * @return the credit
	**/
	function creditCalculation( level,
		                    threshold,
		                    taper,
		                    income )
        {
			
		var credit = 0.0;
		income -= threshold;
		
		if( income < 0.0 ){
			credit = level;	
		} else {
			credit = level - (taper*income);
			credit = Math.max( 0.0, credit );
		}
		return credit;		
	}
	
			
	
	/**
	 *  
	 *  do a stepped calculation, e.g. old uk NI
	 *  or banded (e.g. UK Income Tax)
	 *
	 *@param  rates  (e.g.) array of tax rates
	 *@param  bands  (e.g.) array of tax bands (ascending)
	 *@param  value  input value (e.g. a taxable amount) 
	 *@param  whichOp do stepped or banded calculation
	 *@return        value/length pair (e.g. tax due/end band)
	 */
	function calculate( rates,
       	                    bands,
			    value,
			    whichOp ) 
        {
		if ( whichOp == STEPS ) {
			return calculateSteps( rates, bands, value );
		}
		return calculateBands( rates, bands, value );
	}


	/**
	 *  do a stepped calculation, e.g. old uk NI
	 *
	 *@param  rates  (e.g.) array of tax rates
	 *@param  bands  (e.g.) array of tax bands (ascending)
	 *@param  value  input value (e.g. a taxable amount)
	 *@return        value/length pair (e.g. tax due/end band)
	 */
	function calculateSteps( rates,
	                         bands,
			         value ) 
        {
		var len = 0;

		while ( ( value > bands[len] ) && ( len < bands.length - 1 ) ) {
			len++;
		}
		var val = rates[len] * value;
		valAndLen.val = val;
		valAndLen.lan = len;
		return valAndLen;
	}


	/**
	 *  do a banded calculation, e.g. uk income tax
	 *
	 *@param  rates  (e.g.) array of tax rates
	 *@param  bands  (e.g.) array of tax bands (ascending; topmost value is set to Infinity by this method)
	 *@param  value  input value (e.g. a taxable amount)
	 *@return        value/length pair (e.g. tax due/end band)
	 */
	function calculateBands( rates,
			         bands,
		                 value ) {
		var len = 0;
		var val = 0.0;
		var left = value;
		//bands[bands.length - 1] = Math.Infinity;
		var gap = bands[0];
		while ( left > 0.0 ) {
			if ( len > 0 ) {
				gap = bands[len] - bands[len - 1];
			}

			if ( left > 0.0 ) {
				var x = Math.min( left, gap );
				val += x * rates[len];
				left -= gap;
				len++;
			}
		}
		return val;
	}
