/* 
	Form Highlighter
	Initilise with:
		new FormHighliter(string form_name , string css_class_of_hilight_area [, object exlude_list])
		exclude_list example: {'input':{'type':['button','submit','image','reset']}}
*/

FormHighlighter = Class.create({
	form: {}, // DOM element
	highlight_target: '', // css target
	exclude_list: {}, //format: {tagname: true|{attribute:[values]}}
	elements: [], // list of DOM elements/observers in {element: {}, observer: {}} format
	
	initialize: function(form, field_target, exclude) {
		if (!form || !field_target) { return false; }
		if ((this.form = $(form)) === null) { return false; }
		this.highlight_target = field_target;
		if (exclude) {
			this.exclude_list = exclude;
		}
		this.scan();
	},
	
	// can be called directly to rescan dynamic forms etc
	scan: function() {
		if (!this.form) { return false; }
		this.set_observe(true); // upon scanning, clean element array and remove observers (in case of dynamic form generation) 
		this.elements = [];
		this.form.getElements().each(function(elem) {
			if (!this.is_excluded(elem)) {
				// use an object so we can associate observers to the events
				this.elements.push({element: elem});
			}
		}.bind(this));
		this.set_observe();
	},
	
	set_observe: function(remove) {
		if (remove) {
			this.elements.each(function(elem){
				Event.stopObserving(elem.element, 'focus', elem.observer, false);
			}.bind(this));
		} else {
			this.elements.each(function(elem){
				elem.observer = this.highlight.bindAsEventListener(this); // cache observer to de-reference later if needed
				Event.observe(elem.element, 'focus', elem.observer, false);
			}.bind(this));
		}
	},
	
	// returns true if an element is present in the exlcuded list ()
	is_excluded: function(elem) {
		var tagname;
		if(tagname = this.exclude_list[elem.tagName.toLowerCase()]) {
			if (tagname === true) {
				return true;
			} else {
				// very prototype/ruby based syntax... similar to php "in_array" syntax (ie, just true or false)
				// true if the current form element matches any of the attribute values for the specific attribute (type="submit", name="myfield" etc)
				return($H(tagname).any(function(attribute) {
					return (attribute.value.any(function(value){ return value == elem[attribute.key] }));
				}));
			}
		}
		return false;					
	},
	
	highlight: function(e) {
		var targ = Event.element(e);
		this.form.select(this.highlight_target).each(function(highlight_area) {
			if (targ.descendantOf(highlight_area)) { // descedantOf is SO useful!
				highlight_area.addClassName('focus'); // no need to remove first, as addClassName has dupe detection
			} else {
				highlight_area.removeClassName('focus');
			}
		}.bind(this));
	}
	
});