gallery= function(id, settings){
	this.id=id;
	this.settings= settings;
	var self=this;
	DOMReady(function(){self.init();});
}

gallery.prototype.init= function(){
	this.img= DOM(this.id+'_img')
	if (this.img){
		this.a=DOM(this.id+'_link');
	}
	this.title=DOM(this.id+'_title');
	this.ul=DOM(this.id+'_list');	
	this.initList();

	var self= this;
	//navigation:
	if (this.prev=DOM(this.id+'_prev')){
		this.prev.listen('click', function(e){self.selectItem(self.prevItem());});
	}	
	if (this.next=DOM(this.id+'_next')){
		this.next.listen('click', function(e){self.selectItem(self.nextItem());})
	}
	
	if (this.settings.keyboardNav){
		DOM(null).listen('keyup', function(e){			
			if (self.context=='popup'){					
				return self.settings.popup.keyboardNav(e);
			}
			if (e.ctrlKey){
				switch (e.keyCode){
					case keyCode.left:
						self.selectItem(self.prevItem());
						return false;
					break;
					case keyCode.right:
						self.selectItem(self.nextItem());
						return false;
					break;
					default:
						return true;
					break;
				}
			}
			return true;
		});
	}
	
	if (this.settings.scrollNav){		
		var onScroll=function(e){		
			if (e.scrollDelta<0){
				self.selectItem(self.nextItem());
			}
			else{
				self.selectItem(self.prevItem());
			}
		};
		this.img.listen('scroll', onScroll);
		this.ul.listen('scroll', onScroll);
	}
	//popup:
	if (this.settings.popup){
		this.settings.popup.init(this);
		if (this.a){
			this.a.listen('click', function(e){
				self.context='popup';			
				return self.settings.popup.open(
					function(){					
						self.context='';
						self.selectItem(self.selected);
					}
				);
			});
		}
	}
	
	if (this.settings.hash){
		this.settings.hash.init(this);
	}
	this.updateNav(this.selected);
}

gallery.prototype.initList= function(){
	if (!this.ul) return;
	this.links=[];	
	var list=this.ul.getElementsByTagName('a');
	var pregSelected=/\bselected\b/;
	var a=null;
	var selected=null;
	for (var i=0; i<list.length; i++){
		a=DOM(list[i]);				
		this.initItem(a);		
		a.uid=this.links.length+0;
		this.links[a.uid]=a;
		if (pregSelected.test(a.className)){
			this.selected=a;
		}
	}
}

gallery.prototype.initItem= function(a){
	var self=this;
	a.listen('click', function(e){		
		self.selectItem(a);
	});
}

gallery.prototype.selectItem= function(a){
	if (!a) return null;	
	if (!op.lock(this.id)) return false;
	this.selected=a;
	this.updateNav(a);	
	var self= this;
	
	if (this.img){		
		//если есть "большое" изображение на странице: грузим в него
		this.settings.loader.start(this);
		gallery.util.load(this.img.getAttribute('rel')+a.getAttribute('rel'), function(img){
			self.settings.loader.complete(self, img);
			op.free(self.id);
			self.img.alt=a.title;
			self.a.title=a.title;
			if (self.title) self.title.innerHTML=a.title;
		});		
	}
	else if	(this.settings.popup){	
		//если есть попап:
		this.settings.popup.open();
	}
	else {
		return false;
	}
}

gallery.prototype.nextItem= function(){
	if (!this.selected) return null;
	
	if (this.links[this.selected.uid+1]){		
		this.selected=this.links[this.selected.uid+1];		
		return this.selected;
	}
	return null;
}

gallery.prototype.getSiblingItem= function(i){
	if (!this.selected) return null;
	return this.links[this.selected.uid+i];
}

gallery.prototype.prevItem= function(){
	if (!this.selected) return null;
	if (this.links[this.selected.uid-1]){
		this.selected=this.links[this.selected.uid-1];
		return this.selected;
	}
	return null;
}

gallery.prototype.updateNav= function(){
	if (this.selected){
		var src=this.selected.getAttribute('rel');
		for (var i=0; i<this.links.length; i++){
			if (i==this.selected.uid) this.links[i].attachClass('selected');
			else this.links[i].detachClass('selected');
		}
	}
	//this.a.name=this.id+'='+src;		
	if (this.prev){
		if (this.selected.uid>0) this.prev.detachClass('disabled');
		else this.prev.attachClass('disabled');
	}
	if (this.next){
		if (this.selected.uid<this.links.length-1) this.next.detachClass('disabled');
		else this.next.attachClass('disabled');
	}
	if (this.settings.hash){
		this.settings.hash.update(this);
	}
}
//utils:
gallery.util={
	load: function(src, callback, lock){
		var img= DOM(new Image());	
		img.listen('load', function(){
			if (lock) op.free(lock);
			callback(img);
		});
		if (lock) op.lock(lock);
		img.src=src;
	},
	hash: {
		init: function(gallery){
			var preg= new RegExp('[#|&]'+gallery.id+'\=(.*)');				
			var m=preg.exec(document.location.hash);			
			if (m){		
				
				for (var i=0; i<gallery.links.length; i++){			
					if (gallery.links[i].getAttribute('rel')==m[1]){
						
						gallery.selectItem(gallery.links[i]);
						break;
					}
				}
			}
		},
		update:function(gallery){
			if (gallery.selected){
				document.location.hash=gallery.id+'='+gallery.selected.getAttribute('rel');
			}
		}
	}
}
//popup:
gallery.popup= function(settings){
	this.settings=settings;
}

gallery.popup.prototype.init= function(gallery){
	this.isOpened=false;
	this.gallery=gallery;
	//load exists popup:	
	if (this.popup=DOM(gallery.id+'_popup')){
		this.img=DOM(gallery.id+'_popup_img');
	}
	else {
	//or create new:
		this.popup=op.create('div',gallery.id+'_popup',{style:{display:'none'}});
		this.img=op.create('img',gallery.id+'_popup_img',[], this.popup);
	}
	var self=this;
	this.img.listen('click', function(e){self.nextItem();});
}

gallery.popup.prototype.nextItem= function(){
	var next=this.gallery.nextItem();	
	if (next){
		this.show(next);
	}
	else {
		op.layer.close();
	}
}

gallery.popup.prototype.prevItem= function(){
	var prev=this.gallery.prevItem();	
	if (prev){
		this.show(prev);
	}
}

gallery.popup.prototype.open= function(onclose){
	var self=this;
	if (!self.isOpened){
		self.isOpened=true;		
		op.layer.open({
			onclose:function(){self.isOpened=false, self.popup.hide(); if (onclose) onclose();},
			id:this.id+'_popup',
			settings:this.settings
		});
	}	
	this.show(this.gallery.selected);
}

gallery.popup.prototype.show= function(a){
	var self=this;
	setElementOpacity(self.img,0.5);
	
	var imgURL=null;
	if (a.getAttribute('rel')) imgURL=a.getAttribute('rel');
	else imgURL=a.href;
	
	gallery.util.load(imgURL, function(img){		
		var settings=self.settings;
		self.popup.hide();
		if (this.settings.reloadPopup){
			//если есть логика реализации попапа:
			var size=this.settings.reloadPopup(img);			
			settings.width=size.width;
			settings.height=size.height;
		}
		else {
			//высчитываем:			
			settings.width=img.width+parseInt(self.popup.style.paddingLeft)+parseInt(self.popup.style.paddingRight);
			settings.height=img.height+parseInt(self.popup.style.paddingTop)+parseInt(self.popup.style.paddingBottom);			
		}		
		op.layer.resize(settings, function(){			
			self.img.src=img.src;
			self.img.width=img.width;
			self.img.height=img.height;
			self.popup.detachClass('loading');								
			op.layer.add(self.popup);
			setElementOpacity(self.img,1);
			self.popup.show();
		});
		
	}, this.gallery.id);
}

gallery.popup.prototype.keyboardNav= function(e){
	
	if (e.ctrlKey){
		if (e.keyCode==keyCode.left){
			this.prevItem();
		}
		else if (e.keyCode==keyCode.right){
			this.nextItem();
		}
	}
	return true;
}

gallery.loader= function(settings){
	this.settings=settings;
}
gallery.loader.prototype.start =function(g){
	setElementOpacity(g.img, this.settings.opacity);
}
gallery.loader.prototype.complete= function(g, img){
	setElementOpacity(g.img, 1);
	g.img.src=img.src;
}

gallery.std= {
	hash: 	null,//gallery.util.hash,
	popup:	new gallery.popup([]),
	loader:	new gallery.loader({opacity:0.5}),	
	keyboardNav:true,
	scrollNav:false
}
