/**
 *  Maptimize Embedded Script 2.0
 *  
 *  Copyright 2008 - 2010 Xilinus - All rights reserved
**/
/*
* LabeledMarker Class, v1.2
*
* Copyright 2007 Mike Purvis (http://uwmike.com)
* 
* 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.
*
* This class extends the Maps API's standard GMarker class with the ability
* to support markers with textual labels. Please see articles here:
*
*       http://googlemapsbook.com/2007/01/22/extending-gmarker/
*       http://googlemapsbook.com/2007/03/06/clickable-labeledmarker/
*/

(function(window){var document=window.document,Array=window.Array,Object=window.Object,encodeURIComponent=window.encodeURIComponent,setTimeout=window.setTimeout,console=window.console,EMPTY_FUNCTION=function(){};function getGoogleMapsComponent(name){var google=window.google,googleMaps=google&&google.maps;return googleMaps&&googleMaps[name]||window["G"+name]||window["G_"+name]}if(!getGoogleMapsComponent("Map2")){var loader=arguments.callee;return setTimeout(function(){loader(window)},100)}var _toString=Object.prototype.toString,_hasOwnProperty=Object.prototype.hasOwnProperty,_slice=Array.prototype.slice,undefined=void (0);var ArgumentError=createClass(extend(beget(Error.prototype),{initialize:function(message){this.message=message}}));function extend(destination,source){for(var property in source){destination[property]=source[property]}return destination}function merge(object,other){var result=extend({},object);return extend(result,other)}function beget(object){function F(){}F.prototype=object;return new F}function removeProperty(object,property){var value=object[property];delete object[property];return value}function createClass(body,classMethods){var constructor=removeProperty(body,"initialize");if(constructor==null){constructor=function(){}}extend(constructor.prototype,body);constructor.prototype.constructor=constructor;return extend(constructor,classMethods||{})}function isString(object){return _toString.call(object)==="[object String]"}function isArray(object){return _toString.call(object)==="[object Array]"}function restingArgs(args){return _slice.call(args,args.callee.length)}function each(iterable,callback){for(var i=0,l=iterable.length;i<l;i++){callback(iterable[i],i)}return iterable}function map(iterable,callback){var results=new Array(iterable.length);for(var i=0,l=iterable.length;i<l;i++){results[i]=callback(iterable[i],i)}return results}function toArray(iterable){return _slice.call(iterable,0)}function LatLng(lat,lng){if(lng==null&&isString(lat)){var coords=lat.split(/\s*,\s*/);lat=coords[0];lng=coords[1]}return new GLatLng(lat,lng)}function LatLngBounds(sw,ne){return new GLatLngBounds(sw,ne)}function Point(x,y){return new GPoint(x,y)}function toQueryString(object){var pairs=[];for(var property in object){if(object[property]!==undefined){pairs.push(encodeURIComponent(property)+"="+encodeURIComponent(object[property]))}}return pairs.join("&")}function debug(){}function imageURL(filename){return"http://betav2.maptimize.com/images/"+filename}function swfURL(filename){return"http://betav2.maptimize.com/swf/"+filename}var HEAD=document.getElementsByTagName("HEAD")[0],BODY=document.body,URL;each(document.getElementsByTagName("SCRIPT"),function(script){if(script.src.match(/\/api\/v2-0\/.*\/embed/)){URL=script.src.replace(/embed.*$/,"")}});(function(GEvent,GBounds,GLatLng,GSize,GIcon,GPoint,GMarker,GLatLngBounds,GMercatorProjection,GControl,GControlPosition,G_MAP_MARKER_PANE,G_MAP_MAP_PANE,G_ANCHOR_TOP_RIGHT){function LabeledMarker(latlng,opt_opts){this.latlng_=latlng;this.opts_=opt_opts;this.labelText_=opt_opts.labelText||"";this.labelClass_=opt_opts.labelClass;this.labelOffset_=opt_opts.labelOffset||new GSize(0,0);this.clickable_=opt_opts.clickable||true;this.title_=opt_opts.title||"";this.labelVisibility_=true;if(opt_opts.draggable){opt_opts.draggable=false}GMarker.apply(this,arguments)}LabeledMarker.prototype=extend(new GMarker(new GLatLng(0,0)),{initialize:function(map){GMarker.prototype.initialize.apply(this,arguments);this.map_=map;this.div_=document.createElement("div");this.div_.className=this.labelClass_;this.div_.innerHTML=this.labelText_;this.div_.style.position="absolute";this.div_.style.cursor="pointer";this.div_.title=this.title_;map.getPane(G_MAP_MARKER_PANE).appendChild(this.div_);if(this.clickable_){function newEventPassthru(obj,event){return function(){GEvent.trigger(obj,event)}}var eventPassthrus=["click","dblclick","mousedown","mouseup","mouseover","mouseout"];for(var i=0;i<eventPassthrus.length;i++){var name=eventPassthrus[i];GEvent.addDomListener(this.div_,name,newEventPassthru(this,name))}}},redraw:function(force){GMarker.prototype.redraw.apply(this,arguments);var p=this.map_.fromLatLngToDivPixel(this.latlng_);var z=GOverlay.getZIndex(this.latlng_.lat());this.div_.style.left=(p.x+this.labelOffset_.width)+"px";this.div_.style.top=(p.y+this.labelOffset_.height)+"px";this.div_.style.zIndex=z},remove:function(){GEvent.clearInstanceListeners(this.div_);if(this.div_.outerHTML){this.div_.outerHTML=""}if(this.div_.parentNode){this.div_.parentNode.removeChild(this.div_)}this.div_=null;GMarker.prototype.remove.apply(this,arguments)},copy:function(){return new LabeledMarker(this.latlng_,this.opt_opts_)},show:function(){GMarker.prototype.show.apply(this,arguments);if(this.labelVisibility_){this.showLabel()}else{this.hideLabel()}},hide:function(){GMarker.prototype.hide.apply(this,arguments);this.hideLabel()},setLabelVisibility:function(visibility){this.labelVisibility_=visibility;if(!this.isHidden()){if(this.labelVisibility_){this.showLabel()}else{this.hideLabel()}}},getLabelVisibility:function(){return this.labelVisibility_},hideLabel:function(){this.div_.style.visibility="hidden"},showLabel:function(){this.div_.style.visibility="visible"}});function Condition(){var SPECIAL_CHARS={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\\":"\\\\"};var self,string=parseArguments(arguments);function parseArguments(args){switch(args.length){case 0:return"";case 1:return parseObject(args[0]);default:return parseArray(toArray(args))}}function parseObject(object){if(object instanceof Condition||isString(object)){return object.toString()}var result=Condition();for(var property in object){result.appendAnd(property+"="+litteral(object[property]))}return result.toString()}function parseArray(array){return array.shift().replace(/(.)\?/g,function(_,chr){return chr==="\\"?"?":chr+litteral(array.shift())})}function litteral(object){if(isString(object)){return stringLitteral(object)}if(isArray(object)){return arrayLitteral(object)}return object===undefined?"":String(object)}function stringLitteral(string){var escapedString=string.replace(/[\x00-\x1f\\]/g,function(chr){if(chr in SPECIAL_CHARS){return SPECIAL_CHARS[chr]}return"\\u00"+chr.charCodeAt(0).toPaddedString(2,16)});return'"'+escapedString.replace(/"/g,'\\"')+'"'}function arrayLitteral(array){return"["+map(array,litteral).join(",")+"]"}function appendAnd(){return merge("AND",arguments)}function appendOr(){return merge("OR",arguments)}function merge(operator,args){var condition=parseArguments(args);if(!string){string=condition}else{string="("+string+")"+operator+"("+condition+")"}return self}function toString(){return string}self=extend(beget(Condition.prototype),{appendAnd:appendAnd,appendOr:appendOr});self.toString=toString;return self}function MapStorage(){var SHORTCUTS={properties:"p",zoom:"z",bounds:"b",aggregates:"a",condition:"c",groupingDistance:"d",groupBy:"g",limit:"l",offset:"o"};function clusterize(params){requires(params,"zoom","bounds");validates(params,"properties","zoom","bounds","aggregates","condition","onSuccess","groupingDistance","groupBy","ids");if(isArray(params.aggregates)){params.aggregates=params.aggregates.join(",")}return request("clusterize",params)}function select(params){validates(params,"properties","limit","offset","bounds","condition");return request("select",params)}function show(params){requires(params,"id");return request("show",params)}function request(path,params){requires(params,"onSuccess");formatBounds(params);formatParams(params);return(params.ids?SWFRequest:XSSRequest).send(URL+path,params,removeProperty(params,"onSuccess"))}function requires(params){each(restingArgs(arguments),function(key){if(!(key in params)){throw new ArgumentError("Required parameter : "+key)}})}function validates(params){}function formatBounds(params){if(params.bounds){var bounds=removeProperty(params,"bounds");params.sw=bounds.getSouthWest().toUrlValue();params.ne=bounds.getNorthEast().toUrlValue()}}function formatParams(params){if(!params.ids){removeProperty(params,"ids")}}return{clusterize:clusterize,paginate:select,show:show}}function Map(mapImpl,options){var ORIGIN=LatLng(0,0),EMPTY_BOUNDS=LatLngBounds(ORIGIN,ORIGIN),WHOLE_EARTH=LatLngBounds(LatLng(-90,-180),LatLng(90,180)),DEFAULT_OPTIONS={onClusterClicked:onClusterClicked,onMarkerClicked:onMarkerClicked,theme:Theme.Default};options=merge(DEFAULT_OPTIONS,options);GEvent.addListener(mapImpl,"moveend",viewDidChange);var self,storage=MapStorage(),bounds=EMPTY_BOUNDS,markers=[],clusters=[],zoom=mapImpl.getZoom(),theme=options.theme,condition,properties,aggregates,ids,groupingDistance,groupBy;function onClusterClicked(cluster){if(cluster.canExpandOnMap()){cluster.expandOnMap()}else{fire("clusterClicked",cluster)}}function onMarkerClicked(marker){fire("markerClicked",marker)}function setMarkerIds(newIds){ids=newIds}function setCondition(newCondition){condition=Condition.apply(null,arguments)}function setMarkerProperties(newProperties){properties=newProperties&&newProperties.join(",")}function setClusterAggregates(newAggregates){aggregates=newAggregates&&newAggregates.join(",")}function setGroupingDistance(distance){groupingDistance=distance}function setGroupBy(attribute){groupBy=attribute}function getMapImpl(){return mapImpl}function createCluster(cluster){return theme.createCluster(cluster)}function createMarker(marker){return theme.createMarker(marker)}function isMaxZoom(){return mapImpl.getBoundsZoomLevel(EMPTY_BOUNDS)===mapImpl.getZoom()}function getMarkers(){return filterVisible(markers)}function getClusters(){return filterVisible(clusters)}function filterVisible(overlays){var result=[],mapBounds=mapImpl.getBounds();each(overlays,function(overlay){if(mapBounds.contains(overlay.getGLatLng())){result.push(overlay)}});return result}function getTotalPointsCount(){var count=getMarkers().length;each(getClusters(),function(cluster){count+=cluster.getPointsCount()});return count}function refresh(){bounds=EMPTY_BOUNDS;viewDidChange()}function viewDidChange(){var newZoom=mapImpl.getZoom();if(zoom!==newZoom||!bounds.containsBounds(mapImpl.getBounds())){zoom=newZoom;requestAreaMarkers()}}function requestAreaMarkers(){fire("beforeRefresh");var areaBounds=enlargeBounds(mapImpl.getBounds(),mapImpl.getZoom());clusterize({bounds:areaBounds,onSuccess:function(response){requestDidFinish(response,areaBounds)}})}function requestDidFinish(response,newBounds){bounds=newBounds;replaceMarkers(response.markers);replaceClusters(response.clusters);fire("afterRefresh")}function replaceMarkers(newMarkers){newMarkers=map(newMarkers,Marker._fromParams);replaceOverlays(markers,newMarkers);markers=newMarkers}function replaceClusters(newClusters){newClusters=map(newClusters,Cluster._fromParams);replaceOverlays(clusters,newClusters);clusters=newClusters}function replaceOverlays(overlays,newOverlays){each(overlays,function(o){o._removeFromMap()});each(newOverlays,function(o){o._addToMap(self)})}function enlargeBounds(bounds,zoom){var projection=new GMercatorProjection(zoom+1),sw=projection.fromLatLngToPixel(bounds.getSouthWest(),zoom),ne=projection.fromLatLngToPixel(bounds.getNorthEast(),zoom);sw=projection.fromPixelToLatLng(Point(sw.x-256,sw.y+256),zoom,true);ne=projection.fromPixelToLatLng(Point(ne.x+256,ne.y-256),zoom,true);if((ne.lng()>sw.lng()&&bounds.getNorthEast().lng()<=bounds.getSouthWest().lng())){return WHOLE_EARTH}else{return LatLngBounds(sw,ne)}}function clusterize(params){storage.clusterize(merge({zoom:zoom,condition:condition,aggregates:aggregates,properties:properties,ids:ids,groupingDistance:groupingDistance,groupBy:groupBy},params))}function fire(eventName,object){GEvent.trigger(self,eventName,object)}return self={setCondition:setCondition,setClusterAggregates:setClusterAggregates,setMarkerProperties:setMarkerProperties,setMarkerIds:setMarkerIds,getMarkers:getMarkers,getClusters:getClusters,getTotalPointsCount:getTotalPointsCount,setGroupingDistance:setGroupingDistance,setGroupBy:setGroupBy,refresh:refresh,_getMapImpl:getMapImpl,_clusterize:clusterize,_createCluster:createCluster,_createMarker:createMarker,_isMaxZoom:isMaxZoom,_onMarkerClicked:onMarkerClicked,_onClusterClicked:onClusterClicked}}var Overlay=createClass({initialize:function(gLatLng){this._gLatLng=gLatLng},getGLatLng:function(){return this._gLatLng},getMap:function(){return this._map},_addToMap:function(map){this._map=map;map._getMapImpl().addOverlay(this.getGMarker());this._handle=GEvent.bind(this.getGMarker(),"click",this,this._onClick)},_removeFromMap:function(){this._map._getMapImpl().removeOverlay(this.getGMarker());GEvent.removeListener(this._handle)},openPopup:function(marker_id){var gMarker=this.getGMarker(),element=document.createElement("div");element.className="maptimize_info_window";element.innerHTML='<span class="maptimize_load_message">please wait</span>';gMarker.openInfoWindowHtml(element);this._requestContent({marker_id:marker_id,callback:function(response){element.innerHTML=response.html}})}});var Marker=createClass(merge(Overlay.prototype,{initialize:function(id,gLatLng,properties){Overlay.call(this,gLatLng);this._id=id;this._properties=properties},getId:function(){return this._id},getLabels:function(){return this._labels},hasLabel:function(label){return this._labels.indexOf(Number(label))>-1},setGMarker:function(gMarker){this._gMarker=gMarker},getGMarker:function(){return this._gMarker||(this._gMarker=this._map._createMarker(this))},getProperty:function(name){return this._properties[name]||null},_requestContent:function(options){var self=this,map=self._map;map._clusterize({bounds:LatLngBounds(self.getGLatLng(),self.getGLatLng()),properties:["html"],onSuccess:function(response){if(response.markers.length>1){debug("Several markers where only one expected")}options.callback({html:response.markers[0]["html"]})}})},_onClick:function(){this._map._onMarkerClicked(this)}}),{_fromParams:function(marker){var latLng=LatLng(removeProperty(marker,"coords"));return new Marker(removeProperty(marker,"id"),latLng,marker)}});var Cluster=createClass(merge(Overlay.prototype,{initialize:function(id,latLng,bounds,count,aggregates){Overlay.call(this,latLng);this._id=id;this._bounds=bounds;this._count=count;this._aggregates=aggregates},getPointsCount:function(){return this._count},getGLatLngBounds:function(){return this._bounds},getGMarker:function(){return this._gMarker||(this._gMarker=this._map._createCluster(this))},expandOnMap:function(){var gMap=this._map._getMapImpl(),zoom=gMap.getBoundsZoomLevel(this.getGLatLngBounds());if(zoom<=gMap.getZoom()){zoom=gMap.getZoom()+1}gMap.setCenter(this.getGLatLng(),zoom)},requestIds:function(callback){this._map._clusterize({bounds:this._bounds,aggregates:"concat(id)",onSuccess:function(response){callback(response.clusters[0]["concat(id)"])}})},canExpandOnMap:function(){return !(this._map._isMaxZoom()||this._allPointsAreGrouped())},getAggregate:function(name){return this._aggregates[name]||null},_requestContent:function(options){var self=this,map=self._map;map._clusterize({bounds:self._bounds,aggregates:["concat(html)","concat(id)"],onSuccess:function(response){options.callback({html:self._htmlForContent(response.clusters[0])})}})},_onClick:function(){this._map._onClusterClicked(this)},_allPointsAreGrouped:function(){var bounds=this.getGLatLngBounds(),ne=bounds.getNorthEast(),sw=bounds.getSouthWest();return(ne.lat()-sw.lat())<0.000001||(ne.lat()-sw.lat())<0.000001},_htmlForContent:function(content){var html_snippets=content["concat(html)"],ids=content["concat(id)"];for(var i=0;i<html_snippets.length;i++){html_snippets[i]="<div id='maptimize_marker_"+ids[i]+"'>"+html_snippets[i]+"</div>"}return html_snippets.join('<div class="maptimize_separator"></div>')}}),{_fromParams:function(cluster){var latLng=LatLng(removeProperty(cluster,"coords")),bounds=removeProperty(cluster,"bounds");bounds=LatLngBounds(LatLng(bounds.sw),LatLng(bounds.ne));return new Cluster(cluster.id,latLng,bounds,removeProperty(cluster,"count"),cluster)}});var XSSRequest=createClass({initialize:function(url,params,callback){this._url=url;this._callback=callback;this._params=params},_send:function(){var id=++XSSRequest._lastRequestID,script=this._createScript(id);XSSRequest._prepareCallback(id,this._callback);HEAD.appendChild(script);setTimeout(function(){HEAD.removeChild(script)},5000)},_createScript:function(id){return extend(document.createElement("script"),{src:this._url+"?"+toQueryString(extend(this._params,{callback:XSSRequest._bus+"._"+id})),type:"text/javascript"})}},{_lastRequestID:0,_bus:"XSSRequest._callbacks",_callbacks:{},_prepareCallback:function(id,callback){XSSRequest._callbacks["_"+id]=function(){delete XSSRequest._callbacks[id];debug.apply(null,arguments);callback.apply(null,arguments)}},send:function(url,params,callback){var request=new XSSRequest(url,params,callback);request._send();return request}});var SWFRequest=createClass({initialize:function(url,params,callback){this._url=url;this._callback=callback;this._params=params},_send:function(){SWFRequest._insertSWF();if(!this._getFlashObject().postFunc){var that=this;setTimeout(function(){that._send()},100)}else{var id=++SWFRequest._lastRequestID;SWFRequest._prepareCallback(id,this._callback);this._getFlashObject().postFunc(this._url,toQueryString(extend(this._params,{callback:SWFRequest._bus+"_"+id})))}},_getFlashObject:function(){var name=SWFRequest._flashName;var isIE=navigator.appName.indexOf("Microsoft")!=-1;return(isIE)?document.getElementById(name):document[name]}},{_lastRequestID:0,_bus:"SWFRequest_callbacks",_flashName:"__mapti__flashproxy__",_hasSwf:false,_insertSWF:function(){if(!SWFRequest._hasSwf){var object=document.createElement("div");object.id=SWFRequest._flashName;document.body.appendChild(object);swfobject.embedSWF(swfURL("flashproxy.swf"),SWFRequest._flashName,"1","1","9.0.0",swfURL("expressInstall.swf"),{},{allowScriptAccess:"always"});SWFRequest._hasSwf=true}},_prepareCallback:function(id,callback){window[SWFRequest._bus+"_"+id]=function(){setTimeout(function(){delete window[SWFRequest._bus+"_"+id]},1000);var json=eval("("+arguments[0]+")");callback(json)}},send:function(url,params,callback){var request=new SWFRequest(url,params,callback);request._send();return request}});var Theme={};Theme.Default={markerOptions:[{icon:new GIcon({image:imageURL("maps/marker8.png"),iconSize:new GSize(25,33),iconAnchor:new GPoint(11,33),infoWindowAnchor:new GPoint(11,2),infoShadowAnchor:new GPoint(18,25)}),labelClass:"maptimize_marker_0",labelOffset:new GSize(-11,-26)},{icon:new GIcon({image:imageURL("maps/marker88.png"),iconSize:new GSize(25,33),iconAnchor:new GPoint(11,33),infoWindowAnchor:new GPoint(11,2),infoShadowAnchor:new GPoint(18,25)}),labelClass:"maptimize_marker_1",labelOffset:new GSize(-11,-26)},{icon:new GIcon({image:imageURL("maps/marker88.png"),iconSize:new GSize(29,33),iconAnchor:new GPoint(11,33),infoWindowAnchor:new GPoint(11,2),infoShadowAnchor:new GPoint(18,25)}),labelClass:"maptimize_marker_2",labelOffset:new GSize(-11,-27)},{icon:new GIcon({image:imageURL("maps/marker88.png"),iconSize:new GSize(33,33),iconAnchor:new GPoint(11,33),infoWindowAnchor:new GPoint(11,2),infoShadowAnchor:new GPoint(18,25)}),labelClass:"maptimize_marker_3",labelOffset:new GSize(-11,-32)}],clusterOptions:[{icon:new GIcon({image:imageURL("maps/5.png"),iconSize:new GSize(50,50),iconAnchor:new GPoint(25,25),infoWindowAnchor:new GPoint(25,25),infoShadowAnchor:new GPoint(25,25)}),labelClass:"maptimize_cluster_0",labelOffset:new GSize(-25,-25)},{icon:new GIcon({image:imageURL("maps/4.png"),iconSize:new GSize(55,55),iconAnchor:new GPoint(28,28),infoWindowAnchor:new GPoint(28,28),infoShadowAnchor:new GPoint(28,28)}),labelClass:"maptimize_cluster_1",labelOffset:new GSize(-28,-28)},{icon:new GIcon({image:imageURL("maps/3.png"),iconSize:new GSize(62,62),iconAnchor:new GPoint(31,31),infoWindowAnchor:new GPoint(31,31),infoShadowAnchor:new GPoint(31,31)}),labelClass:"maptimize_cluster_2",labelOffset:new GSize(-31,-31)},{icon:new GIcon({image:imageURL("maps/2.png"),iconSize:new GSize(71,71),iconAnchor:new GPoint(35,35),infoWindowAnchor:new GPoint(35,35),infoShadowAnchor:new GPoint(35,35)}),labelClass:"maptimize_cluster_3",labelOffset:new GSize(-35,-35)},{icon:new GIcon({image:imageURL("maps/1.png"),iconSize:new GSize(85,85),iconAnchor:new GPoint(42,42),infoWindowAnchor:new GPoint(42,42),infoShadowAnchor:new GPoint(42,42)}),labelClass:"maptimize_cluster_4",labelOffset:new GSize(-42,-42)}],createMarker:function(marker){var options=Theme.Default.markerOptions[0];options.labelText=1;return new LabeledMarker(marker.getGLatLng(),options)},createCluster:function(cluster){var count=cluster.getPointsCount(),index=parseInt(Math.log(count)/Math.log(10));if(cluster.canExpandOnMap()){options=Theme.Default.clusterOptions[Math.min(Theme.Default.clusterOptions.length-1,index)]}else{options=Theme.Default.markerOptions[Math.min(Theme.Default.markerOptions.length-1,index)]}options.labelText=count;return new LabeledMarker(cluster.getGLatLng(),options)}};XSSRequest._bus="Maptimize._callbacks";if(!("Maptimize" in window)){window.Maptimize={}}extend(window.Maptimize,{Condition:Condition,Map:Map,LabeledMarker:LabeledMarker,ArgumentError:ArgumentError,_callbacks:XSSRequest._callbacks})}).apply(null,map(("Event Bounds LatLng Size Icon Point Marker LatLngBounds MercatorProjection Control ControlPosition MAP_MARKER_PANE MAP_MAP_PANE ANCHOR_TOP_RIGHT").split(" "),getGoogleMapsComponent))})(this);
