/* Stormwater Discounts Calculator Object */
var swd = {
	// Calculate fixed monthly charge for services to streets and watersheds
	calculateStreets: function () {
		var value = 14.54;
		value = Math.round(value*100) / 100;		// Round to two decimal places
		return value;
	},

	// Calculate fixed monthly charge for on-site private property services
	calculateOnsite: function () {
		var value = 22.37;
		value = Math.round(value*100) / 100;		// Round to two decimal places
		value = value - this.calculateStreets();
		return value;
	},

	// Calculate total fixed monthly charge
	calculateGrossCharge: function () {
		return this.calculateStreets() + this.calculateOnsite()
	},

	// Calculate total discount (percentage of total discount)
	calculateTotalDiscount: function () {
		var offProperty, drywells, landscape, cisterns, pond, ecoroof, imperviousArea, trees;
		offProperty = $('offProperty').checked;
		drywells = $('drywells').checked;
		landscape = $('landscape').checked;
		cisterns = $('cisterns').checked;
		pond = $('pond').checked;
		ecoroof = $('ecoroof').checked;
		imperviousArea = $('imperviousArea').checked;
		trees = $('trees').checked;

		var fullOnsite, partialOnsite, onsiteDetention, smallLotCredit, treeCredit, raw, total;

		if (drywells || landscape || cisterns || ecoroof) {
			if (offProperty || pond ) {
				fullOnsite = 0;
			} else {
				fullOnsite = 1;
			}
		} else {
			fullOnsite = 0;
		}
//		console.info("Full Onsite %f", fullOnsite);

		if (drywells || landscape || cisterns || ecoroof) {
			if (offProperty || pond ) {
				partialOnsite = 0.67;
			} else {
				partialOnsite = 0;
			}
		} else {
			partialOnsite = 0;
		}
//		console.info("Partial Onsite %f", partialOnsite);

		if (pond) {
			onsiteDetention = 0.67;
		} else {
			onsiteDetention = 0;
		}
//		console.info("Onsite detention %f", onsiteDetention);

		if (imperviousArea) {
			smallLotCredit = 0.25;
		} else {
			smallLotCredit = 0;
		}
//		console.info("Small lot %f", smallLotCredit);

		if (trees) {
			treeCredit = Math.round(4*50/2400 * 100) / 100;		// Round to two decimal places
		} else {
			treeCredit = 0;
		}
//		console.info("Trees %d", treeCredit);

		raw = Math.max(fullOnsite, partialOnsite);
		raw = Math.max(raw, onsiteDetention);
		raw += smallLotCredit +  treeCredit;
//		console.info("Raw %d", raw);

		total = Math.min(raw, 1);
//		console.info("Total %f", total);

		return total;
	},

	// Calculate discount qualified for based off of user selected checkboxes
	calculateDiscount: function () {
		var totalDiscount = this.calculateTotalDiscount();

		var discountAmt = this.calculateOnsite() * totalDiscount;
		discountAmt = Math.round(discountAmt * 100) / -100;		// Round to two decimal places
		$('discount').value = formatNumber(discountAmt, "$,.00");

		var netCharge = this.calculateGrossCharge() + discountAmt;
		$('netCharge').value = formatNumber(netCharge, "$,.00");
	},

	showPercentage: function () {
		var totalDiscount = this.calculateTotalDiscount();
		totalDiscount = formatNumber(totalDiscount, "###%");

		alert("This amount equals " + totalDiscount + " of the on-site stormwater charge.");
	}

};



// Setup event listeners
addListener(window, 'load', windowOnLoad);

function windowOnLoad() {
	// Link calculatePension() to button click
	addListener( $('calculate'), 'click', swd.calculateDiscount.bind(swd));

	// Set fixed montly charges
	$('streets').value = formatNumber(swd.calculateStreets(), "$,.00");
	$('onsite').value = formatNumber(swd.calculateOnsite(), "$,.00");
	$('grossCharge').value = formatNumber(swd.calculateGrossCharge(), "$,.00");

	swd.calculateDiscount();
}


/******************************************************************************
*  The Prototype dollar function : Basically a shorthand method for getElementById
*	Use: $('elementID') or $('elementID1', 'elementID2', ...)
******************************************************************************/
function $() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}


/******************************************************************************
*  Binds the 'this' keyword to a specified object when calling a function
*	http://www.brockman.se/writing/method-references.html.utf8
*
*		@param	object	the 'this' object to bind to the function
* 		@return				a function whose 'this' keyword is bound to the parameter
******************************************************************************/
Function.prototype.bind = function (object) {
    var method = this;
    var oldArguments = entries(arguments).slice(1);
    return function () {
        var newArguments = entries(arguments);
        return method.apply(object, oldArguments.concat(newArguments));
    };

};


/******************************************************************************
*  Binds the 'this' keyword to a specified object when calling a function as
*  an event handler. The function has access to the event through the 'event'
*  variable.
*
*		@param	object	the 'this' object to bind to the function
* 		@return				a function whose 'this' keyword is bound to the parameter
******************************************************************************/
Function.prototype.bindEventListener = function (object) {
    var method = this;
    var oldArguments = entries(arguments).slice(1);
    return function (event) {
        return method.apply(object, event || window.event, oldArguments);
    };
};


/******************************************************************************
*  Helper function for bind() and bindEventListener()
*  (Private function)
*
*  Some browsers don't like expressions such as foo.concat(arguments)
*  or arguments.slice(1), due to a kind of reverse duck typing:
*  an argument object looks like a duck and walks like a duck,
*  but it isn't really a duck and it won't quack like one.
******************************************************************************/
function entries(collection) {
    var result = [];  // This is our real duck.

    for (var i = 0; i < collection.length; i++)
        result.push(collection[i]);

    return result;
};
