/*
Event handlers used in conjunction with YAHOO.util.Event 
These functions make use of YAHOO.util.Event and may depend on features of YUI event handling
*/

// This function is used in an event delegation system where an event is attached to an element
// containing the event target, which is specified by id, classname, or tagname. When the event fires,  
// use getTarget() to determine which contained element was the target of the event and whether it has 
// the specified id/classname/tagnameto trigger the event handler. If so, call the event handler on  
// that element, passing it any arguments that have been defined.
var callEventHandler = function(event, args) { 
	var el = YAHOO.util.Event.getTarget(event);

	// Check the event criteria against the target element's properties
	if ( (args.elementId != undefined && el.id != args.elementId) ||
		 (args.elementClassName != undefined && !YAHOO.util.Dom.hasClass(el, args.elementClassName)) ||
		 (args.elementTagName != undefined && el.tagName != args.elementTagName.toUpperCase()) ||
		 (args.elementId == undefined && args.elementClassName == undefined && args.elementTagName == undefined) )
		 	 { return; }
	
	// Call the wrapper function to unpack the arguments 
	// We don't want to pass the function to itself, so get rid of fcn from the args object
	// Not: delete args.fcn, since that modifies the args object and it won't work the next time in
	// Not: newArgs = args, since that creates a reference to the same object
	// But: is this really worth the overhead of creating a new object? Easier to just let the fcn
	// get passed to itself? It's just a reference that gets passed, anyway.
	// var newArgs = cloneObject(args);		
	// delete newArgs.fcn;
	// args.fcn.wrapper(el, newArgs);  
	args.fcn.wrapper(el, args);
	// Cancel any default action for this event (such as following a link)
	// RY 4/4/07 I'm pretty sure we would always want this, so it should be here rather than inside
	// individual event handlers
	YAHOO.util.Event.stopEvent(event); 

};

// Open a link in a new window
// RY This should be in a different file, since it's independent of the event handling mechanism
var openNewWindow = function(el, windowName, focus) {	
	var newwindow = window.open(el.href, windowName);	 
	// default behavior is to bring the new window forward
	// (doesn't work for tabs - they are controlled by user preferences)
	focus = focus || true;
	if (focus) {
		newwindow.focus(); 
	}
};	

// Unpack the args and call the function that does the actual work
// Note that we can't do the unpacking with a generic function that iterates through the object properties, 
// because iteration with for/in doesn't yield a predictable order that can be relied on to order the
// arguments when calling the inner function. It would be nice to have ColdFusion's named argument
// feature here!
openNewWindow.wrapper = function(el, args) { 
	openNewWindow(el, args.elementClassName, args.focus);
};

/*
Toggles between displaying the text and the input field. When the text is unhidden,
the textCallback function is called. When the input becomes unhidden, inputCallback is called.
*/
var toggleClickableTextInput = function(event, args) {
	var text = args["text"],
		input = args["input"],
		textCallback = args["textCallback"],
		inputCallback = args["inputCallback"],
		extraArgs = args["args"];
	
	if( YAHOO.util.Dom.hasClass(input, "hidden") ) {
		if( inputCallback(event, text, input, extraArgs) ) {
			YAHOO.util.Dom.removeClass(input, "hidden");
			YAHOO.util.Dom.addClass(text, "hidden");
			
			input.focus();
		}
	} else {
		if( textCallback(event, text, input, extraArgs) ) {
			YAHOO.util.Dom.removeClass(text, "hidden");
			YAHOO.util.Dom.addClass(input, "hidden");
		}
	}
}

/*
Used to create an editable text string. When the user clicks on the element with id textId,
the textId element will hide and the inputId will unhide. When textId becomes unhidden,
textCallback is called with arguments (textId element, inputId element, and extraErgs). 
When inputId becomes unhidden, inputCallback is called with arguments
(textId element, inputId element, and extraErgs).
*/
var setClickableTextInput = function(text, input, textCallback, inputCallback, extraArgs, extraClickableFields) {
	if( YAHOO.lang.isString(text) ) {
		text = document.getElementById(text);
	}
	
	if( YAHOO.lang.isString(input) ) {
		input = document.getElementById(input);
	}
	
	var args = {
		text: text,
		input: input,
		textCallback: textCallback,
		inputCallback: inputCallback,
		args: extraArgs
	}
	
	// when user clicks on text, toggle to input field
	YAHOO.util.Event.addListener(text, "click", toggleClickableTextInput, args);
	
	if( extraClickableFields ) {
		for( var i = 0; i < extraClickableFields.length; ++i ) {
			YAHOO.util.Event.addListener(extraClickableFields[i], "click", toggleClickableTextInput, args);
		}
	}
	
	// when user is done editing field, toggle to text
	YAHOO.util.Event.addListener(input, "blur", toggleClickableTextInput, args);
	YAHOO.util.Event.addListener(input, "enter", toggleClickableTextInput, args);
}