function ImageQueue(imageData, imageIdx)
{
	this.imageData = imageData;
	this.loadedImages = new Array(imageData.length);
	this.imageIdx = imageIdx;
	this.lastIdx = -1;
}

ImageQueue.prototype.init = function()
{
	this.load();
	
}
//this just sets the imageIndex variable
ImageQueue.prototype.nextIndex = function()
{
	if(!((this.imageIdx != this.lastIdx)&&(this.get(this.imageIdx) === null)))
	{
		var indexBefore = -1, indexAfter = -1;

		for(var i=0,n=this.loadedImages.length;i<n;i++)
		{
			if((this.lastIdx > i)&&(!this.loadedImages[i]))
			{
				indexBefore = i;
			}
			else if(indexAfter > -1)
			{
				break;
			}
			else if((this.lastIdx < i)&&(!this.loadedImages[i]))
			{
				indexAfter = i;
			}
		}
		if(indexAfter > -1)
		{
			 this.imageIdx = indexAfter; 
		}
		else
		{ 
			this.imageIdx = indexBefore;
		}
	}		
	
}
ImageQueue.prototype.get = function(imageIdx)
{
	var image = this.loadedImages[imageIdx];
	if(image){
		if(image.complete)
		{
			return image;
		}
		else return null;	
	}
	else
	{
		this.imageIdx = imageIdx;
	}
	return null;	
}
ImageQueue.prototype.load = function()
{
	var image = document.createElement("img");
	var data = this.imageData[this.imageIdx];
	
	this.lastIdx = this.imageIdx;
	
	this.loadedImages[this.lastIdx] = image;

	//when an image loads -  it calls nextIndex and then load
	var me = this;
	var handleLoad = function(e)
	{
		me.nextIndex();

		if(me.imageIdx != -1)
		{
			me.load();
		}
	
		if (this.addEventListener)
			this.removeEventListener( "load", handleLoad, false );
		else if (this.attachEvent)
	    	this.detachEvent("onload", handleLoad);
	};
	
	if (image.addEventListener)
		image.addEventListener( "load", handleLoad, false );
	else if (image.attachEvent)
    	image.attachEvent("onload", handleLoad);
    	
    image.height = data.height;
    image.width = data.width;
    image.src = data.filename;			
	this.lastIdx = this.imageIdx;
}
function ImageSeries()
{
	this.imageWidth =0;
	this.imageHeight=0;
	this.images=null;
	
}

ImageSeries.prototype.init = function()
{
	ISUtils.addSeries(this);
}

var ISUtils = 
{
	moar:null,
	series:[],
	addSeries:function(series)
	{
		for(var i=0;i<this.series.length;i++)
		{
			if(series === this.series[i]) return;	
		}
		this.series.push(series);
	},
	getAllSeries:function()
	{
		return this.series;
	},
	doMoar:function(click)
	{
		div = document.createElement("div");
		div.className = "ssMoar";
		var link = document.createElement("a");
		link.appendChild(document.createTextNode(this.moar));
		EventUtils.attachClick(link,click);		
	    div.appendChild(link);
	    return div;
	},
	getShortText:function(imageData,numLines)
	{
		var text;
		
		if(!(text = imageData.textShort))
		{
			text = StringUtils.shortenText(imageData.data,38,numLines);
			if(text.length < imageData.data.length)
				text += " ...";
			
			text = text.replace(new RegExp( "\\r\\n", "g" ),"<br />");
			
			imageData.textShort = text;	
		}
		
		return text;
	
	}

}

Slideshow.prototype = new ImageSeries;

function Slideshow(images)
{
	this.currentImageIndex=-1;
	this.slides=["slideshowImg","slideshowImgSpare"];
	this.slideDivInUse=0;
	this.FrameRate=50;
	
	this.forward = true;
	
	this.imageAvailable=false;
	this.swapTimeout=4000;
	//delay for "data" images
	this.loadDelay=500;
	this.lastSwapTime=0;
	this.fadeInProgress=false;
	this.fadeFinish=2000;
	this.images = images;
	this.containerHeight = 250;
	this.data = null;
	this.textDivBgColour = null;
	this.url = null;
	this.largeImage = false;
	this.loadIdx = -1;
	this.viewIdx = -1;

	this.isDisplay = false;
	this.thread = null;
	this.imageQueue = null;
	this.indexSet = false;
}

Slideshow.prototype.init = function()
{
	ImageSeries.prototype.init.call(this);

	if(!this.images[0])
		return;
	this.currentImageIndex = (Math.ceil(Math.random()*this.images.length))-2;
	if(this.images[0].data)
	{
		if(this.images[0].dataObjects.length > 0)
			this.largeImage = true;
		var container = document.getElementById("slideshowContainer");
		var height = this.containerHeight+"px";
		container.style.height=height;
		for(var i=0;i<this.slides.length;i++)
		{
			document.getElementById(this.slides[i]).style.height = height;
		}
		//this.swapTimeout=3000;
		this.fadeFinish=500;
		
	}
	this.imageQueue = new ImageQueue(this.images,this.currentImageIndex+1);
	this.imageQueue.init();
	this.loadImage();
	me = this;
	this.thread = window.setInterval(function() { me.manage(); },this.FrameRate);

}


Slideshow.prototype.manage = function()
{
	if(!this.imageAvailable)
	{
		this.loadImage();
	}
	else
	{
		
		if(this.fadeInProgress)
		{
			this.doFade();
		}
		else if((((this.getTime() - this.lastSwapTime) >= this.swapTimeout))||(this.lastSwapTime === 0))
			this.swapImage(); 
	}
}

Slideshow.prototype.display = function()
{
	if(this.isDisplay) return;
	
	document.getElementById("slideshowContainer").style.visibility = "visible";
	this.isDisplay = true;
	
}

Slideshow.prototype.loadImage=function()
{
	var tempImg;
	this.imageAvailable = false;

	var nextImage = 0;
	if(this.forward)
	{
		nextImage = this.currentImageIndex+1;
	}
	else
	{
		nextImage = this.loadIdx-1;

		if(nextImage < 0) {nextImage = this.images.length -1}

	}
	if((tmpImg = this.imageQueue.get(nextImage)) === null) return;
	
	if((this.images[0].data)&&(this.lastSwapTime === 0))
		this.lastSwapTime = this.getTime()+(this.loadDelay-this.swapTimeout);
		
	this.imageAvailable = true;
	this.currentImageIndex = nextImage;
	this.scratch = tmpImg;
	me = this;	
	
	this.loadIdx = this.currentImageIndex;
	
	if(this.largeImage)
	{
		this.largeImageObj = this.images[this.currentImageIndex].dataObjects[0];
	}

	if(this.images[this.currentImageIndex].data)
	{		
		this.data = ISUtils.getShortText(this.images[this.currentImageIndex],this.textNumLines);
	}
		
	if(this.currentImageIndex >= (this.images.length-1))
		this.currentImageIndex = -1;

	this.forward = true;

}

Slideshow.prototype.showImage = function(viewIdx)
{
	if(!this.imageWindow)
	{
		this.imageWindow = new ImageWindow(this);
	}
	this.imageWindow.show(viewIdx);
}
	
Slideshow.prototype.swapImage=function()
{
	this.lastSwapTime = this.getTime(); 
	var div;
	
	div = document.getElementById(this.slides[this.slideDivInUse]);
	
	if(div.lastChild.nodeName != "IMG")
	{
		var image = document.createElement("img");
		
		if((this.url !== null)||(this.largeImage))
		{
			var click;
			var me = this;
					
			if(this.largeImage)
			{
				click = function(evt)
				{
					me.showImage(me.viewIdx);
				}	
			}
			else			
			{
				var url = this.url;

				click = function(evt)
				{
					window.location = url;
				}
			}
			image.style.cursor = "pointer";

			EventUtils.attachClick(image,click);		
		}
		image.height = this.scratch.height;
		image.width = this.scratch.width;
		image.src = this.scratch.src;
		
		div.appendChild(image);
		ImageUtils.centre(image,this.imageWidth,this.imageHeight);		
		
	}
	else
	{
		if(this.images.length == 1){ window.clearInterval(this.thread); return;}

		div.lastChild.height = this.scratch.height;
		div.lastChild.width = this.scratch.width;
		div.lastChild.src = this.scratch.src;
		ImageUtils.centre(div.lastChild,this.imageWidth,this.imageHeight);		

	}

	this.viewIdx = this.loadIdx;

	if(this.data !== null)
		div.firstChild.innerHTML = this.data;

	this.imageAvailable = false;
	div.style.zIndex = 2;
	div.style.visibility = "visible";
	this.lastSwapTime = this.getTime(); 
	this.doFade();
}

	
Slideshow.prototype.doFade=function()
{
	var opacity = Math.ceil(((this.getTime()-this.lastSwapTime)/this.fadeFinish)*100);
	if(opacity >= 100){
		opacity = 100;
		//hide back layer
		var div = document.getElementById(this.slides[this.slideDivInUse^1]);
		div.style.visibility = "hidden";
		div.style.zIndex = 2;
		//push top layer to the back
		div = document.getElementById(this.slides[this.slideDivInUse]);
		div.style.zIndex = 1;
		//make invisible layer available
		this.slideDivInUse = (this.slideDivInUse)^1;
		this.fadeInProgress = false;
	}else
		this.fadeInProgress = true;
	if(!div)
		var div = document.getElementById(this.slides[this.slideDivInUse]);

	div.style.filter="alpha(opacity="+opacity+")";
	if(opacity == 100) opacity = 1;
	else opacity = opacity/100;
	div.style.opacity = opacity;
}
	
Slideshow.prototype.getTime=function()
{
		var now = new Date();
		return now.valueOf();
}

SlideshowTB.prototype = new Slideshow;

SlideshowTB.prototype.constructor = Slideshow;

function SlideshowTB(images)
{
	this.swapEvents = [];
	this.fadeEvents = [];
	this.toolbar = null
	this.toolbarVisible = false;
	Slideshow.apply(this,arguments);
	this.swapTimeout = 5000;
	this.containerHeight = 260;
	this.textNumLines = 6;
	this.isNav = null;
}


SlideshowTB.prototype.init = function()
{
	Slideshow.prototype.init.call(this);
	this.toolbar = document.createElement("div");
	this.toolbar.className = "toolbar";	
	this.toolbar.style.visibility = "hidden";
	var div;
	var me = this;

	if(this.largeImage)
	{

		var click = function(e){me.showImage(me.viewIdx);};
		this.toolbar.appendChild(ISUtils.doMoar(click));
	}
	if(this.images.length > 1)
	{

		this.isNav = new ISNav(this,
								function(e){
									me.registerNavClick(e);
								});
		this.isNav.show(this.toolbar);
	
	
		this.fadeEvents.push(function(){
			me.unsetNav();
			});			

		this.swapEvents.push(function(){
			me.isNav.updatePicNum();
			me.isNav.updateLabel();
			});

	}
		
	div = document.getElementById("slideshowContainer");
	div.appendChild(this.toolbar);
}


//this should register a click event and,change the next image value, and tell the thing to reload
SlideshowTB.prototype.registerNavClick = function(e)
{
	var active = this.isNav.navActive;
	if(active != null) return;

	if(e.target)
		active  = e.target;
	else if(e.srcElement)	
		active  = e.srcElement;
	if(active.className == "back")
	{
		this.forward = false;
	}
	this.lastSwapTime = 1;
	this.isNav.navActive = active;
	this.isNav.setNavImage(true);	

}

SlideshowTB.prototype.unsetNav = function()
{
	if(this.isNav.navActive == null) return;

	this.isNav.setNavImage(false);	
	this.isNav.navActive = null;
}

SlideshowTB.prototype.swapImage = function()
{
	Slideshow.prototype.swapImage.call(this);
	for(var i=0;i<this.swapEvents.length;i++)
	{
		this.swapEvents[i]();
	}
}
SlideshowTB.prototype.getISIndex = function()
{
	return this.isNav.picNum;
}

SlideshowTB.prototype.doFade = function()
{
	Slideshow.prototype.doFade.call(this);

	if(!this.toolbarVisible&&!this.fadeInProgress)
	{
		this.toolbar.style.visibility = "visible";
		this.toolbarVisible = true;	
	}
	if(!this.fadeInProgress)
	{
		for(var i=0,n=this.fadeEvents.length;i<n;i++)
		{
			this.fadeEvents[i]();
		}
	}
}
//if this is to work, it should be in a container with classname "toolbar"
function ISNav(imageSeries,navClickEvent)
{
	this.prefix = "ss";
	this.picNum = 0;
	this.images = imageSeries.images;
	this.navClickEvent = navClickEvent;
	this.navActive = null;
	this.labelDiv = null;
}
ISNav.prototype.navImgDir = null;
ISNav.prototype.imgCountText = null;

ISNav.prototype.setNavImage = function(active)
{
	if(!this.navActive) return;
	var imgName = this.navActive.className;
	imgName = imgName.substring(0,1).toUpperCase()+imgName.substring(1);
	
	this.navActive.style.backgroundImage = "url('"+this.navImgDir+this.prefix+imgName+"_"+((active)?"a":"n")+".gif')";	

}
ISNav.prototype.show = function(container)
{

	var me = this;
	var attachClick = function(div)
	{
		EventUtils.attachClick(div,me.navClickEvent);		
	}

	var nav = document.createElement("div");
	nav.className = "nav";

	div = document.createElement("div");
	div.className = "back";
	nav.appendChild(div);
	attachClick(div);

	var labelDiv = document.createElement("div");
	labelDiv.className = "imgLabel";

	labelDiv.appendChild(document.createTextNode(" "));

	this.labelDiv = labelDiv;
	nav.appendChild(labelDiv);

	div = document.createElement("div");
	div.className = "next";
	nav.appendChild(div);
	attachClick(div);
	
	var image = new Image();
	image.src = this.navImgDir+this.prefix+"Next_a.gif";

	image = new Image();
	image.src = this.navImgDir+this.prefix+"Back_a.gif";
	container.appendChild(nav);		

}

ISNav.prototype.updatePicNum = function()
{
	var imgs = this.images.length;
	
	if((this.navActive)&&(this.navActive.className == "back"))
	{
		this.picNum--;
		if(this.picNum == 0) this.picNum = imgs;
	}
	else
		this.picNum++;
	
	if(this.picNum > imgs)
	{
		this.picNum = (this.picNum % imgs);
	}

}
ISNav.prototype.updateLabel = function()
{
	//opera hack
	this.labelDiv.innerHTML = StringUtils.labelReplace(this.imgCountText,[this.picNum,this.images.length]);	
}


function ImageWindow(imageSeries)
{
	this.imageWindow = null;
	this.isNav = null;
	this.rootDivId = "SSLargeImg";
	this.imageSeries = imageSeries;
	this.newWin = true;
}

ImageWindow.prototype.imageHeight = 0;
ImageWindow.prototype.imageWidth = 0;
ImageWindow.prototype.imgLoadingText = "set loading text!";

ImageWindow.prototype.show = function(viewIdx,internal)
{
	var data = this.imageSeries.images[viewIdx];
	var text;
	var image;
	var imageFrame;
	var me = this;
	
	var newWin = false;
	
	var picNum = -1;
	
	if(this.imageSeries.images.length > 1)
	{
		if(!internal)
			picNum = this.imageSeries.getISIndex();
		else	
			picNum = this.isNav.picNum;
	}
	
	var imageLoad = function(e)
	{
		loadMsg.style.display = "none";
		image.style.display = "inline";
		if(picNum != -1)
		{
			me.isNav.setNavImage(false);
			me.isNav.activeNav = null;
			me.isNav.updateLabel();	
			if((me.newWin)
			&& (viewIdx == me.isNav.images.length-1))
			{
				me.isNav.picNum = 0;
			}						
		}
	}	

	if(!this.imageWindow)
		this.imageWindow = document.getElementById(this.rootDivId);
	
	if(!this.imageWindow)
	{
		this.imageWindow = document.createElement("div");
		
		newWin = true;
		
		this.imageWindow.setAttribute("id",this.rootDivId);
		var contentContainer = document.getElementById("content_container");

		this.imageWindow.style.top = DOMTools.getOffsetTop(contentContainer)+"px";
		
		var left = DOMTools.getOffsetLeft(contentContainer);
		if((document.all)&&(!window.addEventListener))
		{
			left ++;
			
		}

		left += 2;
		
		this.imageWindow.style.left = left+"px";

		var titleBar = document.createElement("div");
		titleBar.className = "header";
		
		var closeButt = document.createElement("div");		
		closeButt.className = "closeButton";
		
		var hide = function(e)
		{
			me.imageWindow.style.display = "none";
			WindowRegistry.notifyClose(me.imageWindow);
		}
		WindowRegistry.register(hide,me.imageWindow);
		
		EventUtils.attachClick(closeButt,hide);		

		titleBar.appendChild(closeButt);
		
		this.imageWindow.appendChild(titleBar);

		var content = document.createElement("div");
		content.className = "content";
		this.imageWindow.appendChild(content);
		
		var imageContainer = document.createElement("div");
		imageContainer.setAttribute("id","SSLargeImgContainer");
		imageContainer.style.height = this.imageHeight+"px";
		imageContainer.style.width = this.imageWidth+"px";
	
		imageFrame = document.createElement("div");
	
		image = document.createElement("img");
		if (image.addEventListener)
		{
			image.addEventListener( "load", imageLoad, false );
		}
		else if (image.attachEvent)
		{
    		image.attachEvent("onload", imageLoad);
		}	
		image.style.display = "none";

		imageContainer.appendChild(imageFrame);
		imageFrame.appendChild(image);

		var loadMsg = document.createElement("div");
		loadMsg.setAttribute("id","SSLoadMsg");
		loadMsg.className = "loadMsg";
		loadMsg.style.height = "26px";
		loadMsg.style.width = "180px";
		loadMsg.appendChild(document.createTextNode(this.imgLoadingText));

		image.setAttribute("src", data.dataObjects[0].filename);
		image.setAttribute("alt", data.dataObjects[0].alt);
		image.setAttribute("height",data.dataObjects[0].height);
		image.setAttribute("width",data.dataObjects[0].width);
		
		imageFrame.style.height = data.dataObjects[0].height+"px";
		imageFrame.style.width = data.dataObjects[0].width+"px";
		
		imageFrame.appendChild(loadMsg);
		DOMTools.centre(loadMsg);		
		
		content.appendChild(imageContainer);
			
		text = document.createElement("div");
		text.setAttribute("id","SSLargeImgText");
		if(picNum != -1)
		{
			var toolbar = document.createElement("div");
			toolbar.className = "toolbar";
			var me = this;
			var furthur = function(e)
			{
				
				if(e.target)
					active  = e.target;
				else if(e.srcElement)	
					active  = e.srcElement;
				me.isNav.navActive = active;
				me.isNav.setNavImage(true);
				me.isNav.updatePicNum();
				var newNum = me.isNav.picNum-1;
				me.show(newNum,true);
				
			}
			
			this.isNav = new ISNav(this.imageSeries,
									function(e){
										furthur(e);
									});


		
			this.isNav.picNum = picNum;

			this.isNav.show(toolbar);

			this.imageWindow.appendChild(toolbar);
			/*			
			if(picNum == this.isNav.images.length-1)
			{
				this.isNav.picNum = this.isNav.images.length;
			}*/
		}

		this.imageWindow.appendChild(text);
		document.body.appendChild(this.imageWindow);
	
	}
	else
	{
		text = document.getElementById("SSLargeImgText");
		var frame = document.getElementById("SSLargeImgContainer").firstChild;
		
		image = frame.firstChild;

		if((navigator.userAgent.toString().indexOf("Safari")>-1)||(navigator.appName == "Opera"))
		{
			image = document.createElement("img");
			frame.removeChild(frame.firstChild);
			frame.insertBefore(image,frame.firstChild);
			image.addEventListener("load",imageLoad,false);
	
		}
		
		imageFrame = image.parentNode;

		imageFrame.style.height = data.dataObjects[0].height+"px";
		imageFrame.style.width = data.dataObjects[0].width+"px";

		image.style.display = "none";
	
		var loadMsg = frame.lastChild;
		DOMTools.centre(loadMsg);		

		loadMsg.style.display = "inline";

		image.setAttribute("src", data.dataObjects[0].filename);
		image.setAttribute("alt", data.dataObjects[0].alt);
		image.setAttribute("height",data.dataObjects[0].height);
		image.setAttribute("width",data.dataObjects[0].width);

		this.newWin = false;

		if(picNum != -1)
		{
			this.isNav.picNum = picNum;
		}
		
	}
	

	text.innerHTML = data.data.replace(new RegExp( "\\r\\n", "g" ),"<br />");
	WindowRegistry.notifyOpen(this.imageWindow);
	this.imageWindow.style.display = "inline";				
	
	DOMTools.centre(imageFrame);		
	imageFrame.style.paddingTop = imageFrame.style.marginTop;
	imageFrame.style.marginTop = "0px";	
}

ISBasic.prototype = new ImageSeries;

function ISBasic(images)
{
	this.images = images;
	this.imagePrefix = "ISBidx_";
	this.textNumLines = 7;
	this.containerId = null;
}


ISBasic.prototype.init = function()
{
	ImageSeries.prototype.init.call(this);
	
	if(this.images.length == 0) return;
	
	var largeImage = (!this.images[0].dataObjects)||(this.images[0].dataObjects.length > 0);

        var me = this;
	if(largeImage)
	{

		var click = function(e){
			var div;
			if(e.target)
				div  = e.target;
			else if(e.srcElement)	
				div  = e.srcElement;
			
			while((div.className != "container")&&(div.className !="container_last"))
				div = div.parentNode;

			me.viewIdx = Number(div.id.toString().replace(me.imagePrefix,""));
			me.showImage();
			};
		this.viewIdx = -1;
	}
	var parentContainer = document.getElementById(this.containerId);
	for(var i = 0,n=this.images.length;i<n;i++)
	{
		var container = document.createElement("div");
		container.setAttribute("id",this.imagePrefix+i);
		container.className = (i+1 == this.images.length)?"container_last":"container";
		
		var div = document.createElement("div");
		div.className = "img";
		div.style.height = this.imageHeight+"px";		
		div.style.width = this.imageWidth+"px";		
		
		var image = ImageUtils.newImage(this.images[i]);

		div.appendChild(image);

        if (image.attachEvent)
             image.attachEvent("onload", function(e){ImageUtils.centre(image,this.imageWidth,this.imageHeight)});
         else
             ImageUtils.centre(image,this.imageWidth,this.imageHeight);
	
		if(largeImage)
		{
			div.style.cursor = "pointer";
			EventUtils.attachClick(div,click);
		}
		
		container.appendChild(div);
		
		if(this.images[i].data)
		{
			div = document.createElement("div");
			div.className = "text";
			div.innerHTML = ISUtils.getShortText(this.images[i],this.textNumLines);
			container.appendChild(div);
			if(largeImage)
			{
				div = document.createElement("div");
				div.className = "toolbar";
				div.appendChild(ISUtils.doMoar(click));
				container.appendChild(div);
			}
		}
	
		parentContainer.appendChild(container);
		 			
	}
	
}

ISBasic.prototype.getISIndex = function()
{
	return this.viewIdx + 1;
}

ISBasic.prototype.showImage = function()
{
	/*
	 var fromTop = 0;
	 if( typeof( window.pageYOffset ) == 'number' ) {
	   fromTop = window.pageYOffset;
	 } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
	   fromTop = document.body.scrollTop;
	 } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
	   //IE6 standards compliant mode
	   fromTop = document.documentElement.scrollTop;
	 }
	alert(fromTop);*/ 
	if(!this.imageWindow)
	{
		this.imageWindow = new ImageWindow(this);
	}
	this.imageWindow.show(this.viewIdx);
}	