/*
	To use the event handler:
	1. define a behavior name and its corresponding function in HANDLERS
	2. in HTML, for elements that should have that behavior applied to them when an event occurs, add these attributes:
		1. class="behavior" (required)
		2. rel:actions="[event]:[behavior name]" (required)
		3. rel:data="{[behavior name]:{parameters}}" (optional)
	NOTES:
	Functions defined in HANDLERS should accept two parameters, the event object and the optional parameters
	You may specify multiple events; just separate them by spaces. For example:
		rel:actions="[event 1]:[behavior 1 name] [event 2]:[behavior 2 name]"
	The events are associated with elements when the dom is loaded. If you add content to the page after that,
	you must call event_handler.init() to reassign the event handlers. 
*/
var bf_event_handler = function() {
	this.CLASS = '.behavior';
	this.ACTION_ATTRIBUTE = 'rel:actions';
	this.DATA_ATTRIBUTE = 'rel:data';
	this.HANDLERS = {
		// behavior_name : function_definition
		call: function(e,data) {var fn = eval(data.fn); fn(data.data?data.data:data);},
		vote: function(e,data) {badge_vote_manager.flow_vote(e, data)},
		share_email: function(e,data) {BF_ShareEmail.locate_form_and_share_email(data.buzz_id+'-email-form',data.buzz_id)},
		register: function(e,data) {
			var user = new BF_User();
			if ( user.isLoggedIn() ) {bf_register.register_alias(data);}
			else {bf_register.new_register(data)}
		},
		// map value of e.target into data.target's rel:data attribute
		map_into: function(e,data) {
			var target = e.target;
			var update_el = $(data.target);
			var value = target.value;
			if ( data.value ) value = data.value(target);
			if ( update_el ) {
				var json = eval('('+update_el.getAttribute('rel:data')+')');
				var field = data.field.split('.');
				var obj = json;
				var end_field = field.pop();
				while ( field.length ) {
					var f = field.shift();
					if ( typeof obj[f] != 'undefined' ) obj = obj[f];
					else obj[f] = {};
				}
				if ( data.append ) obj[end_field] = (typeof obj[end_field] == 'undefined' ? '' : obj[end_field] + data.append) + value;
				else obj[end_field] = value;
				update_el.setAttribute('rel:data',Object.toJSON(json));
				if ( data.hide && $(data.hide) ) $(data.hide).hide();
			}
		},
		// if e.target has class 'initial-field-state', remove class and clear value of e.target
		clear_default_field: function(e,data){
			var target = e.target;
			var remove_class = (typeof data != 'undefined' && typeof data.remove_class != 'undefined') ? data.remove_class : 'initial-field-state';
			var set_value = (typeof data != 'undefined' && typeof data.set_value != 'undefined' ) ? data.set_value : '';
			if (target.className.match(new RegExp(remove_class))){
				target.removeClassName(remove_class);
				target.value = set_value;
				if ( typeof data != 'undefined' && data.set_type ) {
					try {
						target.setAttribute('type', data.set_type);
					} catch(e){
						// For IE
						var new_field = target.cloneNode(true);
						new_field.setAttribute('type', data.set_type);
						target.parentNode.replaceChild(new_field,target);
					}
				}
			}
		},
		// filter out from e.target.value any chars in data.disallow
		filter_chars : function(e,data) {
			if ( e.keyCode == 37 || e.keyCode == 39 ) return;
			var regex = data.disallow;
			var target = e.target;
			var newValue = target.value.replace(regex,'');
			if ( target.value != newValue ) target.value = newValue;
		},
		upload_image : function(e,data) {
			$('user-image-edit-iframe').src="/static/images/public/backgrounds/bluestripe.png";
			$('user-image-edit-iframe').src=data.iframe_src;
			this.upload_image_type = data.upload_image_type;
			BF_UI.showDialog('user-image-edit');
			event_handler.get_image_settings = function(){
				return data;
			}
		}
	};
	
	// For each element with appropriate behavior and for each event specified
	// in that element's actions attribute, remove the generic handler if it was there, and reassign it.
	this.generic_handler = function(e){event_handler._event_handler(e)}
	this.init = function() {
		var ACTION = 0;
		var HANDLER = 1;
		// For each element with appropriate behavior... 
		var elements = $$(event_handler.CLASS);
		$$(event_handler.CLASS).each( function(el) {
			var actions = el.getAttribute(event_handler.ACTION_ATTRIBUTE);
			if ( actions ) {
				var action_list = actions.split(' ');
				// ... and for each event specified in that element's actions attribute ...
				action_list.each( function(action){
					var pieces = action.split(':');
					// ... remove the generic handler if it was there, and reassign it
					el.stopObserving(pieces[ACTION], event_handler.generic_handler);
					el.observe(pieces[ACTION], event_handler.generic_handler);
				});
			}
		});
	}
	
	// Look for a behavior name for the event that just occurred. If you found one, look for
	// optional data for that behavior and call its definition, passing the event object and optional data.
	this._event_handler = function(e){
		e.stop();
		var ACTION = 0;
		var HANDLER = 1;
		var event_type = e.type;
		var target = e.target;
		var actions = target.getAttribute(event_handler.ACTION_ATTRIBUTE);
		var action_list = actions.split(' ');
		// Look for a behavior name for the event that just occurred 
		action_list.each( function(action){
			var pieces = action.split(':');
			if ( pieces[ACTION] == event_type ) target.handler = pieces[HANDLER];
		});
		// If you found a behavior name, look for optional data for that behavior
		// and call its definition, passing the event object and optional data
		if ( typeof target.handler != 'undefined' ) {
			var data = {};
			var json = target.getAttribute( event_handler.DATA_ATTRIBUTE );
			if ( json ) data = eval('('+json+')');
			data = typeof data[target.handler] != 'undefined' ? data[target.handler] : data;
			if ( typeof event_handler.HANDLERS[target.handler] != 'undefined' ) {
				var fn = event_handler.HANDLERS[target.handler];
				if (fn) fn( e, data );
			}
			else {
				var fn = eval(target.handler);
				data.event = e;
				fn(data);
			}
		}
	}
}

var event_handler = new bf_event_handler();
BuzzLoader.register( event_handler.init, 1 );
