//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

MooTools.More={version:"1.2.4.4",build:"6f6057dc645fdb7547689183b2311063bd653ddf"};Element.implement({measure:function(e){var g=function(h){return !!(!h||h.offsetHeight||h.offsetWidth);
};if(g(this)){return e.apply(this);}var d=this.getParent(),f=[],b=[];while(!g(d)&&d!=document.body){b.push(d.expose());d=d.getParent();}var c=this.expose();
var a=e.apply(this);c();b.each(function(h){h();});return a;},expose:function(){if(this.getStyle("display")!="none"){return $empty;}var a=this.style.cssText;
this.setStyles({display:"block",position:"absolute",visibility:"hidden"});return function(){this.style.cssText=a;}.bind(this);},getDimensions:function(a){a=$merge({computeSize:false},a);
var f={};var d=function(g,e){return(e.computeSize)?g.getComputedSize(e):g.getSize();};var b=this.getParent("body");if(b&&this.getStyle("display")=="none"){f=this.measure(function(){return d(this,a);
});}else{if(b){try{f=d(this,a);}catch(c){}}else{f={x:0,y:0};}}return $chk(f.x)?$extend(f,{width:f.x,height:f.y}):$extend(f,{x:f.width,y:f.height});},getComputedSize:function(a){a=$merge({styles:["padding","border"],plains:{height:["top","bottom"],width:["left","right"]},mode:"both"},a);
var c={width:0,height:0};switch(a.mode){case"vertical":delete c.width;delete a.plains.width;break;case"horizontal":delete c.height;delete a.plains.height;
break;}var b=[];$each(a.plains,function(g,f){g.each(function(h){a.styles.each(function(i){b.push((i=="border")?i+"-"+h+"-width":i+"-"+h);});});});var e={};
b.each(function(f){e[f]=this.getComputedStyle(f);},this);var d=[];$each(a.plains,function(g,f){var h=f.capitalize();c["total"+h]=c["computed"+h]=0;g.each(function(i){c["computed"+i.capitalize()]=0;
b.each(function(k,j){if(k.test(i)){e[k]=e[k].toInt()||0;c["total"+h]=c["total"+h]+e[k];c["computed"+i.capitalize()]=c["computed"+i.capitalize()]+e[k];}if(k.test(i)&&f!=k&&(k.test("border")||k.test("padding"))&&!d.contains(k)){d.push(k);
c["computed"+h]=c["computed"+h]-e[k];}});});});["Width","Height"].each(function(g){var f=g.toLowerCase();if(!$chk(c[f])){return;}c[f]=c[f]+this["offset"+g]+c["computed"+g];
c["total"+g]=c[f]+c["total"+g];delete c["computed"+g];},this);return $extend(e,c);}});Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(b,a){this.elements=this.subject=$$(b);
this.parent(a);},compute:function(g,h,j){var c={};for(var d in g){var a=g[d],e=h[d],f=c[d]={};for(var b in a){f[b]=this.parent(a[b],e[b],j);}}return c;
},set:function(b){for(var c in b){var a=b[c];for(var d in a){this.render(this.elements[c],d,a[d],this.options.unit);}}return this;},start:function(c){if(!this.check(c)){return this;
}var h={},j={};for(var d in c){var f=c[d],a=h[d]={},g=j[d]={};for(var b in f){var e=this.prepare(this.elements[d],b,f[b]);a[b]=e.from;g[b]=e.to;}}return this.parent(h,j);
}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:"click",initialDisplayFx:true,returnHeightToAuto:true},initialize:function(){var c=Array.link(arguments,{container:Element.type,options:Object.type,togglers:$defined,elements:$defined});
this.parent(c.elements,c.options);this.togglers=$$(c.togglers);this.previous=-1;this.internalChain=new Chain();if(this.options.alwaysHide){this.options.wait=true;
}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false;
}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth";
}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";}for(var b=0,a=this.togglers.length;b<a;b++){this.addSection(this.togglers[b],this.elements[b]);
}this.elements.each(function(e,d){if(this.options.show===d){this.fireEvent("active",[this.togglers[d],e]);}else{for(var f in this.effects){e.setStyle(f,0);
}}},this);if($chk(this.options.display)||this.options.initialDisplayFx===false){this.display(this.options.display,this.options.initialDisplayFx);}if(this.options.fixedHeight!==false){this.options.returnHeightToAuto=false;
}this.addEvent("complete",this.internalChain.callChain.bind(this.internalChain));},addSection:function(e,c){e=document.id(e);c=document.id(c);var f=this.togglers.contains(e);
this.togglers.include(e);this.elements.include(c);var a=this.togglers.indexOf(e);var b=this.display.bind(this,a);e.store("accordion:display",b);e.addEvent(this.options.trigger,b);
if(this.options.height){c.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(this.options.width){c.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
}c.fullOpacity=1;if(this.options.fixedWidth){c.fullWidth=this.options.fixedWidth;}if(this.options.fixedHeight){c.fullHeight=this.options.fixedHeight;}c.setStyle("overflow","hidden");
if(!f){for(var d in this.effects){c.setStyle(d,0);}}return this;},detach:function(){this.togglers.each(function(a){a.removeEvent(this.options.trigger,a.retrieve("accordion:display"));
},this);},display:function(a,b){if(!this.check(a,b)){return this;}b=$pick(b,true);if(this.options.returnHeightToAuto){var d=this.elements[this.previous];
if(d&&!this.selfHidden){for(var c in this.effects){d.setStyle(c,d[this.effects[c]]);}}}a=($type(a)=="element")?this.elements.indexOf(a):a;if((this.timer&&this.options.wait)||(a===this.previous&&!this.options.alwaysHide)){return this;
}this.previous=a;var e={};this.elements.each(function(h,g){e[g]={};var f;if(g!=a){f=true;}else{if(this.options.alwaysHide&&((h.offsetHeight>0&&this.options.height)||h.offsetWidth>0&&this.options.width)){f=true;
this.selfHidden=true;}}this.fireEvent(f?"background":"active",[this.togglers[g],h]);for(var j in this.effects){e[g][j]=f?0:h[this.effects[j]];}},this);
this.internalChain.chain(function(){if(this.options.returnHeightToAuto&&!this.selfHidden){var f=this.elements[a];if(f){f.setStyle("height","auto");}}}.bind(this));
return b?this.start(e):this.set(e);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);var a=Array.link(arguments,{container:Element.type});
this.container=a.container;},addSection:function(c,b,e){c=document.id(c);b=document.id(b);var d=this.togglers.contains(c);var a=this.togglers.length;if(a&&(!d||e)){e=$pick(e,a-1);
c.inject(this.togglers[e],"before");b.inject(c,"after");}else{if(this.container&&!d){c.inject(this.container);b.inject(this.container);}}return this.parent.apply(this,arguments);
}});Fx.Scroll=new Class({Extends:Fx,options:{offset:{x:0,y:0},wheelStops:true},initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);
var d=this.cancel.bind(this,false);if($type(this.element)!="element"){this.element=document.id(this.element.getDocument().body);}var c=this.element;if(this.options.wheelStops){this.addEvent("start",function(){c.addEvent("mousewheel",d);
},true);this.addEvent("complete",function(){c.removeEvent("mousewheel",d);},true);}},set:function(){var a=Array.flatten(arguments);if(Browser.Engine.gecko){a=[Math.round(a[0]),Math.round(a[1])];
}this.element.scrollTo(a[0],a[1]);},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(c,g){if(!this.check(c,g)){return this;
}var e=this.element.getScrollSize(),b=this.element.getScroll(),d={x:c,y:g};for(var f in d){var a=e[f];if($chk(d[f])){d[f]=($type(d[f])=="number")?d[f]:a;
}else{d[f]=b[f];}d[f]+=this.options.offset[f];}return this.parent([b.x,b.y],[d.x,d.y]);},toTop:function(){return this.start(false,0);},toLeft:function(){return this.start(0,false);
},toRight:function(){return this.start("right",false);},toBottom:function(){return this.start(false,"bottom");},toElement:function(b){var a=document.id(b).getPosition(this.element);
return this.start(a.x,a.y);},scrollIntoView:function(c,e,d){e=e?$splat(e):["x","y"];var h={};c=document.id(c);var f=c.getPosition(this.element);var i=c.getSize();
var g=this.element.getScroll();var a=this.element.getSize();var b={x:f.x+i.x,y:f.y+i.y};["x","y"].each(function(j){if(e.contains(j)){if(b[j]>g[j]+a[j]){h[j]=b[j]-a[j];
}if(f[j]<g[j]){h[j]=f[j];}}if(h[j]==null){h[j]=g[j];}if(d&&d[j]){h[j]=h[j]+d[j];}},this);if(h.x!=g.x||h.y!=g.y){this.start(h.x,h.y);}return this;},scrollToCenter:function(c,e,d){e=e?$splat(e):["x","y"];
c=$(c);var h={},f=c.getPosition(this.element),i=c.getSize(),g=this.element.getScroll(),a=this.element.getSize(),b={x:f.x+i.x,y:f.y+i.y};["x","y"].each(function(j){if(e.contains(j)){h[j]=f[j]-(a[j]-i[j])/2;
}if(h[j]==null){h[j]=g[j];}if(d&&d[j]){h[j]=h[j]+d[j];}},this);if(h.x!=g.x||h.y!=g.y){this.start(h.x,h.y);}return this;}});Fx.Sort=new Class({Extends:Fx.Elements,options:{mode:"vertical"},initialize:function(b,a){this.parent(b,a);
this.elements.each(function(c){if(c.getStyle("position")=="static"){c.setStyle("position","relative");}});this.setDefaultOrder();},setDefaultOrder:function(){this.currentOrder=this.elements.map(function(b,a){return a;
});},sort:function(e){if($type(e)!="array"){return false;}var i=0,a=0,c={},h={},d=this.options.mode=="vertical";var f=this.elements.map(function(m,j){var l=m.getComputedSize({styles:["border","padding","margin"]});
var n;if(d){n={top:i,margin:l["margin-top"],height:l.totalHeight};i+=n.height-l["margin-top"];}else{n={left:a,margin:l["margin-left"],width:l.totalWidth};
a+=n.width;}var k=d?"top":"left";h[j]={};var o=m.getStyle(k).toInt();h[j][k]=o||0;return n;},this);this.set(h);e=e.map(function(j){return j.toInt();});
if(e.length!=this.elements.length){this.currentOrder.each(function(j){if(!e.contains(j)){e.push(j);}});if(e.length>this.elements.length){e.splice(this.elements.length-1,e.length-this.elements.length);
}}var b=i=a=0;e.each(function(l,j){var k={};if(d){k.top=i-f[l].top-b;i+=f[l].height;}else{k.left=a-f[l].left;a+=f[l].width;}b=b+f[l].margin;c[l]=k;},this);
var g={};$A(e).sort().each(function(j){g[j]=c[j];});this.start(g);this.currentOrder=e;return this;},rearrangeDOM:function(a){a=a||this.currentOrder;var b=this.elements[0].getParent();
var c=[];this.elements.setStyle("opacity",0);a.each(function(d){c.push(this.elements[d].inject(b).setStyles({top:0,left:0}));},this);this.elements.setStyle("opacity",1);
this.elements=$$(c);this.setDefaultOrder();return this;},getDefaultOrder:function(){return this.elements.map(function(b,a){return a;});},forward:function(){return this.sort(this.getDefaultOrder());
},backward:function(){return this.sort(this.getDefaultOrder().reverse());},reverse:function(){return this.sort(this.currentOrder.reverse());},sortByElements:function(a){return this.sort(a.map(function(b){return this.elements.indexOf(b);
},this));},swap:function(c,b){if($type(c)=="element"){c=this.elements.indexOf(c);}if($type(b)=="element"){b=this.elements.indexOf(b);}var a=$A(this.currentOrder);
a[this.currentOrder.indexOf(c)]=b;a[this.currentOrder.indexOf(b)]=c;return this.sort(a);}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Object.type,element:$defined});
this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=$type(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element;
this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.Engine.trident)?"selectstart":"mousedown";this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)};
this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
return this;},start:function(c){if(c.rightClick){return;}if(this.options.preventDefault){c.preventDefault();}if(this.options.stopPropagation){c.stopPropagation();
}this.mouse.start=c.page;this.fireEvent("beforeStart",this.element);var a=this.options.limit;this.limit={x:[],y:[]};for(var d in this.options.modifiers){if(!this.options.modifiers[d]){continue;
}if(this.options.style){this.value.now[d]=this.element.getStyle(this.options.modifiers[d]).toInt();}else{this.value.now[d]=this.element[this.options.modifiers[d]];
}if(this.options.invert){this.value.now[d]*=-1;}this.mouse.pos[d]=c.page[d]-this.value.now[d];if(a&&a[d]){for(var b=2;b--;b){if($chk(a[d][b])){this.limit[d][b]=$lambda(a[d][b])();
}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});
this.document.addEvent(this.selection,this.bound.eventStop);},check:function(a){if(this.options.preventDefault){a.preventDefault();}var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));
if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element);
}},drag:function(a){if(this.options.preventDefault){a.preventDefault();}this.mouse.now=a.page;for(var b in this.options.modifiers){if(!this.options.modifiers[b]){continue;
}this.value.now[b]=this.mouse.now[b]-this.mouse.pos[b];if(this.options.invert){this.value.now[b]*=-1;}if(this.options.limit&&this.limit[b]){if($chk(this.limit[b][1])&&(this.value.now[b]>this.limit[b][1])){this.value.now[b]=this.limit[b][1];
}else{if($chk(this.limit[b][0])&&(this.value.now[b]<this.limit[b][0])){this.value.now[b]=this.limit[b][0];}}}if(this.options.grid[b]){this.value.now[b]-=((this.value.now[b]-(this.limit[b][0]||0))%this.options.grid[b]);
}if(this.options.style){this.element.setStyle(this.options.modifiers[b],this.value.now[b]+this.options.unit);}else{this.element[this.options.modifiers[b]]=this.value.now[b];
}}this.fireEvent("drag",[this.element,a]);},cancel:function(a){this.document.removeEvent("mousemove",this.bound.check);this.document.removeEvent("mouseup",this.bound.cancel);
if(a){this.document.removeEvent(this.selection,this.bound.eventStop);this.fireEvent("cancel",this.element);}},stop:function(a){this.document.removeEvent(this.selection,this.bound.eventStop);
this.document.removeEvent("mousemove",this.bound.drag);this.document.removeEvent("mouseup",this.bound.stop);if(a){this.fireEvent("complete",[this.element,a]);
}}});Element.implement({makeResizable:function(a){var b=new Drag(this,$merge({modifiers:{x:"width",y:"height"}},a));this.store("resizer",b);return b.addEvent("drag",function(){this.fireEvent("resize",b);
}.bind(this));}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false,precalculate:false,includeMargins:true,checkDroppables:true},initialize:function(b,a){this.parent(b,a);
b=this.element;this.droppables=$$(this.options.droppables);this.container=document.id(this.options.container);if(this.container&&$type(this.container)!="element"){this.container=document.id(this.container.getDocument().body);
}var c=b.getStyles("left","top","position");if(c.left=="auto"||c.top=="auto"){b.setPosition(b.getPosition(b.getOffsetParent()));}if(c.position=="static"){b.setStyle("position","absolute");
}this.addEvent("start",this.checkDroppables,true);this.overed=null;},start:function(a){if(this.container){this.options.limit=this.calculateLimit();}if(this.options.precalculate){this.positions=this.droppables.map(function(b){return b.getCoordinates();
});}this.parent(a);},calculateLimit:function(){var d=this.element.getOffsetParent(),g=this.container.getCoordinates(d),f={},c={},b={},i={},k={};["top","right","bottom","left"].each(function(o){f[o]=this.container.getStyle("border-"+o).toInt();
b[o]=this.element.getStyle("border-"+o).toInt();c[o]=this.element.getStyle("margin-"+o).toInt();i[o]=this.container.getStyle("margin-"+o).toInt();k[o]=d.getStyle("padding-"+o).toInt();
},this);var e=this.element.offsetWidth+c.left+c.right,n=this.element.offsetHeight+c.top+c.bottom,h=0,j=0,m=g.right-f.right-e,a=g.bottom-f.bottom-n;if(this.options.includeMargins){h+=c.left;
j+=c.top;}else{m+=c.right;a+=c.bottom;}if(this.element.getStyle("position")=="relative"){var l=this.element.getCoordinates(d);l.left-=this.element.getStyle("left").toInt();
l.top-=this.element.getStyle("top").toInt();h+=f.left-l.left;j+=f.top-l.top;m+=c.left-l.left;a+=c.top-l.top;if(this.container!=d){h+=i.left+k.left;j+=(Browser.Engine.trident4?0:i.top)+k.top;
}}else{h-=c.left;j-=c.top;if(this.container==d){m-=f.left;a-=f.top;}else{h+=g.left+f.left;j+=g.top+f.top;}}return{x:[h,m],y:[j,a]};},checkAgainst:function(c,b){c=(this.positions)?this.positions[b]:c.getCoordinates();
var a=this.mouse.now;return(a.x>c.left&&a.x<c.right&&a.y<c.bottom&&a.y>c.top);},checkDroppables:function(){var a=this.droppables.filter(this.checkAgainst,this).getLast();
if(this.overed!=a){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);}if(a){this.fireEvent("enter",[this.element,a]);}this.overed=a;}},drag:function(a){this.parent(a);
if(this.options.checkDroppables&&this.droppables.length){this.checkDroppables();}},stop:function(a){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed,a]);
this.overed=null;return this.parent(a);}});Element.implement({makeDraggable:function(a){var b=new Drag.Move(this,a);this.store("dragger",b);return b;}});
var Sortables=new Class({Implements:[Events,Options],options:{snap:4,opacity:1,clone:false,revert:false,handle:false,constrain:false},initialize:function(a,b){this.setOptions(b);
this.elements=[];this.lists=[];this.idle=true;this.addLists($$(document.id(a)||a));if(!this.options.clone){this.options.revert=false;}if(this.options.revert){this.effect=new Fx.Morph(null,$merge({duration:250,link:"cancel"},this.options.revert));
}},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(a){this.elements.push(a);
var b=a.retrieve("sortables:start",this.start.bindWithEvent(this,a));(this.options.handle?a.getElement(this.options.handle)||a:a).addEvent("mousedown",b);
},this);return this;},addLists:function(){Array.flatten(arguments).each(function(a){this.lists.push(a);this.addItems(a.getChildren());},this);return this;
},removeItems:function(){return $$(Array.flatten(arguments).map(function(a){this.elements.erase(a);var b=a.retrieve("sortables:start");(this.options.handle?a.getElement(this.options.handle)||a:a).removeEvent("mousedown",b);
return a;},this));},removeLists:function(){return $$(Array.flatten(arguments).map(function(a){this.lists.erase(a);this.removeItems(a.getChildren());return a;
},this));},getClone:function(b,a){if(!this.options.clone){return new Element("div").inject(document.body);}if($type(this.options.clone)=="function"){return this.options.clone.call(this,b,a,this.list);
}var c=a.clone(true).setStyles({margin:"0px",position:"absolute",visibility:"hidden",width:a.getStyle("width")});if(c.get("html").test("radio")){c.getElements("input[type=radio]").each(function(d,e){d.set("name","clone_"+e);
});}return c.inject(this.list).setPosition(a.getPosition(a.getOffsetParent()));},getDroppables:function(){var a=this.list.getChildren();if(!this.options.constrain){a=this.lists.concat(a).erase(this.list);
}return a.erase(this.clone).erase(this.element);},insert:function(c,b){var a="inside";if(this.lists.contains(b)){this.list=b;this.drag.droppables=this.getDroppables();
}else{a=this.element.getAllPrevious().contains(b)?"before":"after";}this.element.inject(b,a);this.fireEvent("sort",[this.element,this.clone]);},start:function(b,a){if(!this.idle){return;
}this.idle=false;this.element=a;this.opacity=a.get("opacity");this.list=a.getParent();this.clone=this.getClone(b,a);this.drag=new Drag.Move(this.clone,{snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables(),onSnap:function(){b.stop();
this.clone.setStyle("visibility","visible");this.element.set("opacity",this.options.opacity||0);this.fireEvent("start",[this.element,this.clone]);}.bind(this),onEnter:this.insert.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)});
this.clone.inject(this.element,"before");this.drag.start(b);},end:function(){this.drag.detach();this.element.set("opacity",this.opacity);if(this.effect){var a=this.element.getStyles("width","height");
var b=this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));this.effect.element=this.clone;this.effect.start({top:b.top,left:b.left,width:a.width,height:a.height,opacity:0.25}).chain(this.reset.bind(this));
}else{this.reset();}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent("complete",this.element);},serialize:function(){var c=Array.link(arguments,{modifier:Function.type,index:$defined});
var b=this.lists.map(function(d){return d.getChildren().map(c.modifier||function(e){return e.get("id");},this);},this);var a=c.index;if(this.lists.length==1){a=0;
}return $chk(a)&&a>=0&&a<this.lists.length?b[a]:b;}});var Asset={javascript:function(f,d){d=$extend({onload:$empty,document:document,check:$lambda(true)},d);
if(d.onLoad){d.onload=d.onLoad;}var b=new Element("script",{src:f,type:"text/javascript"});var e=d.onload.bind(b),a=d.check,g=d.document;delete d.onload;
delete d.check;delete d.document;b.addEvents({load:e,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){e();}}}).set(d);if(Browser.Engine.webkit419){var c=(function(){if(!$try(a)){return;
}$clear(c);e();}).periodical(50);}return b.inject(g.head);},css:function(b,a){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head);
},image:function(c,b){b=$merge({onload:$empty,onabort:$empty,onerror:$empty},b);var d=new Image();var a=document.id(d)||new Element("img");["load","abort","error"].each(function(e){var g="on"+e;
var f=e.capitalize();if(b["on"+f]){b[g]=b["on"+f];}var h=b[g];delete b[g];d[g]=function(){if(!d){return;}if(!a.parentNode){a.width=d.width;a.height=d.height;
}d=d.onload=d.onabort=d.onerror=null;h.delay(1,a,a);a.fireEvent(e,a,1);};});d.src=a.src=c;if(d&&d.complete){d.onload.delay(1);}return a.set(b);},images:function(d,c){c=$merge({onComplete:$empty,onProgress:$empty,onError:$empty,properties:{}},c);
d=$splat(d);var a=[];var b=0;return new Elements(d.map(function(e){return Asset.image(e,$extend(c.properties,{onload:function(){c.onProgress.call(this,b,d.indexOf(e));
b++;if(b==d.length){c.onComplete();}},onerror:function(){c.onError.call(this,b,d.indexOf(e));b++;if(b==d.length){c.onComplete();}}}));}));}};(function(){var a=function(c,b){return(c)?($type(c)=="function"?c(b):b.get(c)):"";
};this.Tips=new Class({Implements:[Events,Options],options:{onShow:function(){this.tip.setStyle("display","block");},onHide:function(){this.tip.setStyle("display","none");
},title:"title",text:function(b){return b.get("rel")||b.get("href");},showDelay:100,hideDelay:100,className:"tip-wrap",offset:{x:16,y:16},windowPadding:{x:0,y:0},fixed:false},initialize:function(){var b=Array.link(arguments,{options:Object.type,elements:$defined});
this.setOptions(b.options);if(b.elements){this.attach(b.elements);}this.container=new Element("div",{"class":"tip"});},toElement:function(){if(this.tip){return this.tip;
}return this.tip=new Element("div",{"class":this.options.className,styles:{position:"absolute",top:0,left:0}}).adopt(new Element("div",{"class":"tip-top"}),this.container,new Element("div",{"class":"tip-bottom"})).inject(document.body);
},attach:function(b){$$(b).each(function(d){var f=a(this.options.title,d),e=a(this.options.text,d);d.erase("title").store("tip:native",f).retrieve("tip:title",f);
d.retrieve("tip:text",e);this.fireEvent("attach",[d]);var c=["enter","leave"];if(!this.options.fixed){c.push("move");}c.each(function(h){var g=d.retrieve("tip:"+h);
if(!g){g=this["element"+h.capitalize()].bindWithEvent(this,d);}d.store("tip:"+h,g).addEvent("mouse"+h,g);},this);},this);return this;},detach:function(b){$$(b).each(function(d){["enter","leave","move"].each(function(e){d.removeEvent("mouse"+e,d.retrieve("tip:"+e)).eliminate("tip:"+e);
});this.fireEvent("detach",[d]);if(this.options.title=="title"){var c=d.retrieve("tip:native");if(c){d.set("title",c);}}},this);return this;},elementEnter:function(c,b){this.container.empty();
["title","text"].each(function(e){var d=b.retrieve("tip:"+e);if(d){this.fill(new Element("div",{"class":"tip-"+e}).inject(this.container),d);}},this);$clear(this.timer);
this.timer=(function(){this.show(this,b);this.position((this.options.fixed)?{page:b.getPosition()}:c);}).delay(this.options.showDelay,this);},elementLeave:function(c,b){$clear(this.timer);
this.timer=this.hide.delay(this.options.hideDelay,this,b);this.fireForParent(c,b);},fireForParent:function(c,b){b=b.getParent();if(!b||b==document.body){return;
}if(b.retrieve("tip:enter")){b.fireEvent("mouseenter",c);}else{this.fireForParent(c,b);}},elementMove:function(c,b){this.position(c);},position:function(e){if(!this.tip){document.id(this);
}var c=window.getSize(),b=window.getScroll(),f={x:this.tip.offsetWidth,y:this.tip.offsetHeight},d={x:"left",y:"top"},g={};for(var h in d){g[d[h]]=e.page[h]+this.options.offset[h];
if((g[d[h]]+f[h]-b[h])>c[h]-this.options.windowPadding[h]){g[d[h]]=e.page[h]-this.options.offset[h]-f[h];}}this.tip.setStyles(g);},fill:function(b,c){if(typeof c=="string"){b.set("html",c);
}else{b.adopt(c);}},show:function(b){if(!this.tip){document.id(this);}this.fireEvent("show",[this.tip,b]);},hide:function(b){if(!this.tip){document.id(this);
}this.fireEvent("hide",[this.tip,b]);}});})();/* 
 * MarkerManager, v1.0
 * Copyright (c) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 *
 *
 * Author: Doug Ricket, others
 * 
 * Marker manager is an interface between the map and the user, designed
 * to manage adding and removing many points when the viewport changes.
 *
 *
 * Algorithm: The MM places its markers onto a grid, similar to the map tiles.
 * When the user moves the viewport, the MM computes which grid cells have
 * entered or left the viewport, and shows or hides all the markers in those
 * cells.
 * (If the users scrolls the viewport beyond the markers that are loaded,
 * no markers will be visible until the EVENT_moveend triggers an update.)
 *
 * In practical consequences, this allows 10,000 markers to be distributed over
 * a large area, and as long as only 100-200 are visible in any given viewport,
 * the user will see good performance corresponding to the 100 visible markers,
 * rather than poor performance corresponding to the total 10,000 markers.
 *
 * Note that some code is optimized for speed over space,
 * with the goal of accommodating thousands of markers.
 *
 */



/**
 * Creates a new MarkerManager that will show/hide markers on a map.
 *
 * @constructor
 * @param {Map} map The map to manage.
 * @param {Object} opt_opts A container for optional arguments:
 *   {Number} maxZoom The maximum zoom level for which to create tiles.
 *   {Number} borderPadding The width in pixels beyond the map border,
 *                   where markers should be display.
 *   {Boolean} trackMarkers Whether or not this manager should track marker
 *                   movements.
 */
;
function MarkerManager(map, opt_opts) {
  var me = this;
  me.map_ = map;
  me.mapZoom_ = map.getZoom();
  me.projection_ = map.getCurrentMapType().getProjection();

  opt_opts = opt_opts || {};
  me.tileSize_ = MarkerManager.DEFAULT_TILE_SIZE_;
  
  var maxZoom = MarkerManager.DEFAULT_MAX_ZOOM_;
  if(opt_opts.maxZoom != undefined) {
    maxZoom = opt_opts.maxZoom;
  }
  me.maxZoom_ = maxZoom;

  me.trackMarkers_ = opt_opts.trackMarkers;

  var padding;
  if (typeof opt_opts.borderPadding == "number") {
    padding = opt_opts.borderPadding;
  } else {
    padding = MarkerManager.DEFAULT_BORDER_PADDING_;
  }
  // The padding in pixels beyond the viewport, where we will pre-load markers.
  me.swPadding_ = new GSize(-padding, padding);
  me.nePadding_ = new GSize(padding, -padding);
  me.borderPadding_ = padding;

  me.gridWidth_ = [];

  me.grid_ = [];
  me.grid_[maxZoom] = [];
  me.numMarkers_ = [];
  me.numMarkers_[maxZoom] = 0;

  GEvent.bind(map, "moveend", me, me.onMapMoveEnd_);

  // NOTE: These two closures provide easy access to the map.
  // They are used as callbacks, not as methods.
  me.removeOverlay_ = function(marker) {
    map.removeOverlay(marker);
    me.shownMarkers_--;
  };
  me.addOverlay_ = function(marker) {
    map.addOverlay(marker);
    me.shownMarkers_++;
  };

  me.resetManager_();
  me.shownMarkers_ = 0;

  me.shownBounds_ = me.getMapGridBounds_();
};

// Static constants:
MarkerManager.DEFAULT_TILE_SIZE_ = 1024;
MarkerManager.DEFAULT_MAX_ZOOM_ = 17;
MarkerManager.DEFAULT_BORDER_PADDING_ = 100;
MarkerManager.MERCATOR_ZOOM_LEVEL_ZERO_RANGE = 256;


/**
 * Initializes MarkerManager arrays for all zoom levels
 * Called by constructor and by clearAllMarkers
 */ 
MarkerManager.prototype.resetManager_ = function() {
  var me = this;
  var mapWidth = MarkerManager.MERCATOR_ZOOM_LEVEL_ZERO_RANGE;
  for (var zoom = 0; zoom <= me.maxZoom_; ++zoom) {
    me.grid_[zoom] = [];
    me.numMarkers_[zoom] = 0;
    me.gridWidth_[zoom] = Math.ceil(mapWidth/me.tileSize_);
    mapWidth <<= 1;
  }
};

/**
 * Removes all currently displayed markers
 * and calls resetManager to clear arrays
 */
MarkerManager.prototype.clearMarkers = function() {
  var me = this;
  me.processAll_(me.shownBounds_, me.removeOverlay_);
  me.resetManager_();
};


/**
 * Gets the tile coordinate for a given latlng point.
 *
 * @param {LatLng} latlng The geographical point.
 * @param {Number} zoom The zoom level.
 * @param {GSize} padding The padding used to shift the pixel coordinate.
 *               Used for expanding a bounds to include an extra padding
 *               of pixels surrounding the bounds.
 * @return {GPoint} The point in tile coordinates.
 *
 */
MarkerManager.prototype.getTilePoint_ = function(latlng, zoom, padding) {
  var pixelPoint = this.projection_.fromLatLngToPixel(latlng, zoom);
  return new GPoint(
      Math.floor((pixelPoint.x + padding.width) / this.tileSize_),
      Math.floor((pixelPoint.y + padding.height) / this.tileSize_));
};


/**
 * Finds the appropriate place to add the marker to the grid.
 * Optimized for speed; does not actually add the marker to the map.
 * Designed for batch-processing thousands of markers.
 *
 * @param {Marker} marker The marker to add.
 * @param {Number} minZoom The minimum zoom for displaying the marker.
 * @param {Number} maxZoom The maximum zoom for displaying the marker.
 */
MarkerManager.prototype.addMarkerBatch_ = function(marker, minZoom, maxZoom) {
  var mPoint = marker.getPoint();
  // Tracking markers is expensive, so we do this only if the
  // user explicitly requested it when creating marker manager.
  if (this.trackMarkers_) {
    GEvent.bind(marker, "changed", this, this.onMarkerMoved_);
  }

  var gridPoint = this.getTilePoint_(mPoint, maxZoom, GSize.ZERO);

  for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
    var cell = this.getGridCellCreate_(gridPoint.x, gridPoint.y, zoom);
    cell.push(marker);

    gridPoint.x = gridPoint.x >> 1;
    gridPoint.y = gridPoint.y >> 1;
  }
};


/**
 * Returns whether or not the given point is visible in the shown bounds. This
 * is a helper method that takes care of the corner case, when shownBounds have
 * negative minX value.
 *
 * @param {Point} point a point on a grid.
 * @return {Boolean} Whether or not the given point is visible in the currently
 * shown bounds.
 */
MarkerManager.prototype.isGridPointVisible_ = function(point) {
  var me = this;
  var vertical = me.shownBounds_.minY <= point.y &&
      point.y <= me.shownBounds_.maxY;
  var minX = me.shownBounds_.minX;
  var horizontal = minX <= point.x && point.x <= me.shownBounds_.maxX;
  if (!horizontal && minX < 0) {
    // Shifts the negative part of the rectangle. As point.x is always less
    // than grid width, only test shifted minX .. 0 part of the shown bounds.
    var width = me.gridWidth_[me.shownBounds_.z];
    horizontal = minX + width <= point.x && point.x <= width - 1;
  }
  return vertical && horizontal;
}


/**
 * Reacts to a notification from a marker that it has moved to a new location.
 * It scans the grid all all zoom levels and moves the marker from the old grid
 * location to a new grid location.
 *
 * @param {Marker} marker The marker that moved.
 * @param {LatLng} oldPoint The old position of the marker.
 * @param {LatLng} newPoint The new position of the marker.
 */
MarkerManager.prototype.onMarkerMoved_ = function(marker, oldPoint, newPoint) {
  // NOTE: We do not know the minimum or maximum zoom the marker was
  // added at, so we start at the absolute maximum. Whenever we successfully
  // remove a marker at a given zoom, we add it at the new grid coordinates.
  var me = this;
  var zoom = me.maxZoom_;
  var changed = false;
  var oldGrid = me.getTilePoint_(oldPoint, zoom, GSize.ZERO);
  var newGrid = me.getTilePoint_(newPoint, zoom, GSize.ZERO);
  while (zoom >= 0 && (oldGrid.x != newGrid.x || oldGrid.y != newGrid.y)) {
    var cell = me.getGridCellNoCreate_(oldGrid.x, oldGrid.y, zoom);
    if (cell) {
      if (me.removeFromArray(cell, marker)) {
        me.getGridCellCreate_(newGrid.x, newGrid.y, zoom).push(marker);
      }
    }
    // For the current zoom we also need to update the map. Markers that no
    // longer are visible are removed from the map. Markers that moved into
    // the shown bounds are added to the map. This also lets us keep the count
    // of visible markers up to date.
    if (zoom == me.mapZoom_) {
      if (me.isGridPointVisible_(oldGrid)) {
        if (!me.isGridPointVisible_(newGrid)) {
          me.removeOverlay_(marker);
          changed = true;
        }
      } else {
        if (me.isGridPointVisible_(newGrid)) {
          me.addOverlay_(marker);
          changed = true;
        }
      }
    }
    oldGrid.x = oldGrid.x >> 1;
    oldGrid.y = oldGrid.y >> 1;
    newGrid.x = newGrid.x >> 1;
    newGrid.y = newGrid.y >> 1;
    --zoom;
  }
  if (changed) {
    me.notifyListeners_();
  }
};


/**
 * Searches at every zoom level to find grid cell
 * that marker would be in, removes from that array if found.
 * Also removes marker with removeOverlay if visible.
 * @param {GMarker} marker The marker to delete.
 */
MarkerManager.prototype.removeMarker = function(marker) {
  var me = this;
  var zoom = me.maxZoom_;
  var changed = false;
  var point = marker.getPoint();
  var grid = me.getTilePoint_(point, zoom, GSize.ZERO);
  while (zoom >= 0) {
    var cell = me.getGridCellNoCreate_(grid.x, grid.y, zoom);

    if (cell) {
      me.removeFromArray(cell, marker);
    }
    // For the current zoom we also need to update the map. Markers that no
    // longer are visible are removed from the map. This also lets us keep the count
    // of visible markers up to date.
    if (zoom == me.mapZoom_) {
      if (me.isGridPointVisible_(grid)) {
          me.removeOverlay_(marker);
          changed = true;
      } 
    }
    grid.x = grid.x >> 1;
    grid.y = grid.y >> 1;
    --zoom;
  }
  if (changed) {
    me.notifyListeners_();
  }
};


/**
 * Add many markers at once.
 * Does not actually update the map, just the internal grid.
 *
 * @param {Array of Marker} markers The markers to add.
 * @param {Number} minZoom The minimum zoom level to display the markers.
 * @param {Number} opt_maxZoom The maximum zoom level to display the markers.
 */
MarkerManager.prototype.addMarkers = function(markers, minZoom, opt_maxZoom) {
  var maxZoom = this.getOptMaxZoom_(opt_maxZoom);
  for (var i = markers.length - 1; i >= 0; i--) {
    this.addMarkerBatch_(markers[i], minZoom, maxZoom);
  }

  this.numMarkers_[minZoom] += markers.length;
};


/**
 * Returns the value of the optional maximum zoom. This method is defined so
 * that we have just one place where optional maximum zoom is calculated.
 *
 * @param {Number} opt_maxZoom The optinal maximum zoom.
 * @return The maximum zoom.
 */
MarkerManager.prototype.getOptMaxZoom_ = function(opt_maxZoom) {
  return opt_maxZoom != undefined ? opt_maxZoom : this.maxZoom_;
}


/**
 * Calculates the total number of markers potentially visible at a given
 * zoom level.
 *
 * @param {Number} zoom The zoom level to check.
 */
MarkerManager.prototype.getMarkerCount = function(zoom) {
  var total = 0;
  for (var z = 0; z <= zoom; z++) {
    total += this.numMarkers_[z];
  }
  return total;
};


/**
 * Add a single marker to the map.
 *
 * @param {Marker} marker The marker to add.
 * @param {Number} minZoom The minimum zoom level to display the marker.
 * @param {Number} opt_maxZoom The maximum zoom level to display the marker.
 */
MarkerManager.prototype.addMarker = function(marker, minZoom, opt_maxZoom) {
  var me = this;
  var maxZoom = this.getOptMaxZoom_(opt_maxZoom);
  me.addMarkerBatch_(marker, minZoom, maxZoom);
  var gridPoint = me.getTilePoint_(marker.getPoint(), me.mapZoom_, GSize.ZERO);
  if(me.isGridPointVisible_(gridPoint) && 
     minZoom <= me.shownBounds_.z &&
     me.shownBounds_.z <= maxZoom ) {
    me.addOverlay_(marker);
    me.notifyListeners_();
  }
  this.numMarkers_[minZoom]++;
};

/**
 * Returns true if this bounds (inclusively) contains the given point.
 * @param {Point} point  The point to test.
 * @return {Boolean} This Bounds contains the given Point.
 */
GBounds.prototype.containsPoint = function(point) {
  var outer = this;
  return (outer.minX <= point.x &&
          outer.maxX >= point.x &&
          outer.minY <= point.y &&
          outer.maxY >= point.y);
}

/**
 * Get a cell in the grid, creating it first if necessary.
 *
 * Optimization candidate
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 * @return {Array} The cell in the array.
 */
MarkerManager.prototype.getGridCellCreate_ = function(x, y, z) {
  var grid = this.grid_[z];
  if (x < 0) {
    x += this.gridWidth_[z];
  }
  var gridCol = grid[x];
  if (!gridCol) {
    gridCol = grid[x] = [];
    return gridCol[y] = [];
  }
  var gridCell = gridCol[y];
  if (!gridCell) {
    return gridCol[y] = [];
  }
  return gridCell;
};


/**
 * Get a cell in the grid, returning undefined if it does not exist.
 *
 * NOTE: Optimized for speed -- otherwise could combine with getGridCellCreate_.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 * @return {Array} The cell in the array.
 */
MarkerManager.prototype.getGridCellNoCreate_ = function(x, y, z) {
  var grid = this.grid_[z];
  if (x < 0) {
    x += this.gridWidth_[z];
  }
  var gridCol = grid[x];
  return gridCol ? gridCol[y] : undefined;
};


/**
 * Turns at geographical bounds into a grid-space bounds.
 *
 * @param {LatLngBounds} bounds The geographical bounds.
 * @param {Number} zoom The zoom level of the bounds.
 * @param {GSize} swPadding The padding in pixels to extend beyond the
 * given bounds.
 * @param {GSize} nePadding The padding in pixels to extend beyond the
 * given bounds.
 * @return {GBounds} The bounds in grid space.
 */
MarkerManager.prototype.getGridBounds_ = function(bounds, zoom, swPadding,
                                                  nePadding) {
  zoom = Math.min(zoom, this.maxZoom_);
  
  var bl = bounds.getSouthWest();
  var tr = bounds.getNorthEast();
  var sw = this.getTilePoint_(bl, zoom, swPadding);
  var ne = this.getTilePoint_(tr, zoom, nePadding);
  var gw = this.gridWidth_[zoom];
  
  // Crossing the prime meridian requires correction of bounds.
  if (tr.lng() < bl.lng() || ne.x < sw.x) {
    sw.x -= gw;
  }
  if (ne.x - sw.x  + 1 >= gw) {
    // Computed grid bounds are larger than the world; truncate.
    sw.x = 0;
    ne.x = gw - 1;
  }
  var gridBounds = new GBounds([sw, ne]);
  gridBounds.z = zoom;
  return gridBounds;
};


/**
 * Gets the grid-space bounds for the current map viewport.
 *
 * @return {Bounds} The bounds in grid space.
 */
MarkerManager.prototype.getMapGridBounds_ = function() {
  var me = this;
  return me.getGridBounds_(me.map_.getBounds(), me.mapZoom_,
                           me.swPadding_, me.nePadding_);
};


/**
 * Event listener for map:movend.
 * NOTE: Use a timeout so that the user is not blocked
 * from moving the map.
 *
 */
MarkerManager.prototype.onMapMoveEnd_ = function() {
  var me = this;
  me.objectSetTimeout_(this, this.updateMarkers_, 0);
};


/**
 * Call a function or evaluate an expression after a specified number of
 * milliseconds.
 *
 * Equivalent to the standard window.setTimeout function, but the given
 * function executes as a method of this instance. So the function passed to
 * objectSetTimeout can contain references to this.
 *    objectSetTimeout(this, function() { alert(this.x) }, 1000);
 *
 * @param {Object} object  The target object.
 * @param {Function} command  The command to run.
 * @param {Number} milliseconds  The delay.
 * @return {Boolean}  Success.
 */
MarkerManager.prototype.objectSetTimeout_ = function(object, command, milliseconds) {
  return window.setTimeout(function() {
    command.call(object);
  }, milliseconds);
};


/**
 * Refresh forces the marker-manager into a good state.
 * <ol>
 *   <li>If never before initialized, shows all the markers.</li>
 *   <li>If previously initialized, removes and re-adds all markers.</li>
 * </ol>
 */
MarkerManager.prototype.refresh = function() {
  var me = this;
  if (me.shownMarkers_ > 0) {
    me.processAll_(me.shownBounds_, me.removeOverlay_);
  }
  me.processAll_(me.shownBounds_, me.addOverlay_);
  me.notifyListeners_();
};


/**
 * After the viewport may have changed, add or remove markers as needed.
 */
MarkerManager.prototype.updateMarkers_ = function() {
  var me = this;
  me.mapZoom_ = this.map_.getZoom();
  var newBounds = me.getMapGridBounds_();
  
  // If the move does not include new grid sections,
  // we have no work to do:
  if (newBounds.equals(me.shownBounds_) && newBounds.z == me.shownBounds_.z) {
    return;
  }

  if (newBounds.z != me.shownBounds_.z) {
    me.processAll_(me.shownBounds_, me.removeOverlay_);
    me.processAll_(newBounds, me.addOverlay_);
  } else {
    // Remove markers:
    me.rectangleDiff_(me.shownBounds_, newBounds, me.removeCellMarkers_);

    // Add markers:
    me.rectangleDiff_(newBounds, me.shownBounds_, me.addCellMarkers_);
  }
  me.shownBounds_ = newBounds;

  me.notifyListeners_();
};


/**
 * Notify listeners when the state of what is displayed changes.
 */
MarkerManager.prototype.notifyListeners_ = function() {
  GEvent.trigger(this, "changed", this.shownBounds_, this.shownMarkers_);
};


/**
 * Process all markers in the bounds provided, using a callback.
 *
 * @param {Bounds} bounds The bounds in grid space.
 * @param {Function} callback The function to call for each marker.
 */
MarkerManager.prototype.processAll_ = function(bounds, callback) {
  for (var x = bounds.minX; x <= bounds.maxX; x++) {
    for (var y = bounds.minY; y <= bounds.maxY; y++) {
      this.processCellMarkers_(x, y,  bounds.z, callback);
    }
  }
};


/**
 * Process all markers in the grid cell, using a callback.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 * @param {Function} callback The function to call for each marker.
 */
MarkerManager.prototype.processCellMarkers_ = function(x, y, z, callback) {
  var cell = this.getGridCellNoCreate_(x, y, z);
  if (cell) {
    for (var i = cell.length - 1; i >= 0; i--) {
      callback(cell[i]);
    }
  }
};


/**
 * Remove all markers in a grid cell.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 */
MarkerManager.prototype.removeCellMarkers_ = function(x, y, z) {
  this.processCellMarkers_(x, y, z, this.removeOverlay_);
};


/**
 * Add all markers in a grid cell.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 */
MarkerManager.prototype.addCellMarkers_ = function(x, y, z) {
  this.processCellMarkers_(x, y, z, this.addOverlay_);
};


/**
 * Use the rectangleDiffCoords function to process all grid cells
 * that are in bounds1 but not bounds2, using a callback, and using
 * the current MarkerManager object as the instance.
 *
 * Pass the z parameter to the callback in addition to x and y.
 *
 * @param {Bounds} bounds1 The bounds of all points we may process.
 * @param {Bounds} bounds2 The bounds of points to exclude.
 * @param {Function} callback The callback function to call
 *                   for each grid coordinate (x, y, z).
 */
MarkerManager.prototype.rectangleDiff_ = function(bounds1, bounds2, callback) {
  var me = this;
  me.rectangleDiffCoords(bounds1, bounds2, function(x, y) {
    callback.apply(me, [x, y, bounds1.z]);
  });
};


/**
 * Calls the function for all points in bounds1, not in bounds2
 *
 * @param {Bounds} bounds1 The bounds of all points we may process.
 * @param {Bounds} bounds2 The bounds of points to exclude.
 * @param {Function} callback The callback function to call
 *                   for each grid coordinate.
 */
MarkerManager.prototype.rectangleDiffCoords = function(bounds1, bounds2, callback) {
  var minX1 = bounds1.minX;
  var minY1 = bounds1.minY;
  var maxX1 = bounds1.maxX;
  var maxY1 = bounds1.maxY;
  var minX2 = bounds2.minX;
  var minY2 = bounds2.minY;
  var maxX2 = bounds2.maxX;
  var maxY2 = bounds2.maxY;

  for (var x = minX1; x <= maxX1; x++) {  // All x in R1
    // All above:
    for (var y = minY1; y <= maxY1 && y < minY2; y++) {  // y in R1 above R2
      callback(x, y);
    }
    // All below:
    for (var y = Math.max(maxY2 + 1, minY1);  // y in R1 below R2
         y <= maxY1; y++) {
      callback(x, y);
    }
  }

  for (var y = Math.max(minY1, minY2);
       y <= Math.min(maxY1, maxY2); y++) {  // All y in R2 and in R1
    // Strictly left:
    for (var x = Math.min(maxX1 + 1, minX2) - 1;
         x >= minX1; x--) {  // x in R1 left of R2
      callback(x, y);
    }
    // Strictly right:
    for (var x = Math.max(minX1, maxX2 + 1);  // x in R1 right of R2
         x <= maxX1; x++) {
      callback(x, y);
    }
  }
};


/**
 * Removes value from array. O(N).
 *
 * @param {Array} array  The array to modify.
 * @param {any} value  The value to remove.
 * @param {Boolean} opt_notype  Flag to disable type checking in equality.
 * @return {Number}  The number of instances of value that were removed.
 */
MarkerManager.prototype.removeFromArray = function(array, value, opt_notype) {
  var shift = 0;
  for (var i = 0; i < array.length; ++i) {
    if (array[i] === value || (opt_notype && array[i] == value)) {
      array.splice(i--, 1);
      shift++;
    }
  }
  return shift;
};

;
var MarkerGrouper = function(map, options) {
	this.map     = map;
	this.options = options;
	this.markers = Array();
	this.bounds  = new GLatLngBounds();
	this.history = {
		latlng: null,
		content: null
	};
}
MarkerGrouper.prototype.createMarker = function(latLng, opts) {
	var options = opts;
	if (!options)
		options = {};
	
	if (options.icon) {
		var image          = options.icon;
		options.icon       = new GIcon(G_DEFAULT_ICON);
		options.icon.image = image;
		
		if (options.iconSize) {
			options.icon.iconSize = options.iconSize;
			options.iconSize      = undefined;
		}
	} else if (this.options && this.options.icon) {
		var image          = this.options.icon;
		options.icon       = new GIcon(G_DEFAULT_ICON);
		options.icon.image = image;
		
		if (this.options.iconSize) {
			options.icon.iconSize = this.options.iconSize;
		}
	}

	var marker = new GMarker(latLng, options);
	
	var me = this;
	var mouseOnImage;
	if (options.mouseOverIcon) {
		mouseOnImage = options.mouseOverIcon;
	} else if(this.options && this.options.mouseOverIcon) {
		mouseOnImage = this.options.mouseOverIcon;
	}
	
	if (options.mouseOverIcon) {
		GEvent.addListener(marker, 'mouseover', function() {
			marker.setImage(options.mouseOverIcon);
		});
		GEvent.addListener(marker, 'mouseout', function() {
			marker.setImage(image);
		});
	} else if (this.options && this.options.mouseOverIcon) {
		GEvent.addListener(marker, 'mouseover', function() {
			marker.setImage(me.options.mouseOverIcon);
		});
		GEvent.addListener(marker, 'mouseout', function() {
			marker.setImage(image);
		});
	}
	
	if (options.overlay) {
		GEvent.addListener(marker, 'mouseover', function() {
			options.overlay.draw(marker);
		});
		GEvent.addListener(marker, 'mouseout', function() {
			options.overlay.remove();
		});
	}
	if (options.overlay && options.draggable) {
		GEvent.addListener(marker, 'dragstart', function() {
			me.history.latlng  = marker.getLatLng();
			me.history.content = options.overlay.getContent();
			options.overlay.remove();
			marker.setImage(mouseOnImage);
		});
		GEvent.addListener(marker, 'dragend', function() {
			var geocoder = new GClientGeocoder();
			geocoder.getLocations(marker.getLatLng(), function(response) {
				if (response && response.Status.code == 200)
					options.overlay.setContent(options.dragend(response, marker));
			});
		});
	}
	if (options.click) {
		GEvent.addListener(marker, 'click', function() {
			options.click();
		});
	}
	if (options.infoWindow) {
		var _isOpen = false;
		GEvent.addListener(marker, 'click', function() {
			if (_isOpen) {
				options.infoWindow.close();
				_isOpen = false;
			} else {
				options.infoWindow.toggle();
				_isOpen = true;
			}
		});
	}
	
	if (!this.bounds.containsLatLng(marker.getLatLng())) {
		this.bounds.extend(marker.getLatLng());
	}
	
	this.markers[this.markers.length] = marker;
	return marker;
}
MarkerGrouper.prototype.add = function(marker) {
	if (!this.bounds.containsLatLng(marker.getLatLng())) {
		this.bounds.extend(marker.getLatLng());
	}
	
	this.markers.push(marker);
}
MarkerGrouper.prototype.show = function() {
	if (this.options && this.options.fitBounds && this.markers.length > 0) {
		this.map.setCenter(this.bounds.getCenter());
		
		var zoomLevel = this.map.getBoundsZoomLevel(this.bounds) - 1;
		if (zoomLevel > 15)
			zoomLevel = 15;
		
		this.map.setZoom(zoomLevel);
	}

	for (var i = 0; i < this.markers.length; i++) {
		this.map.addOverlay(this.markers[i]);
	}
}
MarkerGrouper.prototype.hide = function() {
	for (var i = 0; i < this.markers.length; i++) {
		this.map.removeOverlay(this.markers[i]);
	}
}
MarkerGrouper.prototype.clear = function() {
	for (var i = this.markers.length - 1; i >= 0; i--) {
		this.map.removeOverlay(this.markers[i]);
		this.markers[i] = undefined;
	}
	this.markers = Array();
}
MarkerGrouper.prototype.getMarkers = function() {
	return this.markers;
}
MarkerGrouper.prototype.getBounds = function() {
	return this.bounds;
}
MarkerGrouper.prototype.size = function() {
	return this.markers.length;
}

var CustomControls = function(map, cssClass) {
	this._map       = map;
	this.MAX_HEIGHT = this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.style.height;
	this.MAX_WIDTH  = this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.style.width;
	
	this._div       = document.createElement('div');
	if (cssClass) {
		this._div.className = cssClass;
	}
}
CustomControls.prototype.set = function(cssProperty, cssValue) {
	eval('this._div.style.' + cssProperty + ' = "' + cssValue + '";');
}
CustomControls.prototype.hide   = function() {
	this._div.style.visibility = 'hidden';
}
CustomControls.prototype.show   = function() {
	this._div.style.visibility = 'visible';
}
CustomControls.prototype.inject = function() {
	this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.appendChild(this._div);
}
CustomControls.prototype.createControl = function(elementType, elementContent, cssClass) {
	var element = document.createElement(elementType);
	
	if (elementType == 'img')
		element.src       = elementContent;
	else
		element.innerHTML = elementContent;
	
	if (cssClass)
		element.className = cssClass;
	
	return element;
}
CustomControls.prototype.addZoomInControl = function(element) {
	var me = this;
	GEvent.addDomListener(element, 'click', function() {
		me._map.setZoom(me._map.getZoom() + 1);
	});
	
	this._div.appendChild(element);
}
CustomControls.prototype.addZoomOutControl = function(element) {
	var me = this;
	GEvent.addDomListener(element, 'click', function() {
		me._map.setZoom(me._map.getZoom() - 1);
	});
	this._div.appendChild(element);
}
CustomControls.prototype.addControl        = function(element) {
	this._div.appendChild(element);
}
CustomControls.prototype.addMapTypeControl = function(mapType, element) {
	var me = this;
	GEvent.addDomListener(element, 'click', function() {
		me._map.setMapType(mapType);
		$$('.maptype').setStyle('background-image', 'url(/Site/images/design/icons/clickWhiteBackInactive.png)');
		element.setStyle('background-image', 'url(/Site/images/design/icons/clickWhiteBackActive.png)');
	});
	this._div.appendChild(element);
}

var Overlay = function(map, infoContent, cssClass) {
	this._map         = map;
	this._infoContent = infoContent;
	this._cssClass    = cssClass;
	this._xAdjusted   = 0;
	this._yAdjusted   = 0;
}
Overlay.prototype.adjust = function(position) {
	this._xAdjusted = position.x;
	this._yAdjusted = position.y;
	
	return this;
}
Overlay.prototype.setContent = function(infoContent) {
	this._infoContent = infoContent;
}
Overlay.prototype.getContent = function() {
	return this._infoContent;
}
Overlay.prototype.draw = function(marker) {
	var position       = this._map.fromLatLngToDivPixel(marker.getLatLng());
	var div            = document.createElement('div');
	div.className      = this._cssClass;
	div.style.position = 'absolute';
	div.style.left     = (position.x + this._xAdjusted) + 'px';
	div.style.top      = (position.y + this._yAdjusted) + 'px';
	div.innerHTML      = '<span>' + this._infoContent + '</span>';
	
	this._div          = div;
	this._map.getPane(G_MAP_MARKER_PANE).appendChild(this._div);
}
Overlay.prototype.remove = function() {
	this._map.getPane(G_MAP_MARKER_PANE).removeChild(this._div);
	this._div = undefined;
}

var OverlayPosition = function(x, y) {
	this.x = x;
	this.y = y;
}

var latest;
var InfoWindow = function(map, childElement, options) {
	this._map          = map;
	this._childElement = childElement;
	this._options      = options;
	this._isOpen       = false;
}
InfoWindow.prototype.toggle = function() {
	if (latest) {
		latest.close();
		latest._isOpen = false;
	}
	
	if (this._isOpen) {
		this.close();
		this._isOpen = false;
	}
	
	if (!this._isOpen) {
		var div = document.createElement('div');
		div.style.position = 'relative';
		if (this._options && this._options.cssClass)
			div.className = this._options.cssClass;
		if (this._options && this._options.styles) {
			for (prop in this._options.styles)
				div.style[prop] = this._options.styles[prop];
		}
		if (this._options && this._options.panTo)
			this._map.panTo(this._options.panTo);
		
		div.appendChild(this._childElement);
		var btn = document.createElement('div');
		btn.style.position = 'absolute';
		btn.style.top      = 0;
		btn.style.right    = '5px';
		btn.innerHTML = '<img src="/images/welboxed/close.png" style="margin: 5px; cursor: pointer;" />';
		div.appendChild(btn);
		
		var me = this;
		GEvent.addDomListener(btn, 'click', function() {
			me.close();
			me._isOpen = false;
			
			if (latest) {
				latest.close();
				latest._isOpen = false;
			}
		});
		
		this._div    = div;
		latest       = this;
		this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.appendChild(this._div);
		this._isOpen = true;
	}
}
InfoWindow.prototype.close = function() {
	if (this._div) {
		try {
			this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.removeChild(this._div);
			this._isOpen = false;
		} catch(err) {}
	}
};
var Maps = {
	_map: false,
	_markerManager: false,
	_markerGroupers: {},
	_currentManager: false,
	_currentCategory: 'na',
	_firstZoom: true,
	_createMap: function(placeholder) {
		this._map = new GMap2(placeholder);
		this._map.setCenter(new GLatLng(56.2639200, 9.8017850), 6);
		this._map.enableDoubleClickZoom();
		this._map.enableScrollWheelZoom();
	},
	_createMarker: function(position, options) {
		if (!options)
			options       = {};
		
		var icon;
		if (options.image && options.image != 'static') {
			icon = new GIcon();
			icon.iconSize = new GSize(34, 62);
		} else {
			icon = new GIcon(G_DEFAULT_ICON);
			icon.iconSize = new GSize(26, 35);
		}
		
		if (options.image == 'static')
			icon.image    = '/images/icons/denmarkPin-active.png';
		else if (options.image)
			icon.image    = options.image;
		else
			icon.image    = '/images/icons/denmarkPin.png';
		
		if (options.anchor)
			icon.iconAnchor = options.anchor
			
		var draggable = false;
		if (options.draggable)
			draggable = true;
		
		var marker        = new GMarker(position, {
			icon: icon,
			draggable: draggable
		});
		
		if (options.overlay && options.image != 'static') {
			GEvent.addListener(marker, 'mouseover', function() {
				if (options.mouseoverImage)
					marker.setImage(options.mouseoverImage);
				else
					marker.setImage('/images/icons/denmarkPin-active.png');
				
				options.overlay.draw(marker);
			});
			GEvent.addListener(marker, 'mouseout', function() {
				if (options.image)
					marker.setImage(options.image);
				else
					marker.setImage('/images/icons/denmarkPin.png');
				
				options.overlay.remove();
			});
		}
		if (options.infoWindow) {
			var _isOpen = false;
			GEvent.addListener(marker, 'click', function() {
				if (_isOpen) {
					options.infoWindow.close();
					_isOpen = false;
				} else {
					options.infoWindow.toggle();
					_isOpen = true;
				}
			});
		} else if (options.event) {
			GEvent.addListener(marker, 'click', options.event);
		}
		
		return marker;
	},
	_createMapTypeControls: function(showPanoramaLink) {
		var panoramaLinkHtml = '';
		if (showPanoramaLink) {
			panoramaLinkHtml  = '<div class="button1 radio" style="top: 58px; right: 0" id="mapTypePanorama">';
			panoramaLinkHtml += '<div class="left"><span>Gatunivå</span></div><div class="right"></div></div>';
		}
		
		var buffer = '<div class="button1 radio active" style="top: 0; right: 0" id="mapTypeMap">';
		buffer    += '<div class="left"><span>Karta</span></div><div class="right"></div>';
		buffer    += '</div><div class="button1 radio" style="top: 29px; right: 0;" id="mapTypeSatellite">';
		buffer    += '<div class="left"><span>Satellit</span></div><div class="right"></div>';
		buffer    += '</div>' + panoramaLinkHtml;
		
		var controlsOverlay = new Element('div')
			.set('id', 'mapTypeOverlay')
			.setStyles({
				'position': 'relative',
				'top': '5px',
				'right': '5px',
				'z-index': '10'
			});

		controlsOverlay.set('html', buffer);
		controlsOverlay.inject(this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode);
		
		var me = this;
		$('mapTypeMap').addEvent('click', function(e) {
			new Event(e).stop();
			
			me._map.setMapType(G_NORMAL_MAP);
			$$('#mapTypeOverlay .button1').removeClass('active');
			this.addClass('active');
		});
		$('mapTypeSatellite').addEvent('click', function(e) {
			new Event(e).stop();
			
			me._map.setMapType(G_SATELLITE_MAP);
			$$('#mapTypeOverlay .button1').removeClass('active');
			this.addClass('active');
		});
		if (showPanoramaLink) {
			GEvent.addDomListener(document.getElementById('mapTypePanorama'), 'click', Maps._createStreetViewPanorama);
		}
		
		buffer  = '<div class="button9 zoom plus" style="top: 0; left: 0;">';
		buffer += '<div class="right" id="mapZoomIn"></div>';
		buffer += '</div><div class="button9 zoom minus" style="top: 29px; left: 0;">';
		buffer += '<div class="right" id="mapZoomOut"></div>';
		buffer += '</div>';
		
		var zoomOverlay = new Element('div')
			.set('id', 'mapZoomOverlay')
			.setStyles({
				'position': 'relative',
				'top': '5px',
				'left': '5px',
				'z-index': '10'
			})
			.set('html', buffer)
			.inject(this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode);
		
		$('mapZoomIn').addEvent('click', function(e) {
			new Event(e).stop();
			
			me._map.setZoom(me._map.getZoom() + 1);
		});
		$('mapZoomOut').addEvent('click', function(e) {
			new Event(e).stop();
			
			me._map.setZoom(me._map.getZoom() - 1);
		});
	},
	_createStreetViewPanorama: function(e) {
		new Event(e).stop();
		
		$(document.body).setStyle('overflow', 'hidden');
		$(document.body).scrollTo(0, 0);
		
		screenWidth  = window.getSize().x;
		screenHeight = window.getSize().y;
		
		var layer = new Element('div');
		layer.setStyles({
			'position': 'absolute',
			'top': '-' + (screenHeight + 50) + 'px',
			'left': '0px',
			'width': screenWidth + 'px',
			'height': screenHeight + 'px',
			'background-color': '#fff',
			'z-index': '10'
		});
		
		var container = new Element('div');
		container.set('id', 'gmStreetViewPanorama');
		container.set('name', 'gmStreetViewPanorama');
		container.setStyles({
			'width': screenWidth + 'px',
			'height': screenHeight + 'px',
			'position': 'absolute',
			'top': '0',
			'left': '0',
			'z-index': '10'
		});
		container.inject(layer);
		
		var back = new Element('div');
		back.setStyles({
			'position': 'absolute',
			'bottom': '0px',
			'left': ((screenWidth / 2) - 250) + 'px',
			'z-index': '11',
			'width': '500px',
			'height': '50px',
			'background-image': 'url(/images/backgrounds/panoramaBack.png)',
			'cursor': 'pointer'
		});
		back.addEvent('click', function(e) {
			layer.set('morph', {
				onComplete: function() {
					layer.dispose();
					$(document.body).setStyle('overflow', 'auto');
				}
			});
			layer.morph({
				'top': '-' + (screenHeight + 50) + 'px'
			});
		});
		
		var logo = new Element('div');
		logo.setStyles({
			'position': 'absolute',
			'top': '20px',
			'right': '20px',
			'z-index': '12'
		});
		logo.set('html', '<img src="/images/logo.png" style="border: 0;" />');
		
		var info = new Element('div');
		info.setStyles({
			'position': 'absolute',
			'top': '100px',
			'right': '20px',
			'text-align': 'left',
			'width': '285px',
			'padding': '12px',
			'background-image': 'url(/images/backgrounds/pixelWhite80.png)',
			'border': '1px solid #ff3300',
			'z-index': '13'
		});
		
		info.set('html', '<h1 class="header" style="color: #FF3300; margin-top: 0; font-size: 20px;">' + $('descriptionContainer').getElement('h1').get('text') + '</h1><p>' + $('descriptionContainer').getElement('.descr').get('text') + '</p>');
		
		info.inject(layer);
		logo.inject(layer);
		back.inject(layer);
		layer.inject($(document.body));
		
		var point    = new GLatLng(
			parseFloat(post.latitude),
			parseFloat(post.longitude)
		);
		var features = {
			streetView: true,
			userPhotos: false
		};
		var panorama;
		
		layer.set('morph', {
			onComplete: function() {
				panorama = new GStreetviewPanorama($('gmStreetViewPanorama'), {
					'latlng': point,
					'features': features,
					'enableFullScreen': false
				});
				GEvent.addListener(panorama, 'error', handleError);
			}
		});
		
		function handleError(err) {
			alert("Den här platsen är inte tillgänglig på gatunivå.");
			back.fireEvent('click', back);
			return;
		}
		
		layer.morph({
			'top': '0px'
		});
		
		window.addEvent('resize', function() {
			screenWidth  = window.getSize().x;
			screenHeight = window.getSize().y;
			
			layer.setStyles({
				'top': '0px',
				'left': '0px',
				'width': screenWidth + 'px',
				'height': screenHeight + 'px'
			});
			container.setStyles({
				'top': '0px',
				'left': '0px',
				'width': screenWidth + 'px',
				'height': screenHeight + 'px'
			});
			back.setStyles({
				'left': ((screenWidth / 2) - 250) + 'px'
			});
			
			panorama.checkResize();
		});
	},
	_createInfoWindow: function(title, description, image, url) {
		var content  = new Element('div');
		content.rel = 'infoWindow';
		content.style.padding = '10px 2px 10px 10px';
		var top = new Element('div');
		top.style.height = '180px';
		
		var h1 = new Element('h1');
		h1.innerHTML = title;
		
		h1.inject(top);
		
		if (image && parseInt(image) > 0) {
			var img = new Element('img')
				.set('src', '/images/pointImages/gdkimages/thumbs/' + image + '.jpg')
				.set('align', 'right')
				.setStyles({
					'margin': '5px 10px 0px',
					'width': '100px',
					'height': '75px',
					'border': '1px solid #CCC'
				})
				.inject(top);
		}
		
		var p = new Element('p');
		p.innerHTML = (description.length > 200) ? description.substr(0, 200) + '...' : description;
		p.inject(top);
		
		if (url) {
			var div = new Element('div');
			div.addClass('button2');
			div.addClass('right');
			div.setStyles({
				'position': 'absolute',
				'bottom': '10px',
				'right': '15px'
			});
			div.set('html', '<div class="left"><a href="' + url + '" style="color: #fff;">Mer information</a></div><div class="right"></div>');
			
			div.inject(top);
		}
	
		top.inject(content);
		
		return content;
	},
	_getMarkersForCurrentRegion: function() {
		this._currentManager.clearMarkers();
		
		var me     = this;
		var bounds = this._map.getBounds().toString().replace(/ /g, '').replace(/\(/g, '').replace(/\)/g, '');
		new Request.JSON({
			url: '/karta/markeringar/' + me._currentCategory + '/' + bounds,
			method: 'post',
			onRequest: function() {
				var loader = new Element('div')
					.set('id', 'maps-loading-info')
					.setStyles({
						position: 'absolute',
						top: '0',
						left: '0',
						backgroundImage: 'url(/images/backgrounds/pixelWhite80.png)',
						width: '700px',
						height: '450px',
						zIndex: '999',
						textAlign: 'center'
					});
				new Element('img')
					.set('src', '/images/welboxed/spinner.gif')
					.setStyles({
						marginTop: '217px'
					})
					.inject(loader);
				loader.inject(me._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode);
			},
			onComplete: function(json, response) {
				var markers = [];
				$each(json, function(element) {
					var marker = me._createMarker(new GLatLng(parseFloat(element.latitude), parseFloat(element.longitude)), {
						overlay: new Overlay(me._map, element.name, 'overlay').adjust(new OverlayPosition(17, -34)),
						event: function() {
							var current = element;
							
							new Request.JSON({
								url: '/karta/plats/' + current.id,
								method: 'post',
								onRequest: function() {
									var loader = new Element('div')
										.set('id', 'maps-loading-info')
										.setStyles({
											position: 'absolute',
											top: '0',
											left: '0',
											backgroundImage: 'url(/images/backgrounds/pixelWhite80.png)',
											width: '700px',
											height: '450px',
											zIndex: '999',
											textAlign: 'center'
										});
									new Element('img')
										.set('src', '/images/squeezebox/spinner.gif')
										.setStyles({
											marginTop: '217px'
										})
										.inject(loader);
									loader.inject(me._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode);
								},
								onSuccess: function(post, response) {
									$('maps-loading-info').dispose();
									
									var n   = new InfoWindow(me._map, me._createInfoWindow(current.name, post.description, post.image, post.url), {
										cssClass: 'infoWindow',
										panTo: new GLatLng(parseFloat(current.latitude), parseFloat(current.longitude))
									});
									n.toggle();
									me._getMarkersForCurrentRegion();
								}
							}).send();
						}
					});
					markers.push(marker);
				});
				me._currentManager.addMarkers(markers, 9, 17);
				me._currentManager.refresh();
				$('maps-loading-info').dispose();
			}
		}).send();
	},
	_createMarkerManagers: function() {
		if ($chk(this._markerManager)) {
			this._markerManager.clearMarkers();
		} else {
			this._markerManager  = new MarkerManager(this._map);
		}
		
		var me = this;
		var lastCategory;
		
		var regions   = [];
		regions.push(me._createMarker(new GLatLng(55.31664304437719,10.3271484375), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Fyn', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.31664304437719,10.3271484375));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.67622931180537,12.57608413696289), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Köpenhamn', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.67622931180537,12.57608413696289));
				me._map.setZoom(10);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(56.97492429075949,9.755859375), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Nordjylland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(56.97492429075949,9.755859375));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.893796284148955,12.337646484375), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Nordsjälland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.893796284148955,12.337646484375));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.37286814115173,9.151611328125), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Sydjylland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.37286814115173,9.151611328125));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(56.28605924471002,8.404541015625), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Västjylland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(56.28605924471002,8.404541015625));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(56.13942869386324,10.096435546875), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Ostjylland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(56.13942869386324,10.096435546875));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(54.77534585936447,11.436767578125), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Lolland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(54.77534585936447,11.436767578125));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.31039088379827,12.01904296875), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Sydsjälland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.31039088379827,12.01904296875));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.59076338488527,11.93115234375), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Själland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.59076338488527,11.93115234375));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.1286490684888,14.886474609375), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Bornholm', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.1286490684888,14.886474609375));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		regions.push(me._createMarker(new GLatLng(55.416543608580064,11.3818359375), {
			image: '/images/icons/multiples.png',
			mouseoverImage: '/images/icons/multiples-active.png',
			anchor: new GPoint(17, 55),
			overlay: new Overlay(me._map, 'Västsjälland', 'multiplesOverlay').adjust(new OverlayPosition(17, -55)),
			event: function() {
				me._map.setCenter(new GLatLng(55.416543608580064,11.3818359375));
				me._map.setZoom(9);
				
				me._getMarkersForCurrentRegion();
			}
		}));
		
		this._markerManager.addMarkers(regions, 3, 8);
		this._markerManager.refresh();
	},
	createCategoryMap: function() {
		this._createMap($('gmPlaceHolderCategory'));
		this._createMapTypeControls(false);
		this._currentManager = new MarkerManager(this._map);
		this._createMarkerManagers();
		
		var me = this;
		GEvent.addListener(this._map, 'dragend', function() {
			if (me._map.getZoom() > 8) {
				me._firstZoom = false;
				me._getMarkersForCurrentRegion();
			}
		});
		GEvent.addListener(this._map, 'zoomend', function(from, to) {
			if (from > to) {
				me._getMarkersForCurrentRegion();
			} else if (to > from && me._firstZoom) {
				me._firstZoom = false;
				me._getMarkersForCurrentRegion();
			}
		});
		
		var categoryOverlay = new Element('div')
			.setStyles({
				'position': 'absolute',
				'top': '95px',
				'right': '5px',
				'width': '139px',
				'z-index': '10'
			});
		var htmlBuffer = '<div style="position: relative;" id="mapCategories"><div class="header"><h3>Underkategorier</h3></div></div>';
		categoryOverlay.set('html', htmlBuffer);
		categoryOverlay.inject(this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.parentNode);
		
		var lastCategory;
		var isFirst    = true;
		var categories = $$('.listOneItemText h3 a');
		$each(categories, function(element) {
			if (element.get('text') != lastCategory) {
				var clickable = new Element('div')
					.addClass('clickable')
					.addEvent('click', function(e) {
						new Event(e).stop();
						
						me._currentCategory = element.get('rel');
						me._getMarkersForCurrentRegion();
						$$('#mapCategories .image').removeClass('active');
						this.getElement('.image').addClass('active');
					});
				
				clickable.set('html', '<div class="image"></div><div class="title">' + element.get('text') + '</div><div class="clear"></div>');
				clickable.inject(categoryOverlay.getElement('#mapCategories'));
				
				if (isFirst) {
					me._currentCategory = element.get('rel');
					
					clickable.getElement('.image').addClass('active');
					isFirst = false;
				}
				
				lastCategory = element.category;
			}
		});
	},
	createSubCategoryMap: function() {
		this._createMap($('gmPlaceHolderSubCategory'));
		this._createMapTypeControls(false);
		this._currentManager = new MarkerManager(this._map);
		this._createMarkerManagers();
		
		this._currentCategory = $('left').getElement('h1').get('rel');
		
		var me = this;
		GEvent.addListener(this._map, 'dragend', function() {
			if (me._map.getZoom() > 8) {
				me._firstZoom = false;
				me._getMarkersForCurrentRegion();
			}
		});
		GEvent.addListener(this._map, 'zoomend', function(from, to) {
			if (from > to) {
				me._getMarkersForCurrentRegion();
			} else if (to > from && me._firstZoom) {
				me._firstZoom = false;
				me._getMarkersForCurrentRegion();
			}
		});
	},
	createListMap: function(items) {
		this._createMap($('gmPlaceHolderList'));
		this._createMapTypeControls(false);
		
		var me = this;
		var grouper = new MarkerGrouper(this._map, {
			fitBounds: true
		});
		
		function getAsObject(array) {
			return {
				id: array[0],
				name: array[1],
				lat: array[2],
				lng: array[3]
			};
		}
		/*
		function doRequest(me, id, name, lat, lng) {
			new Request.JSON({
				url: '/karta/plats/' + id,
				method: 'post',
				onComplete: function(post, response) {
					var n = new InfoWindow(me._map, me._createInfoWindow(name, post.description, post.image, post.url), {
						cssClass: 'infoWindow',
						panTo: new GLatLng(parseFloat(lat), parseFloat(lng) - 0.3),
						styles: {
							'top': '100px'
						}
					});
					n.toggle();
				}
			}).send();
		}
		*/
		for (var i = 0; i < items.length; i++) {
			var current = getAsObject(items[i]);
			
			var marker  = me._createMarker(new GLatLng(current.lat, current.lng), {
				overlay: new Overlay(me._map, current.name, 'overlay').adjust(new OverlayPosition(17, -34))/*,
				event: function() {
					doRequest(me, current.id, current.name, current.lat, current.lng);
				}*/
			});
			
			grouper.add(marker);
		}
		
		grouper.show();
	},
	createPostMap: function() {
		this._createMap($('gmPlaceHolderPost'));
		var me = this;
		
		var client   = new GStreetviewClient();
		var panorama = false;
		client.getNearestPanoramaLatLng(new GLatLng(parseFloat(post.latitude), parseFloat(post.longitude)), function(svLatLng) {
			if (svLatLng) {
				panorama = true;
			}
		});
		
		this._map.setCenter(new GLatLng(parseFloat(post.latitude), parseFloat(post.longitude)));
		this._map.setZoom(11);
		
		var marker = this._createMarker(new GLatLng(parseFloat(post.latitude), parseFloat(post.longitude)));
		this._map.addOverlay(marker);
		
		function injectCollapser(_map) {
			var _div = new Element('div');
			_div.setStyles({
				'position': 'absolute',
				'right': '20px',
				'top': '130px',
				'width': '35px',
				'height': '300px',
				'cursor': 'pointer'
			});
			_div.set('html', '<img src="/images/icons/left.png" />');
			_div.addEvent('click', function(e) {
				new Event(e).stop();
				
				_div.dispose();
				morpher.start({
					'width': '240px'
				});
			});
			
			_map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.appendChild(_div);
		}
		
		var mapIsOpen   = false;
		var hasMapTypes = false;
		morpher = new Fx.Morph($('gmPlaceHolderPost'), {
			duration: '700',
			transition: Fx.Transitions.Sine.easeOut,
			onStart: function() {
				if (mapIsOpen) {
					document.getElementById('mapTypeOverlay').style.display = 'none';
					document.getElementById('mapZoomOverlay').style.display = 'none';
				}
			},
			onComplete: function() {
				me._map.checkResize();
				
				if (mapIsOpen) {
					$('expandGmPlaceHolder').setStyle('display', 'block');
					$('galleryPlaceHolder').setStyle('display', 'block');
					
					me._map.panTo(new GLatLng(parseFloat(post.latitude), parseFloat(post.longitude)));
				} else {
					if (!hasMapTypes) {
						me._createMapTypeControls(panorama);
						hasMapTypes = true;
					} else {
						document.getElementById('mapTypeOverlay').style.display = 'block';
						document.getElementById('mapZoomOverlay').style.display = 'block';
					}
					me._map.panTo(new GLatLng(parseFloat(post.latitude), parseFloat(post.longitude)));
					if ($('thumbnailsPlaceHolder').getElements('img').length > 0)
						injectCollapser(me._map);
				}
				
				mapIsOpen = !mapIsOpen;
			}
		});
		
		if ($defined($('expandGmPlaceHolder'))) {
			$('expandGmPlaceHolder').addEvent('click', function(e) {
				new Event(e).stop();
				
				this.setStyle('display', 'none');
				$('galleryPlaceHolder').setStyle('display', 'none');
				morpher.start({
					'width': '700px'
				});
			});
			
			if ($('thumbnailsPlaceHolder').getElements('img').length < 1) {
				$('expandGmPlaceHolder').setStyle('display', 'none');
				$('galleryPlaceHolder').setStyle('display', 'none');
				morpher.start({
					'width': '700px'
				});
			}
		}
	},
	createPositioningMap: function() {
		this._createMap($('editPositionMapHolder'));
		
		this._map.setCenter(new GLatLng(parseFloat($('latPosition').value), parseFloat($('lngPosition').value)));
		this._map.setZoom(11);
		
		var marker = this._createMarker(new GLatLng(parseFloat(post.latitude), parseFloat(post.longitude)), {
			draggable: true
		});
		GEvent.addListener(marker, 'dragend', function(latlng) {
			$('latPosition').value = latlng.lat();
			$('lngPosition').value = latlng.lng();
		});
		this._map.addOverlay(marker);
	},
	createPositionateMap: function() {
		this._createMap($('gmPositionateMap'));
		
		var me = this;
		$('map-address').addEvent('blur', function() {
			me._positionate();
		});
		$('map-city').addEvent('blur', function() {
			me._positionate();
		});
	},
	_positionate: function() {
		if ($('map-address').value.length > 2 || $('map-city').value.length > 2) {
			var pos    = $('map-address').value + ' ' + $('map-city').value + ', Denmark';
			this._geocode(pos);
		}
	},
	_geocode: function(str) {
		var geocoder = new GClientGeocoder();
		var me       = this;
		geocoder.getLocations(str, function(response) {
			me._map.clearOverlays();
			if (response && response.Status.code == 200) {
				me._map.setZoom(14);
				me._map.setCenter(new GLatLng(response.Placemark[0].Point.coordinates[1], response.Placemark[0].Point.coordinates[0]));
				$('lat').value = response.Placemark[0].Point.coordinates[1];
				$('lng').value = response.Placemark[0].Point.coordinates[0];
				
				var marker = me._createMarker(new GLatLng(response.Placemark[0].Point.coordinates[1], response.Placemark[0].Point.coordinates[0]), {
					draggable: true
				});
				GEvent.addListener(marker, 'dragend', function(p) {
					$('lat').value = p.lat();
					$('lng').value = p.lng();
				});
				me._map.addOverlay(marker);
			}
		});
	},
	createPrintableMap: function(container) {
		this._createMap($(container));
		
		this._map.disableDoubleClickZoom();
		this._map.disableScrollWheelZoom();
		this._map.disableDragging();
		
		var latlng  = new GLatLng(parseFloat($('lat').value), parseFloat($('lng').value));
		this._map.setCenter(latlng);
		this._map.setZoom(11);
		
		var overlay = new Overlay(this._map, $(document.body).getElement('h1').get('text'), 'overlay').adjust(new OverlayPosition(17, -34));
		var marker  = this._createMarker(latlng, {
			overlay: overlay,
			image: 'static'
		});
		this._map.addOverlay(marker);
		overlay.draw(marker);
	}
};;var WelBoxed = new Class({
	type: 0xF00,
	elements: [],
	titles: [],
	options: {
		'loader': '/images/bouncy.gif',

		'background-opacity': '.7',
		'controls-opacity': '.5',
		
		'control-next-title': 'next',
		'control-prev-title': 'prev',
		
		'width': 700,
		'height': 304
	},
	initialize: function(anchorClass, type, options) {
		if (options && typeof options == 'object')
			this._mergeOptions(options);
		
		this.type = type;
		
		var me = this;
		$$('.' + anchorClass).each(function(element, index) {
			me.elements.push(element.get('href'));
			
			var title = '';
			if (element.getProperty('title'))
				title = element.getProperty('title');
			
			me.titles.push(title);
			
			element.addEvent('click', function(e) {
				new Event(e).stop();
				
				me.showOverlay(index);
			});
		});
	},
	createOverlay: function() {
		if (!WelBoxed._overlay) {
			WelBoxed._overlay = new Element('div')
				.set('id', 'welboxed-background-layer')
				.addClass('welboxed-background-layer')
				.setStyles({
					'width': (window.getSize().x + 50) + 'px',
					'height': window.getSize().y + 'px',
					'opacity': '0'
				});
			
			if (Browser.Engine.trident && Browser.Engine.version < 6) {
				WelBoxed._overlay.addClass('welboxed-background-layer-ie-fix');
			}
			
			WelBoxed._overlay.inject(document.body);
			
			WelBoxed._overlay.addEvent('click', function(e) {
				new Event(e).stop();
				
				WelBoxed.close();
			});
		}
	},
	showOverlay: function(index) {
		this.createOverlay();
		
		var me = this;
		WelBoxed._overlay.set('morph', {
			'duration': 500,
			onStart: function() {
				WelBoxed._overlay.setStyle('display', 'block');
			},
			onComplete: function() {
				me.openBox(index);
			}
		});
	
		WelBoxed._overlay.morph({
			'opacity': me.options['background-opacity']
		});
	},
	openBox: function(index) {
		var box = new Element('div')
			.set('id', 'welboxed-popup-layer')
			.addClass('welboxed-popup-layer')
			.setStyles({
				'top': (window.getSize().y / 2) + 'px',
				'left': (window.getSize().x / 2) + 'px'
			})
			.set('html', '<center><img src="' + this.options['loader'] + '" style="border: 0; padding: 2px;" /></center>');
		
		if (Browser.Engine.trident && Browser.Engine.version < 6) {
			box.addClass('welboxed-popup-layer-ie-fix');
		}
		
		box.inject(document.body);
		
		if (this.type == WelBoxed.GALLERY) {
			this._showImage(index);
		} else {
			this._showAjax(index);
		}
	},
	_showImage: function(index) {
		var me  = this;
		var img = new Asset.images(this.elements[index], {
			title: 'welboxed-image',
			onComplete: function() {
				me._setPopupTransformation(img[0], index);
			}
		});
	},
	_showAjax: function(index) {
		var me = this;
		new Request({
			'method': 'post',
			'url': me.elements[index],
			'data': {
				'welboxed': 'true'
			},
			'evalScripts': true,
			onComplete: function(response) {
				var div = new Element('div')
					.set('html', response);
				
				me._setPopupTransformation(div, index);
			}
		}).send();
	},
	_setPopupTransformation: function(element, index) {
		$('welboxed-popup-layer').empty();
		
		var me = this;
		$('welboxed-popup-layer').set('morph', {
			duration: 300,
			onComplete: function() {
				me._setElementStyles(element);
				me._createInnerLayer();
				
				me._injectElement(element);
				
				if (me.elements.length > 1)
					me._setUpControls(index);
			}
		});
		
		me._startTransformation(element);
	},
	_startTransformation: function(element) {
		var width, height = 0;
		
		if (this.type == WelBoxed.GALLERY) {
			width  = element.width  + 30;
			height = element.height + 30;
		} else {
			width  = this.options['width'];
			height = this.options['height'];
		}
		
		$('welboxed-popup-layer').morph({
			'width': width + 'px',
			'height': height + 'px',
			'top': ((window.getSize().y / 2) - (height / 2)) + 'px',
			'left': ((window.getSize().x / 2) - (width / 2)) + 'px'
		});
	},
	_setElementStyles: function(element) {
		element.setStyle('opacity', 0);
	},
	_createInnerLayer: function() {
		new Element('div')
			.set('id', 'welboxed-inner-layer')
			.inject($('welboxed-popup-layer'));
		
		if (this.type == WelBoxed.GALLERY)
			$('welboxed-inner-layer').addClass('gallery-container');
		else
			$('welboxed-inner-layer').addClass('ajax-container');
	},
	_injectElement: function(element) {
		element.inject($('welboxed-inner-layer'));
		element.morph({
			'opacity': 1
		});
	},
	_setUpControls: function(currentIndex) {
		var me = this;
		
		if (currentIndex > 0) {
			new Element('div')
				.set('id', 'welboxed-prev-control')
				.addClass('welboxed-popup-control')
				.setStyle('opacity', me.options['controls-opacity'])
				.inject($('welboxed-inner-layer'))
				.addEvent('click', function(e) {
					new Event(e).stop();
					
					me._openSmooth(currentIndex - 1);
				});
			new Element('a')
				.set('html', me.titles[currentIndex - 1]) //me.options['control-prev-title'])
				.inject($('welboxed-prev-control'));
		}
		
		if (currentIndex < (me.elements.length - 1)) {
			new Element('div')
				.set('id', 'welboxed-next-control')
				.addClass('welboxed-popup-control')
				.setStyle('opacity', me.options['controls-opacity'])
				.inject($('welboxed-inner-layer'))
				.addEvent('click', function(e) {
					new Event(e).stop();
					
					me._openSmooth(currentIndex + 1);
				});
			new Element('a')
				.set('html', me.titles[currentIndex + 1]) //me.options['control-next-title'])
				.inject($('welboxed-next-control'));
		}
	},
	_openSmooth: function(index) {
		var me = this;
		
		$$('.welboxed-popup-control').dispose();
		
		$('welboxed-popup-layer').set('morph', {
			onComplete: function() {
				$('welboxed-popup-layer').dispose();
				me.openBox(index);
			}
		});
		
		$('welboxed-popup-layer').morph({
			'opacity': 0
		});
	},
	_mergeOptions: function(options) {
		for (prop in options)
			this.options[prop] = options[prop];
	}
});
WelBoxed.AJAX     = 0xF00;
WelBoxed.GALLERY  = 0xBABE;
WelBoxed._overlay = false;
WelBoxed.open  = function(url, type, options) {
	var w = new Element('a')
		.set('href', url)
		.setStyle('display', 'none')
		.addClass('welboxed-temporary-opener')
		.inject($(document.body));
	
	new WelBoxed('welboxed-temporary-opener', type, options);
	(function() { w.fireEvent('click', w); }).delay(100);
	w.dispose();
}
WelBoxed.close = function() {
	if ($defined($('welboxed-background-layer'))) {
		$('welboxed-background-layer').set('morph', {
			'duration': 300,
			onStart: function() {
				if ($defined($('welboxed-popup-layer')))
					$('welboxed-popup-layer').dispose();
			},
			onComplete: function() {
				$('welboxed-background-layer').setStyle('display', 'none');
			}
		});
		$('welboxed-background-layer').morph({
			'opacity': 0
		});
	}
};var WelIMooges = {
    horizontalGallery: new Class({
        Implements: [Options, Events],
        initialize: function (slideshow, thumbnails, options) {
            if (!options)
                options = {};

            if (!options.width)
                options.width = 700;
            else
                options.width = parseInt(options.width);

            if (!options.height)
                options.height = 300;
            else
                options.height = parseInt(options.height);

			if (options.left) {
				$(options.left).setStyle('visibility', 'hidden');
			}
			
			if (options.left && options.right && $(thumbnails).getElements('img').length < 2) {
				$(options.left).setStyle('visibility', 'hidden');
				$(options.right).setStyle('visibility', 'hidden');
			}

	        var slider = new Element('div');
	        slider.setStyles({
		        'margin-left': '0',
		        'height': options.height + 'px',
		        'width': ($(thumbnails).getElements('img').length * options.width) + 'px'
	        });
	
	        $(thumbnails).getElements('img').each(function (element) {
		        var wrapper = new Element('div');
		        wrapper.setStyles({
			        'width': options.width + 'px',
			        'height': options.height + 'px',
			        'text-align': 'center',
			        'float': 'left',
		        	'padding': '0',
		        	'margin': '0'
		        });
		        var img = new Element('div');
		        img.set('rel', 'imageElement');
		        img.setStyles({
		        	'width': options.width + 'px',
		        	'height': options.height + 'px',
		        	'background-image': "url('" + element.getParent('a').get('href') + "')",
		        	'background-repeat': 'no-repeat',
		        	'background-position': 'center'
		        });
		        img.inject(wrapper);
		
		        wrapper.inject(slider);
	        });

	        slider.inject($(slideshow));
	
	        var current = 1;
	        var margin  = 0;
	        var locked  = false;
	
	        var lefty   = new Fx.Morph(slider, {
		        transition: Fx.Transitions.Sine.easeOut,
		        onStart: function () {
			        locked = true;
		        },
		        onComplete: function () {
			        margin  = margin - options.width;
			        current = current + 1;
			        locked  = false;
			        
			        if (current == $(thumbnails).getElements('img').length) {
			        	$(options.right).setStyle('visibility', 'hidden');
			        }
			        if ($(options.left).getStyle('visibility') == 'hidden') {
			        	$(options.left).setStyle('visibility', 'visible');
			        }
			    }
	        });
	        var righty  = new Fx.Morph(slider, {
		        transition: Fx.Transitions.Sine.easeOut,
		        onStart: function () {
			        locked = true;
		        },
		        onComplete: function () {
			        margin  = margin + options.width;
			        current = current - 1;
			        locked  = false;
			        
			        if (current == 1) {
			        	$(options.left).setStyle('visibility', 'hidden');
			        }
			        if ($(options.right).getStyle('visibility') == 'hidden') {
			        	$(options.right).setStyle('visibility', 'visible');
			        }
		        }
	        });
			
			if (options.right) {
				$(options.right).addEvent('click', function(e) {
					new Event(e).stop();
					
					if (current < $(thumbnails).getElements('img').length && !locked) {
						lefty.start({
							'margin-left': (margin - options.width)
						});
					}
				});
			}
			if (options.left) {
				$(options.left).addEvent('click', function(e) {
					new Event(e).stop();
					
					if(current > 1 && !locked) {
						righty.start({
							'margin-left': (margin + options.width)
						});
					}
				});
			}
			
	        $(thumbnails).getElements('img').each(function (element, i) {
		        element.getParent('a').addEvent('click', function (e) {
			        new Event(e).stop();

			        var index = i + 1;
			        var diff  = current - index;
			
			        new Fx.Morph(slider, {
				        transition: Fx.Transitions.Sine.easeOut,
				        onStart: function () {
					        locked = true;
				        },
				        onComplete: function () {
					        margin  = margin + (diff * options.width);
					        current = index;
					        locked  = false;
				        }
			        }).start({
				        'margin-left': (margin + (diff * options.width))
			        });
		        });
	        });
	
	        $(slideshow).addEvent('mousewheel', function(e) {
		        new Event(e).stop();
		
		        if (current < $(thumbnails).getElements('img').length && e.wheel < 0 && !locked) {
			        locked = true;
			
			        lefty.start({
				        'margin-left': (margin - options.width)
			        });
		        }
		
		        if (current > 1 && e.wheel > 0 && !locked) {
			        locked = true;
			
			        righty.start({
				        'margin-left': (margin + options.width)
			        });
		        }
	        });
        }
    })
};
;
window.addEvent('domready', function() {
	new WelBoxed('welboxed', WelBoxed.AJAX, {
		'background-opacity': '.5',
		'loader': '/images/welboxed/spinner.gif',
		'width': 345,
		'height': 302
	});
	
	function search(el) {
		if (el.get('value') == '')
			return false;
		
		location.href = '/sok/' + encodeURI(el.get('value').replace(' ', '+'));
	}
	
	if ($defined($('error_page_search'))) {
		$('error_page_search').focus();
		$('error_page_button').addEvent('click', function(e) {
			new Event(e).stop();
			
			search($('error_page_search'));
		});
		$('error_page_search').addEvent('keyup', function(e) {
			new Event(e).stop();
			
			if (e.key == 'enter')
				search($('error_page_search'));
		});
	}
	
	if ($defined($('searcher'))) {
		$('searcher').getElement('.searchSubmit').addEvent('click', function(e) {
			new Event(e).stop();
			
			search($('searcher').getElement('.searchInput'));
		});
		$('searcher').getElement('.searchInput').addEvent('keyup', function(e) {
			new Event(e).stop();
			
			if (e.key == 'enter')
				search($('searcher').getElement('.searchInput'));
		});
	}
	
	/* START PAGE  */
	
	if ($defined($('box'))) {
		$('box').getElements('.startBoxImg').addEvents({
			'mouseenter': function() {
				var current = this.getParent('li');
				var others  = $('box').getElements('li').filter(function(item, index) {
					return current !== item;
				});
				others.each(function(elem) {
					elem.getElement('.startBoxImgBack').morph({
						width: '132px',
						height: '98px',
						top: '10px',
						left: '10px'
					});
					elem.getElement('.startBoxImg').morph({
						width: '110px',
						height: '77px',
						top: '20px',
						left: '22px'
					});
				});
				
				this.getParent('li').getElement('.startBoxImgTips').setStyle('display', 'block');
			},
			'mouseout': function() {
				var current = this.getParent('li');
				var others  = $('box').getElements('li').filter(function(item, index) {
					return current !== item;
				});
				others.each(function(elem) {
					elem.getElement('.startBoxImgBack').morph({
						width: '174px',
						height: '124px',
						top: '0',
						left: '0'
					});
					elem.getElement('.startBoxImg').morph({
						width: '150px',
						height: '100px',
						top: '10px',
						left: '12px'
					});
				});
				
				this.getParent('li').getElement('.startBoxImgTips').setStyle('display', 'none');
			}
		});
	}
	
	/* /START PAGE */


/* BUTTONS */
	$$('.button1').addEvents({
		mouseenter: function() {
			if(this.getElement('.left').hasChild('a')){
				this.getElement('.left a').morph({
					'text-decoration':'underline'
				});
			}
		},
		mouseleave: function() {
			if(this.getElement('.left').hasChild('a')){
				this.getElement('.left a').morph({
					'text-decoration':'none'
				});
			}
		},
		click: function() {
			if(this.getElement('.left').hasChild('a')){
				document.location = this.getElement('a').getProperty('href');
			}	
		}
	});



/* START POINT TPL */

	$$('.pointToolsContainer .boxes').setStyles({'opacity':'0','display':'block'});
    $$('.pointToolsContainer .menuMouseLayer div.dropBox').addEvents({
		'mouseenter': function(e) {
			if(this.getParent().getParent().getElement('.'+this.getProperty('rel')+'.boxes').getProperty('rel') == 'open'){}
			else
			{	
				$$('.pointToolsContainer .boxes[rel=open]').setStyles({'height': '16px','opacity': '0'});
    			$$('.pointToolsContainer .boxes[rel=open]').set('rel', 'closed');
				this.getParent().getParent().getElement('.'+this.getProperty('rel')+'.boxes').setStyles({'opacity': '1'});
				this.getParent().getParent().getElement('.'+this.getProperty('rel')+'.boxes').morph({'height': '89px'});
	    		this.getParent().getParent().getElement('.'+this.getProperty('rel')+'.boxes').set('rel', 'open');
	    	}
		}
	});
	$$('.pointToolsContainer .share.boxes').setStyles({'opacity': '1'});
	$$('.pointToolsContainer .share.boxes').morph({'height': '89px'});
	$$('.pointToolsContainer .share.boxes').set('rel', 'open');
	
	var voteBoxes = $$('.voteBox');
		// Add our events to the pages
		voteBoxes.each(function(el) {
			el.getElement('.voteBackground').morph({'width': (el.getProperty('rel')*15+((el.getProperty('rel')-1)*2))});
            el.addEvents({
            	mouseleave: function(){
	        		el.getElement('.voteBackground').morph({
    	        		//get rel element multiply that with 15 (width of a heart) and add 2 extra px for every box before (the padding)
    	        		'width': (el.getProperty('rel')*15+((el.getProperty('rel')-1)*2))
            		});
	        	}
            });
		});	
		$$('.voteBox .voteGradesBoxes div').addEvents({
			mouseenter: function(){
				//Get from here to the div with opacity for moving it
	            this.getParent().getParent().getParent().getElement('.voteBackground').morph({
					//get rel element multiply that with 15 (width of a heart) and add 2 extra px for every box before (the padding)
					'width': (this.getProperty('rel')*15+((this.getProperty('rel')-1)*2))
            	});
	        }
	    });


/* END POINT TPL*/
	
	function mergeSorter(elements, fn, sorter) {
		if (elements.length < 2)
			return;
		
		var left  = [];
		var right = [];
		
		var k     = Math.floor(elements.length / 2);
		
		while (elements.length > k)
			left.push(elements.shift());
		while (elements.length > 0)
			right.push(elements.shift());
		
		mergeSorter(left, fn);
		mergeSorter(right, fn);
		
		while (left.length > 0 && right.length > 0) {
			if (fn(left[0], right[0]) < 0)
				elements.push(left.shift());
			else
				elements.push(right.shift());
		}
		while (left.length > 0)
			elements.push(left.shift());
		while (right.length > 0)
			elements.push(right.shift());
	}

	function sortByGradeReversed(a, b) {
		return b.retrieve('grade') - a.retrieve('grade');
	}
	function sortByGrade(a, b) {
		return a.retrieve('grade') - b.retrieve('grade');
	}
	function sortByHitsReversed(a, b) {
		return b.retrieve('hits') - a.retrieve('hits');
	}
	function sortByHits(a, b) {
		return a.retrieve('hits') - b.retrieve('hits');
	}
	function sortByName(a, b) {
		return a.retrieve('name').charCodeAt(0) - b.retrieve('name').charCodeAt(0);
	}
	function sortByNameReversed(a, b) {
		return b.retrieve('name') - a.retrieve('name');
	}

	function inactivateAll() {
		$$('.categorySortingBar').getLast().getElements('.button1').removeClass('down');
		$$('.categorySortingBar').getLast().getElements('.button1').removeClass('up');
		$$('.categorySortingBar').getLast().getElements('.button1').addClass('inactive');
	}
	
	if ($defined($('collectionContainer'))) {
		var scrollSize      = window.getScrollSize().y;
		var collectionCount = $$('.listOneItemBox').length;
		var lastTime        = new Date().getTime();
		var hasMore         = true;
		if (collectionCount < 15)
			hasMore         = false;
		
		window.addEvent('scroll', function() {
			if ((scrollSize - window.getSize().y) < (window.getScroll().y + 20)) {
				collectItems();
			}
		});
		
		var locked = false;
		var spinner;
		function collectItems() {
			if (!locked && lastTime < (new Date().getTime() - 1000) && hasMore) {
				locked  = true;
				
				req = new Request.JSON({
					url: '/addonjs/fetch/',
					method: 'post',
					data: {
						'categoryUrl': $('left').getElement('h1').get('rel'),
						'collectionCount': (collectionCount),
						'sort': ($$('.categorySortingBar').pop()).get('rel')
					},
					onRequest: function() {
						spinner = new Element('div')
							.setStyles({
								'text-align': 'center',
								'padding': '10px 0'
							})
							.set('html', '<img src="/images/welboxed/spinner.gif" border="0" />')
							.inject($('lastItemInCollection'), 'before');
					},
					onSuccess: function(json, xml) {
						if (spinner)
							spinner.dispose();
						
						var listText   = $$('.listOneItemText').pop();
						var categories = listText.getElement('h5').get('html');
						var urlStart   = listText.getElement('h3').getElement('a').get('href');
						var urlParts   = urlStart.split('/');
						urlStart       = '/' + urlParts[1] + '/' + urlParts[2] + '/';
						
						for (var i = 0; i < json.length; i++) {
							var div = new Element('div')
								.addClass('listOneItemBox');
							
							var image = '/images/heart.png';
							if ((json[i].imageId + "").search(/^\d+$/) != -1)
								image = '/images/pointImages/gdkimages/thumbs/' + json[i].imageId + '.jpg';
							
							var descr = json[i].description.replace(/\\/g, '');
							if (descr.length > 130)
								descr = descr.substr(0, 130) + '...';
							
							new Element('div')
								.addClass('listOneItemBackground')
								.setStyles({
									'background-color': '#fff',
									'opacity': '0'
								})
								.inject(div);
							new Element('div')
								.addClass('listOneItemImg')
								.set('html', '<img src="' + image + '" />')
								.inject(div);
							new Element('div')
								.addClass('listOneItemText')
								.set('html', '<h5 style="margin: 0; color: #aaa; text-transform: uppercase;">' + categories + '</h5><h3 style="margin: 0; color: #CF051D;"><a href="' + urlStart + json[i].id + '-' + json[i].url + '" style="color: #CF051D;">' + json[i].name.replace(/\\/g, '') + '</a></h3><p>' + descr + '</p>')
								.inject(div);
							new Element('div')
								.addClass('listOneItemButton')
								.set('html', '<div class="button2 right"><div class="left"><a style="color: rgb(255, 255, 255);" href="' + urlStart + json[i].id + '-' + json[i].url + '">Visa</a></div><div class="right"></div></div>')
								.inject(div);
								
							div.addEvents({
								'mouseenter': function() {
									this.getElement('.listOneItemBackground').morph({
										'opacity': '.9'
									});
									this.getElement('.listOneItemButton').setStyles({
										'display': 'block',
										'opacity': '1'
									});
								},
								'mouseleave': function() {
									this.getElement('.listOneItemBackground').morph({
										'opacity': '0'
									});
									this.getElement('.listOneItemButton').setStyles({
										'opacity': '0'
									});
								}
							});
							
							div.inject($('lastItemInCollection'), 'before');
						}
						
						scrollSize = window.getScrollSize().y;
						if (json.length < 15)
							hasMore = false;
						
						collectionCount += json.length;
						
						locked = false;
					}
				}).send();
			}
		}
	}
	
	if ($$('.sortable').length > 0) {
		var sorter = new Fx.Sort($('sortContainer').getElements('.sortable'));
		
		var elements = [];
		var lastSort = sortByHitsReversed;

		$('sortContainer').getElements('.sortable').each(function(element, index) {
			var values = element.get('rel').split('|');
			element.store('grade', parseInt(values[0]));
			element.store('hits',  parseInt(values[1]));
			element.store('name',  values[2]);
			
			elements.push(element);
		});
		
		/*$('sortByGrade').addEvent('click', function(e) {
			new Event(e).stop();
			
			inactivateAll();

			if (lastSort && lastSort == sortByGrade) {
				lastSort = sortByGradeReversed;
				this.getParent('div').getParent('div').addClass('down');
			} else {
				lastSort = sortByGrade;
				this.getParent('div').getParent('div').addClass('up');
			}
			this.getParent('div').getParent('div').removeClass('inactive');
			
			mergeSorter(elements, lastSort, sorter);
			sorter.sortByElements(elements);
		});*/
		$('sortByHits').addEvent('click', function(e) {
			new Event(e).stop();

			inactivateAll();

			if (lastSort == sortByHits) {
				lastSort = sortByHitsReversed;
				this.getParent('div').getParent('div').addClass('down');
			} else {
				lastSort = sortByHits;
				this.getParent('div').getParent('div').addClass('up');
			}
			this.getParent('div').getParent('div').removeClass('inactive');
			
			mergeSorter(elements, lastSort, sorter);
			sorter.sortByElements(elements);
		});
		$('sortByName').addEvent('click', function(e) {
			new Event(e).stop();

			inactivateAll();

			if (lastSort == sortByName) {
				lastSort = sortByNameReversed;
				this.getParent('div').getParent('div').addClass('down');
			} else {
				lastSort = sortByName;
				this.getParent('div').getParent('div').addClass('up');
			}
			this.getParent('div').getParent('div').removeClass('inactive');
			
			mergeSorter(elements, lastSort, sorter);
			sorter.sortByElements(elements);
		});
	}
	
	$$('.categoryListRightBox .oneCategoryListRightBox').addEvents({
		mouseenter: function() {
			this.getElement('.left').morph({
				'width':'36px'
			});
		},
		mouseleave: function() {
			this.getElement('.left').morph({
				'width':'7px'
			});
		},
		click: function() {
			document.location = this.getElement('a').getProperty('href');
		}
	});
	$$('.categoryListRightBox .oneCategoryListRightBox.active').removeEvents('mouseenter');
	$$('.categoryListRightBox .oneCategoryListRightBox.active').removeEvents('mouseleave');
	
	$$('.listOneItemBackground').setStyles({
		'background-color': '#fff',
		'opacity': '0'
	});
	
	$$('.listOneItemButton').setStyles({
		'display': 'block',
		'opacity': '0'
	});
	
	$$('.listOneItemBox').addEvents({
		'mouseenter': function(e) {
			if (this.hasClass('listSmallBox')) {
				this.getElement('p').setStyles({
					'opacity': '0',
					'display': 'block'
				});
				
				var me = this;
				this.set('morph', {
					onComplete: function() {
						me.getElement('p').morph({
							'opacity': '1'
						});
						
						var img = '/images/heart.png';
						if (me.getElement('.listOneItemText').get('rel') != '' && parseInt(me.getElement('.listOneItemText').get('rel')) > 0)
							img = '/images/pointImages/gdkimages/thumbs/' + me.getElement('.listOneItemText').get('rel') + '.jpg';
						
						new Element('img')
							.set('src', img)
							.setStyle('opacity', '0')
							.inject(me.getElement('.listOneItemImg'))
							.morph({
								'opacity': '1'
							});
					}
				});
				this.morph({
					'height': '100px',
					'padding': '15px 0'
				});
			} else if (this.getElement('.listOneItemButton')) {
				this.getElement('.listOneItemButton').setStyles({
					'opacity': '1'
				});
			}
			this.getElement('.listOneItemBackground').morph({
				'opacity': '.9'
			});
		},
		'mouseleave': function(e) {
			if (this.hasClass('listSmallBox')) {
				this.set('morph', {
					onComplete: function() {}
				});
				
				this.getElement('.listOneItemImg').empty();
				
				this.getElement('p').setStyles({
					'opacity': '0',
					'display': 'none'
				});
				this.morph({
					'height': '30px',
					'padding': '5px 0'
				});
			} else if (this.getElement('.listOneItemButton')) {
				this.getElement('.listOneItemButton').setStyles({
					'opacity': '0'
				});
			}
			this.getElement('.listOneItemBackground').morph({
				'opacity': '0'
			});
		},
		'click': function(e) {
			if (this.hasClass('no-follow'))
				return;
			
			var anchors       = this.getElements('a');

			var index = 0;
			if (this.get('rel') == 'no-click')
				index = anchors.length - 1;
			
			if (anchors.length > 0)
				document.location = anchors[index].get('href');
		}
	});
	
	$$('.truncatedDescriptionButton').addEvent('click', function(e) {
		var t = this;
		$$('.truncatedDescription').each(function(element) {
			element.set('morph', {
				onStart: function() {
					t.dispose();
				},
				onComplete: function() {
					element.setStyle('overflow', 'visible');
				}
			});
			element.morph({
				'height': element.getElement('p').getSize().y + 'px'
			});
		});
	});

	/* DRAGGABLES */
	var sort = new Sortables($('draggableContainer'), {
		handle: '.draggable',
		constrain: true,
		clone: true,
		rervert: true,
		onStart: function(elem, clone) {
			elem.setStyle('opacity', '.5');
			clone.setStyle('opacity', '.5');
		},
		onComplete: function(elem) {
			elem.setStyle('opacity', '1');
			
			var buffer = '';
			$('draggableContainer').getElements('.draggable').each(function(element, index) {
				buffer += element.get('rel') + '=' + (index + 1) + '&';
			});
			buffer += 'listId=' + $('listId').get('value');
			
			new Request.JSON({
				url: '/profil/order',
				method: 'post',
				onSuccess: function(json, xml) {
					$('draggableContainer').set('morph', {
						onStart: function() {
							$('draggableContainer').setStyles({
								'background-color': 'transparent'
							});
						},
						onComplete: function() {
							$('draggableContainer').setStyles({
								'background-color': 'transparent'
							});
						}
					});
					$('draggableContainer').morph({
						'background-color': '#FFFC30'
					});
				}
			}).send(buffer);
		}
	});
	
	function acceptChanges() {
		$('acceptChangesBtn').dispose();
		$$('.editLinks').setStyle('display', 'inline');
		
		if ($defined($('inputUserListName'))) {
			$('userListName').set('text', $('inputUserListName').get('value'));
			$('inputUserListName').dispose();
			$('userListName').setStyle('display', 'inline');
		} else if ($defined($('inputUserListDescription'))) {
			$('userListDescription').set('text', $('inputUserListDescription').get('value'));
			$('inputUserListDescription').dispose();
			$('userListDescription').setStyle('display', 'inline');
		}

		new Request({
			url: '/profil/updatelist',
			method: 'post',
			data: {
				listId: $('userListName').get('rel'),
				name: $('userListName').get('text'),
				description: $('userListDescription').get('text')
			}
		}).send();
	}
	
	function setupEditables() {
		$$('.editLinks').setStyle('display', 'none');
		
		new Element('span')
			.set('id', 'acceptChangesBtn')
			.setStyles({
				'font-size': '14px',
				'font-weight': 'normal',
				cursor: 'pointer',
				'text-decoration': 'underline'
			})
			.set('text', 'OK')
			.inject($('userListName').getParent('.header'))
			.addEvent('click', acceptChanges);
	}
	
	if ($defined($('showListMap'))) {
		if (items.length > 0) {
			$('showListMap').addEvent('click', function(e) {
				new Event(e).stop();
				
				$('gmPlaceHolderList').getParent('div').set('morph', {
					onComplete: function() {
						$('gmPlaceHolderList').getParent('div').setStyles({
							'overflow': 'auto'
						});
						Maps.createListMap(items);
					}
				});
				$('gmPlaceHolderList').getParent('div').morph({
					'height': '315px'
				});
			});
		}
	}
	
	if ($defined($('userListName'))) {
		$('editUserListName').addEvent('click', function(e) {
			new Event(e).stop();
			
			setupEditables();
			
			$('userListName').setStyle('display', 'none');
			new Element('input')
				.set('type', 'text')
				.set('id', 'inputUserListName')
				.set('value', $('userListName').get('text'))
				.addClass('editUserListName')
				.inject($('userListName').getParent('.header'), 'top');
		});
		$('editUserListDescription').addEvent('click', function(e) {
			new Event(e).stop();
			
			setupEditables();
			
			$('userListDescription').setStyle('display', 'none');
			new Element('textarea')
				.set('id', 'inputUserListDescription')
				.set('text', $('userListDescription').get('text'))
				.addClass('editUserListDescription')
				.inject($('userListDescription').getParent());
		});
		
		var req;
		$(document.body).setStyle('height', (window.getScrollSize().y - $('page').getSize().y) + 'px');
		$(document.body).addEvent('click', function() {
			if ($('autoComplete').getStyle('display') == 'block')
				$('autoComplete').setStyle('display', 'none');
		});
		
		function addMouseEvents(element, style) {
			element.addEvents({
				'mouseenter': function() {
					this.morph({
						'background-color': '#fff'
					});
				},
				'mouseleave': function() {
					this.morph({
						'background-color': style
					});
				}
			})
		}
		
		$('findItemToList').addEvent('keyup', function(e) {
			var search = $('findItemToList').get('value');
			if (search.length > 2) {
				if (req)
					req.cancel();
				
				req = new Request.JSON({
					url: '/search/post',
					method: 'post',
					data: {
						'search': search
					},
					onRequest: function() {
						$('autoComplete').empty();
						$('autoComplete').setStyles({
							'text-align': 'center',
							'display': 'block'
						});
						$('autoComplete').set('html', '<img src="/images/welboxed/spinner.gif" style="margin: 5px;" />');
					},
					onSuccess: function(json, xml) {
						$('autoComplete').empty();
						$('autoComplete').setStyle('text-align', 'left');
						for (var i = 0; i < json.data.length && i < 10; i++) {
							var name = json.data[i].name;
							var id   = json.data[i].id;
							var url  = json.data[i].url;
							
							if (name.length > 35)
								name = name.substr(0, 35) + '...';
								
							var rx   = new RegExp(search, 'ig');
							name     = name.replace(rx, '<b>' + search + '</b>');
							
							var bgColors = ['#eee', '#ccc'];
							var div      = new Element('div')
								.setStyles({
									'padding-left': '15px',
									'height': '29px',
									'line-height': '29px',
									'background-color': (i % 2 == 0) ? bgColors[0] : bgColors[1],
									'position': 'relative'
								});
							addMouseEvents(div, (i % 2 == 0) ? bgColors[0] : bgColors[1]);
							
							var html     = '<div style="position: absolute; top: 0; right: 0;"><a href="/profil/post/' + $('listId').get('value') + '/' + id + '"><img src="/images/design2/buttons/button1/mapPlus.png" style="border: 0;" /></a></div><a href="/profil/post/' + $('listId').get('value') + '/' + id + '">' + name + '</a>';
							div.set('html', html);
							div.inject($('autoComplete'));
						}
					}
				}).send();
			}
		});
	}
	
	if ($defined($('galleryPlaceHolder'))) {
		new WelIMooges.horizontalGallery('galleryPlaceHolder', 'thumbnailsPlaceHolder', {
			width: 450,
			height: 300,
			left: 'leftControl',
			right: 'rightControl'
		});
	}
	
	new Accordion($('right'), 'h3.accordion', 'div.accordion', {
		opacity: false,
		onActive: function(toggler, element) {
			toggler.setStyle('color', '#D1031C');
			$$('.linkListRightTopBox').removeClass('active');
			toggler.getParent().toggleClass('active');
		},
		onBackground: function(toggler, element) {
			toggler.setStyle('color', '#333333');
			toggler.getParent().removeClass('active');
		}
	});
	
	var openEditor;
	
	function updateNote(itemId, listId, text) {
		new Request({
			url: '/profil/updatenote',
			method: 'post',
			data: {
				itemId: itemId,
				listId: listId,
				note:   text
			}
		}).send();
	}
	
	function restoreNotes(e) {
		if (e)
			new Event(e).stop();
		
		var text = $('textarea-note').get('value');
		if (text.replace(new RegExp('[\\s]+$', 'g'), '') == '')
			text = '(ingen egen notering, klicka för att ändra)';
		
		openEditor.set('text', text);
		$('textarea-note').dispose();
		$('textarea-counter').dispose();
		openEditor.setStyle('display', 'inline');
		
		$$('.draggable').setStyle('cursor', 'move');
		
		var ids = openEditor.get('rel').split('|');
		updateNote(ids[0], ids[1], text);
		
		openEditor = false;
		$(document.body).removeEvent('click', restoreNotes);
		
		sort.attach();
	}
	
	$$('.noteEditor').addEvent('click', function(e) {
		new Event(e).stop();
		
		if (openEditor) {
			restoreNotes();
		}
		
		openEditor = this;
		
		sort.detach();
		var left = 160;
		
		this.setStyle('display', 'none');
		$$('.draggable').setStyle('cursor', 'auto');
		var counter = new Element('div')
			.set('id', 'textarea-counter')
			.setStyles({
				'position': 'absolute',
				'top': '30px',
				'right': '40px',
				'font-size': '24px',
				'font-family': 'Georgia',
				'color': '#bbb'
			})
			.inject(this.getParent('.draggable'));
		
		var area = new Element('textarea')
			.set('id', 'textarea-note')
			.setStyles({
				'border': '1px solid #ddd',
				'width': '450px',
				'height': '50px',
				'margin': '10px 0'
			})
			.inject(this.getParent('.description'))
			.addEvents({
				'keydown': function(e) {
					if (left <= 0 && e.key != 'delete' && e.key != 'backspace')
						return false;
				},
				'keyup': function(e) {
					var current = this.get('value').length;
					left        = 160 - current;
					$('textarea-counter').set('text', left + '');
					
					if (left <= 20 && left > 0) {
						$('textarea-counter').setStyle('color', '#d9d507');
					} else if (left <= 0) {
						$('textarea-counter').setStyle('color', '#ff0000');
						this.set('value', this.get('value').substr(0, 160));
					} else {
						$('textarea-counter').setStyle('color', '#bbb');
					}
				},
				'click': function(e) {
					new Event(e).stop();
					return false;
				}
			});
		
		counter.set('text', (160 - area.get('text').length) + '');
		
		if (this.get('text') != '(ingen egen notering, klicka för att ändra)') {
			area.set('value', this.get('text'));
		}
		
		$(document.body).addEvent('click', restoreNotes);
	});
	
	if ($defined($('gmPlaceHolderCategory'))) {
		Maps.createCategoryMap();
	}
	if ($defined($('gmPlaceHolderSubCategory'))) {
		Maps.createSubCategoryMap();
	}
	if ($defined($('gmPlaceHolderPost'))) {
		Maps.createPostMap();
		/*$('listThis').addEvents({
			mouseenter: function() {
				this.set('src', '/images/design2/images/listThisOn.png');
			},
			mouseleave: function() {
				this.set('src', '/images/design2/images/listThis.png');
			}
		});*/
	}
	if ($defined($('gmPositionateMap'))) {
		Maps.createPositionateMap();
	}
});