function getFileNameOnly(str) {
	var slash = '/';
	var li = str.lastIndexOf(slash);
	if (li == -1) return str;
	return str.substr(li+1);
}

var NGaleria = Class.create();

NGaleria.prototype = {
	
    images: [],
    activeImage: undefined,
    hiddenElements: [],
    slideEffects: new Hash,
    params: {},
    set: false,
    active: false,
    imageLoader: 0,
    thumbsSelected: [],
    
    initialize: function(params) {

		this.params = Object.extend({
		    overlayOpacity: 0.8,   
		    overlayDuration: .2,
		    defDuration: 1,
		    thumbScrollDuration: .5,    
			galleryService: '/galeria.php',
			loaderGifThumb: '/images/galeria/i/loader_small.gif',
			closerImage: '/images/galeria/i/bezar.gif',
			backgroundImage: '/images/galeria/i/bigBg.png',
			leftButtonImage: '/images/galeria/i/leftButton.png',
			rightButtonImage: '/images/galeria/i/rightButton.png',
			thumbBorderImage: '/images/galeria/i/thumbBorder.png',
			thumbBorderImageOn: '/images/galeria/i/thumbBorderOn.png',
			//GAactive: true,
			//thumbsVisible: true,
			titleVisible: true,
			//subTitleVisible: true,
			//downloadableVisible: true,
			//fullSizeVisible: true,
			textSlideDuration: 1,
			width: 759,
			height: 647,
			thumbMargin: 16,
			thumbWidth: 63,
			thumbHeight: 48,
			maxImageWidth: 730,
			maxImageHeight: 535
		}, params || {})    	
        
        this.keyboardAction = this.keyboardAction.bindAsEventListener(this);
		
    },
    setUp: function() {
    	this.body = $$('body').first();
    	this.overlay = new Element('DIV');
    	this.overlay.addClassName('GOverlay');
    	this.overlay.setStyle({display : 'none', left: '0px', top: '0px', zIndex: 2500, position: 'absolute', width: '0px', height: '0px'});
    	this.body.insert({top: this.overlay});
    	this.container = new Element('DIV');
    	this.container.addClassName('GContainer');
    	this.container.setStyle({
			display : 'none',
			left: '0px',
			top: '0px',
			zIndex: 2501,
			position: 'absolute',
			width: this.params.width+'px',
			height: this.params.height+'px'
		});
		var bgImg = new Image();
		bgImg.onload = function() {
			this.container.setStyle({
				background: 'transparent url('+this.params.backgroundImage+') center center no-repeat'	
			});	
		}.bind(this);
		bgImg.src = this.params.backgroundImage;
		this.overlay.observe('click', this.end.bind(this));
    	this.body.insert({top: this.container});
    	this.set = true;
    },
    
    autoPosition: function(isStart) {
    	var Dim = document.viewport.getDimensions();
    	var BodyDim = this.body.getDimensions();
    	var Scroll = document.viewport.getScrollOffsets();
    	this.overlay.setStyle({
    		left: 0+'px',
    		top: 0+'px',
    		width: Math.max(Dim.width, BodyDim.width) +'px',
    		height: Math.max(Dim.height, BodyDim.height)+'px'
    	});
    	
    	if ( Dim.height < this.params.height ) {
    		var top = 15 + Scroll.top;
    	} else {
    		var top = (Scroll.top+Math.round((Dim.height - this.params.height) / 2));
    	}

    	if ( Dim.width < this.params.width ) {
    		var left = 15 + Scroll.left;
    	} else {
    		var left = (Scroll.left+Math.round((Dim.width - this.params.width) / 2));
    	}

    	this.container.setStyle({
    		left: left+'px',
    		top: top + 'px'
    	});    	
    },

    loadImage: function(i) {
    	if (!this.images[i] || !this.active) return;
    	if (this.activeImage == i*1) return;
    	this.thumbNailSelect(i);
    	this.activeImage = i;
    	this.imageLoader++;
    	var image = this.images[i];
    	var newImage = new Image();
    	newImage.alt = image.title; 	
    	newImage.onload = function(i, id) {
    		if (this.imageLoader != id) return;
			var ratio = i.width / i.height;
			this.imgDiv.removeClassName('loading');
			if (ratio > (this.params.maxImageWidth / this.params.maxImageHeight)) {
    			if (i.width > this.params.maxImageWidth) {
    				i.height = Math.round(i.height * (this.params.maxImageWidth / i.width));
    				i.width = this.params.maxImageWidth;
    			}
    			if (i.height > this.params.maxImageHeight) {
    				i.width = Math.round(i.width * (this.params.maxImageHeight / i.height));
    				i.height = this.params.maxImageHeight;
    			}
    		} else {
    			if (i.height > this.params.maxImageHeight) {
    				i.width = Math.round(i.width * (this.params.maxImageHeight / i.height));
    				i.height = this.params.maxImageHeight;
    			}
    			if (i.width > this.params.maxImageWidth) {
    				i.height = Math.round(i.height * (this.params.maxImageWidth / i.width));
    				i.width = this.params.maxImageWidth;
    			}
    		}
	    	this.imgDiv.setStyle({
	    		left: Math.floor((this.imageHolderWidth - i.width)/2)+'px',
	    		top: Math.floor((this.params.maxImageHeight - i.height)/2)+'px',
	    		width: i.width+'px',
	    		height: i.height+'px'
	    	});
    		Element.setOpacity(i, 0);
    		this.imgDiv.insert({top: i});
    		new Effect.Opacity(i, {to: 1, duration: this.params.defDuration/2});
    	}.bind(this, newImage, this.imageLoader);
    	$A(this.imgDiv.childNodes).each(Element.remove);  
    	this.imgDiv.addClassName('loading');
    	newImage.src = image.url;
    	if (this.params.titleVisible) this.startSlide(this.imageHolder.select('.title').first(), 1, image.title);
        var iNext, iPrev;
        if (this.images.length - 1 > i) {
            iNext = new Image();
            iNext.src = this.images[(i + 1)].url;
            this.buttonRight.addClassName('clickable');
        } else {
        	this.buttonRight.removeClassName('clickable');
        }
        if (i > 0) {
            iPrev = new Image();
            iPrev.src = this.images[(i - 1)].url;
            this.buttonLeft.addClassName('clickable');
        } else {
        	this.buttonLeft.removeClassName('clickable');
        }
    },
    
    thumbNailSelect: function(i) {
    	while (j = this.thumbsSelected.shift()) {
    		j.removeClassName('on');
    		if (j.select('img').length == 2) {
    			//new Effect.Opacity(j.down(1), {to: .6, duration: this.params.defDuration/2});
    			j.select('.TBorder').first().src = this.params.thumbBorderImage;
    		}
    	}
    	if ($('gThumb'+i)) {
    		$('gThumb'+i).addClassName('on');
    		this.thumbSelector.style.left = (i*(this.params.thumbWidth+this.params.thumbMargin))+'px';
    		$('gThumb'+i).select('.TBorder').first().src = this.params.thumbBorderImageOn;
    		this.thumbsSelected.push($('gThumb'+i));
    	}
		this.thumbNailScrollToPage(Math.floor(i / this.thumbPerPage));    	
    },
    
    thumbNailScrollToPage: function(pg, add) {
    	if (pg === null) {
    		var pg = this.thumbNailAt + add;
    	}
    	if (pg < 0 || pg >= this.thumbPageCount) return;
    	if (this.thumbNailAt != pg) {
    		this.thumbNailAt = pg;
	    	var posOffset = pg*this.thumbPerPage*(this.params.thumbWidth+this.params.thumbMargin);
	    	new Effect.Morph(this.holder_, {duration: this.params.thumbScrollDuration, style: 'left: -'+posOffset+'px;'});
    	}
    	if (pg == 0) {
    		this.thumbNailHolder.select('.l').first().removeClassName('clickable');
    	} else {
    		this.thumbNailHolder.select('.l').first().addClassName('clickable');
    	}
    	if (pg == this.thumbPageCount-1) {
    		this.thumbNailHolder.select('.r').first().removeClassName('clickable');
    	} else {
    		this.thumbNailHolder.select('.r').first().addClassName('clickable');
    	}
    },
    
    loadGallery: function() {
    	var i = 0;
    	this.responseData.each(function(e) {
    		var i = Object.extend({
    			key: '',
    			id: '',	
    			title: '',
    			subtitle: '',
    			url_thumb: '',
    			url: '',
    			url_big: '',
    			fileName: ''
    		}, e);
    		if (i.url) {
    			if (!i.url_thumb) i.url_thumb = i.url;
    			if (!i.url_big) i.url_big = i.url;
    			i.key = this.images.length;
    			i.fileName = getFileNameOnly(i.url);
    			this.images.push(i);
    		}
    	}.bind(this));
    	if (this.startWith !== undefined) {
	    	if (this.startWith >= 0 && this.startWith < this.images.length) {
				i = parseInt(this.startWith);
	    	} else {
	    		var image = this.images.find(function(e) {return e.fileName == this;}.bind(this.startWith));
	    		if (image) i = parseInt(image.key);
	    	}
	    }
	    this.loadThumbNails();
    	this.loadImage(i);
    },
    
    initImageHolder: function() { 
    	this.imageHolder = new Element('DIV');
    	this.imageHolder.addClassName('GimageHolder');
    	this.imageHolder.update('<div class="titleHolder"><div class="title"><div></div></div></div><div class="im"><div class="l"><img src="'+this.params.leftButtonImage+'" alt="" /></div><div class="img loading"></div><div class="r"><img src="'+this.params.rightButtonImage+'" alt="" /></div></div><div class="subtitle"><div></div></div>');
    	this.imageHolder.select('.l, .r').each(function(e) {
    		if (e.hasClassName('l')) {
    			this.buttonLeft = e;
    		} else {
    			this.buttonRight = e;
    		}
    		Event.observe(e, 'click', function() {
    			if (this.activeImage == undefined) return;
    			var i = this.activeImage;
    			this.loadImage(i + (e == this.buttonLeft ? -1 : +1));
    		}.bind(this));
    		Event.observe(e, 'dblclick', function() {
    			Event.stop(e);
    			if (this.activeImage == undefined) return;
    			var i = this.activeImage;
    			this.loadImage(i + (e == this.buttonLeft ? -1 : 1));
    		}.bind(this));    		
    	}.bind(this));
    	this.buttonLeft.setOpacity(0);
    	this.buttonRight.setOpacity(0);
    	[this.buttonLeft, this.buttonRight].each(function(e) {
    		Element.observe(e, 'mouseover', function(e){
    			e.setOpacity(1);
    		}.bind(this, e));
    		Element.observe(e, 'mouseout', function(e){
    			e.setOpacity(0);
    		}.bind(this, e));
    	}.bind(this));
    	this.container.insert({top: this.imageHolder});    
    	this.closerImage = new Element('IMG');
    	this.closerImage.addClassName('GcloserImage');
    	this.closerImage.setStyle({
    		position: 'absolute',
    		cursor: 'pointer'
    	});
    	this.closerImage.setOpacity(0);
    	this.closerImage.src = this.params.closerImage;
    	this.closerImage.observe('click', this.end.bind(this));
    	this.container.insert({top: this.closerImage}); 
    	new Effect.Opacity(this.closerImage, {to: 1, duration: this.params.defDuration});   
    	this.imgDiv = this.imageHolder.select('.img').first(); 	  	
    	this.imageHolderWidth = this.imageHolder.select('.im').first().getWidth();
    },
    
    initThumbnailHolder: function() {
    	this.thumbNailHolder = new Element('DIV');
    	this.thumbNailHolder.addClassName('GthumbNailHolder');
    	this.thumbNailHolder.update('<div class="l"><div></div></div><div class="r"><div></div></div><div class="c"><div class="thumbs"><div class="selector"></div></div></div>');
    	this.thumbSelector = this.thumbNailHolder.select('.selector').first();
    	this.container.insert({bottom: this.thumbNailHolder});    	
    },
    
    loadThumbNails: function() {
    	this.holder_ = this.thumbNailHolder.select('.c .thumbs').first();
    	this.thumbNailAt = 0;
    	this.thumbPerPage = Math.floor((this.holder_.up().getWidth()+this.params.thumbMargin) / (this.params.thumbWidth+this.params.thumbMargin));
    	this.thumbPageCount = Math.ceil(this.images.length / this.thumbPerPage);
    	this.images.each(function(i, index) {
    		var o = new Element('DIV');
    		var oi = new Image();
    		if (i.title != '') {
	    		oi.alt = i.title;
    			oi.title = i.title;
    		} else {
    			oi.alt = ' ';	
    		}	
   			o.id = 'gThumb'+i.key;
   			var j = new Element('IMG');
   			j.className = 'loader';
			o.update('<img src="'+this.params.thumbBorderImage+'" width="'+this.params.thumbWidth+'" height="'+this.params.thumbHeight+'" style="z-index: 3000;" class="TBorder" />');
   			o.insert({bottom:j});
    		o.setStyle({
    			width: this.params.thumbWidth+'px',
    			height: this.params.thumbHeight+'px',
    			left: (4+index*(this.params.thumbWidth+this.params.thumbMargin))+'px'
    		});
    		o.title = i.title;
    		this.holder_.insert({bottom: o});
   			j.src = this.params.loaderGifThumb;
    		oi.onload = function(oi, o, index) {
    			Element.setOpacity(oi, 0);
	    		oi.width = this.params.thumbWidth;
	    		oi.height = this.params.thumbHeight;        			
    			o.select('.loader').first().remove();
    			o.insert({bottom: oi});
    			new Effect.Opacity(oi, {to: 6, afterFinish: function(index, oi) {
    			}.bind(this, index, oi), duration: this.params.defDuration/4});
    		}.bind(this, oi, o, index);
    		oi.src = i.url_thumb;
    	}.bind(this));
    	this.thumbNailHolder.select('.l').first().observe('click', this.thumbNailScrollToPage.bind(this, null, -1));
    	this.thumbNailHolder.select('.r').first().observe('click', this.thumbNailScrollToPage.bind(this, null, 1));
    	this.thumbNailHolder.select('.l').first().observe('dblclick', function(e) {
    		Event.stop(e);
    		this.thumbNailScrollToPage(null, -1);
    	}.bind(this));
    	this.thumbNailHolder.select('.r').first().observe('dblclick', function(e) {
    		Event.stop(e);
    		this.thumbNailScrollToPage(null, 1);    	
    	}.bind(this));
    	this.holder_.observe('click', this.thumbNailClicked.bindAsEventListener(this));
    	this.thumbNailScrollToPage(null, 0);
    },
    
    thumbNailClicked: function(event) {
    	var e = Event.element(event);
    	if (e) {
    		if (e.tagName == 'IMG') e = e.up();
    		if (e.tagName == 'DIV' && e.id) {
    			this.loadImage(parseInt(e.id.replace('gThumb', '')));
    		}
    	}
    },
    
    startSlide: function(element, direction, newContent) {
    	var effect = this.slideEffects.get(element.className);
    	if (effect) effect.cancel();
    	var eContent = element.down(0);
    	var gHeight = element.getHeight();
		var duration = (element.down(0).innerHTML == '' ? this.params.textSlideDuration/4:this.params.textSlideDuration/2);
		var start = (element.down(0).innerHTML == '' ? gHeight:eContent.style.top.replace('px', '')*1);
    	this.slideEffects.set(element.className, new Effect.Tween(null, start, gHeight*2, {duration: duration}, function(e, newContent, gHeight, set, p){
			if (p > gHeight && !set) {
				e.update(newContent);
				set = true;
			}
			e.style.top = (gHeight > p ? Math.round(p) : gHeight - (p - gHeight)  ) +'px';		
    	}.bind(this, eContent, newContent, gHeight, false)));
    },
    
    show: function(gID, startWith, params) {
		this.params = Object.extend(this.params, params || {})
		if (!this.set) this.setUp();
        $$('select', 'object', 'embed').findAll(function(n){return (!n.style.visibility || n.style.visibility == 'visible');}).each(function(n){ n.style.visibility = 'hidden'; this.hiddenElements.push(n); }.bind(this));
        this.autoPosition(true);
        this.startWith = startWith;
        Event.observe(window, 'resize', this.autoPosition.bind(this));
        // Event.observe(window, 'scroll', this.autoPosition.bind(this));
		this.overlay.setOpacity(0);
		this.container.setOpacity(0);
        this.overlay.style.display = 'block';
        this.container.style.display = 'block';
        this.images = [];
        this.activeImage = undefined;    
        this.responseData = undefined;
		new Ajax.Request(this.params.galleryService, {
			method: 'post',
			parameters: {control:'get', id: gID},
			onSuccess: function(transport) {
				if (transport && transport.responseJSON && Object.isArray(transport.responseJSON)) {
					this.responseData = transport.responseJSON;
					if (this.active) this.loadGallery();
				} else {
					this.showError();
				}
			}.bindAsEventListener(this),
			onFailure: function() {this.showError();}
		});
        new Effect.Parallel([
			new Effect.Opacity(this.overlay, {
	        	sync: true,
	        	from: 0,
	        	to: this.params.overlayOpacity
	        }),
			new Effect.Opacity(this.container, {
	        	sync: true,
	        	from: 0,
	        	to: 1
	        })
        ], {
        	duration: this.params.overlayDuration,
        	afterFinish: function() {
        		this.initImageHolder();
        		this.initThumbnailHolder();
        		this.active = true;
        		this.enableKeyboardNav();
        		if (this.responseData) this.loadGallery();
        	}.bind(this)
        });   
        return;
    },
    
    enableKeyboardNav: function() {Event.observe(document, 'keydown', this.keyboardAction);},
    disableKeyboardNav: function() {Event.stopObserving(document, 'keydown', this.keyboardAction); },
    keyboardAction: function(event) {
        var keycode = event.keyCode;
        var escapeKey;
        if (event.DOM_VK_ESCAPE) {
            escapeKey = event.DOM_VK_ESCAPE;
        } else { 
            escapeKey = 27;
        }
        var key = String.fromCharCode(keycode).toLowerCase();
        if (key.match(/x|o|c/) || (keycode == escapeKey)) {
            this.end();
        } else if ((key == 'e') || (key == 'p') || (keycode == 37)) {
            this.loadImage(this.activeImage - 1);
        } else if ((key == 'k') ||(key == 'n') || (keycode == 39)) {
            this.loadImage(this.activeImage + 1);
        }
    },

    end: function() {
    	if (!this.active) return;
    	this.closerImage.remove();
    	this.active = false;
        this.disableKeyboardNav();
        if (this.imageHolder) this.imageHolder.remove();
        if (this.thumbNailHolder) this.thumbNailHolder.remove();
        new Effect.Parallel([
        	new Effect.Fade(this.overlay, {sync: true}),
        	new Effect.Fade(this.container, {sync: true})
        ], {
        	duration: this.params.overlayDuration
        });
		while (e = this.hiddenElements.shift()) {
			e.style.visibility = 'visible';
		}
    },

    showError: function() {
    	alert('error');	
    }
    
}

document.observe('dom:loaded', function () {
	NGaleria = new NGaleria();
});

function showGallery(id, num){
	var sor = num - 1;
	NGaleria.show(id, sor, {galleryService: '/galeria_show.php'});
}
