/**
* Global JavaScript Definitions
*
* @author				Matt Gifford
* @copyright			2009 Timeshifting Interactive Limited
* @version			1.6
*/

var viewHandler = WebPage;


// Execute on load handler
dojo.addOnLoad(
	function()
		{
		if (viewHandler !== WebPage)
			{
			// Extend the base page class and create the xhtml object
			viewHandler.inheritsFrom( WebPage );
			xhtml = new viewHandler();
			}
		else
			{
			// Create a generic page xhtml object
			xhtml = new WebPage();
			}

		// Main page initialization
		xhtml.init();
		}
	);


/**
* Creates a new WebPage object with methods used by all pages, can be extended to add page specific methods.
*
* @author				Matt Gifford
* @copyright			2009 Timeshifting Interactive Limited
*/
function WebPage()
	{
	// Step 1. Define Properties

	var _instance = this;
	this.log = function(msg) { if (typeof(console) != 'undefined') { console.log(msg); } };
	this.animationReferences = {};

	// Scrolling regions (global variables to improve performance in IE)
	__scrollbars =
		{
		contentHeight: {},
		contentRange: {},
		grabberY: {},
		grabberSize: {},
		grabberRange: {},
		previousMouseY: 0,
		regionBeingDragged: '',
		eventHandlersAdded: false,
		locked: false
		}
	__isTrident = !!(window.attachEvent && !window.opera);
	__artboard = null;
	__grabber = null;


	// Step 2. Define Public Methods

	/**
	* Sets up the initial page state and event handlers
	*/
	this.init = function()
		{
		this.initAnchors();
		this.initInputButtons();
	
		// Set class as initialized
		this.initialized = true;
		}

	
	/**
	* Adds standard event handlers to process in-page links and offsite links
	*/
	this.initAnchors = function()
		{
		var links = document.getElementsByTagName('a');
		for (var x = 0; x < links.length; x++)
			{
			// 1. Make offsite links and pdfs open in a new tab/window
			if (/\b(offsite|pdf)\b/.exec(links[x].className))
				{
				links[x].onclick = function()
					{
					window.open(this.href,'_blank');
					return false;
					}
				}

			// 2. Set the active class on links to the current page
			if ((links[x].href == window.location.href || links[x].href == window.location.href + 'index.html') && links[x].href.indexOf('#') == -1)
				{
				if (links[x].className.indexOf('active') == -1)
					{
					links[x].className += ' active';
					}
				}
			}
		}


	/**
	* Adds rollover support to input[type=image] elements
	*/
	this.initInputButtons = function()
		{
		var rolloverCache = [];
		var inputs = dojo.query('input.hasRollover');
		for (var x = 0; x < inputs.length; x++)
			{
			// 1. Add event handlers to swap the images
			inputs[x].onmouseover = function()
				{
				this.src = this.src.replace(/\.(gif|jpg|png)/, '-over.$1');
				}
			inputs[x].onmouseout = function()
				{
				this.src = this.src.replace(/-over\.(gif|jpg|png)/, '.$1');
				}

			// 2. Pre-cache the rollover image
			var newImage = new Image();
			newImage.src = inputs[x].src.replace(/\.(gif|jpg|png)/i, '-over.$1');
			rolloverCache[rolloverCache.length] = newImage;
			}
		}


	/**
	* Shares the current page on the specified network
	*
	* @param		network		The network to share on (optional, displays full share dialog if omitted)
	*/
	this.share = function(network)
		{
		// Update the share params
		this.shareUpdate();

		// Select the correct url to throw
		switch (network)
			{
			case 'Facebook':
				var url = 'http://www.facebook.com/sharer.php?u=%url%&t=%title%';
				break;

			case 'Twitter':
				var url = 'http://twitter.com/home?status=Currently+reading+%url%';
				break;

			case 'Digg':
				var url = 'http://digg.com/submit?url=%url%&title=%title%';
				break;

			case 'MySpace':
				var url = 'http://www.myspace.com/Modules/PostTo/Pages/?u=%url%&t=%title%';
				break;

			default:
				// No network specified, so display share box
				xhtml.shareDialog();
				return;
			}

		// Confirm, add the content and throw
		if (confirm('Would you like to post this item to your ' + network + ' account?') == true)
			{
			url = url.replace('%url%', encodeURIComponent(document.getElementById('shareURL').getAttribute('content')));
			url = url.replace('%title%', encodeURIComponent(document.getElementById('shareTitle').getAttribute('content')));

			// Throw the url
			if (network == 'Facebook')
				{
				window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
				}
			else
				{
				window.open(url, '_blank');
				}
			return false;
			}
		}


	/**
	* Updates the share this meta tags from the anchor clicked on
	*
	* @param		obj		The anchor clicked on
	*/
	this.shareUpdate = function(obj)
		{
		if (arguments.length)
			{
			// Update with the supplied values
			if (obj.getAttribute('rel'))
				{
				document.getElementById('shareURL').setAttribute('content', obj.getAttribute('rel'));
				}
			else
				{
				document.getElementById('shareURL').setAttribute('content', window.location.href);
				}
			document.getElementById('shareTitle').setAttribute('content', obj.getAttribute('title'));
			}
		
		// Check if the url has the http:// prefix
		if (document.getElementById('shareURL').getAttribute('content').indexOf('http://') == -1)
			{
			document.getElementById('shareURL').setAttribute('content', 'http://www.endeavormgmt.com' + document.getElementById('shareURL').getAttribute('content'))
			}
		return false;
		}


	/**
	* Displays the share this dialog (social networking or email)
	*/
	this.shareDialog = function()
		{
		// Kill any existing share dialog
		if (!!document.getElementById('share') == true)
			{
			document.body.removeChild( document.getElementById('share') );
			}

		// Build the dialog html
		var html = [];
		html.push('<div id="shareBackground" onclick="document.body.removeChild(document.getElementById(\'share\'));"></div>');
		html.push('<div id="shareDialog">');
		html.push('<div id="shareDialogSocial" class="social">');
		html.push('<h3>Share via Social Networking</h3>');
		html.push('<ul class="list1">');
		html.push('<li><a onclick="xhtml.shareSocial(\'facebook\');" href="javascript:;" class="facebook">Facebook</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'bebo\');" href="javascript:;" class="bebo">Bebo</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'delicious\');" href="javascript:;" class="delicious">Delicious</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'digg\');" href="javascript:;" class="digg">Digg</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'google\');" href="javascript:;" class="google">Google Bookmarks</a></li>');
		html.push('</ul>');
		html.push('<ul class="list2">');
		html.push('<li><a onclick="xhtml.shareSocial(\'myspace\');" href="javascript:;" class="myspace">MySpace</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'technorati\');" href="javascript:;" class="technorati">Technorati</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'windowslive\');" href="javascript:;" class="windowslive">Windows Live</a></li>');
		html.push('<li><a onclick="xhtml.shareSocial(\'yahoomyweb\');" href="javascript:;" class="yahoomyweb">Yahoo! My Web</a></li>');
		html.push('</ul>');
		html.push('</div>');
		html.push('<div class="email">');
		html.push('<h3>Email to a Friend</h3>');
		html.push('<form id="formShareEmail" onsubmit="return false" method="post" action="#">');
		html.push('<fieldset>');
		html.push('<label class="hidden"><b>Missing Information</b><br/>Please complete the name &amp; email addresses fields and ensure the email addresses are valid.</label>');
		html.push('<label class="hidden"><b>Sending Message</b><br/>Please wait...</label>');
		html.push('</fieldset>');
		html.push('<fieldset>');
		html.push('<label>Friend\'s Email</label>');
		html.push('<input type="text" value="" name="toAddress" class="text"/>');
		html.push('<label>Your Name</label>');
		html.push('<input type="text" value="" name="fromName" class="text"/>');
		html.push('<label>Your Email</label>');
		html.push('<input type="text" value="" name="fromAddress" class="text"/>');
		html.push('<label>Message</label>');
		html.push('<textarea name="message"></textarea>');
		html.push('<input id="formShareEmailUrl" type="hidden" name="url" value=""/>');
		html.push('<input id="formShareEmailTitle" type="hidden" name="title" value=""/>');
		html.push('<input class="button" type="submit" value="Send Message" onclick="xhtml.shareEmail();"/>');
		html.push('</fieldset>');
		html.push('</form>');
		html.push('</div>');
		html.push('<br class="clear"/>');
		html.push('<a class="close" href="javascript:;" onclick="document.body.removeChild(document.getElementById(\'share\'));"></a>');
		html.push('</div>');

		// Create the dialog
		var share = document.createElement('div');
		share.id = 'share';
		share.innerHTML = html.join('\n');
		document.body.appendChild( share );
		return false;
		}


	/**
	* Shares the current page via social networking
	*
	* @param		network		The social media network
	*/
	this.shareSocial = function(network)
		{
		// Select the correct url to throw
		switch (network)
			{
			case 'bebo':
				var url = 'http://www.bebo.com/c/share?Url=%url%&t=%title%';
				break;

			case 'delicious':
				var url = 'http://del.icio.us/post?url=%url%&title=%title%';
				break;

			case 'digg':
				var url = 'http://digg.com/submit?url=%url%&title=%title%';
				break;

			case 'facebook':
				var url = 'http://www.facebook.com/sharer.php?u=%url%&t=%title%';
				break;

			case 'google':
				var url = 'http://www.google.com/bookmarks/mark?op=edit&bkmk=%url%&title=%title%';
				break;

			case 'myspace':
				var url = 'http://www.myspace.com/Modules/PostTo/Pages/?u=%url%&t=%title%';
				break;

			case 'stumbleupon':
				var url = 'http://www.stumbleupon.com/submit?url=%url%&title=%title%';
				break;

			case 'technorati':
				var url = 'http://www.technorati.com/faves?add=%url%';
				break;

			case 'windowslive':
				var url = 'https://favorites.live.com/quickadd.aspx?marklet=1&mkt=en-us&url=%url%&title=%title%&top=1';
				break;

			case 'yahoomyweb':
				var url = 'http://myweb2.search.yahoo.com/myresults/bookmarklet?u=%url%&t=%title%';
				break;

			default:
				document.body.removeChild(document.getElementById('share'));
				return;
			}

		// Configure the url
		url = url.replace('%url%', encodeURIComponent(document.getElementById('shareURL').getAttribute('content')));
		url = url.replace('%title%', encodeURIComponent(document.getElementById('shareTitle').getAttribute('content')));

		// Throw the url
		window.open(url, '_blank');

		// Close the share box
		document.body.removeChild(document.getElementById('share'));
		}


	/**
	* Shares the current page via email
	*/
	this.shareEmail = function()
		{
		// Check for blank input
		var obj = document.getElementById('formShareEmail');
		var inputs = obj.getElementsByTagName('input');
		for (var x = 0; x < 3; x++)
			{
			if (inputs[x].value == '')
				{
				obj.getElementsByTagName('fieldset')[0].className = '';
				obj.getElementsByTagName('label')[0].className = 'missing';
				return;
				}
			}

		// Check for valid email addresses
		var regex = /^[a-z0-9_+-.]+@[a-z0-9_-]*\.?[a-z0-9_-]*\.?[a-z0-9_-]*\.[a-z]+$/i;
		if (regex.test(inputs[0].value) == false || regex.test(inputs[2].value) == false)
			{
			obj.getElementsByTagName('fieldset')[0].className = '';
			obj.getElementsByTagName('label')[0].className = 'missing';
			return;
			}

		// Inject the page details
		document.getElementById('formShareEmailUrl').value = document.getElementById('shareURL').getAttribute('content');
		document.getElementById('formShareEmailTitle').value = document.getElementById('shareTitle').getAttribute('content');

		// Send the request
		dojo.xhrPost(
			{
			url: '/ajax/share.php',
			form: 'formShareEmail',
			handleAs: "text",
				load: function(data)
					{
					xhtml.shareEmailSent();
					},
				error: function(error)
					{
					}
				}
			);

		// Update the share box
		obj.getElementsByTagName('fieldset')[0].className = '';
		obj.getElementsByTagName('label')[0].className = 'hidden';
		obj.getElementsByTagName('label')[1].className = 'sending';
		}


	/**
	* Displays the message send message, and closes the share dialog
	*/
	this.shareEmailSent = function()
		{
		// Update the share box message
		document.getElementById('formShareEmail').getElementsByTagName('fieldset')[0].className = '';
		document.getElementById('formShareEmail').getElementsByTagName('label')[0].className = 'hidden';
		document.getElementById('formShareEmail').getElementsByTagName('label')[1].className = 'sending';
		document.getElementById('formShareEmail').getElementsByTagName('label')[1].innerHTML = '<b>Message Sent!</b>';
		document.getElementById('formShareEmail').getElementsByTagName('fieldset')[1].className = 'hidden';

		// Close the share box
		setTimeout("if (!!document.getElementById('share')==true){document.body.removeChild( document.getElementById('share'));}", 1750);
		}


	/**
	* Initializes the scrolling for a region
	*
	* @param		region		The region to add scrolling to
	*/
	this.scrollingRegionInit = function(region)
		{
		// Add global mouse tracking event handlers on first call
		if (__scrollbars.eventHandlersAdded == false)
			{
			if (this.isMobileSafari == false)
				{
				document.body.onmousemove = this._eventHandlerScrollBarGrabberMove;
				document.body.onmouseup = this._eventHandlerScrollBarGrabberUp;
				}
			__scrollbars.eventHandlersAdded = true;
			}

		// Calculate the scrolling region and grabber bar heights
		var scrollingRegionHeight = document.getElementById(region + 'Artboard').parentNode.offsetHeight;
		var grabberBarHeight = document.getElementById(region + 'Grabber').parentNode.offsetHeight;

		// Calculate content size and range
		__scrollbars.contentHeight[region] = parseInt(document.getElementById(region + 'Artboard').offsetHeight);
		__scrollbars.contentRange[region] = (__scrollbars.contentHeight[region] - scrollingRegionHeight) < 0 ? 0 : (__scrollbars.contentHeight[region] - scrollingRegionHeight);

		// Calculate the grabber size and range
		var pages = __scrollbars.contentHeight[region] / scrollingRegionHeight;
		pages = (pages < 1 ? 1 : pages);
		__scrollbars.grabberSize[region] = parseInt(grabberBarHeight / pages);
		__scrollbars.grabberRange[region] = grabberBarHeight - __scrollbars.grabberSize[region];

		// Add event handler to the grabber
		if (__isTrident)
			{
			document.getElementById(region + 'Grabber').onmousedown = this._eventHandlerScrollBarGrabberDown;
			document.getElementById(region + 'Artboard').onmousewheel = this._eventHandlerScrollBarGrabberWheel;
			document.getElementById(region + 'Grabber').onclick = function()
				{
				// Cancel the default event response
				window.event.cancelBubble = true;
				window.event.returnValue = false;
				}
			}
		else
			{
			if (this.isMobileSafari == false)
				{
				document.getElementById(region + 'Grabber').ondragstart  = function() { return false; }
				document.getElementById(region + 'Grabber').onmousedown = function() { return false; }
				document.getElementById(region + 'Grabber').onclick = this._eventHandlerCancelBubbleAndDefault;

				document.getElementById(region + 'Grabber').onmousedown = this._eventHandlerScrollBarGrabberDown;
				document.getElementById(region + 'Artboard').onmousewheel = this._eventHandlerScrollBarGrabberWheel;
				document.getElementById(region + 'Artboard').onDOMMouseScroll = this._eventHandlerScrollBarGrabberWheel;
				}
			}

		// Set the grabber size and position
		document.getElementById(region + 'Grabber').style.top = '0px';
		document.getElementById(region + 'Grabber').style.height = __scrollbars.grabberSize[region] + 'px';
		__scrollbars.previousMouseY = 0;

		// Set the current location
		document.getElementById(region + 'Artboard').style.top = '0px';

		// If there's not enough content to scroll, grey out the scrollbars
		if (__scrollbars.grabberRange[region] == 0)
			{
			document.getElementById(region + 'Grabber').parentNode.parentNode.className += ' scrollbarDisabled';
			}
		else
			{
			document.getElementById(region + 'Grabber').parentNode.parentNode.className = document.getElementById(region + 'Grabber').parentNode.parentNode.className.replace(/\s?scrollbarDisabled/g, '');
			}
		}


	/**
	* Updates the entry/grabber position while the grabber is being dragged
	*
	* @param		mouseY		The mouse position
	*/
	this.scrollingRegionDrag = function(mouseY)
		{
		// Calculate the new grabber position
		var newGrabberPosition = (((mouseY * 1) - (__scrollbars.previousMouseY * 1)) * 1) + (parseInt(__grabber.style.top) * 1);

		// Save the mouse location
		__scrollbars.previousMouseY = mouseY;

		// Range check grabber
		var grabberRange = __scrollbars.grabberRange[__scrollbars.regionBeingDragged];
		if (newGrabberPosition < 0)
			{
			newGrabberPosition = 0;
			}
		if (grabberRange < newGrabberPosition)
			{
			newGrabberPosition = grabberRange;
			}

		// Move the grabber
		__grabber.style.top = newGrabberPosition + 'px';

		// Move the content
		__artboard.style.top = (parseInt((newGrabberPosition / grabberRange) * __scrollbars.contentRange[__scrollbars.regionBeingDragged]) * -1) + 'px';
		}


	/**
	* Scrolls the scrolling region up
	*
	* @param		region		The region to scroll
	*/
	this.scrollingRegionUp = function(region)
		{
		try
			{
			// Calculate the new grabber position
			var newGrabberPosition = (parseInt(document.getElementById(region + 'Grabber').style.top) * 1) - 50;

			// Range check grabber
			if (newGrabberPosition < 0)
				{
				newGrabberPosition = 0;
				}
			if (__scrollbars.grabberRange[region] < newGrabberPosition)
				{
				newGrabberPosition = __scrollbars.grabberRange[region];
				}

			// Move the grabber
			document.getElementById(region + 'Grabber').style.top = newGrabberPosition + 'px';

			// Move the content
			document.getElementById(region + 'Artboard').style.top = (parseInt((newGrabberPosition / __scrollbars.grabberRange[region]) * __scrollbars.contentRange[region]) * -1) + 'px';
			}
		catch(e)
			{
			}
		}


	/**
	* Scrolls the scrolling region down
	*
	* @param		region		The region to scroll
	*/
	this.scrollingRegionDown = function(region)
		{
		try
			{
			// Calculate the new grabber position
			var newGrabberPosition = (parseInt(document.getElementById(region + 'Grabber').style.top) * 1) + 50;

			// Range check grabber
			if (newGrabberPosition < 0)
				{
				newGrabberPosition = 0;
				}
			if (__scrollbars.grabberRange[region] < newGrabberPosition)
				{
				newGrabberPosition = __scrollbars.grabberRange[region];
				}

			// Move the grabber
			document.getElementById(region + 'Grabber').style.top = newGrabberPosition + 'px';

			// Move the content
			document.getElementById(region + 'Artboard').style.top = (parseInt((newGrabberPosition / __scrollbars.grabberRange[region]) * __scrollbars.contentRange[region]) * -1) + 'px';
			}
		catch(e)
			{
			}
		}


	/**
	* Starts the drag of the grabber
	*
	* @param		event		The browser event object
	*/
	this._eventHandlerScrollBarGrabberDown = function(event)
		{
		// Build the function based on rendering engine
		if (__isTrident)
			{
			return function()
				{
				var event = window.event;

				if (__scrollbars.locked == true || __scrollbars.regionBeingDragged != '')
					{
					return;
					}

				// Get the mouse location and save region being dragged
				__scrollbars.previousMouseY = event.clientY;
				__scrollbars.startMouseY = event.clientY;
				__scrollbars.regionBeingDragged = this.id.replace('Grabber', '');

				// Disable text selection
				document.body.onselectstart = function() { return false; };

				// Save references for the current scrolling region
				__artboard = document.getElementById(__scrollbars.regionBeingDragged + 'Artboard');
				__grabber = document.getElementById(__scrollbars.regionBeingDragged + 'Grabber');
				}
			}
		else
			{
			// 2. Gecko, Webkit & Presto
			return function(event)
				{
				if (__scrollbars.locked == true || __scrollbars.regionBeingDragged != '')
					{
					return;
					}

				// Get the mouse location and save region being dragged
				__scrollbars.previousMouseY = event.pageY;
				__scrollbars.startMouseY = event.pageY;
				__scrollbars.regionBeingDragged = this.id.replace('Grabber', '');

				// Save references for the current scrolling region
				__artboard = document.getElementById(__scrollbars.regionBeingDragged + 'Artboard');
				__grabber = document.getElementById(__scrollbars.regionBeingDragged + 'Grabber');

				// Cancel the dragging in firefox 3
				return false;
				}
			}
		}();



	/**
	* Processes the drag of the grabber
	*
	* @param		event		The browser event object
	*/
	this._eventHandlerScrollBarGrabberMove = function(event)
		{
		// Build the function based on rendering engine
		if (__isTrident)
			{
			return function()
				{
				// Check if we're dragging a grabber, if so move the it
				if (__scrollbars.regionBeingDragged != '' && __scrollbars.grabberRange[__scrollbars.regionBeingDragged])
					{
					xhtml.scrollingRegionDrag(window.event.clientY);
					return;
					}
				}
			}
		else
			{
			// 2. Gecko, Webkit & Presto
			return function(event)
				{
				// Check if we're dragging a grabber, if so move the it
				if (__scrollbars.regionBeingDragged != '' && __scrollbars.grabberRange[__scrollbars.regionBeingDragged])
					{
					xhtml.scrollingRegionDrag(event.pageY);
					return;
					}
				}
			}
		}();


	/**
	* Processes the scroll of the mouse wheel
	*
	* @param		event		The browser event object
	*/
	this._eventHandlerScrollBarGrabberWheel = function(event)
		{
		// Get the event object if necessary
		!!event ? event : window.event

		var delta = 0;

		// Find the delta
		if (event.wheelDelta)
			{
			delta = event.wheelDelta/120;
			if (window.opera)
				{
				delta *= -1;
				}
			}
		else if (event.detail)
			{
			delta = -event.detail/3;
			}

		// Scroll the region
		if (delta != 0)
			{
			if (delta < 0)
				{
				xhtml.scrollingRegionDown(this.id.replace('Artboard', ''));
				}
			else
				{
				xhtml.scrollingRegionUp(this.id.replace('Artboard', ''));
				}
			}

		// Cancel the default event response
		xhtml._eventHandlerCancelBubbleAndDefault(event);
		}


	/**
	* End the drag of the grabber
	*/
	this._eventHandlerScrollBarGrabberUp = function()
		{
		// Build the function based on rendering engine
		if (__isTrident)
			{
			return function(event)
				{
				if (__scrollbars.regionBeingDragged == '')
					{
					return;
					}

				// Set the artboard as not being dragged
				__scrollbars.regionBeingDragged = '';

				// Clear references for the current scrolling region
				__artboard = null;
				__grabber = null;

				// Enable text selection
				document.body.onselectstart = null;

				// Cancel the default event response
				window.event.cancelBubble = true;
				window.event.returnValue = false;
				}
			}
		else
			{
			// 2. Gecko, Webkit & Presto
			return function(event)
				{
				if (__scrollbars.regionBeingDragged == '')
					{
					return;
					}

				// Set the artboard as not being dragged
				__scrollbars.regionBeingDragged = '';

				// Clear references for the current scrolling region
				__artboard = null;
				__grabber = null;

				// Cancel the default event response
				event.stopPropagation();
				event.preventDefault();
				}
			}
		}();


	/**
	* Cancels the propagation of the event up the dom tree and the default event action
	*
	* @param		event		The browser event object
	*/
	this._eventHandlerCancelBubbleAndDefault = function(event)
		{
		if(__isTrident)
			{
			// Cancel the default event response
			window.event.cancelBubble = true;
			window.event.returnValue = false;
			}
		else
			{
			// Cancel the default event response
			event.stopPropagation();
			event.preventDefault();
			}
		}
	}



/**
* Inherts a prototype from the specified class, updates the constructor reference
*
* @param		parent		The parent class or object
* @return		The inherted object
*/
Function.prototype.inheritsFrom = function( baseClass )
	{
	// Inherit the base class
	this.prototype = new baseClass;
	this.prototype.constructor = this;

	// Add access to the base's methods
	this.prototype.base = {};
	for (method in this.prototype)
		{
		// hasOwnProperty test is a workaround for "for..in" bug, see: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
		if (typeof this.prototype[method] === 'function' && this.prototype.hasOwnProperty(method) && this.prototype[method] !== this.prototype.constructor)
			{
			this.prototype.base[method] = this.prototype[method];
			}
		}
	return this;
	}