function TTotalizer() {
	//public
	this.get = TTotalizer__get;

	//private
	this.map = new TMap();
}
function TTotalizerCount() {
	//public
	this.addSourceElement = TTotalizerCount__addSourceElement;
	this.addTotalElement = TTotalizerCount__addTotalElement;
	this.updateTotal = TTotalizerCount__updateTotal;
    this.resetValuesOnOneHundredSelection = TTotalizerCount__resetValuesOnOneHundredSelection;

	//private
	this.totalElement = null;
	this.sourceElements = new Array();
	this.getUserValue = TTotalizerCount__getUserValue;
}

function TTotalizer__get(val) {
	var count = this.map.get(val);
	if (count==null) {
		count = new TTotalizerCount();
		this.map.put(val, count);
	}
	return count;
}

function TTotalizerCount__addSourceElement(objEl) {
	this.sourceElements[this.sourceElements.length] = objEl;
}
function TTotalizerCount__addTotalElement(objEl) {
	this.totalElement = objEl;
}

function TTotalizerCount__resetValuesOnOneHundredSelection(resetValues) {
	this.resetValuesOnOneHundredSelection = resetValues;
}


function TTotalizerCount__updateTotal(srcElement) {
	if (this.totalElement==null || this.totalElement.type!="text") { return; }
    if (this.resetValuesOnOneHundredSelection == null) this.resetValuesOnOneHundredSelection = false;

    var total = 0;
	for (var i=0;i<this.sourceElements.length;i++) {
		var el = this.sourceElements[i];
		if (el.tagName=="INPUT") {
			if (el.type=="text") {
				var elTotal = parseFloat(this.getUserValue(el.value));
				if (!isNaN(elTotal)) {
					total += elTotal;
				}
			}
		} else if (el.tagName=="SELECT" || el.type.indexOf("select")>=0) {
			for (var j=0;j<el.options.length;j++) {
				var opt = el.options[j];
				if (opt.selected) {
					var elTotal = parseInt(opt.text);
					if (!isNaN(elTotal)) {
						total += elTotal;
					}
				}
			}
		} else {
			alert("el="+el.type);
		}
	}
	this.totalElement.value = total;
    if (srcElement!=null) {
	    // changed for nu:
	    // this part auto-calculates the 100% double drop down action
	    // however, we have two input fields that are not 100% values,
	    // therefore this nice code is screwing us by auto-calculating
	    // to 100.  Therefore our solution is to only auto-cacluate for
	    // select fields.
		if ((this.sourceElements.length==2 || this.resetValuesOnOneHundredSelection) && srcElement.tagName != "INPUT") {
			//we can update the other element
			total = -1;
			if (srcElement.tagName=="INPUT") {
				if (srcElement.type=="text") {
					total = parseFloat(this.getUserValue(srcElement.value));
				}
			} else if (srcElement.tagName=="SELECT" || el.type.indexOf("select")>=0) {
				//get the selected value
				for (var i=0;i<srcElement.options.length;i++) {
					var opt = srcElement.options[i];
					if (opt.selected) {
						total = parseInt(opt.text);
					}
				}
			}
            // if they have selected 100, then reset all the other values
            if (!isNaN(total) && total == 100 && this.resetValuesOnOneHundredSelection) {
                for (var i=0;i<this.sourceElements.length;i++) {
                    var el = this.sourceElements[i];
                    if (el!=srcElement) {
                        if (el.tagName=="SELECT" || el.type.indexOf("select")>=0) {
                            //select the correct one
                            el.selectedIndex = 1;
                        }
                    }
                }
                //update the total
                this.updateTotal(null);

            } else if (!isNaN(total) && total>=0) {
				total = 100-total;
				//update other element
				for (var i=0;i<this.sourceElements.length;i++) {
					var el = this.sourceElements[i];
					if (el!=srcElement) {
						if (el.tagName=="INPUT") {
							//must be text
							el.value = total;
						} else if ((el.tagName=="SELECT" || el.type.indexOf("select")>=0) && !this.resetValuesOnOneHundredSelection) {
							//select the correct one
							for (var j=0;j<el.options.length;j++) {
								var opt = el.options[j];
								var optVal = parseInt(opt.text);
								if (!isNaN(optVal)) {
									if (optVal==total) {
										opt.selected = true;
									}
								}
							}
						}
					}
				}
				//update the total
				this.updateTotal(null);
			}
		}
	}
}
function TTotalizerCount__getUserValue(val) {
	var parsed = "";
	for (var i=0;i<val.length;i++) {
		if ((val.charAt(i)>='0' && val.charAt(i)<='9') || val.charAt(i)=='.') {
			parsed+=val.charAt(i);
		}
	}
	return parsed;
}

document.customObjects.put("totalizer", new TTotalizer());
