/**
 * Resize Events
 * @version 0.5
 * Changelog:
 *   * 0.5 Added API bind() function to make it easier to add listeners.
 * 
 * There is no standard event for when a user resizes the text in their browser.
 * There is also no consistency between browser implementations of the window resize event
 * (some trigger as the window is resized, some only trigger as the user drops the resize handle).
 * This extension polls to detect these changes, and reports them immediately as custom events
 * ('x-text-resize' and 'x-window-resize') that other code can listen for and react to accordingly.
 * Resize Events also send an 'x-initial-size' event on load.
 * 
 * The custom events triggered are sent with emPixels, textHeight and windowWidth variables.
 * emPixels is a unit that estimates much space you have to work with but is resolution, text size
 * and zoom level independant. Use this value to base layout decisions on, and the layout will
 * always fit.
 * 
 * This extension is based on the 'text resize' events work of Lawrence Carvalho <http://www.alistapart.com/articles/fontresizing/>.
 * 
 * @author Lawrence Carvalho <carvalho@uk.yahoo-inc.com>
 * @author Andrew Ramsden <http://irama.org/>
 * @license GNU GENERAL PUBLIC LICENSE (GPL) <http://www.gnu.org/licenses/gpl.html>
 * @see http://irama.org/web/dhtml/resize-events/
 * @requires jQuery (tested with 1.3.1) <http://jquery.com/>
 */
var ResizeEvents = {
	baseTextHeight      : 0,
	currentTextHeight   : 0,
	baseWindowWidth     : 0,
	currentWindowWidth  : 0,
	initialised         : false,
	intervalReference   : null,
	controlElement      : null,
	eventElement        : $(document),
	conf                : {
		textResizeEvent    : 'x-text-resize',
		windowResizeEvent  : 'x-window-resize',
		initialResizeEvent : 'x-initial-sizes',
		pollFrequency      : 500, // 200
		controlElementId   : 'text-resize'
	}
};
 // start closure (protects variables from global scope)
(function($){
	
	// on DOMReady
		$(function(){
			// initialise if it hasn't happened already
				if (ResizeEvents.initialised !== true) {
					ResizeEvents.initialise();
				}
		});
	
	ResizeEvents.initialise = function () {
		
		if (ResizeEvents.initialised === true) {
			return; // already initialised
		}
		
		// create text resize control element, and push it offscreen
			// assign shortcut to element
			ResizeEvents.controlElement = $('<span id="'+ResizeEvents.conf.controlElementId+'">&nbsp;</span>')
				.css({
					position      : 'absolute',
					left          : '-9999px',
					'font-size'   : '100%',
					'font-family' : 'Courier New, mono',
					padding       : '0',
					margin        : '0'
				})
				.get(0)
			;
			$('body').append(ResizeEvents.controlElement);
		
			
		// init base measures
			ResizeEvents.baseTextHeight = ResizeEvents.currentTextHeight = getTextHeight();
			ResizeEvents.baseWindowWidth = ResizeEvents.currentWindowWidth = getWindowWidth();
		
		// start polling
			startResizePolling();
		
		ResizeEvents.initialised = true;
		
		// Establish the element events will be triggered on
			//ResizeEvents.eventElement = $('html');
		
		// trigger onload
			windowWidthNow = getWindowWidth();
			textHeightNow = getTextHeight();
			emPixelNow = windowWidthNow/textHeightNow;
			//ResizeEvents.eventElement.trigger(ResizeEvents.conf.initialResizeEvent, [emPixelNow, textHeightNow, windowWidthNow]);
			ResizeEvents.triggerEvent(ResizeEvents.conf.initialResizeEvent, [emPixelNow, textHeightNow, windowWidthNow]);
	};
	
	/**
	 * A simple way to add a listener for resize events.
	 * 
	 * @param String events A space delimited list of events that should trigger this handler.
	 * @param function handler The handler function to be called when an event occurs.
	 */
	ResizeEvents.bind = function (events, handler) {
		ResizeEvents.eventElement.bind(
			events,
			handler
		);
	}
	
	/**
	 * An internal function used to trigger the custom events.
	 */
	ResizeEvents.triggerEvent = function (eventType, args) {
		ResizeEvents.eventElement.trigger(eventType, args);
	}
	
	/**
	 * This function is called a number of times each second to check if text size or window size has changed
	 */
	ResizeEventsPoll = function () {
		
		// get latest values
			windowWidthNow = getWindowWidth();
			textHeightNow = getTextHeight();
			emPixelNow = windowWidthNow/textHeightNow;
			
		// test for text size change
			if (ResizeEvents.currentTextHeight != textHeightNow) {
				// Send custom event (with new text size)
					//ResizeEvents.eventElement.trigger(ResizeEvents.conf.textResizeEvent, [emPixelNow, textHeightNow, windowWidthNow]);
					ResizeEvents.triggerEvent(ResizeEvents.conf.textResizeEvent, [emPixelNow, textHeightNow, windowWidthNow]);
				// update current height
					ResizeEvents.currentTextHeight = textHeightNow;
			}
			
		// test for window width change
			if (ResizeEvents.currentWindowWidth != windowWidthNow) {
				// Send custom event (with new text size)
					//ResizeEvents.eventElement.trigger(ResizeEvents.conf.windowResizeEvent, [emPixelNow, textHeightNow, windowWidthNow]);
					ResizeEvents.triggerEvent(ResizeEvents.conf.windowResizeEvent, [emPixelNow, textHeightNow, windowWidthNow]);
				// update current height
					ResizeEvents.currentWindowWidth = windowWidthNow;
			}
	};
	
	getTextHeight = function () {
		return ResizeEvents.controlElement.offsetHeight;
	};
	
	getWindowWidth = function () {
		if (document.documentElement && document.documentElement.clientWidth) {
			// IE6 in standards mode (more reliable for IE6)
				return document.documentElement.clientWidth;
		} else if (typeof document.body.clientWidth != 'undefined') {
			return document.body.clientWidth;
		} else {
			return window.innerWidth;
		};
	};
	
	startResizePolling = function () {
		//window.bind('resize', ResizeEventsPoll);
		
		if (ResizeEvents.intervalReference == null) {
			ResizeEvents.intervalReference = window.setInterval('ResizeEventsPoll()', ResizeEvents.conf.pollFrequency);
		}
	};
	
	stopResizePolling = function () {
		//window.unbind('resize', ResizeEventsPoll);
		
		if (ResizeEvents.intervalReference != null) {
			window.clearInterval(ResizeEvents.intervalReference);
			ResizeEvents.intervalReference = null;
		}
	};
	
})(jQuery); /* end closure */