var  updaters = {};
var  listeners = {};
inited = false;

var updateFields = [];
var d = 0;
function r_alert ( s, v ) {
	alert ( s );
	return s;
}

monitor = {timeout:null,fn:function(){}};

function _doUpdate () {
	updateFields.each ( function ( fn ) {
   	var field = document.getElementById(fn);
   	try{
      if ( '_update' in field ) {
			d++;
      	if (field.readOnly) {
	         field._update ();
         } 
			d--;
      }
      } catch ( e ) { 
		   alert ( e.message + ' in field ' + fn ) ; 
		}
	}.bind(this) );
	if (typeof updateTotals == 'function') {
	   updateTotals();
	}
}

function _updateAll () {
   if ( monitor.timeout ) {
      clearTimeout ( monitor.timeout )
   }
   monitor.timeout = setTimeout ( 'doUpdate()', 750 );
}

function init (form) {
	if (inited) {
		return;
	}
	inited = true;
	updateAll = _updateAll.bind ( form );
	doUpdate = _doUpdate.bind ( form );
	
	$A(document.getElementsByTagName('input')).each (
	   function ( e ) {
	   	if ( e.type == 'radio' && e.checked ) {
	   	   e.click ();
	   	}
	   }
	);
	
	$H(updaters).each ( function ( updater ) {
		if ( $(updater.key) ) {
			var field = $(updater.key);
			updateFields.push ( updater.key );
			field.readOnly=true;
			field._update = (new Function ( updater.value )).bind(field);
			Element.addClassName ( field, 'auto' );
			updateFields.push(updater.key);
			if ( Element.hasClassName ( field, 'switch' ) ) {
				var tr = $ancestor(field,'tr');
				if ( Element.hasClassName ( tr, 'total' ) ) {
					$child_c(tr,'field').appendChild ( getSwitchLock ( field ) );
				} else {
					var th = $child(tr,'th');
					th.insertBefore ( getSwitchLock ( field ), th.firstChild );
				}
			}
		}
	} );

	$H(listeners).each ( function ( listener ) {
		var list;
		try {
			var fn =(new Function(listener.value));
		}catch(e){
			alert('listener.' . listener.key + ' is invalid');
		}
		
		if ( $(listener.key) ) {
			var field = $(listener.key);
			if ( field.type == 'radio' ) { // IE bug
				$A(field.form.elements[field.name]).each ( function ( radio ) {
					Event.observe ( radio, 'click', fn.bind(field), false );
				});
			} else if (field.nodeName.toLowerCase() == 'select' ) {
				Event.observe( field, 'change', fn.bind(field), false );
			} else {
				Event.observe( field, 'keyup', fn.bind(field), false );
			}
		} else if ( list = document.getElementsByName ( listener.key ) ) {
			// probably radio button
			for ( var i = 0; i < list.length; i ++ ) {
				Event.observe ( list.item(i), 'click', fn.bind(field), false );
			} 
		}
	} );
	
	$A(document.getElementsByTagName ('span')).each(function ( e ) {
		if (  /value-of\s(.+)/.test ( e.className ) ) {
			e.firstChild.nodeValue = FormUtils.valueOf ( e.className.match ( /value-of\s(.+)/ ) [1] );
			Event.observe($(e.className.match ( /value-of\s(.+)/ ) [1]), 'keyup', function () {
				var m = this.className.match ( /value-of\s(.+)/ );
				this.firstChild.nodeValue = FormUtils.valueOf ( $(m[1]) ) ;
			}.bind (e), false );
		}
	});
	
	if ( typeof values != 'undefined' ) {
		$H(values).each ( function ( v ) {
			setUserValue ($(v.key), v.value);
		} );
	}
   updateAll ();
}

function setUserValue ( input, value ) {
	if ( input.readOnly ) {
		if ( input.switchLock ) {
			input.switchLock.src = 'template/gfx/icons/unlock.gif';
			Element.addClassName( input, 'switch-on' );
			FormUtils.setValue ( input, value );
			input.readOnly = false;
		}
	} else {
		FormUtils.setValue ( input, value );
	}
}

function getSwitchLock ( input ) {
	var img = document.createElement ( 'img' );
	img.src = 'template/gfx/icons/lock.gif';
	img.className = 'switch-lock';
	input.switchLock = img;	
	Tooltips['SwitchLockOn'].attachTo ( img, 0 );
	Event.observe ( img, 'click', function () {
		Tooltips['SwitchLockOn'].hide ();
		Tooltips['SwitchLockOff'].hide ();
		
		Element.flipSrc (img, ['lock.gif','unlock.gif'] );
		Element.flipClassName ( this, 'switch-on' );
		if ( !this.readOnly ) {
			this.userValue = FormUtils.valueOf ( this );
			Tooltips['SwitchLockOn'].attachTo ( img, 0 );
			Tooltips['SwitchLockOff'].detachFrom ( img );
		} else if ( 'userValue' in this ) {
			Tooltips['SwitchLockOff'].attachTo ( img, 0 );
			Tooltips['SwitchLockOn'].detachFrom ( img );
			FormUtils.setValue ( this, this.userValue );
		}
		this.readOnly = ! this.readOnly;
		updateAll ();
	}.bind(input), false );
	return img;
}

function initTooltips () {
	$A(document.getElementsByTagName ( 'img' )).each ( function ( img ) {
		if ( Element.hasClassName ( img, 'help' ) && img.name ) {
	      var help_id = img.name;
			if ( !Tooltips[help_id] ) {
				alert ( 'Help id "' + help_id + '" is invalid' );
				return;
			} 
	      Tooltips[help_id].attachTo ( img, 10 );
	      document.body.appendChild ( Tooltips[help_id].element );
		}
	});
	document.body.appendChild ( Tooltips['SwitchLockOn'].element );
	document.body.appendChild ( Tooltips['SwitchLockOff'].element );
}


Event.observe(window,'load',initTooltips,false);
Event.observe(window,'load',FormUtils.setFieldTypes,false);
Event.observe(window,'load',function(){
   if ($('mainForm'))
      init($('mainForm'))
   },false
);

function pc() {
   var s = '';
   for (var i in Constants) {
      s += i + ': ' + Constants[i] + '\n';
   }
   alert(s);
}