﻿/*Enum*/
var StoreLocatorDisplayModes = {'FULLLOCATOR':0,'IFRAMEDLOCATOR':1,'MINILOCATOR':2,'SITEMAP':3}
var StoreLocatorProcessModes = {'SEARCH_STORES':0,'SEARCH_DIRECTIONS':1};

function StoreLocatorMainControl(id, brandID, getDataFeed, mapCanvasID, mapLat, mapLong, zoomLevel, options){
    //const
    this.ZOOMTHRESHOLD = 5;
    
    //properties
    this.ID = id;
    this.BrandID = brandID;  
    this.DataSource = null;     //basic info for DataSource is brandID, lat, long
    this.GetDataFeed = getDataFeed;
    this.Options = options;
    this.HasSearchResultListing = (options.DisplayMode==StoreLocatorDisplayModes.FULLLOCATOR || options.DisplayMode==StoreLocatorDisplayModes.IFRAMEDLOCATOR);
  
    this.Map = null;
    this.MapCenter = null;
    this.Zoom = zoomLevel;
    this.Geocoder = null;
    this.MapCanvasID = mapCanvasID;
    this.DirectionDisplay = null;
    this.DirectionService = null;
    this.SearchCenterPoint = null;
    this.SearchCenterIcon = null;
    this.customInfoWindowItem = null;
    this.AnimateMarkerOnClick = options.AnimateMarkerOnClick;
      
    this.Markers = [];  
    //icon handler
    this.brandIconImages = [];  
    this.brandIconImagesReady = false;
    //save the max width for the search result listing
    this.maxIconWidth = 0;
    this.lastSelectedSearchItemID = '';
    
    this.ProcessMode = StoreLocatorProcessModes.SEARCH_STORES;    
    this.SelectedStoreAddress = '';
    
    this.lastSearchParameter = {};
    
    this.isInitCall = true;
    this.invokedSearchAddress = false;
  
    this.event = gbEvent;
  
    //call init
    this.init(mapLat, mapLong);  
}

StoreLocatorMainControl.prototype = {
    getIconImagesPath: function(brandIDOverride){
        var brandID = this.BrandID;
        if(arguments.length==1){
            brandID = brandIDOverride;
        }
        return String.format('/images/{0}/station_locator/', brandID);    
    },
    
    getPinURL: function(isBig, isHi, brandIDOverride){
        var brandID = this.BrandID;
        if(arguments.length==3){
            brandID = brandIDOverride;
        }
        return String.format('{0}{1}map-pin{2}.png', this.getIconImagesPath(brandID), (isBig?'big-':''), (isHi?'-hi':''));
    },
  
    setPin: function(x, isHi){
        var row = this.DataSource[x];
        if(row){
            var pinURL = this.getPinURL(this.useBigPin(), isHi, row.BrandID);
            if(this.DataSource[x].Marker){
                this.DataSource[x].Marker.setIcon(pinURL);
            }
        }
    },
  
    useBigPin: function(){
        return this.Map.getZoom() >= 12;
    },
    
    updateMapCenter: function(point){
        if(point){
            //set map center
            this.Map.setCenter(point);
    
            this.updateMapCenterIcon(point);
        }
        else{
            alert('Not found');
        }
    },
  
    updateMapCenterIcon: function(point){
        //create the center icon
        var centerIconImageURL = '/images/station_locator/search_center.png';
        var miCenterIcon = new google.maps.MarkerImage(centerIconImageURL,      
        new google.maps.Size(15, 15),      
        new google.maps.Point(0,0),      
        new google.maps.Point(7, 7));
    
        this.SearchCenterPoint = point;
    
        //if center icon is existing, remove center icon
        if(this.SearchCenterIcon){
            this.SearchCenterIcon.setMap(null);
        }
    
        this.SearchCenterIcon = new google.maps.Marker({
            position: point,
            map: this.Map,
            icon: miCenterIcon
        });
    },
    
    render: function(){
        var oThis = this;
        if(oThis.DataSource){
            var i = oThis.DataSource.length - 1;            
            var divSearchResultContainer = $('searchResultListing');
            
            //delete existing direction
            oThis.removeDirections();
    
            //delete existing markers, if there's any
            oThis.deleteMarkers();
    
            //delete existing search result items, if there's any
            oThis.deleteSearchResultItems(divSearchResultContainer);
                      
            if(i >= 0){
                var currentZoonLevel = oThis.Map.getZoom();
                
                
                while(i >= 0){
                    var row = oThis.DataSource[i];
          
                    //
                    if(!row.BrandID){
                        row.BrandID = oThis.BrandID;
                    }                    
          
                    var pinURL = oThis.getPinURL(oThis.useBigPin(), false, row.BrandID);
          
                    var markerPosition = new google.maps.LatLng(row.Latitude, row.Longitude);
                    var marker =  new google.maps.Marker({
                        position: markerPosition,
                        map: oThis.Map,
                        icon: pinURL //brandMarkerIcon.MarkerIcon
                    });
          
                    //save marker
                    oThis.DataSource[i].Marker = marker;
                    //
                    oThis.Markers.push(marker);
                    
                    marker.slDataIndex = i;
          
                    google.maps.event.addListener(marker, 'mouseover', function(){oThis.setPin(this.slDataIndex, true)});
                    google.maps.event.addListener(marker, 'mouseout', function(){oThis.setPin(this.slDataIndex, false)});
          
                    if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.FULLLOCATOR || oThis.Options.DisplayMode==StoreLocatorDisplayModes.IFRAMEDLOCATOR || oThis.Options.DisplayMode==StoreLocatorDisplayModes.MINILOCATOR){
                        google.maps.event.addListener(marker, 'click', function(){            
                            if(currentZoonLevel >= 0 && currentZoonLevel <= oThis.ZOOMTHRESHOLD){
                                //state level       
                                //set map center to the marker and zoom
                                oThis.Map.setCenter(this.position);
                                oThis.Map.setZoom(currentZoonLevel+1);
                            }
                            else{
                                var dataIndex = this.slDataIndex;
                                if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.FULLLOCATOR || oThis.Options.DisplayMode==StoreLocatorDisplayModes.IFRAMEDLOCATOR){
                                    oThis.showInfoWindow.call(oThis, dataIndex);            
                                    oThis.selectSearchResultItem.call(oThis, divSearchResultContainer, dataIndex);
                                }
                                else if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.MINILOCATOR){
                                    //redirect to store site or store page
                                    var obj = oThis.DataSource[dataIndex];                                    
                                    if(obj && !isBlank(obj.StationUrl) && obj.StationUrl != '#'){
                                        window.top.location = obj.StationUrl;
                                    }                                    
                                }
                            }
                        });
                    }
          
          
                    //if display mode is full locator or iframed locator, process the search results listing
                    if(oThis.HasSearchResultListing){
                        
                        var isStateLevel = (currentZoonLevel >= 0 && currentZoonLevel <= oThis.ZOOMTHRESHOLD);
                        oThis.createSearchResultItem(row, i, divSearchResultContainer, isStateLevel);
                    }
              
                    i--;
                }
                if(oThis.HasSearchResultListing){
                    var mapParentDiv = $(oThis.MapCanvasID);
                    var heightDelta = mapParentDiv.offsetTop + mapParentDiv.offsetHeight - divSearchResultContainer.offsetTop;
                    if(divSearchResultContainer.offsetHeight > heightDelta){
                        divSearchResultContainer.style.height = String.format('{0}px', heightDelta);
                        divSearchResultContainer.style.overflowY = 'auto';
                    }
                }
            }
            else{
                oThis.updateSearchResultItem('No locations found in the viewing area');
            }
      
            oThis.updateSearchResultCount();
        }
    },
    
    showInfoWindow: function(index){
        var oThis = this;
        var row = oThis.DataSource[index];
        var objMarker = row.Marker;
        var currentZoonLevel = oThis.Map.getZoom();
        var mapParentDiv = $(oThis.MapCanvasID);
        var html = '';
            
        if(currentZoonLevel >= 0 && currentZoonLevel <= oThis.ZOOMTHRESHOLD){                
            //state level      
            html = oThis.createCustomInfoWindowItemHTML(row, index, true);
        }
        else{
            //create station level                      
            html = oThis.createCustomInfoWindowItemHTML(row, index, false);
        }
            
        objMarker.infoWindowHTML = html;
    
        oThis.closeInfoWindow();        
        if(oThis.AnimateMarkerOnClick){
            if(!oThis.Animating){
                objMarker.setAnimation(google.maps.Animation.DROP);
                oThis.Animating = true;
                  
                setTimeout(function(){
                    oThis.customInfoWindowItem = new CustomInfoWindow(objMarker, mapParentDiv, oThis.Map);
                    oThis.Animating = false;
                }, 300);
            }
        }
        else{
            oThis.customInfoWindowItem = new CustomInfoWindow(objMarker, mapParentDiv, oThis.Map);
        }
    },
    
    selectSearchResultItem: function(divSearchResultContainer, index){
        var oThis = this;    
        if(oThis.HasSearchResultListing && divSearchResultContainer){      
            //remove highlighted item if there's any
            if(!isBlank(oThis.lastSelectedSearchItemID)){
                var divLastSelectedRow = $(oThis.lastSelectedSearchItemID);
                if(divLastSelectedRow){
                    divLastSelectedRow.className = divLastSelectedRow.className.replace('div-srl-row-selected', '');
                }
            }
      
            var divRow = $(String.format('divSRLRow_{0}', index));
            if(divRow){
                if(divRow.offsetTop < divSearchResultContainer.scrollTop || (divRow.offsetTop + divRow.offsetHeight) > (divSearchResultContainer.scrollTop + divSearchResultContainer.offsetHeight)){
                    divSearchResultContainer.scrollTop = divRow.offsetTop;
                }        
                divRow.className += (isBlank(divRow.className)?'':' ') + 'div-srl-row-selected';        
                oThis.lastSelectedSearchItemID = divRow.id;        
            }     
        }
    },
    
    createSearchResultItem: function(obj, index, container, isStateLevel){
        if(obj && container){
            var oThis = this;
            var divRow = document.createElement('div');
            divRow.id = String.format('divSRLRow_{0}', index);
            divRow.className = 'div-srl-row';      
            
            oThis.event.addListener(divRow, 'mouseover', function(){
                var index = this.id.split('_')[1]*1;
                oThis.setPin(index, true);
            });
      
            oThis.event.addListener(divRow, 'mouseout', function(){        
                var index = this.id.split('_')[1]*1;
                oThis.setPin(index, false);
            });
      
            
      
            var brandID = (obj.BrandID?obj.BrandID:oThis.BrandID);      
            var divItem = document.createElement('div');            
            divItem.style.background = String.format('transparent url({0}) no-repeat scroll left center', this.getPinURL(false, false, brandID));      
            divItem.style.padding = String.format('5px 0px 5px {0}px', oThis.maxIconWidth + 3);
       
        
            if(isStateLevel){
                var divState = document.createElement('div');              
                divState.appendChild(document.createTextNode(obj.State));
          
                var divCount = document.createElement('div');        
                divCount.appendChild(document.createTextNode(String.format('{0} Locations', obj.StationCount)));
        
                divItem.appendChild(divState);
                divItem.appendChild(divCount);
                
                oThis.event.addListener(divRow, 'click', function(){
                    oThis.Map.setCenter(obj.Marker.position);
                    oThis.Map.setZoom(oThis.Map.getZoom()+1);
                });
            }
            else{
                var divStoreName = document.createElement('div');
                divStoreName.className = 'srHdrName';
                divStoreName.appendChild(document.createTextNode(obj.DisplayName));
                
                var divAddress = document.createElement('div');
                divAddress.appendChild(document.createTextNode(obj.Address));
        
        
                var divCityState = document.createElement('div');
                divCityState.className = 'fl';
                divCityState.appendChild(document.createTextNode(String.format('{0}, {1}', obj.City, obj.State)));
        
                var divDistance = document.createElement('div');
                var convertedDistance = obj.Distance * this.Options.DistanceMultiplier;
                divDistance.className = 'fr tar div-srl-distance';
                divDistance.appendChild(document.createTextNode(String.format('{0} {1}', convertedDistance.toFixed(2), this.Options.DistanceDescriptor)));
        
                var divClearFloat = document.createElement('div');
                divClearFloat.className = 'cb';
        
                var divCityStateDistance = document.createElement('div');
                divCityStateDistance.appendChild(divCityState);
                divCityStateDistance.appendChild(divDistance);
                divCityStateDistance.appendChild(divClearFloat);
                
                divItem.appendChild(divStoreName);
                divItem.appendChild(divAddress);
                divItem.appendChild(divCityStateDistance);
                
                
                oThis.event.addListener(divRow, 'click', function(){
                    var index = this.id.split('_')[1]*1;
                    oThis.showInfoWindow.call(oThis, index);
                    oThis.selectSearchResultItem.call(oThis, container, index);
                });
            }
      
            divRow.appendChild(divItem);
      
            var firstChild = container.firstChild;
            if(firstChild){
                container.insertBefore(divRow, firstChild);        
            }
            else{        
                container.appendChild(divRow);
            }
      
        }
    },
  
    deleteSearchResultItems: function(container){
        if(container){
            container.innerHTML = '';
        }
    },
  
    updateSearchResultItem: function(msg){
        if(this.HasSearchResultListing){
            var divSearchResultContainer = $('searchResultListing');
            divSearchResultContainer.innerHTML = msg;
        }
    },
  
    updateSearchResultCount: function(clear){
        if(this.HasSearchResultListing){
            var divResultsCount = $('divResultsCount');
            if(divResultsCount){
                var hasLocationCount = this.Map.getZoom() > this.ZOOMTHRESHOLD && this.DataSource.length > 0;
                divResultsCount.innerHTML = (hasLocationCount && !clear?String.format('{0} location(s)', this.DataSource.length):'');
            }
        }
    },
    
    createCustomInfoWindowItemHTML: function(obj, index, isStateLevel){
        var retVal = '';
    
        if(obj){
            var sbCustomInfoWindow = [];
            var oThis = this;
            var brandID = (obj.BrandID?obj.BrandID:oThis.BrandID);
            
            sbCustomInfoWindow.push(String.format('<div style="height:31px; background:url(/images/{0}/station_locator/pop_bg.png) repeat-x bottom left; padding-left:10px;"><div class="pop_logo" style="float:left;background-image:url(\'/images/{0}/station_locator/misc.png\');"></div><div id="imgClose" class="x5" style="float:right; padding-top:5px; padding-right:3px; cursor:pointer; position:relative; left:14px; top:-11px;background-image:url(\'/images/{0}/station_locator/misc.png\');" title="Close" alt="Close" onclick="closeIW();"></div>', brandID));
            sbCustomInfoWindow.push(String.format('<div style="clear:both;"></div></div><div style="height:84px; padding:10px; padding-top:5px; background:url(/images/{0}/station_locator/pop_content_bg.png) repeat-x bottom left"><span style="font-size:18px; font-weight:bold; text-transform:capitalize;" class="poptitle">', brandID));
            sbCustomInfoWindow.push(String.format('{0}</span><br /><span style="font-size:14px;text-transform:capitalize;"></span><span class="popupaddress">{1}<br />{2}, {3}, {4}<br /><div id="divPhone" style="display:inline">', obj.DisplayName, obj.Address, obj.City, obj.State, obj.Zip));
                
            var convertedDistance = obj.Distance * oThis.Options.DistanceMultiplier;
            sbCustomInfoWindow.push(String.format('<div style="float:right; font-size:11px; line-height:15px;">{0} {1} from <img src="/images/station_locator/search_center.png" alt="Search"></div>', convertedDistance.toFixed(2), oThis.Options.AbbreviatedDistanceDescriptor));
            sbCustomInfoWindow.push(String.format('{0}<div style="clear:right;"></div></div></span>', obj.PrimaryPhone));
            
            sbCustomInfoWindow.push(String.format('<div id="divDirections">Directions: <a href="javascript:void(0);" onclick="getAddy(2, \'From\');">To Here</a> | <a href="javascript:void(0);" onclick="getAddy(1, \'To\');">From Here</a></div>'));
            
            sbCustomInfoWindow.push('<div id="divDirectionAddy" style="display:none;"><div id="divDirectionType" style="display:inline; font-weight:bold;"></div>: <input type="text" id="txtDirAddress"><br /><input type="submit" id="btnGetDirections" value="Get Directions"><input type="button" id="btnCancel" value="Cancel" onclick="cancelDirections();"><input type="hidden" id="hdnType"></div>');
            
            //sbCustomInfoWindow.push(String.format('<div id="divDirectionAddy" style="display:none;position:relative;z-index:10000;margin-top:10px;height:24px;"><label id="lblDirectionLabel" style="float:left;padding:0px;font-size:14px;line-height:24px;">To:&nbsp;</label><input type="text" id="txtDirAddress" style="float:left;width:170px;">&nbsp;<input type="image" src="/images/{2}/buttons/go-bt.png" class="image-button" style="float:right;" /><div class="clear:both;"></div></div>', directionLabel, txtDirAddressWidth, obj.BrandID));
            sbCustomInfoWindow.push('</div><div class="bottombar">');
            
            oThis.Map.setOptions({draggable:false});            
            oThis.SelectedStoreAddress = String.format('{0} {1} {2}', obj.Address, obj.City, obj.State);
                

            if(!isBlank(obj.StationUrl) && obj.StationUrl != '#'){
                var str = 'Site';
                var targetAttr = 'target="_blank"';
                if(!obj.HasStationSite){
                    str = 'Page'
                    targetAttr = 'target="_top"';
                }
                sbCustomInfoWindow.push(String.format('<a href="{0}" {1} class="bottombar_icon">Visit Store {2}</a>', obj.StationUrl, targetAttr, str));
            }
                        
            sbCustomInfoWindow.push('</div>');
            retVal = sbCustomInfoWindow.join('');
        }    
        return retVal;
    },
  
    createBrandMarkerIcon: function(brandID){
        var pinURL = this.getPinURL(this.useBigPin(), false, brandID);
        //create temp image to get width and height
        var imgTemp = new Image();
        imgTemp.src = pinURL;
        var miMarkerIcon = new google.maps.MarkerImage(pinURL, new google.maps.Size(imgTemp.width, imgTemp.height));
    
        //save imgTemp for later use
        //this.currentIcon = imgTemp
        if(imgTemp.width > this.maxIconWidth){
            this.maxIconWidth = imgTemp.width;      
        }
    
        //imgTemp = null;
       
        var obj = {BrandID: brandID, MarkerIcon: miMarkerIcon}
        return obj;
    },
    
    deleteMarkers: function(){
        if(this.Markers){
            var i = this.Markers.length-1;
            while(i>=0){
                if(this.Markers[i]){
                    this.Markers[i].setMap(null);
                }
                i--;
            }
        }
    },
    
    closeInfoWindow: function(){
        if(this.customInfoWindowItem){
            this.customInfoWindowItem.remove();
      
            if(this.HasSearchResultListing){
                //remove highlighted item if there's any
                if(!isBlank(this.lastSelectedSearchItemID)){
                    var divLastSelectedRow = $(this.lastSelectedSearchItemID);
                    if(divLastSelectedRow){
                        divLastSelectedRow.className = divLastSelectedRow.className.replace('div-srl-row-selected', '');
                        this.lastSelectedSearchItemID = '';
                    }
                }
            }
        }
    },
    
    searchAddress: function(flag){
        var oThis = this;
        oThis.invokedSearchAddress = true;
        
        if(oThis.HasSearchResultListing){      
      
            var txtSearch = $('txtSearch');
            if(txtSearch){
                var address = txtSearch.value;
                if(!isBlank(address)){
                    oThis.Geocoder = new google.maps.Geocoder();
                    oThis.Geocoder.geocode({'address': address}, function(results, status){
                        if(status == google.maps.GeocoderStatus.OK){                            
                            var boundingBoxItem = oThis.getBoundingBox(results[0].geometry.location, results[0].geometry.viewport);
                                
                            StationWebsites.StoreLocatorMainControl1.gscabb(boundingBoxItem, function(res){
                                if(res && res.value && res.value.ResponseCode == 1){
                                    var storesBoundingBox = res.value.Payload;
                                    var location = new google.maps.LatLng(storesBoundingBox.CenterLatitude, storesBoundingBox.CenterLongitude);                                        
                                    var southWest = new google.maps.LatLng(storesBoundingBox.MinLat, storesBoundingBox.MaxLong);
                                    var northEast = new google.maps.LatLng(storesBoundingBox.MaxLat, storesBoundingBox.MinLong);                                        
                                    var bounds = new google.maps.LatLngBounds();
                                    bounds.extend(southWest);
                                    bounds.extend(northEast);
                                    
                                    oThis.updateMapCenter(bounds.getCenter());
                                    oThis.Map.fitBounds(bounds);
                                    oThis.updateDataSource.call(oThis);                                        
                                }
                            });
                            //oThis.updateMapCenter(results[0].geometry.location);
                            //oThis.Map.fitBounds(results[0].geometry.viewport);
                            //oThis.updateDataSource.call(oThis);
                    
                            //save successful address search to cookie if not yet existing in the list                    
                            oThis.updateRecentSearchesCookie(address);
                        }
                        else{
                            var msg = '';
                            if(status == google.maps.GeocoderStatus.ERROR){
                                msg = 'There was a problem contacting the Google servers. Please try again later.';
                            }
                            else if(status == google.maps.GeocoderStatus.INVALID_REQUEST){
                                msg = 'This GeocoderRequest was invalid.';
                            }
                            else if(status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT){
                                msg = 'The webpage has gone over the requests limit in too short a period of time. Please try again later.';
                            }
                            else if(status == google.maps.GeocoderStatus.REQUEST_DENIED){
                                msg = 'The webpage is not allowed to use the geocoder.';
                            }
                            else if(status == google.maps.GeocoderStatus.UNKNOWN_ERROR){
                                msg = 'The request could not be processed due to a server error. The request may succeed if you try again.';
                            }
                            else if(status == google.maps.GeocoderStatus.ZERO_RESULTS){
                                msg = 'No corresponding geographic location could be found for the specified address. This may be due to the fact that the address is relatively new, or it may be incorrect.';
                            }                  
                  
                            oThis.updateSearchResultItem(String.format('{0} Error Code: {1}', msg, status));
                            txtSearch.focus();
                            txtSearch.select();
                  
                            oThis.updateSearchResultCount(true);
                        }
                    });
                }
                else{
//                    if(flag==true){
//                        oThis.Map.setZoom(oThis.Zoom);
//                        oThis.updateMapCenter(oThis.MapCenter);
//                    }
                    oThis.updateDataSource();
                }
            }
        }
    },
    
    updateRecentSearchesCookie: function(address){
        var oThis = this;
        var strSLRecentSearches = getCookie(oThis.Options.RecentSearchesCookie);
        var recentSearchesArr = [];
        var isNewCookie = true;
        if(strSLRecentSearches){
            recentSearchesArr = eval(String.format('[{0}]', unescape(strSLRecentSearches)));
            if(recentSearchesArr){
                if(contains(recentSearchesArr, address, false)){
                    isNewCookie = false;
                }
            }                      
        }
        
        if(isNewCookie){
            if(recentSearchesArr.length == 5){ //only save 5 recent searches
                recentSearchesArr.shift(); //remove first item
            }
            var newSearchArr = [];
            for(var i=0,l=recentSearchesArr.length;i<l;i++){
                newSearchArr.push(String.format('"{0}"', recentSearchesArr[i]));
            }
            newSearchArr.push(String.format('"{0}"', address));
            setCookie(oThis.Options.RecentSearchesCookie, String.format('{0}', newSearchArr.toString()));
        }
    },
  
    updateDataSource: function(){
        var oThis = this;
        //map.checkResize();    
        //google.maps.event.trigger(oThis.Map, 'resize');
        
        //attach update datasource call after done showing direction
        if(oThis.Options.HasDirectionDisplay){
            oThis.removeDirections();
            oThis.Options.HasDirectionDisplay = false;
            google.maps.event.addListener(oThis.Map, 'idle', function(){oThis.updateDataSource.call(oThis)});
        }
    
        var zoom = oThis.Map.getZoom();
        var bounds = oThis.Map.getBounds();
        var bSW = bounds.getSouthWest();
        var bNE = bounds.getNorthEast();
        var dOffset = .00;
    
        var dCurCenterLong = oThis.SearchCenterPoint.lng();
        var dCurCenterLat = oThis.SearchCenterPoint.lat();
    
        var sbAmenities = [];
        var divStoreLocatorFeatures = $('divStoreLocatorFeatures');
        if(divStoreLocatorFeatures){
            var chks = divStoreLocatorFeatures.getElementsByTagName('input');
            if(chks){
                for(var i=0,l=chks.length;i<l;i++){
                    var chk = chks[i];
                    if(chk.type=='checkbox'){
                        if(chk.checked){
                            sbAmenities.push(chk.value);
                        }
                    }
                }
            }
        }
        
        var currentSearchParameter = {
            zoomLevel: zoom,
            minX: bSW.lng() - dOffset,
            maxX: bNE.lng() + dOffset,
            minY: bSW.lat() - dOffset,
            maxY: bNE.lat() + dOffset,
            centerX: dCurCenterLong,
            centerY: dCurCenterLat,
            amenityFilters: sbAmenities
        }
        
        var isSearchParamTheSameAsPrevious = areObjectsEqual(oThis.lastSearchParameter, currentSearchParameter) && areObjectsEqual(oThis.lastSearchParameter.amenityFilters, currentSearchParameter.amenityFilters);
        
        if(!isSearchParamTheSameAsPrevious){
            oThis.clearSearchBox();
            //reset invoked value
            oThis.invokedSearchAddress = false;
            
            
            oThis.lastSearchParameter = currentSearchParameter;
    
            StationWebsites.StoreLocatorMainControl1.gusV2(zoom, bSW.lng() - dOffset, bNE.lng() + dOffset, bSW.lat() - dOffset, bNE.lat() + dOffset, dCurCenterLong, dCurCenterLat, sbAmenities, function(res){
                if(res && res.value && res.value.ResponseCode == 1){
                    oThis.DataSource = res.value.Payload;
                    oThis.preloadBrandImages();
            
                    renderTimer = setInterval(function(){
                        if(oThis.isBrandImagesReady()){
                            clearInterval(renderTimer);
                            renderTimer = null;
                            oThis.render();
                            
                            //if coming from mini locator, search given address
                            if(oThis.isInitCall){
                                oThis.isInitCall = false;
                              
                                if(oThis.HasSearchResultListing){
                                    var txtSearch = $('txtSearch');
                                    if(txtSearch){
                                        if(!isBlank(txtSearch.value)){
                                            oThis.searchAddress();
                                        }
                                    }
                                }
                              
                            }
                        }
                    }, 100);
                    //setTimeout(function(){oThis.render()}, 1000);
                }
                else{
                    //no records
                    alert(String.format('Error occured: {0} {1}', res.value.ResponseCode, res.value.Message));
                }
            });
        }
    },
    
    getBoundingBox: function(centerPoint, bounds){        
        var bSW = bounds.getSouthWest();
        var bNE = bounds.getNorthEast();
        var dOffset = .00;
        
        var result = {
            CenterLongitude: centerPoint.lng(),
            CenterLatitude: centerPoint.lat(),
            MinLat: bSW.lat() - dOffset,
            MaxLat: bNE.lat() + dOffset,
            MinLong: bSW.lng() - dOffset,            
            MaxLong: bNE.lng() + dOffset 
        }
        
        return result;
    },
  
    preloadBrandImages: function(){
        var oThis = this;
        if(oThis.DataSource){
            var existingBrandIDs = [];
            var i = oThis.brandIconImages.length;
            while(i--){
                existingBrandIDs.push(oThis.brandIconImages.id);
            }
      
            var imgPrefix = 'img';
            var i = oThis.DataSource.length;
            while(i--){
                var brandID = oThis.DataSource[i].BrandID;
                if(!brandID){
                    brandID = oThis.BrandID;
                }
                if(brandID){
                    var imgID = imgPrefix + brandID;
                    var j = oThis.brandIconImages.length;
                    var found =false;
                    while(j--){
                        if(oThis.brandIconImages[j].id == imgID){
                            found = true;
                            break;
                        }
                    }          
                    if(!found){
                        var img = new Image();                        
                        img.id = imgID;
                        img.isready = false;
                        img.onload = function(){
                            this.isready = true;              
                            if(this.width > oThis.maxIconWidth){
                                oThis.maxIconWidth = this.width;                
                            }
                        }
                        img.src = oThis.getPinURL(false, false, brandID);
                        oThis.brandIconImages.push(img);                        
                    }
                }
            }      
        }
    },
  
    isBrandImagesReady: function(){
        var oThis = this;    
        var isReady = true;
        var i = oThis.brandIconImages.length;
        while(i--){
            var img = oThis.brandIconImages[i];
            if(!img.isready){
                isReady = false;
                break;
            }
        }
        return isReady;
    },
    
    renderDirection: function(dirOrigin, dirDestination){
        var oThis = this;
        oThis.DirectionService = new google.maps.DirectionsService();
        oThis.DirectionDisplay = new google.maps.DirectionsRenderer();
        oThis.DirectionDisplay.setMap(oThis.Map);    
        oThis.DirectionDisplay.setPanel($('directionsPanel'));    
        var request = {
            origin:dirOrigin,
            destination:dirDestination,
            travelMode: google.maps.TravelMode.DRIVING
        };
        setTimeout(function(){
            oThis.DirectionService.route(request, function(response, status){
                if(status == google.maps.DirectionsStatus.OK){
                    $('divDirectionsCont').style.display = 'block';
                    oThis.DirectionDisplay.setDirections(response);
                    setTimeout('resizeIFrame();', 10);
                    //save successful address search to cookie if not yet existing in the list                    
                    //oThis.updateRecentSearchesCookie(address);
                }
                else{
                    resizeIFrame();
                    handleDirectionErrors(status);
                }
            });
        }, 1);
    },
  
    removeDirections: function(){
        if(this.Options.HasDirectionDisplay){
            this.DirectionDisplay.setMap(null);
            $('divDirectionsCont').style.display = 'none';
            resizeIFrame();
        }
    },
    
    clearSearchBox: function(){
        var oThis = this;        
        var txtSearch = $('txtSearch');
        
        //if searchbox is not blank and center and zoom level is different than the last search parameter values, clear searchbox
        if(txtSearch && oThis.lastSearchParameter){            
            if(!isBlank(txtSearch.value)){
                var zoom = oThis.Map.getZoom();
                var currMapCenter = oThis.Map.getCenter();
                var dCurCenterLong = currMapCenter.lng();
                var dCurCenterLat = currMapCenter.lat();
                
                if(!oThis.isInitCall && !oThis.invokedSearchAddress && (oThis.lastSearchParameter.centerY != dCurCenterLat || oThis.lastSearchParameter.centerX != dCurCenterLong || oThis.lastSearchParameter.zoomLevel != zoom)){                    
                    txtSearch.value = '';
                }
            }
        }
    },
    
    init: function(mapLat, mapLong){  
        var oThis = this;
        
        //sitemap has fixed zoom level
        if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.SITEMAP){            
            oThis.Zoom = 15;
        }
    
        var mapCenter = new google.maps.LatLng(mapLat, mapLong);
        var mapOptions = {
            zoom: oThis.Zoom,
            center: mapCenter,
	        panControl: oThis.Options.HasPanControl,
            zoomControl: oThis.Options.HasZoomControl,
            scaleControl: oThis.Options.HasScaleControl,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControl: false
        }
        
        oThis.Map = new google.maps.Map($(oThis.MapCanvasID), mapOptions);
        oThis.MapCenter = mapCenter;
        
        if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.FULLLOCATOR || oThis.Options.DisplayMode==StoreLocatorDisplayModes.IFRAMEDLOCATOR){
            if(oThis.Options.HasDirectionDisplay){
                oThis.renderDirection(oThis.Options.DirectionOrigin, oThis.Options.DirectionDestination);      
            }
            else{
                oThis.updateMapCenterIcon(mapCenter);
      
                google.maps.event.addListener(oThis.Map, 'idle', function(){oThis.updateDataSource.call(oThis)});
                //google.maps.event.addListener(oThis.Map, 'moveend', function(){alert('moveend');oThis.updateDataSource.call(oThis)});
                //google.maps.event.addListener(oThis.Map, 'idle', function(){oThis.searchAddress.call(oThis)});
                //google.maps.event.addListener(oThis.Map, 'moveend', function(){oThis.searchAddress.call(oThis)});
            }            
        }
        else if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.MINILOCATOR){
            oThis.updateMapCenterIcon(mapCenter);
            google.maps.event.addListener(oThis.Map, 'idle', function(){oThis.updateDataSource.call(oThis)});
        }
        else if(oThis.Options.DisplayMode==StoreLocatorDisplayModes.SITEMAP){
            var iconURL = oThis.getPinURL(false, false, oThis.BrandID);
            var marker =  new google.maps.Marker({
                position: mapCenter,
                animation: google.maps.Animation.DROP,
                map: oThis.Map,
                icon: iconURL
            });
        }    
        resizeIFrame();
    }
}

function handleDirectionErrors(status){
  var msg = '';
  if(status == google.maps.DirectionsStatus.INVALID_REQUEST){
    msg = 'The direction request provided was invalid.';
  }
  else if(status == google.maps.DirectionsStatus.MAX_WAYPOINTS_EXCEEDED){
    msg = 'Too many Directions Way points were provided in the Directions Request. The total allowed waypoints is 8, plus the origin and destination.';
  }
  else if(status == google.maps.DirectionsStatus.NOT_FOUND){
    msg = 'At least one of the origin, destination, or waypoints could not be geocoded.';
  }
  else if(status == google.maps.DirectionsStatus.OVER_QUERY_LIMIT){
    msg = 'The webpage has gone over the requests limit in too short a period of time.';
  }
  else if(status == google.maps.DirectionsStatus.REQUEST_DENIED){
    msg = 'The webpage is not allowed to use the directions service.';
  }
  else if(status == google.maps.DirectionsStatus.UNKNOWN_ERROR){
    msg = 'A directions request could not be processed due to a server error. The request may succeed if you try again.';
  }
  else if(status == google.maps.DirectionsStatus.ZERO_RESULTS){
    msg = 'No route could be found between the origin and destination.';
  }
  
  if(!isBlank(msg)){
    alert(msg + '\nError code: ' + status)
  }
  
//  if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
//         alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);
//       else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
//         alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
//       else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
//         alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);
//       else if (gdir.getStatus().code == G_GEO_BAD_KEY)
//         alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);
//       else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
//         alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
//       else alert("An unknown error occurred.");
}

function resizeIFrame(){  
//  if(window.frameElement){
//    //window.frameElement.height = window.document.body.scrollHeight;
//    
//    //remove scrollbar in Safari and Chrome  
//    var html = document.getElementsByTagName('html')[0];
//    html.style.overflow = 'hidden';
//  }
  //alert(window.frameElement.height);
    
  
  
//  if (sParentFrameSrc == ''){
//    
//  }
//  else{
//    var iframe = document.getElementById( 'inneriframe' );
//    var height = Math.max( document.body.offsetHeight, document.body.scrollHeight );
//    iframe.src = sParentFrameSrc + '?height='+height;
//  }
}

// CustomInfoWindow Class
function CustomInfoWindow(marker, mapParentDiv, map) {
  this.Marker = marker;
  this.HTML = marker.infoWindowHTML;
  this.MapParentDiv = mapParentDiv;
  this.Map = map;
  this.ClassName = 'ciwClass';
  
  this.setMap(map);
}

CustomInfoWindow.prototype = new google.maps.OverlayView();

CustomInfoWindow.prototype.onAdd = function(){

  var div = document.createElement('div');
  div.className = this.ClassName;
    
  var shadow = document.createElement('div');
  
  var pointer = document.createElement('div');
  pointer.id = 'divPointer';
  
  
  this.Div = div;
  this.Shadow = shadow;
  this.Pointer = pointer;
  
  
  var panes = this.getPanes();
  panes.floatPane.appendChild(shadow);
  panes.floatPane.appendChild(div);
  panes.floatPane.appendChild(pointer);  
}

CustomInfoWindow.prototype.draw = function(){
  var oThis = this;
  
  oThis.Div.onmouseover = function() { oThis.Map.setOptions({draggable:false}) };
  oThis.Div.onmouseout = function() { oThis.Map.setOptions({draggable:true}) };
  oThis.Div.className = oThis.ClassName;
  oThis.Div.innerHTML = oThis.HTML;
  
  google.maps.event.addDomListener(oThis.Div, 'mousedown', cancelEvent);   //cancels drag/click
  google.maps.event.addDomListener(oThis.Div, 'click', cancelEvent);       // cancels click
  google.maps.event.addDomListener(oThis.Div, 'dblclick', cancelEvent);    // cancels double click
  google.maps.event.addDomListener(oThis.Div, 'contextmenu', cancelEvent);  //cancels double right click 
    
  var iPointerTop, iPointerLeft;
  var iPointerWidth = 15;
  var iPointerHeight = 15;

  var overlayProjection = oThis.getProjection();

  var divPoint = overlayProjection.fromLatLngToDivPixel(oThis.Marker.getPosition());
  var pinOffsetY = divPoint.y;
  var containerPoint = overlayProjection.fromLatLngToContainerPixel(oThis.Marker.getPosition());
    
  var iCurQuadrantX = Math.floor(containerPoint.x / (parseInt(oThis.MapParentDiv.offsetWidth) / 3)) + 1;
  if (iCurQuadrantX < 1) { iCurQuadrantX = 1; }
  if (iCurQuadrantX > 3) { iCurQuadrantX = 3; }
  var iCurQuadrantY = Math.floor(containerPoint.y / (parseInt(oThis.MapParentDiv.offsetHeight) / 3)) + 1;
  if (iCurQuadrantY < 1) { iCurQuadrantY = 1; }
  if (iCurQuadrantY > 3) { iCurQuadrantY = 3; }
  var iCurQuadrant = iCurQuadrantX + (3 * (iCurQuadrantY - 1));

  var popupX, popupY;
  var popupWidth = parseInt(oThis.Div.offsetWidth);
  var popupHeight = parseInt(oThis.Div.offsetHeight);
  switch (iCurQuadrant){
    case 1:
      popupX = divPoint.x + iPointerWidth - 1;
      popupY = pinOffsetY;
      iPointerLeft = popupX - iPointerWidth + 1;
      iPointerTop = popupY;
      break;
    case 2: case 5:
      popupX = divPoint.x - (popupWidth / 2) - 1;
      popupY = pinOffsetY + iPointerHeight - 1;
      iPointerLeft = popupX + (popupWidth / 2) - (iPointerWidth / 2) + 1;
      iPointerTop = popupY - iPointerHeight + 1;
      break;
    case 3:
      popupX = divPoint.x - popupWidth - iPointerWidth + 1;
      popupY = pinOffsetY;
      iPointerLeft = popupX + popupWidth - 1;
      iPointerTop = popupY;
      break;
    case 4:
      popupX = divPoint.x + iPointerWidth - 1;
      popupY = pinOffsetY - (popupHeight / 2);
      iPointerLeft = popupX - iPointerWidth + 1;
      iPointerTop = popupY + (popupHeight / 2) - (iPointerHeight / 2) + 1;
      break;
    case 6:
      popupX = divPoint.x - popupWidth - iPointerWidth + 1;
      popupY = pinOffsetY - (popupHeight / 2);
      iPointerLeft = popupX + popupWidth - 1;
      iPointerTop = popupY + (popupHeight / 2) - (iPointerHeight / 2) + 1;
      break;
    case 7:
      popupX = divPoint.x + iPointerWidth - 1;
      popupY = pinOffsetY - popupHeight + 1;
      iPointerLeft = popupX - iPointerWidth + 1;
      iPointerTop = popupY + popupHeight - iPointerHeight;
      break;
    case 8:
      popupX = divPoint.x - (popupWidth / 2);
      popupY = pinOffsetY - popupHeight - iPointerHeight + 1;
      iPointerLeft = popupX + (popupWidth / 2) - (iPointerWidth / 2) + 1;
      iPointerTop = popupY + popupHeight - 1;
      break;
    case 9:
      popupX = divPoint.x - popupWidth - iPointerWidth + 1;
      popupY = pinOffsetY - popupHeight + 1;
      iPointerLeft = popupX + popupWidth - 1;
      iPointerTop = popupY + popupHeight - iPointerHeight;
      break;
    default:
      break;
  }

  var oThisDivStyle = oThis.Div.style;
  var oThisPointerStyle = oThis.Pointer.style;
  if (iCurQuadrant >= 1 && iCurQuadrant <= 9) {
      oThisDivStyle.left = popupX + 'px';
      oThisDivStyle.top = popupY + 'px';

      oThisPointerStyle.position = 'absolute';
      oThisPointerStyle.left = iPointerLeft + 'px';
      oThisPointerStyle.top = iPointerTop + 'px';
      oThis.Pointer.className = 'pointer' + iCurQuadrant;
  }
  
  var iSmallNavHeight = '230px';
    //var iBigNavHeight = '434px';
  var iBigNavHeight = '370px';
  var iZoomThreshold = 5;
  var iShadowOffset = 7;
  var iShadowOpacity = 35;
    
  var oShadowStyle = oThis.Shadow.style;
  oShadowStyle.position = 'absolute';
  oShadowStyle.top = (parseInt(oThisDivStyle.top) + iShadowOffset) + 'px';
  oShadowStyle.left = (parseInt(oThisDivStyle.left) + iShadowOffset) + 'px';
  oShadowStyle.width = oThis.Div.offsetWidth + 'px';
  oShadowStyle.height = oThis.Div.offsetHeight + 'px';
  oShadowStyle.backgroundColor = '#000000';
  oShadowStyle.opacity = iShadowOpacity / 100;
  oShadowStyle.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + iShadowOpacity + ')';
    
  if($('imgClose')){
    if(iCurQuadrant == 3){
      $('imgClose').style.left = '-' + (oThis.Div.offsetWidth - ($('imgClose').offsetWidth / 2) - 3) + 'px';
      $('imgClose').className = 'x6';
    }
    else{
      $('imgClose').className = 'x5';
    }
    
    $('imgClose').onclick = function(e){
      if(!e){
        var e = window.event;
      }
      e.cancelBubble = true;
      if(e.stopPropagation){
        e.stopPropagation();
      }
      oThis.remove()
      oThis.Map.setOptions({draggable:true});
    }
  }
}

CustomInfoWindow.prototype.remove = function(){
  var oThis = this;
  if (oThis.Div) {
    if(oThis.Div.parentNode){oThis.Div.parentNode.removeChild(oThis.Div);}
    if(oThis.Pointer.parentNode){oThis.Pointer.parentNode.removeChild(oThis.Pointer);}
    if(oThis.Shadow.parentNode){oThis.Shadow.parentNode.removeChild(oThis.Shadow);}
  }
  oThis = null;
}

function getAddy(iType, sType){
        //map.disableDragging();
        $('hdnType').value = iType;
        $('divDirections').style.display = 'none';
        $('divPhone').style.display = 'none';
        $('divDirectionType').innerHTML = sType;
        $('divDirectionAddy').style.display = 'block';
        
        //$('txtDirAddress').style.color = '#808080';
        //$('txtDirAddress').value = sDirectionsText;
        $('txtDirAddress').focus();
}
    
function cancelDirections() {
    //map.enableDragging();
    $('divDirections').style.display = '';
    $('divPhone').style.display = '';
    $('divDirectionAddy').style.display = 'none';
}


