var diva =
{
	/**
	 * Is the current browser MSIE? (Note that this works around Opera and
	 * KHTML lying about who they are in their User Agent, but otherwise is
	 * not intended to prevent someone from lying and saying they are IE.)
	 */
	isIE: false,
	
	/**
	 * Initialize the DIVA client-side.
	 * 
	 * Called automatically on load.
	 */
	init: function ()
	{
		var userAgent = navigator.userAgent;
		
		if (userAgent)
		{
			userAgent = userAgent.toLowerCase();
			
			if (userAgent.indexOf('msie') != -1 &&
				userAgent.indexOf('opera') == -1 &&
				userAgent.indexOf('konqueror') == -1 &&
				userAgent.indexOf('safari') == -1)
			{
				// userAgent contains MSIE, but does not contain Opera, Konqueror,
				// or Safari (all of which put MSIE in their User Agent header).
				diva.isIE = true;
			}
		}
		
		for (var key in window.diva)
		{
			if (typeof window.diva[key] == 'object' && typeof window.diva[key].init == 'function')
			{
				window.diva[key].init();
			}
		}
		
		diva.resizeRows();
		Event.observe(window, 'resize', diva.resizeRows);
				
		// Define draggable observer:
		var linkGuardObserver = {
			onStart: function (eventName, draggable, event)
			{
				var src = Event.element(event);
				
				if (src.onclick)
					src.linkGuard_onclick = src.onclick;
				else
					src.linkGuard_onclick = function () { return true; };
				
				src.onclick = function () { return false; };
			},
			
			onEnd: function (eventName, draggable, event)
			{
				var src = Event.element(event);
				
				setTimeout(
					function ()
					{
						if (src.linkGuard_onclick == null)
							src.onclick = function () { return true; };
						else
							src.onclick = src.linkGuard_onclick;
						
						src.linkGuard_onclick = null;
					},
					250
				);
			}
		};
		Draggables.addObserver(linkGuardObserver);
	},
	
	/**
	 * Create an action link.
	 * 
	 * @param string icon
	 * @param string title
	 * @param string explanation
	 */
	buildActionLink: function (icon, title, explanation)
	{
		var anchor = diva.buildElement('a',
			{
				href: 'javascript:void(null);',
				title: explanation,
				'class': 'option'
			}
		);
		
		var img = diva.buildElement('img',
			{
				src: icon,
				height: '16px',
				width: '16px',
				alt: '',
				'class': 'transparent leftimg'
			}
		);
		
		var anchorText = document.createTextNode(title);
		
		anchor.appendChild(diva.fixImage(img));
		anchor.appendChild(anchorText);
		return anchor;
	},
	
	/**
	 * Get an XML node.
	 * 
	 * @param Document xmlDocument
	 * @param String nodeName
	 * @param int index
	 */
	getXmlNode: function (container, nodeName, index)
	{
		if (index == undefined) index = 0;
		var node = container.getElementsByTagName(nodeName);
		
		if (node.length > index)
			return node[index];
		else
			return null;
	},
	
	/**
	 * Get the value of an XML node.
	 * 
	 * @param Node xmlNode
	 */
	getXmlNodeValue: function (xmlNode)
	{
		if (xmlNode.firstChild)
			return xmlNode.firstChild.nodeValue;
		else
			return null;
	},
	
	/**
	 * Invoke a server method.
	 * 
	 * @param String handler
	 * @param String method
	 * @param object urlargs
	 * @param object options
	 */
	invokeServerMethod: function (handler, method, urlargs, options)
	{
		var url = diva.baseURL + '/rest' + '&c=' + escape(handler) + '&m=' + escape(method);;
		
		for (var arg in urlargs)
		{
			url += '&' + escape(arg) + '=' + escape(urlargs[arg]);
		}
		
		var requestOptions =
		{
			asynchronous: true,
			method: 'get',
			onComplete: options.callback
		};
		
		if (options.form)
		{
			requestOptions.postBody = Form.serialize(options.form);
			requestOptions.method = 'post';
			requestOptions.contentType = 'application/x-www-form-urlencoded;charset=utf-8';
		}
		else if (options.postBody)
		{
			requestOptions.postBody = options.postBody;
			requestOptions.method = 'post';
		}
		else if (options.method)
		{
			requestOptions.method = options.method;
		}
		
		new Ajax.Request(url, requestOptions);
	},
	
	/**
	 * Build an HTML element.
	 * 
	 * @param String nodeName
	 * @param object attrs
	 */
	buildElement: function (nodeName, attrs)
	{
		var node = document.createElement(nodeName);
		
		for (var attrName in attrs)
			node.setAttribute(attrName, attrs[attrName]);
		
		return node;
	},
	
	maxBoxesPerLine: 3,
	
	/**
	 * Resize the rows of control boxes.
	 */
	resizeRows: function ()
	{
		var boxes = document.getElementsByClassName('control_box');
		var contentCol = document.getElementsByClassName('contentcol')[0];
		
		if (boxes.length == 0)
		{
			// No control boxes on this page.
			return;
		}
		
		var bodyWidth = contentCol.offsetWidth - 32;
		var boxWidth = boxes[0].offsetWidth + 12; // plus the margin
		var boxesPerLine = Math.floor(bodyWidth / boxWidth);
		
		if (boxesPerLine > diva.maxBoxesPerLine)
			boxesPerLine = diva.maxBoxesPerLine;
		
		for (var i = 0; i < boxes.length; i++)
		{
			if ((i % boxesPerLine) == 0)
				boxes[i].style.clear = 'left';
			else
				boxes[i].style.clear = 'none';
		}
	},
	
	/**
	 * Fix PNG transparency for images in IE.
	 */
	fixImage: function (elt)
	{
		if (diva.isIE && (/MSIE ((5.5)|[6789]|([1-9][0-9]+))/.test(navigator.userAgent) && navigator.platform == 'Win32'))
		{
			if (/.png$/.test(elt.src.toLowerCase()))
			{
				// IE will change the width and height we've set when we change
				// the image src property.
				
				var origSrc = elt.src;
				var w = elt.width;
				var h = elt.height;
				
				elt.src = 'images/blank.gif';
				elt.width = w;
				elt.height = h;
				
				elt.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + origSrc + "',sizingMethod='scale')";
			}
		}
		return elt;
	},
	
	/**
	 * Visually center an element over the page.
	 * 
	 * @param Node elt
	 */
	centerElement: function (elt)
	{
		var bodySize = diva.getBodyDimensions();
		var scrollOffset = diva.getScrollOffset();
		var eltSize = Element.getDimensions(elt);
		
		elt.style.position = 'absolute';
		elt.style.zIndex = 101;
		
		var left = 0;
		var top = 0;
		
		if (bodySize.width > eltSize.width)
			left = (bodySize.width - eltSize.width) / 2;
		if (bodySize.height > eltSize.height)
			top = (bodySize.height - eltSize.height) / 2 + scrollOffset;
		
		elt.style.left = left + 'px';
		elt.style.top = top + 'px';
	},
	
	/**
	 * Get the vertical scrolling offset of the page (e.g., the number of
	 * pixels hidden on the page by vertical scroll).
	 * 
	 * @return int
	 */
	getScrollOffset: function ()
	{
		var offset = 0;
		
		if (typeof window.pageYOffset != 'undefined')
			offset = window.pageYOffset;
		else if (document.documentElement && document.documentElement.scrollTop)
			offset = document.documentElement.scrollTop;
		else if (document.body)
			offset = document.body.scrollTop;
		else if (window.scrollY)
			offset = window.scrollY;
		
		return offset;
	},
	
	/**
	 * Get the dimensions of the page body.
	 * 
	 * @return array
	 */
	getBodyDimensions: function ()
	{
		var w = 0, h = 0;
		
		if (window.innerWidth)
		{
			// Firefox, other browsers.
			w = window.innerWidth;
			h = window.innerHeight;
		}
		else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight))
		{
			// IE in strict mode.
			w = document.documentElement.clientWidth;
			h = document.documentElement.clientHeight;
		}
		else if (document.body && (document.body.clientWidth || document.body.clientHeight))
		{
			// IE in quirks mode.
			w = document.body.clientWidth;
			h = document.body.clientHeight;
		}
		
		return { width: w, height: h };
	},
	
	/**
	 */
	getPageSize: function ()
	{
		var pageSize = { width: 0, height: 0 };

		if (diva.isIE)
		{
			var availableHeight = self.screen.availHeight - self.screenTop - 28;
			var availableWidth = self.screen.availWidth - 32;
			
			// Internet Explorer Method
			pageSize.height = Math.max(availableHeight, Math.max(document.body.scrollHeight, document.body.offsetHeight));
			pageSize.width = Math.max(availableWidth, Math.max(document.body.scrollWidth, document.body.offsetWidth));
		}
		else if (window.innerHeight && document.body.clientWidth)
		{
			// Firefox?
			pageSize.height = window.innerHeight + window.scrollMaxY;
			pageSize.width = document.body.clientWidth + window.scrollMaxX;
		}
		else
		{
			pageSize.height = document.body.scrollHeight;
			pageSize.width = document.body.scrollWidth;
		}
		
		return pageSize;
	},
	
	/**
	 * Flash a message to the user.
	 * 
	 * @param string message
	 */
	flash: function (message, duration)
	{
		var flashBox = $('flash');
		
		var innerDiv = diva.buildElement('div');
		var textNode = document.createTextNode(message);
		innerDiv.appendChild(textNode);
		
		if (flashBox)
		{
			flashBox.appendChild(innerDiv);
			return;
		}
		
		if (duration == undefined) duration = 5;
		
		flashBox = diva.buildElement('div', { id: 'flash', 'class': 'yourmom' });
		
		var pageBody = $('pagebody');
		var td = pageBody.getElementsByTagName('td')[0];
		flashBox.appendChild(innerDiv);
		td.insertBefore(flashBox, td.firstChild);
		
		new Effect.Fade(flashBox,
			{
				duration: duration,
				afterFinish: function (effect) { flashBox.parentNode.removeChild(flashBox); },
				queue: { scope: 'flash', position: 'end' }
			}
		);
	}
};

Event.observe(window, 'load', diva.init);


/**
 * Stupid utility function.
 * 
 * @param String str
 */
function trimSpaces (str)
{
	return str.replace('/^\s*(.*)\s*$/', '\1');
}
