/* Gallery class. Copyright by ADenis (adeniss@ukr.net) */

function Gallery(initObj){

	var base = initObj.base;
	var _class = initObj._class;
	var xsl = initObj.xsl;
	
	var preloader = new PreLoader();
	//var animator = new Animator();
	//var mouse = new Mouse();

	var pane =  initObj.pane;

	var previewFront = initObj.previewFront;
	var previewBack = initObj.previewBack;
	
	var clipAnimatorFront = new ClipAnimator(previewFront);
	var clipAnimatorBack = new ClipAnimator(previewBack);	
	
	var buttonScrollUp = initObj.buttonScrollUp;
	var buttonScrollDown = initObj.buttonScrollDown;

	var scrollArea = initObj.scrollArea;
	var scroller = initObj.scroller;
	
	var isScrollAble = false;
	if(buttonScrollUp && buttonScrollDown && scrollArea && scroller)
		isScrollAble = true;

	var canvasId = initObj.canvasId;
	var list = null;
	var listId = initObj.listId;
	
	var thumbnailName = initObj.thumbnailName;
	
	var galleryXML = new XML();
	
	var COLS_COUNT = 3;
	var ROWS_COUNT = 3;
	
	if(initObj.COLS_COUNT)
		COLS_COUNT = initObj.COLS_COUNT;
	if(initObj.ROWS_COUNT)
		ROWS_COUNT = initObj.ROWS_COUNT;
	
	this.items = 0;
	
	var THUMBNAILS_COUNT = 0;
	var FOLDERS_COUNT = 0;
	var IMAGES_COUNT = 0;
	
	var SCROLL_TIME = 1;
	var SLIDESHOW_INTERVAL = 5;
	
	var THUMBNAIL_WIDTH = 79;
	var THUMBNAIL_HEIGHT = 79;
	var CANVAS_WIDTH = 0;
	var CANVAS_HEIGHT = 0;
	var LIST_HEIGHT = 0;
	
	var STATE_READY = 0;
	var STATE_SCROLL = 1;
	var STATE_LOAD = 2;
	
	this.state = STATE_READY;
	var currentImage = null;
	
	var isScroll = false;
	var isSlideshow = false;
	
	var EFFECT_FADE = 0;
	var EFFECT_SLICE = 1;
	var EFFECT_SLIDE_H = 2;
	var effect = EFFECT_FADE;
	
	var onLoadListener = initObj.onLoadListener;
	var onLoadHandler = initObj.onLoadHandler;
	
	this.debug = false;

////	REQUEST SERVICES	////

	this.loadFolder = function(folder){
		this.stopSlideshow();
		
		var action = "";		
		
		if(folder == ""){
			action = false;
		}else if(!folder){			
			action = "parent";
			folder = "";
		}else if(folder != ""){
			action = "goto";
		}
		
		this.updateGalleryData(action, folder);
	}
	
	this.updateGalleryData = function(action, folder){
		preloader.removeLoader(pane);
		preloader.addLoader(pane);
		
		galleryXML.listener = this;
		galleryXML.onLoad = this.drawGalleryPane;
		
		var request = "";
		
		if(!action){
			request = base + "/index.php?template="+xsl+"&class="+_class;
		}else{
			request = base + "/index.php?template="+xsl+"&"+_class+"[folder][name]="+folder+"&"+_class+"[folder][action]="+action+"&class="+_class;
		}
		
		//window.open(request+"&xml");		
		galleryXML.load(request);
	}

	this.updateImageData = function(action, id, url){
		preloader.removeLoader(pane);
		preloader.addLoader(pane);
		
		galleryXML.listener = this;
		galleryXML.onLoad = this.drawGalleryPane;
		
		var parts = url.split("/");
		var filename = parts[parts.length-1];
		
		var request = base + "/index.php?template="+xsl+"&"+_class+"[image][id]="+id+"&"+_class+"[image][action]="+action+"&"+_class+"[image][filename]="+filename+"&class="+_class;		
		galleryXML.load(request);
	}

	this.drawGalleryPane = function(nodes, html, status){
		//alert(html);
		
		pane.innerHTML = html;
		
		var canvas = document.getElementById(canvasId);
		list = document.getElementById(listId);
		
		var images = getChildsByName(list, thumbnailName);
		var folders = getChildsByName(list, "folder");
		
		FOLDERS_COUNT = folders.length;
		IMAGES_COUNT = images.length;
		THUMBNAILS_COUNT = FOLDERS_COUNT + IMAGES_COUNT;
		
		this.items = THUMBNAILS_COUNT;
		
		if(THUMBNAILS_COUNT){
			
			CANVAS_WIDTH = THUMBNAIL_WIDTH *COLS_COUNT + 2;
			CANVAS_HEIGHT = THUMBNAIL_HEIGHT *ROWS_COUNT;
			
			LIST_HEIGHT = parseInt(THUMBNAILS_COUNT/COLS_COUNT+0.7)*THUMBNAIL_HEIGHT;
			
			//alert(CANVAS_WIDTH);
			
			list.style.width = CANVAS_WIDTH.toString() + "px";

			if(!isScrollAble)
				CANVAS_WIDTH += 22;
				
			//alert(CANVAS_WIDTH);

			canvas.style.width = CANVAS_WIDTH.toString() + "px";
			canvas.style.height = CANVAS_HEIGHT.toString() + "px";

			if(isScrollAble){
				var visible = "hidden";
				if(CANVAS_HEIGHT < LIST_HEIGHT){
					visible = "visible";
										
					var dHeight = buttonScrollUp.clientHeight + buttonScrollDown.clientHeight;
					
					scrollArea.style.height = CANVAS_HEIGHT - dHeight + "px";
					scroller.style.height = parseInt((CANVAS_HEIGHT/LIST_HEIGHT)*CANVAS_HEIGHT) - dHeight + "px";
				}
				scrollArea.style.visibility = visible;
			}
		}else if(isScrollAble){
			scrollArea.style.visibility = "hidden";
		}
		
		if(isScrollAble)
			this.updateAfterScroll();
		this.updateSeekButtons();
		
		preloader.removeLoader(pane);
		
		if(onLoadHandler){
			if(onLoadListener){
				onLoadHandler.call(onLoadListener);
			}else{
				onLoadHandler();
			}
		}
	}

////	IMAGE LOAD	////

	this.loadImage = function(thumbnail){
		
		if(this.debug)
			alert("Gallery: loadImage");
		
		if(this.state != STATE_READY)
			return 0;

		removeListener(previewFront, "onload", this, this.switchFrontBuffer);
		
		var preview = thumbnail.getAttribute('preview', true);
		var source = thumbnail.getAttribute('source', true);
		var title = thumbnail.title;

		if(this.debug)
			alert("Gallery: loadImage "+preview);

		if(currentImage){
			currentImage.style.border = "2px solid orange";
		}
		
		currentImage = thumbnail;
		
		this.state = STATE_LOAD;
		if(0){
			preloader.addLoader(previewBack);
			
			removeListener(previewFront, "onclick", this, this.onPreviewClick);
			addListener(previewBack, "onload", this, this.showImage, true);
			
			previewFront.alt = title;
			previewFront.title = title;
			previewFront.setAttribute("source", source, true);
			previewBack.src = preview;
		}else{
			this.updateSeekButtons();
			
			this.state = STATE_READY;			
		}	
	}
	
	this.showImage = function(){
		//effect = EFFECT_SLICE;

		if(this.debug)
			alert("Gallery: showImage "+previewBack.src);

		preloader.removeLoader(previewBack);
		removeListener(previewBack, "onload", this, this.showImage);
			
		if(previewBack.filters){
			try{
				previewBack.filters.item(0).opacity = 100;
			}catch(e){
			}
		}else{
			previewBack.style.MozOpacity = 1;
			previewBack.style.opcaity = 1;
		}

		if(previewFront.filters){
			try{
				previewFront.filters.item(0).opacity = 100;
			}catch(e){
			}
		}else{
			previewFront.style.MozOpacity = 1;
			previewBack.style.opcaity = 1;
		}
		
		switch(effect){
			case EFFECT_FADE:
				previewFront.style.position = "relative";
				previewBack.style.position = "relative";

				if(previewFront.filters){
					try{
						animator.animateObj(previewFront.filters.item(0), 'opacity', 100, 0, true, 0.5, this, this.reorderBuffers, 'parabola');
					}catch(e){
						this.reorderBuffers();
					}
				}else{
					animator.animateObj(previewFront.style, 'MozOpacity', 1, 0, true, 0.5, this, this.reorderBuffers, 'parabola');
					animator.animateObj(previewFront.style, 'opacity', 1, 0, true, 0.5, this, this.reorderBuffers, 'parabola');
				}
			break;
				
			case EFFECT_SLICE:
				previewFront.style.position = "absolute";
				previewBack.style.position = "absolute";
				
				animator.animateObj(clipAnimatorFront, 'left', "0px", parseInt(previewFront.clientWidth/2)+"px", true, 0.25);
				animator.animateObj(clipAnimatorFront, 'right', previewFront.clientWidth+"px", parseInt(previewFront.clientWidth/2)+"px", true, 0.25);
				animator.animateObj(clipAnimatorFront, 'top', "0px", parseInt(previewFront.clientHeight/2)+"px", true, 0.25);
				animator.animateObj(clipAnimatorFront, 'bottom', previewFront.clientHeight+"px", parseInt(previewFront.clientHeight/2)+"px", true, 0.25, this, this.reorderBuffers);
			break;
						
			case EFFECT_SLIDE_H:
				previewFront.style.position = "relative";
				previewBack.style.position = "relative";
				
				animator.animateObj(previewBack.style, 'left', "-"+previewBack.clientWidth+"px", "0px", true, 0.5, null, null, 'parabola');
				animator.animateObj(previewFront.style, 'left', "0px", previewFront.clientWidth+"px", true, 0.5, this, this.reorderBuffers, 'parabola');				
			break;
		}
	}
	
	this.reorderBuffers = function(){
		if(this.debug)
			alert("Gallery: reorderBuffers");

		addListener(previewFront, "onload", this, this.switchFrontBuffer, true);
		
		previewFront.src = previewBack.src;
		
		this.switchFrontBuffer();
	}
	
	this.switchFrontBuffer = function(){		
		if(this.debug)
			alert("Gallery: switchFrontBuffer");

		removeListener(previewFront, "onload", this, this.switchFrontBuffer);
		
		switch(effect){
			case EFFECT_FADE:				
				if(previewFront.filters){
					try{
						previewFront.filters.item(0).opacity = 100;
					}catch(e){
					}
				}else{
					previewFront.style.MozOpacity = 1;
					previewFront.style.opacity = 1;
				}
					
				effect = EFFECT_SLICE;
			break;

			case EFFECT_SLICE:
				//previewFront.style.position = "relative";
				previewFront.style.clip = "rect(0px,"+previewFront.clientWidth+"px,"+previewFront.clientHeight+"px,0px)";				
				
				//alert(previewFront.style.clip);
				effect = EFFECT_SLIDE_H;				
			break;
			
			case EFFECT_SLIDE_H:
				//previewFront.style.position = "relative";
				previewFront.style.left = "0px";
				previewBack.style.left = "0px";
				
				//alert(previewFront.style.clip);
				effect = EFFECT_FADE;
			break;
		}
		
		addListener(previewFront, "onclick", this, this.onPreviewClick);
		
		if(currentImage){
			currentImage.style.border = "2px solid white";
		}
		
		this.updateSeekButtons();
		
		this.state = STATE_READY;
	}
	
	this.onPreviewClick = function(_event){
		if(_event){
			var object = (_event.srcElement)?_event.srcElement:_event.target;
			imageViewer.load(object.getAttribute("source"), object.title);
		}else{
			imageViewer.load(currentImage.getAttribute("source"), currentImage.title);
		}
	}

////	SCROLL FUNCTIONS	////

	this.updateAfterScroll = function(){
		if(buttonScrollUp && buttonScrollDown){		
			var y = 0;
			
			if(THUMBNAILS_COUNT){
				y = parseFloat(list.style.top);					
				y = isNaN(y)?0:y;
			}else{
				buttonScrollDown.style.visibility = "hidden";
				buttonScrollUp.style.visibility = "hidden";
				this.state = STATE_READY;
				return false;
			}
			
			//alert("Gallery: y "+y+" LIST_HEIGHT "+gallery.LIST_HEIGHT+" CANVAS_HEIGHT "+gallery.CANVAS_HEIGHT);
		
			var visible = "visible";
			
			if((y + LIST_HEIGHT) <= CANVAS_HEIGHT){
				visible= "hidden";
			}
			
			buttonScrollDown.style.visibility = visible;		
			
			visible = "visible";
			if(y >= 0){
				visible = "hidden";
			}
			
			buttonScrollUp.style.visibility = visible;
		}
		
		this.state = STATE_READY;
	}
	
	this.scrollList = function(isDown){
		if(this.state != STATE_SCROLL && (LIST_HEIGHT > CANVAS_HEIGHT)){
			this.state = STATE_SCROLL;
			
			var dY = parseFloat(list.style.top);
			var time = 0;
			
			dY = isNaN(dY)?0:dY;
			
			if(isDown){
				dY = LIST_HEIGHT + dY - CANVAS_HEIGHT;
							
				if(dY > CANVAS_HEIGHT)
					dY = CANVAS_HEIGHT;
					
				time = SCROLL_TIME * dY/CANVAS_HEIGHT;
			}else{
				if(dY < -CANVAS_HEIGHT)
					dY = -CANVAS_HEIGHT;
				
				time = -SCROLL_TIME * dY/CANVAS_HEIGHT;
			}
			
			animator.animateObj(list.style, 'top', '0px', -dY, false, time, this, this.updateAfterScroll, 'parabola');
		}
	}
	
	this.scrollDown = function(){
		this.scrollList(true);
	}
	
	this.scrollUp = function(){
		this.scrollList(false);
	}
	
	this.update = function(){
		if(isScrollAble){
			if(scrollArea.style.visibility == "visible"){
				var y = parseFloat(list.style.top);
				y = isNaN(y)?0:y;
				scroller.style.top = parseInt(-((CANVAS_HEIGHT)/(LIST_HEIGHT))*y) + "px";
			}
		}		
	}
	
	this.startScroll = function(){
		if(isScrollAble){
			scroller.setAttribute("startMouseY", MOUSE.y);
			var startListY = parseFloat(list.style.top);
			startListY = isNaN(startListY)?0:startListY;
			scroller.setAttribute("startListY", startListY);
			this.state = STATE_SCROLL;
			addListener(document, "onmouseup", this, this.stopScroll, true);
			isScroll = true;
		}
	}

	this.scroll = function(){
		
		var from = -(LIST_HEIGHT - CANVAS_HEIGHT);
		var to = 0;
		
		var startMouseY = parseFloat(scroller.getAttribute("startMouseY"));
		var startListY = parseFloat(scroller.getAttribute("startListY"));
		
		var y = (MOUSE.y - startMouseY)/(CANVAS_HEIGHT);
		y = y*(LIST_HEIGHT) - startListY;
		y = -y;
		
		if(y < from)
			y = from;
		if(y > to)
			y = to;
		
		list.style.top = parseInt(y) + "px";
	}

	this.stopScroll = function(){
		isScroll = false;
		this.updateAfterScroll();
		removeListener(document, "onmouseup", this, this.stopScroll);
	}

////	FOLDER COMMANDS	////

	this.removeFolder = function(folder){
		this.updateGalleryData("remove", folder);
	}
	
	this.createFolder = function(folder){
		this.updateGalleryData("create", folder);
	}

////	IMAGE COMMANDS	////

	this.removeImage = function(id, url){
		this.updateImageData("remove", id, url);
	}

////	IMAGE VIEW	////
	this.onFullViewLoad = function(){
		if(isSlideshow){
			
			this.continueSlideshow();
			/*
			var images = getChildsByName(list, thumbnailName);
			var index = this.getNextThumbnailIndex(true);
			var image = new Image();
			image.src = images[index].getAttribute("source");*/
		}
	}	
	
	this.seekImage = function(isNext){

		if(this.state != STATE_READY || !imageViewer.loaded)
			return 0;
		
		var images = getChildsByName(list, thumbnailName);
		if(images.length){
			var index = this.getNextThumbnailIndex(isNext);
			
			this.pauseSlideshow();
			
			//this.loadImage(images[index]);
			//removeUpdateListener(this, this.showNext);
			
			images[index].onclick();
			
			imageViewer.load(images[index].getAttribute("source"), images[index].title);
		}		
	}
	
	this.getNextThumbnailIndex = function(isNext){
		var index = 0;
		
		var images = getChildsByName(list, thumbnailName);
		if(images.length){
			
			var wasFound = false;
			for(var i in images){
				if(images[i] == currentImage){
					index = i;
					wasFound = true;
					break;
				}
			}
			
			if(wasFound){
				if(isNext){
					index++;
				}else{
					index--;
				}
			}else{
				index = 0;
			}
			
			if(index < 0)
				index = images.length-1;
			
			if(index >= images.length)
				index = 0;			
		}
		
		return index;
	}
	
	this.updateSeekButtons = function(){
		//alert("Gallery: updateSeekButtons " + (buttonPrevImage && buttonNextImage));
		if(buttonPrevImage && buttonNextImage && list){
			var images = getChildsByName(list, thumbnailName);
			if(images.length > 1){
				var index = 0;
				
				for(var i in images){
					if(images[i] == currentImage){
						index = i;
						break;
					}
				}

				buttonPrevImage.style.display = "";
				buttonNextImage.style.display = "";		

				var visibility = (index <= 0)?"hidden":"visible";
				buttonPrevImage.style.visibility = visibility;
								
				visibility = (index >= images.length-1)?"hidden":"visible";
				buttonNextImage.style.visibility = visibility;
				
				//alert(IMAGES_COUNT);				
				display = (isSlideshow)?"none":"";
				buttonStartSlideshow.style.visibility = "visible";
				buttonStartSlideshow.style.display = display;
				display = (!isSlideshow)?"none":"";
				buttonStopSlideshow.style.visibility = "visible";
				buttonStopSlideshow.style.display = display;
			}else{
				var visibility = "hidden";
				var display = "none";
				buttonPrevImage.style.display = display;
				buttonNextImage.style.display = display;				
				buttonStartSlideshow.style.display = display;
				buttonStopSlideshow.style.display = display;
			}
		}
	}

	this.showNext = function(){
		this.seekImage(true);
	}

	this.showPrev = function(){		
		this.seekImage(false);
	}
	
	this.startSlideshow = function(){
		isSlideshow = true;
		this.updateSeekButtons();
		//this.showNext();
		this.continueSlideshow();
	}

	this.pauseSlideshow = function(){
		removeUpdateListener(this, this.showNext);
	}

	this.continueSlideshow = function(){
		addUpdateListener(this, this.showNext, SLIDESHOW_INTERVAL);
	}
	
	this.stopSlideshow = function(){
		isSlideshow = false;
		this.updateSeekButtons();
		this.pauseSlideshow();
	}
	
////	EVENTS ROUTINE	////
	
	this.onStopDrag = function(object){
		object.style.position = "static";		
	}

	this.onThumbnailOver = function(object){
		if(object.filters){
			animator.animateObj(object.filters.item(0), 'opacity', object.filters.item(0).opacity, 50, true, 0.25);
		}else{
			animator.animateObj(object.style, 'MozOpacity', object.style.MozOpacity, 0.5, true, 0.25);
			animator.animateObj(object.style, 'opacity', object.style.opacity, 0.5, true, 0.25);
		}
	}
	
	this.onThumbnailOut = function(object){
		if(object.filters){
			animator.animateObj(object.filters.item(0), 'opacity', object.filters.item(0).opacity, 100, true, 0.25);
		}else{
			animator.animateObj(object.style, 'MozOpacity', object.style.MozOpacity, 1, true, 0.25); 
			animator.animateObj(object.style, 'opacity', object.style.opacity, 1, true, 0.25); 
		}
	}

	this.onThumbnailLoad = function(object){
		if(object.filters){
			animator.animateObj(object.filters.item(0), 'opacity', 0, 100, true, 0.25);
		}else{
			animator.animateObj(object.style, 'MozOpacity', 0, 1, true, 0.25);
			animator.animateObj(object.style, 'opacity', 0, 1, true, 0.25);
		}
	}

	this.onMouseMove = function(){		
		if(isScroll){
			this.scroll();
		}
	}

	this.onMouseWheel = function(_event){
		if(isScrollAble){
			var wheelData = 0;		
			if(_event.wheelDelta)
				wheelData = _event.wheelDelta/120;
			else
				wheelData = -_event.detail/3;
				
			if(wheelData > 0){
				this.scrollUp();
			}else if(wheelData < 0){
				this.scrollDown();
			}
			
			return false;
		}
	}
	
	this.onKeyDown = function(_event){
		if(isScrollAble){
			var keyCode = _event.keyCode;
			
			switch(keyCode){
				case 40: this.scrollDown(); break;
				case 38: this.scrollUp(); break;
			}
		}
	}

	var buttons = new Array();
	
	buttons[0] = new ViewerButtonPrototype("showPrevious", "&lt;&lt;", this, this.showPrev);
	buttons[1] = new ViewerButtonPrototype("startSlideshow", "&gt;", this, this.startSlideshow);
	buttons[2] = new ViewerButtonPrototype("stopSlideshow", "||", this, this.stopSlideshow);
	buttons[3] = new ViewerButtonPrototype("showNext", "&gt;&gt;", this, this.showNext);
	
	var imageViewer = new ImageViewer(buttons);
	
	imageViewer.listener = this;
	imageViewer.onHide = this.stopSlideshow;
	imageViewer.onLoad = this.onFullViewLoad;

	var buttonPrevImage = buttons[0].button;
	var buttonNextImage = buttons[3].button;
	var buttonStartSlideshow = buttons[1].button;
	var buttonStopSlideshow = buttons[2].button;
	
	if(isScrollAble){
		addListener(pane, "onmousewheel", this, this.onMouseWheel, false, true, true);
		addListener(pane, "DOMMouseScroll", this, this.onMouseWheel, false, true, true);
		addListener(scrollArea, "onmousewheel", this, this.onMouseWheel, false, true, true);
		addListener(scrollArea, "DOMMouseScroll", this, this.onMouseWheel, false, true, true);	
	}
	addListener(document, "onmousemove", this, this.onMouseMove, true);

	addUpdateListener(this, this.update);
	
	var request = parseHTMLArgs();
	var folder = "";
	
	if(request != ""){
		if(request["folder[name]"])
			folder = request["folder[name]"];
			
		if(request["image[show]"]){
			var image = document.createElement("img");
			image.setAttribute('preview', request["image[preview]"]);
			image.setAttribute('source', request["image[source]"]);
			
			this.loadImage(image);
		}
	}
	
	var request = parseHTMLArgs();
	
	if(request["debug"]){
		this.debug = true;
	}
	
	this.loadFolder(folder);
}

function GalleryAttributes(){
	//Request params
	this.base = "";
	this.xsl = "";
	this._class = "";
	
	//UI objects
	this.buttonScrollUp = null;
	this.buttonScrollDown = null;
	this.buttonPrevImage = null;
	this.buttonNextImage = null;
	this.buttonStartSlideshow = null;
	this.buttonStopSlideshow = null;
	
	this.previewFront = null;
	this.previewBack = null;
	this.pane = null;
	this.scrollArea = null;
	this.scroller = null;

	//UI ids
	this.thumbnailName = "";
	this.canvasId = "";
	this.listId = "";
}