var SlideShow = Class.create();
SlideShow.prototype = {
    
		/*------- GLOBAL VARIABLES --------------------------------*/
	APP_VERSION: '1.0 rc',
	APP_NAME: 'Ajax SlideShow',
	APP_COMMENT: 'Ajax SlideShow - Flickr Compatible',
	APP_WEBSITE: 'http://slideshow.zzup.net',
	APP_AUTHOR: 'ManuX',
	APP_AUTHOR_EMAIL: 'ajax@zzup.net',
	
	        /*------- CONFIGURATION -----------------------------------*/
	imagesDir: 'images/',
	btns: [
		['moveBtn','images/move.gif','move'],
		['zoomInBtn','images/zoomin.gif','zoomin'],
		['zoomOutBtn','images/zoomout.gif','zoomout'],
		['zoomFit','images/zoomfit.gif','zoomfit']
		], //Format: id, image_src, command
			
	        /*------- STARTUP ELEMENTS --------------------------------*/
	dummyImage: null,
	loadedImages: 0,
	sources: [],
	titles: [],
	images: [],
	currentZoom: 100,
	directions: ['left','right','up','down','leftup','leftdown','rightup','rightdown','default'],
	startUpWidth: 500,
	startUpHeight: 150,
	startUpBackground: 'black',
	startUpTextColor: 'white',
	        /*------- METHODS ----------------------------------------*/
	
	initialize: function(dst) {
	    
		this.id = dst;
		this.d = $(this.id);
		if (!this.d) {
			alert("Wrong destination ID!");
			return false;
		}
		//SlideShows[SlideShows.length] = this;
		Event.observe(window, 'unload', this.cleanUp.bind(this), false);
		this.titles = new Array();
		this.startUpSetup(dst);
		this.setStatus('SlideShow is loading configuration...');		
		var options = Object.extend({
			statusTexts: [
				'<nobr>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed iaculis vestibulum nisl. Nulla a orci non odio blandit convallis. In aliquet risus ac turpis. Vivamus mauris nulla, pretium ac, viverra nec, volutpat nec, sem. Quisque et magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam non nibh sed augue congue malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas rhoncus vestibulum ligula. Suspendisse in lectus in sem tristique scelerisque. Proin pellentesque ipsum ut quam. Vivamus rutrum, urna ut ultricies luctus, ligula augue pharetra arcu, quis lacinia lectus sem quis leo. Fusce ac purus. Pellentesque in quam eu tortor varius viverra. Sed neque ipsum, molestie quis, molestie non, dignissim vel, libero. Donec at est eu nisi lacinia mattis. Phasellus pretium gravida nisl. Phasellus blandit elit eget velit. Etiam eu mi. Suspendisse egestas lacinia mauris. Aliquam erat volutpat. Ut tincidunt odio ut velit. Curabitur sed diam. Aliquam consequat varius sapien. Nunc in eros id est vulputate imperdiet. Suspendisse venenatis. Aenean urna. Sed justo. Morbi accumsan mattis pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sit amet nisl ac sapien vulputate blandit. Duis purus sem, hendrerit nec, tempor quis, cursus eu, neque. Nunc nec orci nec lacus commodo mattis. Nullam eget purus. Etiam semper ullamcorper est. Vivamus ut augue. Mauris ligula lorem, placerat varius, tincidunt nec, auctor in, risus. Nam est. Aenean sit amet est. Donec lectus. Duis egestas, odio sed tristique facilisis, pede nunc posuere ipsum, eget auctor justo nibh ac justo. Ut non nibh vel tellus gravida fringilla. Aliquam pretium, tellus quis mollis vulputate, lorem neque dignissim ante, quis egestas elit sapien vitae nunc. Morbi nibh felis, hendrerit et, cursus id, consectetuer vel, nisl. Pellentesque elementum venenatis augue. Cras aliquam lacus gravida ipsum. Integer dapibus dignissim lectus. Etiam faucibus felis id justo. Sed tempus sodales ipsum. Etiam rutrum, nisl vel viverra lobortis, dolor libero condimentum dolor, sed venenatis orci dolor sed augue. Curabitur adipiscing sollicitudin mauris. Fusce vel arcu eget leo aliquam euismod. Suspendisse orci. Proin aliquet, quam ut condimentum accumsan, elit lectus varius erat, sit amet commodo est ante sed ante. Nullam nisi. Praesent odio. Morbi non mauris. In ac neque. Aenean sit amet enim vitae nisi fermentum bibendum.</nobr>',
				'<font face="Arial" size="2" color="white">Please wait, loading picture...</font>',
				'<font face="Arial" size="2" color="white">Ready</font>',
				'<font face="Arial" size="2" color="white">Loading better picture...</font>',
				'<font face="Arial" size="2" color="white">Better image loaded</font>',
				'<font face="Arial" size="2" color="red">Sorry, the requested image was not found on server</font>',
				],
			autoLoad: false, // false/true -> AUTOLOAD THE FIRST IMAGE
			singleClickCommands: true, //false/true -> IF TRUE, CLICKING ON ZOOM IN/OUT/FIT DOES THE COMMAND
			zoomOutScale: 70,
			zoomInScale: 130,
			inDirection: 'random', // 'up','down','left','right'
			outDirection: 'random', // 'up','down','left','right'
			autoSlideShow: false,
			maxZoom: 300, //This is relative to the slideshow screen!
			minZoom: 100,  //This is relative to the slideshow screen! i.e. 100 = first view!
			url: null,
			useFlickr: false,
			flickrKey: '',
			flickrTags: '',
			flickrTagMode: 'and',
			flickrPerPage: 10,
			flickrUserId: '',
			flickrExtras: '',
			spinner: 'images/spinner.gif'
			
			
			}, arguments[1] || {});
		this.options = options;
		
		
                if (this.options.url != undefined && this.options.url != "") {

        		this.setStatus('SlideShow is loading external XML configuration...');
                        
                    new Ajax.Request(
    			this.options.url, 
    			{
    				method: 'get', 
    				onComplete: this.parseXMLConfiguration.bind(this),
    				onException: function(obj,e) { alert("Got exception! " + e.message || e ); },
    				onFailure: function(obj) { alert("Failed loading XML Configuration"); }
    			});
                    
                } else {
                    
                    if (this.options.images.length > 0) {
                        this.images = this.options.images;
                        this.setStatus('SlideShow is starting up...');		
                        this.setup();
                    }
                    
                }
		

			

		
	},

		
	startUpSetup: function(dst) {
	    $(dst).innerHTML = "<div id='" + dst + "_temporary_status' style='color:" + this.startUpTextColor + "; width: " + this.startUpWidth + "; height:" + this.startUpHeight + "; background-color:" + this.startUpBackground + ";'></div>";
	    this.temp_status = $(dst + "_temporary_status");
	},

	cleanUp: function() {
		this.i = null;
		this.c = null;
		this.status = null;
		this.s = null;
		this.draggable = null;
		//this.d.innerHTML = "<div style='background-color:" + myBgcolor + "; width: " + this.width + "; height: " + this.height + "'></div>";
		this.d = null;
		if (this.t) {
        		for (var i = 0; i < this.t.length; i++) {
        			this.t[i].onclick = null;
        		}
        		this.t = null;
        	}
		this.scroller = null;
		this.preview = null;
		this.p = null;
	},
	



        parseXMLConfiguration: function(req) {
            this.setStatus('SlideShow is parsing external XML configuration...');
            var res = Try.these(
            
                function() { return new DOMParser().parseFromString(req.responseText, 'text/xml'); },
                function() { var xmldom = new ActiveXObject('Microsoft.XMLDOM'); xmldom.loadXML(req.responseText); return xmldom; }
           
            );
            
            var options = res;
            
            for (var i = 0; i < res.childNodes.length; i++) {
                if (res.childNodes[i].tagName == "slideshow") {
                    var ss = res.childNodes[i];
                    for (var y = 0; y < ss.childNodes.length; y++) {
                        if(ss.childNodes[y].tagName == "options") {
                            var opts = ss.childNodes[y];
                            for (var z = 0; z < opts.childNodes.length; z++) {
                                if (opts.childNodes[z].nodeName != undefined) {
                                    var tag = opts.childNodes[z].nodeName;
                                    
                                    if  ( opts.childNodes[z].firstChild ) {
                                                    
                                        if (opts.childNodes[z].getAttribute("type") == "bool") {
                                            this.options[tag] = opts.childNodes[z].firstChild.nodeValue == "true" ;
                                        } else if (opts.childNodes[z].getAttribute("type") == "js") {
                                            this.options[tag] = eval(opts.childNodes[z].firstChild.nodeValue);
                                            } else {
                                            this.options[tag] = opts.childNodes[z].firstChild.nodeValue;
                                        }
                                    }
                                }
                            }
                        }

                        if(ss.childNodes[y].tagName == "slides") {
                            this.options.useFlickr = false;
                            this.options["images"] = [];
                            var slides = ss.childNodes[y];
                            for (var z = 0; z < slides.childNodes.length; z++) {
                                var sl = slides.childNodes[z];
                                if (sl.tagName == "slide") {
                                    this.options.images[this.options.images.length] = [];
                                    for (var j = 0; j < sl.childNodes.length; j++) {
                                        var im = sl.childNodes[j];
                                        if (im.tagName == "image") {
                                            var thisi = this.options.images.length;

                                            this.options.images[thisi-1].push(im.firstChild.nodeValue);
                                        }
                                    }
                                 }
                            }  
                            
                            
                           
                        }                        
                        
                        
                        
                        
                        
                    }
                }
            }
            this.checkFlickr();
        },

        checkFlickr: function() {
                
                if (!this.options.useFlickr) {
                    this.setStatus("SlideShow is loading...");
                    this.images = this.options.images;
                    this.setup();
                } else {
                    this.setStatus("SlideShow is loading data from Flickr.com...");
                    if (this.options.flickrKey == undefined) {
                        alert("Fatal error: missing Flickr required values with Flickr Mode enabled");
                    } else {
                        
                            //Mozilla specific code!
                            

                            
                            

                            
                            
                            new Ajax.Request(
            			this.options.flickrUrl, 
            			{
            			        parameters: 'method=' + 'flickr.photos.search' + '&api_key=' + this.options.flickrKey + '&tags=' + this.options.flickrTags + '&tag_mode=' + this.options.flickrTagMode + '&per_page=' + this.options.flickrPerPage + '&user_id=' + this.options.flickrUserId + '&extras=' + this.options.flickrExtras,
            				method: 'get', 
            				onComplete: this.getFlickrFotos.bind(this),
            				onFailure: function() { alert("Got error!"); },
            				onException: this.mozillaSecurity.bind(this)
            			});
            		//alert(pippo.options.transport);
                        
                    }
                }  
            
        },

        mozillaSecurity: function(obj, e) {
            if (e == "Permission denied to call method XMLHttpRequest.open") {
                
                try {
                    if (netscape.security.PrivilegeManager.enablePrivilege) {
                        try {
            
                            netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
                            var pippo = new Ajax.Request(
            			this.options.flickrUrl,  
            			{
            			        parameters: 'method=' + 'flickr.photos.search' + '&api_key=' + this.options.flickrKey + '&tags=' + this.options.flickrTags + '&tag_mode=' + this.options.flickrTagMode + '&per_page=' + this.options.flickrPerPage + '&user_id=' + this.options.flickrUserId + '&extras=' + this.options.flickrExtras,
            				method: 'get', 
            				onComplete: this.getFlickrFotos.bind(this),
            				onFailure: function() { alert("Got error!"); },
            				onException: this.mozillaSecurity.bind(this)
            			});
            
                        } catch (ex) {
            
                                alert("Sorry, can't continue without permission");
            
                        }
            
            
            
                    }
            
                } catch (e) {
                    //We are not on Mozilla!
                    
                }
            
            } else {
                alert("Generic error!\n" + e.message || e);
            }
            
        },

        getFlickrFotos: function(req) {
            
            var res = Try.these(
            
            function() { return new DOMParser().parseFromString(req.responseText, 'text/xml'); },
            function() { var xmldom = new ActiveXObject('Microsoft.XMLDOM'); xmldom.loadXML(req.responseText); return xmldom; }
            
            );
            
            //alert(res.xml);
            
            for (var i = 0; i < res.childNodes.length; i++) {
                if (res.childNodes[i].nodeName == "rsp") var rsp = res.childNodes[i];
            }
            if (rsp.nodeName != "rsp" || rsp.getAttribute('stat') != "ok") {
                alert("Error getting Flickr.com pictures.\nAborting!\n" + req.responseText);
                return;
            } else {
            
                for (var i = 0; i < rsp.childNodes.length; i++) {
                    if (rsp.childNodes[i].tagName == "photos") {
            
                        var photos = rsp.childNodes[i];
                        this.options.images = new Array();
                        
                        for (var z = 0; z < photos.childNodes.length; z++) {

                            if (photos.childNodes[z].tagName == "photo") {

                                var ph = photos.childNodes[z];
                                var s_id = ph.getAttribute('server');
                                var sec = ph.getAttribute('secret');
				var originalsecret = ph.getAttribute('originalsecret');
                                var id = ph.getAttribute('id');
                                var owner = ph.getAttribute('ownername');
                                var original_format = ph.getAttribute('originalformat') || 'jpg';
                                
                                
                                var ti = ph.getAttribute('title');
                                if (owner != null) { ti += " (by <a href=\"http://www.flickr.com/photos/" + owner + "\" target=\"_new\" style=\"color: white\">" + owner + "</a> @ <a href=\"http://www.flickr.com\" target=\"_new\" style=\"color: white\">Flickr.com</a>)"; }
                                var t_url = "http://static.flickr.com/" + s_id + "/" + id + "_" + sec + "_t.jpg";
                                var f_url = "http://static.flickr.com/" + s_id + "/" + id + "_" + sec + ".jpg";
				b_url = f_url;
				if (originalsecret) {
					b_url = "http://static.flickr.com/" + s_id + "/" + id + "_" + originalsecret + "_o." + original_format;
				}
                                var cur = this.options.images.length;
                                this.options.images[cur] = [t_url, f_url, b_url];
                                this.titles[cur] = ti;
                                
                                
                            }
                            
                        }
            
                    }
                }

            }
            
            
            if (this.options.images.length > 0) {
                
                    this.images = this.options.images;
                    this.setup();
                    
            } else {
                alert("Sorry, no images found on Flickr.com");
                    this.images = this.options.images;
                    this.setup();
            }
            
            
        },


	mousePreviewMove: function(e) {
			var posx = 0;
			var posy = 0;
			if (!e) var e = window.event;
			if (e.pageX || e.pageY)
			{
				posx = e.pageX;
				posy = e.pageY;
			}
			else if (e.clientX || e.clientY)
			{
				posx = e.clientX + document.body.scrollLeft;
				posy = e.clientY + document.body.scrollTop;
			}
			
		posy = posy - findPosY(this.p)
		
		//dbg(posy + " " + parseInt(this.p.style.height)/2 + " " + this.p.scrollTop);
		
		//this.p.scrollHeight:this.p.height = x:posy
		var nextScroll = posy * (this.p.scrollHeight - parseInt(this.p.style.height)) / parseInt(this.p.style.height);
		//this.p.scrollTop = parseInt(nextScroll);
		this.previewScroll = parseInt(nextScroll);
		//dbg("Entering..." + this.previewScroll + " " + this.p.scrollTop);
		if (this.previewChecking == false) {
			//dbg("Launching...");
			this.previewScrollCheck();
		} else {
			//dbg("Not launching..." + this.previewChecking);
		}
		//if (posy < (parseInt(this.p.style.height)/2)) { this.p.scrollTop = parseInt(nextScroll)};
		//if (posy > (parseInt(this.p.style.height)/2)) { this.p.scrollTop = parseInt(nextScroll)};
	},

	previewScrollCheck: function() {
		if (this.previewChecking == true) { return; }
		this.previewChecking = true;
		if ( this.previewScroll != null && parseInt(this.p.scrollTop) != parseInt(this.previewScroll) ) {
		
			if (this.p.scrollTop > this.previewScroll) { this.p.scrollTop = this.p.scrollTop - Math.ceil((this.p.scrollTop-this.previewScroll)/(4)); } 
			if (this.p.scrollTop < this.previewScroll) { this.p.scrollTop = this.p.scrollTop + Math.ceil((this.previewScroll-this.p.scrollTop)/(4)); }
			if (!this.scrollTimer) {
				this.scrollTimer = setInterval(this.previewScrollCheck.bind(this),100);
			}
		}
		this.previewChecking = false;
		
	},

	mousePreviewOut: function(e) {

	},
	
	mousePreviewIn: function(e) {
		
		this.previewScrollCheck();
	},
	setup: function() {
		this.temp_status = null;
		this.d.innerHTML = "";
		
		var total = this.options.width || this.width;
		var left_divisor = this.options.left_divisor || 5;
		var right_width = Math.round(total/left_divisor);
		var left_width = total - right_width;
		var myheight = this.options.height || this.height;
		var center_height = myheight - 43 - 30;
		var myBgcolor = this.options.bgcolor || "white";
		
		var myTable = document.createElement('TABLE');
		this.d.appendChild(myTable);
			myTable.width = total;
			myTable.height = myheight;
			myTable.border = 0;
			myTable.cellSpacing = 0;
			myTable.cellPadding = 0;
			myTable.id = this.id + "_slideShow" + "_maintable" ;

		var myTbody = document.createElement('TBODY');
		myTable.appendChild(myTbody);

		var myTr = document.createElement('TR');
		myTbody.appendChild(myTr);
		
		var mytlTd = document.createElement('TD');
		myTr.appendChild(mytlTd);
		
			mytlTd.style.backgroundColor = myBgcolor;
			mytlTd.style.paddingLeft = '5px';
			mytlTd.style.paddingRight = '5px';
			mytlTd.style.height = "43px";
			mytlTd.innerHTML = this.options.versionText || "";
			
		
		
		var mytcTd = document.createElement('TD');
		myTr.appendChild(mytcTd);
			mytcTd.style.backgroundColor = myBgcolor;
			mytcTd.style.paddingLeft = '5px';
			mytcTd.style.paddingRight = '15px';
			mytcTd.style.height = "43px";
			mytcTd.align = "right";
			mytcTd.valign = "top";
			mytcTd.colSpan = 1;
			myTr.appendChild(mytcTd);
		
		
		var mytrTd = document.createElement('TD');
		myTr.appendChild(mytrTd);
			mytrTd.style.backgroundColor = myBgcolor;
			mytrTd.style.paddingLeft = '5px';
			mytrTd.style.paddingRight = '5px';
			mytrTd.style.width = right_width + "px";
			mytrTd.style.height = "43px";
		
		
		var myCTr = document.createElement('TR');
		myTbody.appendChild(myCTr);
		
		var mycltd = document.createElement('TD');
		myCTr.appendChild (mycltd);
			mycltd.colSpan = 2;
			mycltd.style.backgroundColor = myBgcolor;
			mycltd.style.width = left_width + "px";
			mycltd.style.height = center_height + "px";
			mycltd.align = "left";
			mycltd.valign = "top";

		
		
		
		var mycrtd = document.createElement('TD');
		myCTr.appendChild (mycrtd);
			mycrtd.style.backgroundColor = myBgcolor;
			mycrtd.style.width = right_width + "px";
			mycrtd.style.height = center_height + "px";
			mycrtd.vAlign = "middle";		

		var myBTr = document.createElement('TR');
		myTbody.appendChild(myBTr);
		
		var mybltd = document.createElement('TD');
		myBTr.appendChild(mybltd);
			
			mybltd.style.backgroundColor = myBgcolor;
			mybltd.style.width = total + "px";
			mybltd.style.height = 20 + "px";
			mybltd.colSpan = 3;
			mybltd.style.paddingLeft = '5px';
			mybltd.style.paddingRight = '5px';
			mybltd.style.backgroundColor = myBgcolor;
			mybltd.align = "left";
		var mystatus = document.createElement('<div>');
		mybltd.appendChild(mystatus);
		mystatus.style.width = (total - 10 ) + "px";
		mystatus.style.height = mybltd.style.height;
		mystatus.style.fontFamily = "Arial";
		mystatus.style.color = "white";
		mystatus.style.fontSize = "14px";
		mystatus.style.cursor = 'default';
		new Control.betterSlidingDiv(mystatus, { fps: 25, speed: 5, points: 5, stopOnExit: false });
		this.status = mystatus;	
		
		//TABLE CREATED!
		
		
	
		var container = document.createElement('div');
		mycltd.appendChild(container);
			container.id = "container";
			container.style.width = left_width + "px";
			container.style.height = (center_height) + "px";
			container.style.backgroundColor = myBgcolor;
			container.style.overflow = 'hidden';
		this.c = container;
		

		
		this.t = [];
		for (var i = 0; i < this.btns.length; i++) {
			var img = document.createElement('IMG');
			mytcTd.appendChild(img);
			
			img.id = this.id + this.btns[i][0];
			img.src = this.btns[i][1];
			img.border = 0;
			img.style.width = "32px";
			img.style.height = "32px";
			img.onclick = this.setMode.bind(this, img.id, this.btns[i][2]);
			img.style.cursor = 'pointer';
			img.style.marginLeft = "3px";
			
			this.t[this.t.length] = img;
		}
		
	
		
		
		var im = document.createElement('IMG');
		container.appendChild(im);
			im.style.cursor = 'move';
			im.style.display = 'none';
			im.style.position = 'relative';
			im.style.top = "0px";
			im.style.left = "0px";
			im.id = this.id + "_FullImage";
			im._slideShowId = this.id;
			im.width = 0;
			im.height = 0;
		this.i = im;

		var mySpinner = document.createElement('IMG');
		container.appendChild(mySpinner);
			mySpinner.id = 'mySpinner';
			mySpinner.src = this.options.spinner;
			mySpinner.style.position = 'relative';
			mySpinner.style.left = left_width/2-9;
			mySpinner.style.top = center_height/2-9;
			mySpinner.style.zIndex = 1000000;
		
		this.s = mySpinner;
		
		//var Tpreview = new geometryScroller(right_width, center_height);
		//var preview = Tpreview.node;
		var preview = document.createElement('DIV');
		mycrtd.appendChild(preview);
			preview.style.position = 'relative';
			preview.style.width = right_width + "px";
			preview.style.height = center_height + "px";
			preview.style.backgroundColor = myBgcolor;
			preview.style.textAlign = 'left';
			preview.style.verticalAlign = 'middle';
			preview.style.paddingTop = '5px';
			preview.style.paddingBottom = '5px';
			preview._type = 'preview';
		this.scroller = new Control.betterSlidingDiv(preview, { fps: 20, speed: this.images.length * 8, points: 20, stopOnExit: true });
		//	preview.onmousemove = this.mousePreviewMove.bindAsEventListener (this);
		//	preview.onmouseout = this.mousePreviewOut.bindAsEventListener( this );
		//	preview.onmouseover = this.mousePreviewIn.bindAsEventListener( this );
		
		
		


		this.p = preview;
		//this.preview = Tpreview;
		
		for (var i = 0; i < this.images.length; i++) {
			var img = document.createElement('IMG');
			preview.appendChild(img);
			img.id = this.id + "_preview_" + i;
			img.style.width = right_width - 30 + "px";
			img.style.marginBottom = '5px';
			img.style.marginLeft = '10px';
			img.style.border = '1px solid white';
			img.style.clear = "both";
			img.style.display = 'none';
			img._type = 'preview';
			
			var src = this.images[i][0];
			var source_copy = new Array();
			for (var y = 1; y < this.images[i].length; y++) {
				source_copy[source_copy.length] = this.images[i][y];
			}
			img.onload = this.setupPreview.bind (this, i, source_copy); 
			
			img.style.cursor = 'pointer';
			img.src = src;
		}
		


		


			
		this.i = im;
		/*
		this.i.onclick = function(e) {
			SlideShows[this._slideShowId].imageClick();
			//this.imageClick.bindAsEventListener (this);
		}
		*/
		this.status.innerHTML = this.getText(0);
		
	},
	
	getText: function(n) {
		var append = "";
		if (arguments.length > 1) {
			for (var i = 1; i < arguments.length; i++) {
				append = append + arguments[i];
			}
		}
		if (this.options.statusTexts[n]) { return this.options.statusTexts[n] + append; } else { return append; }
	},
	
	thumbnailEvents: [],
	
	setupPreview: function (i, images) {
				
				if (typeof $(this.id + "_preview_" + i) != "object") {
					alert("We have a problem!");
				}
				new Effect.Appear(this.id + "_preview_" + i, {
				
				queue: {
			            position:'front', 
			            scope: this.id + '_preview_' + i}
				
				});
				var tg = $(this.id + "_preview_" + i);
				//alert("Setting up preview with images: " + this.images[i]);
				var s = new Array();
				for (var y = 0; y < images.length; y++) {
					
					s[s.length] = images[y];
				}
				//alert("Sending: " + s);
				this.thumbnailEvents[i] = this.previewClick.bind( this, i, s);
				//tg.onclick = this.previewClick.bind( this, i, s);
				Event.observe(tg,'click',this.thumbnailEvents[i], true);
				this.loadedImages++;
				
				if (this.loadedImages == this.images.length && this.options.autoLoad) {
					var z = new Array();
					for (var y = 1; y < this.images[0].length; y++) {
						
						z[z.length] = this.images[0][y];
					}
					//alert(this.getText(1)); 
					//this.s.innerHTML = this.getText(1);
					this.setStatus(this.getText(1));
					this.previewClick(0,z);
					if (this.options.autoSlideShow == true) {
					    this.startSlideShow();
					    //this.autoShowInterval = setInterval(this.autoSlide.bind(this), 8000);
					}

				
				}
			
	},
	
	startSlideShow: function() {
	    if (!this.autoShowInterval)
	        this.autoShowInterval = setInterval(this.autoSlide.bind(this), 8000);
	},
	
	stopSlideShow: function() {
	    clearInterval(this.autoShowInterval);
	    this.autoShowInterval = null;
	},
	
	autoSlide: function() {
	    if (this.currentIndex == (this.images.length -1)) {
	        this.stopSlideShow();
	        return;
	    
	    }
	    this.currentIndex++;
	    var z = new Array();
            for (var y = 1; y < this.images[this.currentIndex].length; y++) {
                z[z.length] = this.images[this.currentIndex][y];
            }
            var x = $(this.id + "_preview_" + this.currentIndex).offsetLeft;
            var y = $(this.id + "_preview_" + this.currentIndex).offsetTop - (parseInt(this.p.offsetHeight)/2 - $(this.id + "_preview_" + this.currentIndex).offsetHeight/2);
            this.scroller.scrollTo(x,y);
	    this.previewClick(this.currentIndex,z);
	
	},
	
	previewClick: function (i, ims) {
		this.currentIndex = i;
		
		this.loading = false;
		this.replacing = false;
		if (this.dummyImage) {
			this.dummyImage.onload = null;
			this.dummyImage.onerror = null;
		}
		this.dummyImage = null;
		
		var s = new Array();
		this.sources = new Array();
		for (var y = 0; y < ims.length; y++) {
			s[y] = ims[y];
			this.sources[y] = ims[y];
		}
		
		//alert($(this.id + "_preview_" + i).offsetTop );
		
		
		
		
		new Effect.Pulsate(this.id + "_preview_" + i, {
			//Nice hack to pass the object forth and back!
			queue: {
			    position:'end', 
			    scope: this.id + '_preview_' + i},
			slideShow: this,
			index: i,
			ximages: ims,
			beforeStart: function(el) { 
			                        var o = el.options;
                				Event.stopObserving(el.element,'click',o.slideShow.thumbnailEvents[i], true);
		                          },
			afterFinish: function(el) { 
                				var o = el.options;
		                		Event.observe(el.element,'click',o.slideShow.thumbnailEvents[i], true);
				        }
			}
			);
                
			var myDirection = this.options.outDirection;
			if (this.options.outDirection == 'random') {
			    var ind = Math.floor(Math.random() * (this.directions.length -1) + 1);
			    myDirection = this.directions[ind];
			}

			switch(myDirection) {
			    case "down":
			        var xOffset = 0;
			        var yOffset = -1 * (this.c.offsetHeight);
			    break;
			    
			    case "up":
			        var xOffset = 0;
			        var yOffset = this.c.offsetHeight;
			    break;
			    
			    case "right":
			        var xOffset = -1 * (this.c.offsetWidth);
			        var yOffset = 0;
			    break;
			    
			    case "left":
			        var xOffset = (this.c.offsetWidth);
			        var yOffset = 0;			    
			    break;
			    
			    case "rightdown":
			        var xOffset = -1 * (this.c.offsetWidth);
			        var yOffset = -1 * (this.c.offsetHeight);
			    break;
			    
			    case "leftdown":
			        var xOffset = (this.c.offsetWidth);
			        var yOffset = -1 * (this.c.offsetHeight);
			    break;
			    
			    case "rightup":
			        var xOffset = -1 * (this.c.offsetWidth);
			        var yOffset = (this.c.offsetHeight);
			    break;
			    
			    case "leftup":
			        var xOffset = (this.c.offsetWidth);
			        var yOffset = (this.c.offsetHeight);
			    break;			    
			    
			    default:
			        var xOffset = 0;
			        var yOffset = 0;
			    break;
			}
                
		new Effect.Parallel([
		        
			new Effect.Fade(this.i, { duration: 1, sync: true }),
			new Effect.Appear(this.s, { duration: 1, sync: true }),
			new Effect.Move(this.i, { x: -1 * (xOffset), y: -1 * (yOffset), duration: 1, sync: true })
		],  {
        			duration: 1,
        			slideShow: this,
        			afterFinish: function(el) {
        				var o = el.options;
        				o.slideShow.i.src = null;
        				o.slideShow.loading = true;
        				o.slideShow.setSource();
        			}
        	});

		
		


	},
	
	
	setStatus: function(t) {
	        //alert("Setting status" + this.status);
		if (typeof this.status == "object") {
			this.status.innerHTML = "<nobr>" + t + "</nobr>";
		} else if (typeof this.temp_status == "object") {
		        this.temp_status.innerHTML = "<nobr>" + t + "</nobr>";
		}
	},
	setSource: function() {

		this.setStatus(this.getText(1));
		this.dummyImage = new Image();
		this.dummyImage.onload = this.imageLoaded.bind (this);
		this.dummyImage.onerror =  this.fileNotFound.bind (this);
		this.dummyImage.src = this.sources.shift();
		
		
	},
	
	fileNotFound: function() {
		this.status.innerHTML = this.getText(5);
	},
	
	imageLoaded: function() {
		
		
		if (this.loading) {
		        
		        this.currentZoom = 100;
			/* Change source */
			this.i.src = this.dummyImage.src;
			if (this.dummyImage) {
				this.dummyImage.onload = null;
				this.dummyImage.onerror = null;
			}
				
			/* Center in container */
			/* Assume X centering... */
			var newX = (this.c.offsetWidth - 20) ;
			var newY = Math.round(parseInt(this.c.offsetWidth - 20)*this.dummyImage.height/this.dummyImage.width);
			
			if (newY > (this.c.offsetHeight-20)) {
				
				/* INVERT !!! */
				newY = (this.c.offsetHeight - 20);
				newX = Math.round(parseInt(this.c.offsetHeight - 20)*this.dummyImage.width/this.dummyImage.height);
			}
			
			this.i.style.width = newX + "px";
			this.i.style.height = newY + "px";
			var myDirection = this.options.inDirection;
			if (this.options.inDirection == 'random') {
			    var ind = Math.floor(Math.random() * (this.directions.length -1) + 1);
			    myDirection = this.directions[ind];
			}
			switch(myDirection) {
			    case "down":
			        var xOffset = 0;
			        var yOffset = -1 * (this.c.offsetHeight);
			    break;
			    
			    case "up":
			        var xOffset = 0;
			        var yOffset = this.c.offsetHeight;
			    break;
			    
			    case "right":
			        var xOffset = -1 * (this.c.offsetWidth);
			        var yOffset = 0;
			    break;
			    
			    case "left":
			        var xOffset = (this.c.offsetWidth);
			        var yOffset = 0;			    
			    break;
			    
			    case "rightdown":
			        var xOffset = -1 * (this.c.offsetWidth);
			        var yOffset = -1 * (this.c.offsetHeight);
			    break;
			    
			    case "leftdown":
			        var xOffset = (this.c.offsetWidth);
			        var yOffset = -1 * (this.c.offsetHeight);
			    break;
			    
			    case "rightup":
			        var xOffset = -1 * (this.c.offsetWidth);
			        var yOffset = (this.c.offsetHeight);
			    break;
			    
			    case "leftup":
			        var xOffset = (this.c.offsetWidth);
			        var yOffset = (this.c.offsetHeight);
			    break;
			    
			    default:
			        var xOffset = 0;
			        var yOffset = 0;
			    break;
			}
			
			this.i.style.left = parseInt(this.c.offsetWidth/2) - parseInt(this.i.style.width)/2 + xOffset;
			this.i.style.top = parseInt(this.c.offsetHeight/2) - parseInt(this.i.style.height)/2 + yOffset;
			/* Change global mode */
			this.setMode(this.t[0],'move');
		
			new Effect.Parallel([
				new Effect.Fade(this.s, { duration: 1, sync: true }),
				new Effect.Appear(this.i, { duration: 1, sync: true }),
				new Effect.Move(this.i, { x: -1 * xOffset, y: -1 * yOffset, duration: 1, sync: true })
				]);
			
			this.setStatus(this.getText(2));
			
			if (this.titles[this.currentIndex] != "" && this.titles[this.currentIndex] != undefined) this.setStatus(this.titles[this.currentIndex]);
			this.dummyImage = null;
				
		} else if (this.replacing) {
			this.i.src = this.dummyImage.src;
			if (this.dummyImage) {
				this.dummyImage.onload = null;
				this.dummyImage.onerror = null;
				this.dummyImage = null;
			}
			//this.status.innerHTML = this.getText(4) + " " + this.i.src;
			this.setStatus(this.getText(2));
			if (this.titles[this.currentIndex] != "" && this.titles[this.currentIndex] != undefined) this.setStatus(this.titles[this.currentIndex]  );
		}
		
		
	},
	
	setMode: function(b,m) {
		var skip = false;
		if (this.i.src.length < 1) { m = "move"; skip = true }
		if (this.draggable) this.draggable.destroy();
		switch(m.toLowerCase()) {
			case 'move':
				this.mode = 'move';
				
				
				this.draggable = new Draggable(this.i, {
				
				snap: function(x,y,el) {
						
						var w = el.parentNode.offsetWidth;
						var h = el.parentNode.offsetHeight;
						var iw = el.offsetWidth;
						var ih = el.offsetHeight;
						x<w ?  x > (-1*(iw-10)) ? x = x : x = -1 *(iw-10) : x = w - 10;
						y<h ?  y > (-1*(ih-10)) ? y = y : y = -1 *(ih-10) : y = h - 10;
					      	return [x,y];
					    }});
				
				this.i.style.cursor = 'move';
				this.i.onclick = null;
			break;
			case 'zoomin':
				if (!this.options.singleClickCommands) {
					this.mode = 'zoomin';
					if (this.draggable) this.draggable.destroy();
					this.i.style.cursor = "url('images/zoomin.cur'), default";
					Event.observe(this.i,'click',this.imageClick.bindAsEventListener (this), true);
					//this.i.onclick = this.imageClick.bindAsEventListener (this);
				} else {
				
					//this.draggable = new Draggable(this.i, {
					
					
					this.draggable = new Draggable(this.i, {
					
					snap: function(x,y,el) {
							
							var w = el.parentNode.offsetWidth;
							var h = el.parentNode.offsetHeight;
							var iw = el.offsetWidth;
							var ih = el.offsetHeight;
							x<w ?  x > (-1*(iw-10)) ? x = x : x = -1 *(iw-10) : x = w - 10;
							y<h ?  y > (-1*(ih-10)) ? y = y : y = -1 *(ih-10) : y = h - 10;
						      	return [x,y];
						    }});
					
				
					var x = parseInt(this.i.style.width)/2;
					var y = parseInt(this.i.style.height)/2;
					this.imageZoom(this.options.zoomInScale,parseInt(x),parseInt(y));
				}

			break;
			case 'zoomout':
				if (!this.options.singleClickCommands) {
					this.mode = 'zoomout';
					if (this.draggable) this.draggable.destroy();
					this.i.style.cursor = "url('images/zoomout.cur'), default";
					Event.observe(this.i,'click',this.imageClick.bindAsEventListener (this), true);
					//this.i.onclick = this.imageClick.bindAsEventListener (this);
				} else {
				
					
					this.draggable = new Draggable(this.i, {
					
					snap: function(x,y,el) {
							
							var w = el.parentNode.offsetWidth;
							var h = el.parentNode.offsetHeight;
							var iw = el.offsetWidth;
							var ih = el.offsetHeight;
							x<w ?  x > (-1*(iw-10)) ? x = x : x = -1 *(iw-10) : x = w - 10;
							y<h ?  y > (-1*(ih-10)) ? y = y : y = -1 *(ih-10) : y = h - 10;
						      	return [x,y];
						    }});
					
				
					var x = parseInt(this.i.style.width)/2;
					var y = parseInt(this.i.style.height)/2;
					this.imageZoom(this.options.zoomOutScale,parseInt(x),parseInt(y));
				}

			break;
			
			case 'zoomfit':
				if (this.i.src) {
					var newX = (this.c.offsetWidth - 20) ;
					var newY = Math.round(parseInt(this.c.offsetWidth - 20)*this.i.height/this.i.width);
					
					if (newY > (this.c.offsetHeight-20)) {
						
						/* INVERT !!! */
						newY = (this.c.offsetHeight - 20);
						newX = Math.round(parseInt(this.c.offsetHeight - 20)*this.i.width/this.i.height);
					}
					
					this.i.style.width = newX + "px";
					this.i.style.height = newY + "px";

					this.i.style.left = parseInt(this.c.offsetWidth/2) - parseInt(this.i.style.width)/2;
					this.i.style.top = parseInt(this.c.offsetHeight/2) - parseInt(this.i.style.height)/2;
				}
				
					
					this.draggable = new Draggable(this.i, {
					
					snap: function(x,y,el) {
							
							var w = el.parentNode.offsetWidth;
							var h = el.parentNode.offsetHeight;
							var iw = el.offsetWidth;
							var ih = el.offsetHeight;
							x<w ?  x > (-1*(iw-10)) ? x = x : x = -1 *(iw-10) : x = w - 10;
							y<h ?  y > (-1*(ih-10)) ? y = y : y = -1 *(ih-10) : y = h - 10;
						      	return [x,y];
						    }});
					
				

			break;
			
		}
		if (!skip) new Effect.Pulsate(b,{ 
				from: 0.5, 
				duration: 1, 
				slideShow: this, 
				mymode: m, 
				afterFinish: function(el) {
					el.element.onclick = el.options.slideShow.setMode.bind (el.options.slideShow, el.element.id, el.options.mymode); 
				}, 
				beforeStart: function(el) { 
					el.element.onclick = null; 
				} 
			}
		);
	}, 
	imageZoom: function(scale, x, y) {
		
		
				var clickPos = [x,y];
				var destX;
				var destY;
				destX = (this.c.offsetWidth/2);// - ($('myImage').offsetWidth/2) ;
				destY = (this.c.offsetHeight/2); // - ($('myImage').offsetHeight/2);
				var curX = parseFloat(Element.getStyle(this.i,'left')||'0');
				var curY = parseFloat(Element.getStyle(this.i,'top')||'0');
				curX = curX + (clickPos[0]/100*scale) ;
				curY = curY + (clickPos[1]/100*scale) ;
				
				new Effect.Parallel([
					new Effect.Move(this.i,{ sync: true, x:(destX-curX), y:(destY-curY) }),
					new Effect.Scale(this.i,scale)]);
			/* Check if we have more pictures! */
			if (scale > 100) {
				//alert(this.sources);
				if (this.sources.length > 0) {
					var src = this.sources[0];
					
					var s = new Array();
					for (var i = 1; i < this.sources.length; i++) {
						s[s.length] = this.sources[i];
					}
					
					this.sources = s;
					this.replacing = true;
					this.loading = false;
					if (this.dummyImage) {
						this.dummyImage.onload = null;
						this.dummyImage.onerror = null;
					}
					this.dummyImage = null;
					this.dummyImage = new Image();
					this.dummyImage.onload = this.imageLoaded.bind (this);
					this.dummyImage.onerror = this.fileNotFound.bind (this);
					
					//this.status.innerHTML = this.getText(3);
					//this.setStatus(this.getText(3) + " ... " + src);
					this.setStatus(this.getText(3));
					
					this.dummyImage.src = src;
					
				}
			}
	
	},
	
	imageClick: function(e) {
		//This is supposed to zoom in or out
		var move = false;
		e.shiftKey ? move = true : move = false;
		
		if (move) {
			//return true;
			//this.draggable = new Draggable(this.i);
			//this.i.style.cursor = 'move';
		} else {

			switch(this.mode) {
				case "zoomin":
					var scale = 130;
					
				break;
				case "zoomout":
					var scale = 70;
				break;
			}		
		
			var posx = 0;
			var posy = 0;
			if (!e) var e = window.event;
			if (e.pageX || e.pageY)
			{
				posx = e.pageX;
				posy = e.pageY;
			}
			else if (e.clientX || e.clientY)
			{
				posx = e.clientX + document.body.scrollLeft;
				posy = e.clientY + document.body.scrollTop;
			}
		
				var clickPos = [posx - findPosX(this.i), posy - findPosY(this.i)]
				var destX;
				var destY;
				destX = (this.c.offsetWidth/2);// - ($('myImage').offsetWidth/2) ;
				destY = (this.c.offsetHeight/2); // - ($('myImage').offsetHeight/2);
				var curX = parseFloat(Element.getStyle(this.i,'left')||'0');
				var curY = parseFloat(Element.getStyle(this.i,'top')||'0');
				curX = curX + (clickPos[0]/100*scale) ;
				curY = curY + (clickPos[1]/100*scale) ;
				
				new Effect.Parallel([
					new Effect.Move(this.i,{ sync: true, x:(destX-curX), y:(destY-curY) }),
					new Effect.Scale(this.i,scale)]);
			/* Check if we have more pictures! */
			if (scale > 100) {
				//alert(this.sources);
				if (this.sources.length > 0) {
					var src = this.sources[0];
					
					var s = new Array();
					for (var i = 1; i < this.sources.length; i++) {
						s[s.length] = this.sources[i];
					}
					
					this.sources = s;
					this.replacing = true;
					this.loading = false;
		
					if (this.dummyImage) {
						this.dummyImage.onload = null;
						this.dummyImage.onerror = null;
					}
					this.dummyImage = null;
					this.dummyImage = new Image();
					this.dummyImage.onload = this.imageLoaded.bind (this);
					this.dummyImage.onerror = this.fileNotFound.bind (this);
					
					this.status.innerHTML = this.getText(3);
					
					this.dummyImage.src = src;
				}
			}

		}
	}
	
};

function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}
function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}
