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.8,resizeLimit:false,hideSource:true,addClick:true,resizeOptions:{},resizeOpacity:1,fxsOptions:{},generateTitle:null,showTitle:null,onBuild:$empty,onLoad:$empty,onOpen:$empty,onOpenEnd:$empty,onClose:$empty,onCloseEnd:$empty},initialize:function(element,options){this.element=$(element);this.setOptions(options);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')},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();return}var to={x:loader.width,y:loader.height};if(!this.image){this.image=(Client.Engine.webkit419)?new Element('img',{'src':loader.src}):$(loader);this.image.addClass('remo-img').inject(this.content)}else loader=null;this.openImage.create({'delay':(loader&&fast!==true)?1:null,'arguments':[to],'bind':this})()}.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:Client.getWidth()*this.options.resizeFactor,y:Client.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};if(this.options.resizeOpacity!=1)vars.opacity=[this.options.resizeOpacity,1];else this.box.setStyle('opacity',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:ReMooz.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)}this.fxs.element=$$(btn,this.title);this.fxs.set(0);this.box.inject(document.body)}});ReMooz.factory=$extend;ReMooz.factory({options:{zIndex:41,zIndexFocus:42,query:'a.remooz',optionsField:'rel',classOptions:{}},initialize:function(elements,options){this.setOptions(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);