FormUtils = {
	
	forceIntVal:function (field,signed) {
		FormUtils.setValue ( $(field), FormUtils.getIntVal (field,signed) );
	},
	
	forceFloatVal:function (field,signed) {
		if ( field.nodeName.toLowerCase()=='select') {
			return;
		}
		FormUtils.setValue ( $(field), FormUtils.getFloatVal ( field, signed ) );
	},
	
	sum:function () {
		ret = 0;
		$A(arguments).each ( function ( v ) {
			ret += FormUtils.getPrimitiveValue ( v );
		} );
		return ret;
	},
	
	diff:function () {
		var a = $A(arguments);
		var first = FormUtils.getPrimitiveValue ( a.shift() );
		a.each ( function ( v ) {
			first -= FormUtils.getPrimitiveValue ( v );
		})
		return first;		
	},
	
	product:function () {
		ret = 1;
		$A(arguments).each ( function ( f ) {
			ret *= FormUtils.getPrimitiveValue ( f );
		} );
		return ret;
	},
	
	valueOf:function ( f ) {
		var ret = null;
		if ( $(f) ) {
			return FormUtils.getPrimitiveValue ( $(f) );
		} else {
			// assume radio
			var items = document.getElementsByName(f);
			for ( var i = 0; i < items.length; i ++ ) {
				if ( items.item(i).checked ) {
					ret = $F(items.item(i))
					break;
				}
			}
		}
		return ret;
	},
	
	percentage:function ( field, p ) {
		if ( typeof field != 'number' ) {
			field = FormUtils.valueOf ( field );
		}
		return Math.roundAt ( field * ( p / 100 ), 2 ); 
	},
	
	getPrimitiveValue:function ( field ) {
		var ret = null, type = null;
		switch ( type = FormUtils.getPrimitiveType ( field ) ) {
			case 'int':
				ret = FormUtils.getIntVal ( field, Element.hasClassName ( field, 'signed' ) );
				break;
			case 'float':
				ret = FormUtils.getFloatVal ( field, Element.hasClassName ( field, 'signed' ) );
				break;
			case 'money':
				ret = FormUtils.getMoneyVal ( field, Element.hasClassName ( field, 'signed' ) );
				break;
			default:
				if ( field.type == 'radio' ) {
					var selected = $A(field.form.elements[field.name]).find ( function ( i ) {
						return i.checked;
					});
					if ( selected ) {
						ret = selected.value;
					} else {
						ret = null;
					}
				} else if ( $F(field ) ) {
					ret = $F (field);
				} else if ( field.value ) {
					ret = field.value;
				} else {
					alert ( 'Value of field ' + field.id + ' cannot be determined' );
				}
		}
		
		return ret;
	},
	
	getPrimitiveType:function ( field ) {
		var ret = null;
		if ( Element.hasClassName (field, 'int' ) ) {
			ret = 'int';
		} else if ( Element.hasClassName ( field, 'float' ) ) {
			ret = 'float';
		} else if ( Element.hasClassName ( field, 'money' ) ) {
			ret = 'money';
		} 
		return ret;
	},
	
	getIntVal:function ( field, signed ) {
		var value = parseInt ( $F(field) );

		if ( (value < 0 && !signed) || isNaN ( value ) ) {
			value = 0;
		} 
		
		return value;
	},
	
	setFieldTypes:function () {
		var fields = [];
		$A(document.getElementsByTagName ( 'input' ) ).each ( function ( f ) {
			fields.push(f);
		});
		$A(document.getElementsByTagName ( 'select' ) ).each ( function ( f ) {
			fields.push(f);
		});
		$A(fields).each ( function( e ) {
			try {
				if ( Element.hasClassName ( e, 'int' ) ) {
					if ( Element.hasClassName (e, 'force' ) ) {
					 	Event.observe(e,'keyup',
							function(){
								FormUtils.forceIntVal ( this, Element.hasClassName ( e, 'signed' ) ); 
							}.bind(e)
						);
					} else {
						Event.observe(e,'blur',
							function(){
								FormUtils.forceIntVal ( this, Element.hasClassName ( e, 'signed' ) ); 
							}.bind(e)
						)
					}
				} else if ( Element.hasClassName ( e, 'float' ) ) {
					if ( Element.hasClassName (e, 'force' ) ) {
					 	Event.observe(e,'keyup',
							function(){
								FormUtils.forceFloatVal ( this, Element.hasClassName ( e, 'signed' ) ); 
							}.bind(e)
						);
					} else {
						Event.observe(e,'blur',
							function(){
								FormUtils.forceFloatVal ( this, Element.hasClassName ( e, 'signed' ) ); 
							}.bind(e)
						)
					}
				}
			} catch ( e ) { alert ( e ); }
		});
	},
	
	setValue:function ( field, value ) {
		if ( Element.hasClassName ( field, 'percentage' ) ) {
			if ( Element.hasClassName ( field, 'signed' ) ) {
				value = Math.between ( value, -100, 100 );
			} else {
				value = Math.between ( value, 0, 100 );
			}
		}
		switch ( FormUtils.getPrimitiveType(field) ) {
			case 'float': case 'int':
				if ( isNaN ( value ) ) {
					value = 0;
				}
				
				if ( Element.hasClassName ( field, 'int' ) ) {
					value = Math.roundAt ( value, 0 );
				} else if ( Element.hasClassName ( field, 'financial' ) ) {
					value = Math.roundAt ( value, 2 );
				}
				if ( value == 0 && ! Element.hasClassName ( field, 'total' ) ) {
					value = '';
				}
		}
		if ( FormUtils.getPrimitiveType( field ) == 'float' ) {
			value = ('' + value).replace ( '.', ',' );
		}
		field.value = value;
	},
	
	copy:function ( src, dest ) {
		FormUtils.setValue ( dest, FormUtils.valueOf ( src ) );
	},
	
	getFloatVal:function ( field, signed ) {
		var value = parseFloat ( $F(field).replace ( ',', '.' ) );
		if ( (value < 0 && !signed) || isNaN ( value ) ) {
			value = 0;
		} 
		return value;
	},
	
	radioSwitch:function (input,eid) {
		$A(eid).each ( function ( e ) {
			Element[input.value==1?'removeClassName':'addClassName']($(e), 'hidden');
		});
	}
}