var ReMooz=new Class({Implements:[Events,Options],options:{url:null,type:'image',className:null,positionToCenter:false,dragging:true,shadow:true,resize:true,margin:20,resizeFactor:0.95,resizeLimit:null,hideSource:true,addClick:true,resizeOptions:{},resizeOpacity:1,fxsOptions:{},generateTitle:null,showTitle:null,onBuild:$empty,onLoad:$empty,onOpen:$empty,onOpenEnd:$empty,onClose:$empty,onCloseEnd:$empty,next:null,back:null},initialize:function(element,options){this.setOptions(options);this.element=$(element);this.url=this.options.url||this.element.href||this.element.src;this.addEvent('onBlur',function(){this.focussed=false;this.box.removeClass('remo-box-focus').setStyle('z-index',ReMooz.options.zIndex);}.bind(this));this.addEvent('onFocus',function(){this.focussed=true;this.box.addClass('remo-box-focus').setStyle('z-index',ReMooz.options.zIndexFocus);}.bind(this));this.element.addClass('remo-zoom-in').addEvent('trash',this.destroy.bind(this));this.clickEvent=function(e){this.open.delay(1,this);return false;}.bind(this);if(this.options.addClick)this.bindToElement();},destroy:function(unload){if(this.box&&!unload)this.box.destroy();this.box=this.boxFx=this.content=null;return null;},bindToElement:function(el){($(el)||this.element).addEvent('click',this.clickEvent);return this;},getSourceCoordinates:function(){var coords=this.element.getCoordinates();delete coords.right;delete coords.bottom;return coords;},open:function(e){if(this.opened)return(e)?this.close():this;this.opened=true;if(!this.box)this.build();this.coords=this.getSourceCoordinates();this.coords.opacity=0.7;this.boxFx.set(this.coords);this.box.setStyle('display','').addClass('remo-loading');this.boxDrag=this.boxDrag||new Drag.Move(this.box,{'snap':15,'onStart':function(){if(!this.focussed&&!this.loading){ReMooz.focus(this);this.focusEvent=true;}}.bind(this),'onSnap':function(){this.dragging=true;this.box.addClass('remo-box-dragging');}.bind(this),'onComplete':function(){if(!this.dragging&&!this.focusEvent)this.close();this.dragging=this.focusEvent=false;this.box.removeClass('remo-box-dragging');}.bind(this)}).detach();this.fireEvent('onLoad');this.loadImage();return this;},openEnd:function(){ReMooz.open(this);this.zoomed=true;if(this.options.dragging)this.boxDrag.attach();this.fxs.start(0,1);this.fireEvent('onOpenEnd');},close:function(){if(!this.opened)return this;this.fireEvent('onClose');this.opened=this.zoomed=false;ReMooz.close(this);if(this.loading){this.box.setStyle('display','none');return this;}
this.boxDrag.detach();this.fxs.set(0);if(this.boxFx.timer)this.boxFx.clearChain();var vars=this.getSourceCoordinates();if(this.options.resizeOpacity!=1)vars.opacity=this.options.resizeOpacity;this.boxFx.start(vars).chain(this.closeEnd.bind(this));return this;},closeEnd:function(){this.element.setStyle('visibility','visible');this.box.setStyle('display','none');this.fireEvent('onCloseEnd');},to:null,loadImage:function(){this.loading=true;var loader=new Image();loader.onload=loader.onabort=loader.onerror=function(fast){this.loading=loader.onload=loader.onabort=loader.onerror=null;if(!loader.width||!this.opened){this.close();}
if(!this.image){this.image=new Element('img',{'src':this.options.source});this.image.load=function(){if(!this.to)this.to={x:this.image.width,y:this.image.height};this.openImage.create({'delay':null,'arguments':[this.to],'bind':this})();this.image.addClass('remo-img').inject(this.content);}.bind(this);var timerTime=50;var imageTimer=setInterval(function(){if(this.image.complete){this.image.load();clearInterval(imageTimer);}
timerTime=260;}.bind(this),timerTime);}
else{this.image.load();}}.bind(this);loader.src=this.url;if(loader&&loader.complete&&loader.onload)loader.onload(true);},openImage:function(size){if(this.options.hideSource)this.element.setStyle('visibility','hidden');this[(this.options.resize)?'zoomRelativeTo':'zoomTo'](size);},zoomRelativeTo:function(to){var max=this.options.resizeLimit||{x:Window.getWidth()*this.options.resizeFactor,y:Window.getHeight()*this.options.resizeFactor};for(var i=2;i--;){if(to.x>max.x){to.y*=max.x/to.x;to.x=max.x;}else if(to.y>max.y){to.x*=max.y/to.y;to.y=max.y;}}
return this.zoomTo({'x':to.x.toInt(),'y':to.y.toInt()});},zoomTo:function(to){var box=Window.getSize();var pos=(!this.options.positionToCenter)?{x:(this.coords.left+(this.coords.width/2)-to.x/2).toInt().limit(box.scroll.x+this.options.margin,box.scroll.x+box.size.x-this.options.margin-to.x),y:(this.coords.top+(this.coords.height/2)-to.y/2).toInt().limit(box.scroll.y+this.options.margin,box.scroll.y+box.size.y-this.options.margin-to.y)}:{x:box.scroll.x+((box.size.x-to.x)/2).toInt(),y:box.scroll.y+((box.size.y-to.y)/2).toInt()};this.box.removeClass('remo-loading');this.fireEvent('onOpen');var vars={'left':pos.x,'top':pos.y,'width':to.x,'height':to.y,'opacity':0};vars.opacity=[this.options.resizeOpacity,1];this.boxFx.start(vars).chain(this.openEnd.bind(this));},generateTitle:function(){var title=this.options.title||this.element.getProperty('title');if(!title)return false;title=title.split(' :: ');var ret=[new Element('h4').setHTML(title[0])];if(title[1])ret.push(new Element('p').setHTML(title[1]));return ret;},build:function(){this.box=new Element('div',{'class':'remo-box',styles:{display:'none',zIndex:this.options.zIndex},events:{click:function(){if(this.zoomed)return true;this.close();return false;}.bind(this)}});if(this.options.className)this.box.addClass(this.options.className);this.boxFx=new Fx.Styles(this.box,$merge({duration:400,unit:'px',transition:Fx.Transitions.Quart.easeOut,wait:false},this.options.resizeOptions));if(this.options.shadow){var shadow=new Element('div',{'class':'remo-bg-wrap'}).inject(this.box);['n','ne','e','se','s','sw','w','nw'].each(function(dir){new Element('div',{'class':'remo-bg remo-bg-'+dir}).inject(shadow);});var shadowFx=new Fx.Style(shadow,'opacity',{wait:false}).hide();this.addEvent('onOpen',shadowFx.start.pass(1,shadowFx)).addEvent('onClose',shadowFx.hide.bind(shadowFx));}
this.content=new Element('div',{'class':'remo-content'}).inject(this.box);var btn=new Element('a',{'class':'remo-btn-close',events:{'click':this.close.bind(this)}}).inject(this.box);this.fxs=new Fx.Style(btn,'opacity',$merge({duration:300,wait:false},this.options.fxsOptions));var title=(this.options.generateTitle||this.generateTitle).call(this);if(title){this.title=new Element('div',{'class':'remo-title'}).inject(new Element('div',{'class':'remo-title-wrap'}).inject(this.box));new Element('div',{'class':'remo-title-bg'}).setOpacity(0.8).inject(this.title);new Element('div',{'class':'remo-title-txt'})
[$type(title)=='string'?'setHTML':'adopt'](title).inject(this.title);}
if(this.options.next){var next=new Element('div',{'class':'remo-next'}).setOpacity(0.3).inject(this.box);next.addEvent('click',function(){this.close();this.options.next();}.bind(this));var fxs=new Fx.Style(next,'opacity',{'duration':200,'wait':false});next.addEvent('mouseover',function(){fxs.start(1);});next.addEvent('mouseout',function(){fxs.start(0.3);});}
if(this.options.back){var back=new Element('div',{'class':'remo-back'}).setOpacity(0.3).inject(this.box);back.addEvent('click',function(){this.close();this.options.back();}.bind(this));var fxs2=new Fx.Style(back,'opacity',{'duration':200,'wait':false});back.addEvent('mouseover',function(){fxs2.start(1);});back.addEvent('mouseout',function(){fxs2.start(0.3);});}
this.fxs.element=$$(btn,this.title);this.fxs.set(0);this.box.inject(document.body);}});ReMooz.factory=$extend;ReMooz.factory(ReMooz,{options:{zIndex:1200,zIndexFocus:1201,query:'a.remooz',optionsField:'rel',classOptions:{}},initialize:function(elements,options){return $$(elements||this.options.query).map(function(el){var obj=el.getProperty(this.options.optionsField);if(obj&&(obj=Json.decode(obj,true)))obj=$merge(obj,this.options.classOptions);return(el.$attributes.remooz=new ReMooz(el,obj||this.options.classOptions));},this);},stack:[],open:function(obj){this.focus(obj);},close:function(obj){var last=this.stack.length-1;if(this.stack.indexOf(obj)==last)this.focus(this.stack[last-1]);this.stack.remove(obj);},focus:function(obj){var last=this.stack.getLast();if(!obj||last==obj)return;if(last)last.fireEvent('onBlur',[last],10);obj.fireEvent('onFocus',[obj],10);this.stack.remove(obj).push(obj);}});ReMooz.factory(new Options);