//jGMLSC.js

// Copyright 2008, Jeremy R. Geerdes
// For more information or a project quote:
// http://jgeerdes.home.mchsi.com
// jgeerdes@mchsi.com

// Permission to use this script on your own site is given, free of charge, provided the following conditions are met:
// 1. The associated Javascript file(s) are not alterned in any way except to (a) save them to your own server and/or (b) adjust the value of style_url, to specify the appropriate location of the necessary stylesheet.
// 2. Your site does not contain pornographic, illegal, or otherwise immoral material, or promote or condone the same. Such material shall include, but not be limited to, content pertaining to abortion, homosexuality, transsexuality, bisexuality, and other forms of adultery.
// 3. You do not in any way obscure any links that the copyright holder deems fit to include (e.g., attribution links)
// 4. You have obtained written permission from the copyright holder by emailing jgeerdes@mchsi.com with an explanation of the application's purpose 

// jGMLSC.js is a custom Google Maps/Local Search Control designed to be more flexible than Google's, and prettier :)

// To use, call new jeremy.jGMLSC(options?);
// The following options can be specified using object literal:
// searchRadius : the radius that you want to confine your search results to (default: none)
// searchRadiusUnit : the unit in which you have specified searchRadius, specified with the following syntax: {abbr:"unit_abbreviation",label:"unit_label",ratio:"meters_per_unit"}
//   Built in choices: jeremy.jGMLSC.units["..."] (default: MILES)
//   KILOMETERS
//   METERS
//   CENTIMETERS
//   MILES
//   FEET
//   INCHES
// noResultsString : string to display when there are no results (default: "No results available")
// maxZoomLevel : maximum zoom level
// suppressMapPanAndZoom : when true, the map will not be adjusted to show all results (default: false)
// suppressMapPan : when true, the map will not move to center of results cluster (default: false)
// suppressMapZoom : when true, the map will not zoom to fit all results in window (default: false)
// suppressDetails : when true, result details will not be shown
// resultSetSize : specifies the result set size to return from Google search (default: LARGE_RESULTSET)
// anchor : specifies location to anchor control, specified as object literal with following syntax: {ga:G_ANCHOR_TOP_LEFT,x:hor_offset,y:vert_offset}
//   PLEASE NOTE that ga must be specified in the proper Google namespace (i.e., G* or google.*.*). ALTERNATIVELY, use jeremy.jGMLSC.findInGoogleNamespace().
//   Built in choices: jeremy.jGMLSC.anchors["..."] (default: TOP_CENTER)
//   TOP_LEFT
//   TOP_CENTER
//   TOP_RIGHT
//   BOTTOM_LEFT
//   BOTTOM_CENTER
//   BOTTOM_RIGHT
// noIWOpenOnHover : when true, marker infowindows will not open while hovering over listing item (default: false)
// idleOpacity : opacity when idle, specified in decimal format (e.g., .5=50% opacity) (default: .5)
// activeOpacity : opacity when idle, specified in decimal format (e.g., .9=90% opacity) (default: .9)
// directionsHint : hint to be used in empty directions fields (default: "Directions from...")
// directionsButtonText : Text to include in directions submit buttons (default: "->")
// searchHint : Text to include in search box (default: 'Search the map...')
 
(function(){
 var style_url='http://jgeerdes.home.mchsi.com/site/jGMLSC.css';
 document.write('<link rel="stylesheet" type="text/css" href="'+style_url+'" /\>');
 function za(a,b){b=b.replace(/^G\_?(?![a-z])/,'');b=b.replace(/^G((web|local|image|news|video|blog|book|adSense|sa))/,function(d,e){return e.replace(/^./,function(f){return f.toUpperCase();});});var bA=b.replace(/^([A-Z])/,function(d){return d.toLowerCase();});if(typeof(google)!='undefined'&&typeof(google[a])!='undefined'&&typeof(google[a][b])!='undefined'){return google[a][b];}else if(window['G'+b]){return window['G'+b];}else if(window['G'+bA]){return window['G'+bA];}else if(window['G_'+b]){return window['G_'+b];}else{throw('jGMLSC error: Unable to locate '+b+' in Google '+a+' namespace.');}}
	function aa(a){this.options={activeOpacity:.9,mapTypeControl:1,searchHint:'Search the map...',directionsHint:'Directions from...',directionsButtonText:'->',idleOpacity:.5,noResultsString:'No results available',maxZoomLevel:16,anchor:aa.anchors.TOP_CENTER,searchRadiusUnit:aa.units.MILES,resultSetSize:(za('search','Search')).LARGE_RESULTSET};if(!a){a={};}for(var z in a){this.options[z]=a[z];}}
	aa.prototype=new (za('maps','Control'))();
	aa.prototype.initialize=function(a){var z=this,init_fade=function(){z.fade_timer=setTimeout(function(){z.fadeOut();},2500);},d=z.b=ba('jGMLSC jGMLSCsearchForm'),c=z.sf=new (za('search','SearchForm'))(0,d),e=z.c=ba('jGMLSC jGMLSCdrawer jGMLSCsearchResults',z.options.noResultsString),h=z.e=ba('jGMLSC jGMLSCdrawer jGMLSCdrawerControl',[ba('jGMLSC jGMLSCdrawer jGMLSCdrawerControl clear',undefined,{onclick:function(){z.clearResults();z.openDrawer();},title:'Click to clear results'}),ba('jGMLSC jGMLSCdrawer jGMLSCdrawerControl close',undefined,{onclick:function(){z.toggleDrawer();},title:'Click to open/close drawer'})]),g=z.d=ba('jGMLSC jGMLSCdrawer',[e,h],undefined,{position:'absolute'}),b=z.a=ba('jGMLSC jGMLSCbase',[d,g]),f=z.gs=new (za('search','LocalSearch'))(),n=function(){if(c.input.value==z.options.searchHint){c.input.value='';}else if(c.input.value==''){c.input.value=z.options.searchHint;}};z.gmap=a;c.input.onfocus=n;c.input.onblur=n;b.onmouseover=function(){z.fadeIn();};b.onmouseout=function(e){if(!e){e=window.event;}var es=e.target?e.target:e.srcElement,et=e.relatedTarget?e.relatedTarget:e.toElement;while(et){if(es==et||et==c){return;}try{et=et.parentNode;}catch(xx){et=es;}}init_fade();};bb(a.getContainer(),b);var opt=z.options,ait=opt.anchor.ga==za('maps','ANCHOR_TOP_LEFT')||opt.anchor.ga==za('maps','ANCHOR_TOP_RIGHT')?1:0,air=opt.anchor.ga==za('maps','ANCHOR_TOP_RIGHT')||opt.anchor.ga==za('maps','ANCHOR_BOTTOM_RIGHT')?1:0,m=z.getContainer();c.input.value=opt.searchHint;g.style[ait?'top':'bottom']=d.offsetHeight+'px';g.style[air?'right':'left']='0px';h.style[ait?'bottom':'top']='0px';e.style[ait?'top':'bottom']='0px';e.style['margin'+ait?'Top':'Bottom']='0px';e.style['padding'+(ait?'Top':'Bottom')+'Width']='0px';e.style.overflowY='auto';g.style.height=h.offsetHeight+'px';c.setOnSubmitCallback(z,aa.prototype.execute);f.setCenterPoint(a);f.setResultSetSize(z.options.resultSetSize);f.setSearchCompleteCallback(z,aa.prototype.searchComplete);init_fade();return b;};
	aa.prototype.getDefaultPosition=function(){var a=this.options.anchor,e=this.gmap.getContainer(),f=this.getContainer(),b=a.ga,c=typeof(a.y)!='undefined'?a.y:Math.round((e.offsetHeight-f.offsetHeight)/2),d=typeof(a.x)!='undefined'?a.x:Math.round((e.offsetWidth-f.offsetWidth)/2);return new (za('maps','ControlPosition'))(b,new (za('maps','Size'))(d,c));};
 aa.prototype.printable=function(){return 0;};
 aa.prototype.selectable=function(){return 1;};
	aa.prototype.getContainer=function(){return this.a;};
	aa.prototype.getDrawer=function(){return this.d;};
	aa.prototype.getResultsDiv=function(){return this.c;};
	aa.prototype.getDrawerControl=function(){return this.e;};
 aa.prototype.execute=function(a){var z=this,gs=z.gs,sf=z.sf,sfi=sf.input,b=gs.results;z.closeDrawer();z.clearResults();if(typeof(a)=='string'){sfi.value=a;}else if(sfi.value!=''){a=sfi.value;}else{return;}gs.execute(a);};
 aa.prototype.searchComplete=function(){var z=this,gs=z.gs,gm=z.gmap,a=gs.results,b=z.c,d=z.options.anchor.ga;z.bounds=new (za('maps','LatLngBounds'))();z.hasResults=0;for(var y=0;y<a.length;y++){var c=a[y];c.latlng=new (za('maps','LatLng'))(parseFloat(c.lat),parseFloat(c.lng));if(z.options.searchRadius&&c.latlng.distanceFrom(gm.getCenter())/z.options.searchRadiusUnit.ratio>z.options.searchRadius){continue;}z.hasResults=1;if(!c.html){gs.generateHtml(c);}var i='jGMLSC jGMLSC',j='detail ',e=ba(i+'title',c.title),f=ba(i+'details',[ba(i+j+'streetAddress',c.streetAddress),ba(i+j+'city',c.city+', '+c.region),ba(i+j+'phoneNumber',c.phoneNumbers[0]?c.phoneNumbers[0]['number']:'')]);c.listing=ba(i+'listing',[e,f]);bb(f,bf(z,c,z.options.directionsHint,z.options.directionsButtonText));c.directionsDiv=ba(i+'detail jGMCLSdirections');bb(f,c.directionsDiv);bb(b,c.listing);z.bounds.extend(c.latlng);c.marker=new (za('maps','Marker'))(c.latlng);c.marker.bindInfoWindowHtml(c.html);gm.addOverlay(c.marker);c.listing.onmouseover=be(z,z.highlightListing,[c]);c.listing.onmouseout=be(z,z.unHighlightListing,[c]);c.listing.onclick=be(z,z.toggleListingLock,[c]);}if(!z.hasResults){bb(b,ba('jGMLSC jGMLSCnoResults',z.options.noResultsString));z.openDrawer();return;}var opts=z.options;if(!opts.suppressMapPanAndZoom){var nc=opts.suppressMapPan?gm.getCenter():z.bounds.getCenter(),nz=gm.getCurrentMapType().getBoundsZoomLevel(z.bounds,gm.getSize()),cz=nz<opts.maxZoomLevel?nz:opts.maxZoomLevel;gm.setCenter(nc,nz);}z.openDrawer();};
 aa.prototype.toggleDrawer=function(){var z=this;if(parseInt(bc(z.d,'height'))>z.getDrawerControl().offsetHeight){z.closeDrawer();}else{z.openDrawer();}};
 aa.prototype.openDrawer=function(){var z=this,a=z.getDrawer(),f=z.getResultsDiv(),b=f.offsetHeight,c=z.getDrawerControl().offsetHeight,y=b-parseInt(bc(f,'height'));f.style.maxHeight=((z.options.anchor.ga==za('maps','ANCHOR_TOP_LEFT')||z.options.anchor.ga==za('maps','ANCHOR_TOP_RIGHT')?z.gmap.getContainer().offsetHeight-z.getContainer().offsetTop-z.getDrawer().offsetTop:z.getContainer().offsetTop)-y-c-5)+'px';var e=Math.round(f.offsetHeight/10),d=parseInt(bc(z.getDrawer(),'height'));if(e<25){e=25;}if(z.drawer_timer){clearTimeout(z.drawer_timer);}if(d==b+c){return;}if(b+c<d){d=d-e<b+c?b+c:d-e;}else if(b+c>d){d=d+e>b+c?b+c:d+e;}z.getDrawer().style.height=d+'px';if(d!=b+c){z.drawer_timer=setTimeout(function(){z.openDrawer();},50);}else{f.style.visibility='visible';}};
 aa.prototype.closeDrawer=function(){var z=this,a=z.getDrawer(),c=z.getDrawerControl().offsetHeight,f=z.getResultsDiv(),e=50,d=parseInt(bc(z.getDrawer(),'height'));if(z.drawer_timer){clearTimeout(z.drawer_timer);}f.style.visibility='hidden';if(d<=c){a.style.height=c+'px';return;}d=d-e<c?c:d-e;a.style.height=d+'px';if(d>c){z.drawer_timer=setTimeout(function(){z.closeDrawer();},50);}};
 aa.prototype.fadeIn=function(){var z=this,a=z.getContainer(),c=parseFloat(bc(a,'opacity')),d=.1,e=z.options.activeOpacity,f=function(g){return setTimeout(function(){z.fadeIn();},g);};if(z.fade_timer){clearTimeout(z.fade_timer);}if(c<e){c+=d;}if(c>e){c=e;}a.style.opacity=c;if(navigator.userAgent.match(/MSIE 6.0/)){a.style.filters='alpha(opacity='+(c*100)+')';}if(c<e){z.fade_timer=f(50);}};
 aa.prototype.fadeOut=function(b){var z=this,a=z.getContainer(),c=parseFloat(bc(a,'opacity')),d=.1,e=z.options.idleOpacity,f=function(g){return setTimeout(function(){z.fadeOut();},g);};if(z.fade_timer){clearTimeout(z.fade_timer);}if(c>e){c-=d;}if(c<e){c=e;}a.style.opacity=c;if(navigator.userAgent.match(/MSIE 6.0/)){a.style.filters='alpha(opacity='+(c*100)+')';}if(c>e){z.fade_timer=f(50);}};
 aa.prototype.highlightListing=function(event,a){var z=this,opt=z.options,c=a[0];if(z.detail_timer){clearTimeout(z.detail_timer);}c.listing.className+=' active';z.gmap.panTo(c.marker.getLatLng());if(!opt.noIWOpenOnHover){(za('maps','Event')).trigger(c.marker,'click');}if(!opt.suppressDetails){z.detail_timer=setTimeout(function(){z.showDetails(c);},2500);}};
 aa.prototype.unHighlightListing=function(event,a){var z=this,opt=z.options,c=a[0];if(!event){event=window.event;}if(bd(c.listing,event.toElement?event.toElement:event.relatedTarget)){return;}if(z.detail_timer){clearTimeout(z.detail_timer);}z.hideDetails(c);c.listing.className=c.listing.className.replace(/ active/g,'');if(!opt.noIWOpenOnHover){(za('maps','Event')).trigger(c.marker,'click');}};
 aa.prototype.showDetails=function(a){var z=this,b=z.gs.results;for(var y=0;y<b.length;y++){if(!b[y].listing){continue;}var c=b[y],d=c.listing.childNodes[1].childNodes;for(var x=0;x<d.length;x++){d[x].style.display=a==c||c.listingLock?'block':'';}}z.openDrawer();};
 aa.prototype.hideDetails=function(a){if(a.listingLock||!a.listing){return;}var b=a.listing.childNodes[1].childNodes;for(var z=0;z<b.length;z++){b[z].style.display='';}this.openDrawer();};
 aa.prototype.toggleListingLock=function(event,a){var c=a[0];this.showDetails(c);c.listingLock=c.listingLock?0:1;}
 aa.prototype.clearResults=function(){var z=this,a=z.gs.results;if(!a){return;}while(z.c.firstChild){z.c.removeChild(z.c.firstChild);}for(var y=0;y<a.length;y++){var b=a[y];if(b.marker){z.gmap.removeOverlay(b.marker);}}};
 aa.prototype.getDirections=function(a,b){var z=this,gm=z.gmap,c=a.directionsDiv,gd=new (za('maps','Directions'))(gm,c),ge=za('maps','Event');if(z.directions){z.directions.clear();ge.clearListeners(z.directions,'load');}z.directions=gd;ge.addListener(gd,'addoverlay',function(){c.appendChild(ba('jGMLSC jGMLSCdirections close','X Clear Directions',{onclick:function(){gd.clear();this.parentNode.removeChild(this);}}));z.openDrawer();});gd.load('from: '+b+' to: '+a.streetAddress+' '+a.city+' '+a.region);z.openDrawer();return 0;};
 aa.prototype.setOption=function(a,b){this.options[a]=b;};
 aa.anchors={TOP_LEFT:{ga:za('maps','ANCHOR_TOP_LEFT'),x:5,y:5},TOP_RIGHT:{ga:za('maps','ANCHOR_TOP_RIGHT'),x:5,y:5},BOTTOM_LEFT:{ga:za('maps','ANCHOR_BOTTOM_LEFT'),x:65,y:document.all?2:5},BOTTOM_RIGHT:{ga:za('maps','ANCHOR_BOTTOM_RIGHT'),x:5,y:5},TOP_CENTER:{ga:za('maps','ANCHOR_TOP_LEFT'),y:5},BOTTOM_CENTER:{ga:za('maps','ANCHOR_BOTTOM_LEFT'),y:5},LEFT_CENTER:{ga:za('maps','ANCHOR_TOP_LEFT'),x:5},RIGHT_CENTER:{ga:za('maps','ANCHOR_TOP_RIGHT'),x:5}};
 aa.units={KILOMETERS:{abbr:'km',label:'kilometers',ratio:1000},METERS:{abbr:'m',label:'meters',ratio:1},CENTIMETERS:{abbr:'cm',label:'centimeters',ratio:.01},MILES:{abbr:'mi',label:'miles',ratio:1609.344},FEET:{abbr:'ft',label:'feet',ratio:0.3048},INCHES:{abbr:'in',label:'inches',ratio:0.0254}};
	function ba(a,c,d,e){var b=document.createElement('div');if(a){b.className=a;}if(c){if(typeof(c)=='object'&&c.length){for(var z=0;z<c.length;z++){bb(b,c[z]);}}else{bb(b,c);}}if(typeof(d)=='object'){for(var z in d){if(z.match(/^on/)){b[z]=d[z];}else{b.setAttribute(z,d[z]);}}}if(typeof(e)=='object'){for(var z in e){b.style[z]=e[z];}}return b;}
	function bb(a,b){if(!a||!b){return;}if(typeof(b)=='string'||typeof(b)=='number'){a.innerHTML=b;}else{try{a.appendChild(b);}catch(e){}}}
 function bc(a,b){if(a.currentStyle){return a.currentStyle[b];}else{var c;try{c=document.defaultView.getComputedStyle(a,null).getPropertyValue(b.replace(/([A-Z])/g,function(d){return "-"+d.toLowerCase();}));}catch(e){c=a.style[b];}return c;}}
 function bd(a,b){while(b){if(b==a){return 1;}try{b=b.parentNode}catch(e){b=a;}}return 0;}
 function be(a,b,c){if(!c){c=[];}else if(typeof(c)!='object'||typeof(c.length)=='undefined'){c=[c];}return function(e){return b.apply(a,[e?e:window.event,c]);};}
 function bf(f,g,h,i){var a=document.createElement('form'),e='jGMLSC jGMLSC',k='directionForm',b=ba(),c=document.createElement('input'),d=document.createElement('input'),j=function(){if(c.value==h){c.value='';}else if(c.value==''){c.value=h;}},k=function(l){if(!l){l=window.event;}if(l.stopPropagation){l.stopPropagation();}else if(l.preventBubble){l.preventBubble();}l.cancelBubble=1;};a.className=e+'detail '+k;c.type='text';c.onclick=k;d.onclick=k;c.value=h;c.onfocus=j;c.onblur=j;d.type='submit';d.value=i;a.onsubmit=function(e){if(!e){e=window.event;}if(e.preventDefault){e.preventDefault();}return f.getDirections(g,c.value);};bb(b,c);bb(b,d);bb(a,b);return a;}
	if(!window.jeremy){window.jeremy={};}
	window.jeremy.jGMLSC=aa;
	window.jeremy.jGMLSC.findInGoogleNamespace=za;
})();