/*
 * hyCMS
 * Copyright(C)2008 by Friedrich Gräter
 * Published under the terms of the Lesser GNU General Public License v2
 *
 * WidgetKit backend: Event handling
 *
 * Please Note: This module has to be clean from all dependencies to predicateJS!
 *
 *				Also this module requires "widget-kit.css" to be
 *				embedded to the parent site for styling the widgets.
 *
 */

/*
 * wk_declareEvents(view, ...)
 *
 * Declares all events of the given "view" object. The
 * name of the event handlers are given as arbitrary string
 * arguments.
 *
 * Later on, events can be handled, by pushing a handler to
 * the list by: view.events[NAME].push(HANDLER). Whereas
 * HANDLER is a function with the following singature:
 *
 * HANDLER(eventName, view, domEvent)
 *
 * Whereas "eventName" is the name of the WK-Event, "view"
 * is a reference to the view object and "domEvent" is the
 * DOM-Event that triggered the wk-Event (might be null).
 *
 * If the view already had events declared, the existing
 * events will be extended.
 */
function wk_declareEvents(view)
{
	if (view.events == null)
		view.events = {};

	var events = view.events;

	for (var idx = 1; idx < arguments.length; idx ++)
	{
		view.events[arguments[idx]] = [];
	}
}

/*
 * wk_registerDOMEvent(view, event, handler)
 *
 * Registers a handler for a DOM-Event to the given view object.
 *
 */
function wk_registerDOMEvent(view, event, handler)
{
	if (view.addEventListener)
		view.addEventListener(event, handler, true);
	else
		view.attachEvent("on"+event, handler);
}

/*
 * wk_skipEvent(event)
 *
 * Tries to skip the further handling of the given event.
 * This function will return a value, that has to be passed
 * to the caller of the event handler.
 *
 */
function wk_skipEvent(event)
{
	if (event.preventDefault) {
		event.preventDefault();
		event.stopPropagation()
	}
	 else {
	 	event.cancelBubble = true;
	}
	
	return false;
}

/*
 * wk_triggerEvent(view, eventName[, event = null])
 *
 * Sends the given event "eventName" of the given view
 * and passes a DOM-Event descriptor to it.
 *
 */
function wk_triggerEvent(view, eventName, event)
{
	if ((view.events == null) || (view.events[eventName] == null))
		return;

	for (var idx = 0; idx < view.events[eventName].length; idx ++) {
		view.events[eventName][idx](eventName, view, event)
	}
}

/*
 * wk_eventRedirectionFromChild(child, view, source, dest[, preHandler[, postHandler]])
 *
 * Redirects the DOM-Event "source" to the given WK-Event "dest" on
 * the given view. The event itself will be triggered from the child
 * DOM element "child".
 *
 * "preHandler" is a function that is called before the event will
 * be redirected. If this function returns "false", the handling will
 * be prevented. 
 *
 * "postHandler" is a function that is called after the event was
 * redirected.
 *
 * Both function will receive the event descriptor.
 *
 */
function wk_eventRedirectionFromChild(view, child, source, dest, preHandler, postHandler)
{
	function __handler(event)
	{
		if (preHandler != null)
			if (preHandler(event) == false) return;
	
		wk_triggerEvent(view, dest, event);
		
		if (postHandler != null)
			postHandler(event);
	}

	wk_registerDOMEvent(child, source, __handler);
}

/*
 * wk_eventRedirection(view, source, dest[, preHandler[, postHandler]])
 *
 * Redirects the DOM-Event "source" to the given WK-Event "dest" on
 * the given view.
 *
 * "preHandler" is a function that is called before the event will
 * be redirected. If this function returns "false", the handling will
 * be prevented. 
 *
 * "postHandler" is a function that is called after the event was
 * redirected.
 *
 */
function wk_eventRedirection(view, source, dest, preHandler, postHandler)
{
	wk_eventRedirectionFromChild(view, view, source, dest, preHandler, postHandler)
}

/*
 * wk_scroll_item(element, axis, direction)
 *
 * Scrolls the given element into "direction". Axis can be "top"
 * or "left".
 *
 */
function wk_scroll_item(element, axis, direction)
{
	var realAxis = (axis == "left") ? "scrollLeft" : "scrollTop";
	element[realAxis] += direction * 10;
	
}

/*
 * wk_begin_scroll_item(element, axis, direction)
 *
 * Scrolls the given element into "direction". Axis can be "top"
 * or "left".
 *
 */
function  wk_begin_scroll_item(element, axis, direction)
{
	var signum = (direction < 0) ? -1 : 1;

	// Accelerating scroll
	function __scroll() {
		if (Math.abs(direction) < 3)
			element.__scrollSpeed += 0.01 * signum;
	
		wk_scroll_item(element, axis, element.__scrollSpeed); 
	}

	direction /= 10;
	
	element.__scrollAxis = axis;
	element.__scrollSpeed = direction;

	if (element.__scrollTimer != null)
		clearInterval(element.__scrollTimer);

	element.__scrollTimer = setInterval(__scroll, 5);
}

/*
 * wk_stop_scroll_item(element, axis, direction)
 *
 * Scrolls the given element into "direction". Axis can be "top"
 * or "left".
 *
 */
function wk_stop_scroll_item(element)
{
	var signum = (element.__scrollSpeed < 0) ? -1 : 1;
	
	// Slow down scrolling before stop
	function __scroll() {
		element.__scrollSpeed -= 0.1 * signum;

		var newsig = (element.__scrollSpeed < 0) ? -1 : 1;
		
		if (newsig != signum) {
			clearInterval(element.__scrollTimer);
			return;
		}
	
		wk_scroll_item(element, element.__scrollAxis, element.__scrollSpeed); 
	}

	if (element.__scrollTimer != null)
		clearInterval(element.__scrollTimer);
		
	element.__scrollTimer = setInterval(__scroll, 5);		
}


