if ( typeof NPL_UI != 'undefined' )
{
	if ( typeof _NPL_Dbg != 'undefined' ) { _NPL_Dbg('NPLib: "UI" already defined.'); }
}
else
{
	NPL.UI = function ()
	{
		return {
		
			PhotoGallery: function ( pDescriptor )
			{
				var _myuid = NPL.NewUID();
				var _descriptor = NPL.ParseDescriptor(pDescriptor);
				var _element;
				var _imageHeight;
				var _captions = false;
				
				function _initMetaFunction ()
				{
					return function ()
					{
						if ( def(_descriptor.width) )
						{
							_descriptor.width = parseInt(_descriptor.width);
						}
						if ( def(_descriptor.height) )
						{
							_descriptor.height = parseInt(_descriptor.height);
						}
						if ( def(_descriptor.element) )
						{
							//	Default to a crossfade effect.
							if ( undef(_descriptor.fade) ) { _descriptor.fade = 'crossfade'; }
							_element = NPL.Select(_descriptor.element);
							//	Images will be absolutely positioned, so the parent element needs a relative positioning.
							_element.style('position', 'relative').width(_descriptor.width).height(_descriptor.height);
							_imageHeight = parseInt(_descriptor.height) - 22;
							//	Set up the other nested elements.
							_element.innerHtml('<div id="' + _myuid + '_imagearea"></div>');
							//	Captions?
							if ( def(_descriptor.captions) )
							{
								_captions = true;
								_element.innerHtml(_element.innerHtml() + '<div id="' + _myuid + '_photo_caption" class="gallery_photo_caption"><br><br></div>');
								var xCaption = NPL.Select('#' + _myuid + '_photo_caption');
								xCaption.style('text-align', 'left').style('line-height', '1em').style('margin-bottom', '10px').style('margin-top', '5px').style('color', '#1a1a3a').height(xCaption.height());
								_imageHeight -= xCaption.height() + 15;
							}
							//	Thumbnails?
							if ( def(_descriptor.thumbnails) )
							{
								_element.innerHtml(_element.innerHtml() + '<div id="' + _myuid + '_thumbnails"><ul></ul></div>');
								//	Set up the positioning for the thumbnails.
								NPL.Select(_descriptor.element + ' #' + _myuid + '_thumbnails').style('position', 'absolute').style('bottom', '0').style('float', 'left').style('overflow', 'hidden').style('margin-top', '20px').width(_descriptor.width).IMS('autoscroll');
								NPL.Select(_descriptor.element + ' #' + _myuid + '_thumbnails ul').style('list-style-type', 'none').style('white-space', 'nowrap').style('display', 'inline-block');
								//	Attempt to start loading thumbnails.
								_getThumbnails();
							}
							NPL.Select('#' + _myuid + '_imagearea').height(_imageHeight);
						}
					}
				};
				
				function _getThumbnails ( pURL )
				{
					if ( def(pURL) )
					{
						_descriptor.url = pURL;
						NPL.Channel.Open(pURL + '/images', _thumbsMetaFunction());
					}
					else if ( def(_descriptor.url) )
					{
						NPL.Channel.Open(_descriptor.url + '/images', _thumbsMetaFunction());
					}
				};
				
				function _thumbsMetaFunction ()
				{
					//	This is one of the few times where it's totally appropriate to use a closure.
					return function (pChannel)
					{
						//	First stuff the response text into the element so that we can DOM-traverse it.
						NPL.Select(_descriptor.element + ' #' + _myuid + '_thumbnails ul').innerHtml(pChannel.xhr.responseText);
						//	Now iterate over each item in the list.
						var xThumbnailList = NPL.Select(_descriptor.element + ' #' + _myuid + '_thumbnails ul li');
						var xThumbnail;
						while ( xThumbnail = xThumbnailList.element() )
						{
							xThumbnail = NPL.Select(xThumbnail);
							xThumbnail.innerHtml('<a href="' + _descriptor.url + '/' + xThumbnail.innerHtml() + '"><img src="' + _descriptor.url + '/' + xThumbnail.innerHtml() + '?100x35" border="0"></a>');
							xThumbnail.style('display', 'inline').style('float', 'none').style('margin-left', '5px').style('margin-right', '5px').style('border-width', '2px').style('border-style', 'solid').style('border-color', 'transparent');
						}
						NPL.Select(_descriptor.element + ' #' + _myuid + '_thumbnails ul li a').onclick(_imageLoadMetaFunction()).style('border', '0').style('text-decoration', 'none');
						_imageHeight = _imageHeight - NPL.Select('#' + _myuid + '_thumbnails').height() - 20;
						NPL.Select('#' + _myuid + '_imagearea').height(_imageHeight);
						//	The click action has to be set up as a task because Internet Explorer 7 will totally vomit otherwise.
						var xClickTask = NPL.Tasks.NewTask(function(){if (def(this._go)){this._element.click();return 0;}else{this._go=true;return 10}});
						xClickTask._element = NPL.Select(NPL.Select(_descriptor.element + ' #' + _myuid + '_thumbnails ul li a').element());
						xClickTask.Start();
					}
				};
				
				function _imageLoadMetaFunction ()
				{
					//	Another case for a closure. :-/
					return function ()
					{
						if ( _descriptor.fade == 'fade' )
						{
							NPL.Select('#' + _myuid + '_imagearea img').Fade('begin: 1; end: 0', function(pElement){pElement.remove()});
						}
						var xImage = NPL.Image(this + '?' + parseInt(_descriptor.width) + 'x' + parseInt(_imageHeight));
						xImage.style('position', 'absolute').onload(_imageDisplayMetaFunction());
						NPL.Channel.Open(this + '?notes', function(pChannel){NPL.Select('#' + _myuid + '_photo_caption').innerHtml(pChannel.xhr.responseText)});
						return false;
					}
				};

				function _imageDisplayMetaFunction ()
				{
					return function ( pImage )
					{
						var xOldImageID = NPL.NewUID();
						var xOldImage = NPL.Select('#' + _myuid + '_imagearea img').id(xOldImageID).style('z-index', '1');
						var xSideMargins = parseInt((_descriptor.width - pImage.width()) / 2);
						pImage.opacity(0).classname('full').style('position', 'absolute').style('margin-left', xSideMargins + 'px').style('z-index', '5');
						NPL.Select('#' + _myuid + '_imagearea').element().appendChild(pImage.element());
						if ( _descriptor.fade == 'crossfade' )
						{
							pImage.Fade('begin: 0; end: 1; rate: 1.6', new Function('','NPL.Select("#' + xOldImageID + '").remove()'));
						}
						else if ( _descriptor.fade == 'fade' )
						{
							pImage.Fade('begin: 0; end: 1');
						}
					}
				};
				
				NPL.Select('body').onload(_initMetaFunction());	//	This is an IE hack; it chokes if the page isn't loaded before the photo gallery.
				
			},

			ImageBox: function (pDescriptor)
			{
				var xDescriptor = NPL.ParseDescriptor(pDescriptor);
				var _divuid = NPL.NewUID();
				var _element;
				var _caption;
				var _imagewidth;
				var _imageheight;
				var _image;
				var _imageurl;
				
				var _loadCaption = function (pChannel)
				{
					if ( pChannel.xhr.responseText != '' )
					{
						_caption = NPL.Select('#' + _divuid + ' p');
						_caption.innerHtml(pChannel.xhr.responseText);
						_element.height(_element.height() + _caption.height() + 7);
					}
				};
				
				var _loadImage = function ()
				{
					_element.width(_image.width() + 14);
					_element.height(_image.height() + 14);
					NPL.Channel.Open(_imageurl + '?notes', _loadCaption);
				};

				if ( def(xDescriptor.element) && def(xDescriptor.image) )
				{
					_element = NPL.Select(xDescriptor.element).innerHtml('<div id="' + _divuid + '" style="background-color: white; border: 1px solid gray"></div>');
					_element = NPL.Select('#' + _divuid);
					if ( def(xDescriptor.width) )
					{
						_imagewidth = parseInt(xDescriptor.width);
						_element.width(_imagewidth + 14);
					}
					if ( def(xDescriptor.height) )
					{
						_imageheight = parseInt(xDescriptor.height);
						_element.height(_imageheight + 14);
					}
					_imageurl = xDescriptor.image;
					_element.innerHtml('<img src="' + _imageurl + '?' + _imagewidth + 'x' + _imageheight + '" style="margin: 7px"><p style="font-size: .8em; margin: 7px; margin-top: 0; padding: 0; text-indent: 0; text-align: left; line-height: 1.1em; color: black"></p>');
					_image = NPL.Select('#' + _divuid + ' img');
					_image.onload(_loadImage);
				};

				return {};
			},
			
			ModalDialog: function ( pDialogText )
			{
				var _dismiss = function ()
				{
					$('#modalDialog').Fade('begin: 1; end: 0; rate: 1.2', function(){
						document.body.removeChild($('#modalDialog').element());
					});
					$('#modalScreen').Fade('begin: .98; end: 0; rate: 1.2', function(){
						document.body.removeChild($('#modalScreen').element());
					});
				}
				//	Bootstrap a div#modalScreen element to block out the background.
				var xModalBackground = document.createElement('div');
				xModalBackground.setAttribute('id', 'modalScreen');
				document.body.appendChild(xModalBackground);
				//	Now select the element through NPL.
				xModalBackground = NPL.Select('div#modalScreen');
				xModalBackground.style('position', 'absolute')
					.top(0)
					.left(0)
					.height(NPL.Window.Height())
					.width(NPL.Window.Width())
					.style('z-index', '9000')
					.style('background-color', '#00183e')
					.style('margin', '0')
					.style('padding', '0')
					.opacity(0)
					.Fade('begin: 0; end: .98; rate: 1.4')
					.onclick(function(){
						_dismiss();
					});
				//	Create another element...
				var xModalDialog = document.createElement('div');
				xModalDialog.setAttribute('id', 'modalDialog');
				document.body.appendChild(xModalDialog);
				xModalDialog = NPL.Select('div#modalDialog');
				xModalDialog.style('position', 'absolute')
					.top(NPL.Window.Height() / 2 - 100)
					.left(NPL.Window.Width() / 2 - 200)
					.height(200)
					.width(400)
					.style('z-index', '9001')
					.style('margin', '0')
					.style('padding', '0')
					.opacity(0)
					.Fade('begin: 0; end: 1; rate: 1.2');
				var xModalElement = document.createElement('div');
				xModalElement.setAttribute('id', 'modalDialogFrame');
				xModalDialog.element().appendChild(xModalElement);
				xModalElement = NPL.Select('div#modalDialogFrame');
				xModalElement.style('position', 'relative')
					.height(xModalDialog.height())
					.width(xModalDialog.width())
					.style('margin', '0')
					.style('padding', '0')
//					.style('border', '1px solid #035899')
					.style('background-color', 'white')
					.style('font-size', '14px')
					.opacity(.3);
				xModalElement = document.createElement('div');
				xModalElement.setAttribute('id', 'modalDialogContent');
				xModalDialog.element().appendChild(xModalElement);
				xModalElement = NPL.Select('div#modalDialogContent');
				xModalElement.style('position', 'absolute')
					.top(9)
					.left(10)
					.height(xModalDialog.height() - 60)
					.width(xModalDialog.width() - 60)
					.style('margin', '0')
					.style('padding', '20px')
					.style('border', '1px solid #198dce')
					.style('background-color', 'white')
					.style('font-family', 'Tahoma, Verdana, sans-serif')
					.style('font-size', '14px')
					.style('line-height', '20px')
					.innerHtml(pDialogText);
				xModalElement = document.createElement('div');
				xModalElement.setAttribute('id', 'modalDialogBtnstab');
				xModalDialog.element().appendChild(xModalElement);
				xModalElement = NPL.Select('div#modalDialogBtnstab');
				xModalElement.style('position', 'absolute')
					.top(xModalDialog.height())
					.height(30)
					.width(parseInt(xModalDialog.width() / 2.5))
					.opacity(.3)
					.style('background-color', 'white')
					.style('right', '0');
				xModalElement = document.createElement('div');
				xModalElement.setAttribute('id', 'modalDialogBtns');
				xModalDialog.element().appendChild(xModalElement);
				xModalElement = NPL.Select('div#modalDialogBtns');
				xModalElement.style('position', 'absolute')
					.top(xModalDialog.height())
					.height(30)
					.width(parseInt(xModalDialog.width() / 2.5))
					.style('color', 'white')
					.style('text-shadow', '0px 0px 4px white')
					.style('font-size', '18px')
					.style('font-family', 'Verdana, sans-serif')
					.style('right', '0')
					.innerHtml('<a href="#" id="modalDialogBtnOK">OK</a><a href="#" id="modalDialogBtnCancel">Cancel</a>');
				xModalElement.select('a').style("{\
					text-decoration: none;						\
					display: inline-block;						\
					margin-left: 18px;							\
					margin-right: 18px;							\
					color: white;								\
				}");
				$('#modalDialogBtnCancel').onclick(function(){
					this.style.outline = 0;
					_dismiss();
					return false;
				});
				//	Accessing server... message.
				//		-> "Sorry, access denied." (white letters, blue background, OK button)
				//		-> Continue to control panel screen
			}
		}
	}()
}
