var Try = {
    these: function() {
        var returnValue;

        for (var i = 0; i < arguments.length; i++) {
            var lambda = arguments[i];
            try {
                returnValue = lambda();
                break;
            } catch (e) {}
        }

        return returnValue;
    }
}

function LokiAPI()
{
    return Try.these(
    function() {return new ActiveXObject("Loki.LocationFinder.1");},
    function() {return new Loki();}
    ) || false;
}

function stopKeys(evt) {
    ignorekeys = [6,18,37,38,39,40,20,17,35,27,36,45,144,16,9,91,224,13,8];
    for(var i = 0; i<ignorekeys.length; i++) {
        if( evt.which == ignorekeys[i] ) {
            return true;
        }
    }
    return false;
}


var ConnectorLocationSelect = new Class({

    localMapDisabled:false,
    icon:false,
    map:false,
    marker:false,
    currentLocation:false,
    locationResultsMarkers:[],
    bounds:false,
    latSum: 0,
    lonSum:0,
    latLonSum:0,
    points:[],
    markers:[],
    data:[],
    sliderResults:false,
    sliderChangeLocation:false,

    initialize: function(){
        this.sliderResults = new Fx.Slide('sbLocationResultsContainer');
        this.sliderResults.hide();
        // look up location
        this.initMap();
    },

    resetMarkers:function(){
        this.resetMarkersImage();
        for( var i = 0; i < this.markers.length; i++ ){
            GEvent.clearInstanceListeners( this.markers[i] );
            this.map.removeOverlay( this.markers[i] );
        }
        // reset the array
        this.markers = [];
        this.points = [];
        this.data = [];
        this.bounds =false;
    },

    resetMarkersImage:function(){
        for( var i = 0; i < this.markers.length; i++ ){
            this.markers[i].setImage( "/images/maps/map-pin.png" );
        }
    },

    findMe:function( event ){
        // reset markers
        this.resetMarkers();
        this.resetBackgrounds();
        new Event(event).stop();
        if( $( 'location_q' ).value.length > 3 ){
            this.findLocation( $( 'location_q' ).value );
        }
    },

    findLocation:function( q ){
        this.showLoader();
        new Ajax("/findme/findLocation.php",{
            method:'post',
            data: $('location_city_form').toQueryString() + '&location_q=' + q,
            onComplete:this.locationSearchResponse.bind(this),
            onFailure:function( response ){ this.hideLoader.bind(this); }
        }).request();
    },

    hideLoader:function(){
        if( $('sbLocationSearchLoaderIcon') ){
            $('sbLocationSearchLoaderIcon').setStyle( 'display', 'none' );
        }
    },

    showLoader:function(){
        if( $('sbLocationSearchLoaderIcon') ){
            $('sbLocationSearchLoaderIcon').setStyle( 'display', '' );
        }
    },

    resetBackgrounds:function(){
        var places = $$( 'li.sbLocationEntry' );
        if( places ){
            if( places.length > 0 ){
                for( var i = 0; i < places.length; i++ ){
                    places[i].removeClass( 'hlite' );
                }
            }
        }
    },

    cancel:function( key ){
        this.map.closeInfoWindow();
        this.resetMarkersImage();
        this.resetBackgrounds();
        var latAvg = this.latSum / this.latLonSum;
        var lonAvg = this.lonSum / this.latLonSum;
        var point = new GLatLng( Number( latAvg ), Number( lonAvg ) );
        this.bestFitWithCenter( this.bounds, point );
        return false;
    },

    click:function( key ){
        if( this.markers[key] ){
            this.openMarkerWindow( this.markers[key].getPoint() );
        }
        return false;
    },

    openMarkerWindow:function( point ){
        if( this.points.contains( point ) ){
            var key = this.points.indexOf( point );
            if( this.markers[key] ){
                this.resetBackgrounds();
                this.resetMarkersImage();
                var marker = this.markers[key];
                var data = this.data[key];
                // zoom in
                this.map.setCenter( marker.getPoint(), 12 );
                // ok open info window with form
                this.map.openInfoWindowHtml( marker.getPoint(), '<div id="sbInfoWindowContainer"><h3>Change your location to ' + data.title +  '?</h3><p><a id="sbLocationAcceptBtn" href="' + data.link + '" rel="nofollow">Change</a> <a id="sbLocationCancelBtn" href="#" rel="nofollow" onclick="return cl_locationSelect.cancel( ' + key + ' );">Cancel</a></p></div>', { 'noCloseOnClick':true } );
                //this.map.setZoom( 12 );
                this.markers[key].setImage( "/images/maps/map-pin-on.png" );
                if( $( 'e-' + key ) ){
                    $( 'e-' + key ).addClass( 'hlite' );
                }
            }
        }
    },

    displayMarker:function( data ){
        var point = new GLatLng( Number( data.latitude ), Number( data.longitude ) );
        this.latSum = this.latSum + Number( data.latitude );
        this.lonSum = this.lonSum + Number( data.longitude );
        this.latLonSum++;
        this.bounds.extend( point );
        var marker = new GMarker(point, {icon:this.setupIcon('red'), draggable: false, title: data.title});

        // open info window marker on click
        GEvent.addListener( marker, "click", function( point ) {
            this.openMarkerWindow( point );
        }.bind( this) );


        this.markers.push( marker );
        this.points.push( point );
        this.map.addOverlay( marker );
    },

    locationSearchResponse:function( response ){
        this.hideLoader();
        $('sbLocationResults').empty();
        //$('sbLocationResultsContainer').setStyle( 'display', '' );
        var location = Json.evaluate( response );
        if( location ){
            if( !location.error ){
                if( location.total.toInt() > 0 ){
                    var resText = 'location';
                    if( location.total.toInt() > 1 ){
                        resText = 'locations';
                    }
                    var locationList = new Element('ul');
                    this.locationData = location.data;
                    this.data = this.locationData;
                    this.bounds = new GLatLngBounds();
                    // add current location marker to bounds
                    var point = new GLatLng( Number( this.currentLocation.latitude ), Number( this.currentLocation.longitude ) );
                    this.latSum = this.latSum + Number( this.currentLocation.latitude );
                    this.lonSum = this.lonSum + Number( this.currentLocation.longitude );
                    this.latLonSum++;
                    this.bounds.extend( point );
                    new Element('p',{'class':'locationResultsText'}).setText( 'We found ' + location.total + ' ' + resText + ' matching your search.' ).injectInside( $('sbLocationResults') );
                    for( var i = 0; i < location.data.length; i++ ){
                        var locationEntry = location.data[i];
                        var locationContainer = new Element('li',{'id':'e-' + i, 'class':'sbLocationEntry'});
                        var insideHtml = '<a href="' + locationEntry.link + '" onclick="return cl_locationSelect.click( ' + i + ' );"><img src="/images/map-slide-arrow.png" alt="Location Icon" style="height:16px;width:24px;" />' + locationEntry.title + '</a><a href="' + locationEntry.link + '" rel="nofollow" class="sbLocationChangeBtn">[CHANGE]</a>';
                        locationContainer.innerHTML = insideHtml;
                        locationContainer.injectInside( locationList );
                        this.displayMarker( locationEntry );
                    } // end for
                    locationList.injectInside( $('sbLocationResults') );
                    var latAvg = this.latSum / this.latLonSum;
                    var lonAvg = this.lonSum / this.latLonSum;
                    var point = new GLatLng( Number( latAvg ), Number( lonAvg ) );
                    this.bestFitWithCenter( this.bounds, point );
                    this.sliderResults.slideIn();
                    return true;
                }
            }
        }
        new Element('p',{'class':'locationResultsError'}).setText( 'We were unable to find that location. Please try again.' ).injectInside( $('sbLocationResults') );
        this.sliderResults.slideIn();
    },

    setupIcon:function(colorName){
        var icon = new GIcon();
        icon.image = "/images/maps/map-pin.png";
        icon.iconSize = new GSize(24, 24);
        icon.iconAnchor = new GPoint(12, 24);
        icon.infoWindowAnchor = new GPoint(12, 1);
        return icon;
    },

    bestFitWithCenter:function( bounds, mapCenter ){
        var swLL = bounds.getSouthWest();
        var neLL = bounds.getNorthEast();

        //leave margin each side
        var marginRatio = 0.0001;

        var minLat = Math.min(2*mapCenter.lat() - neLL.lat(), swLL.lat());
        var maxLat = Math.max(2*mapCenter.lat() - swLL.lat(),  neLL.lat());
        var minLng = Math.min(2*mapCenter.lng() - neLL.lng(), swLL.lng());
        var maxLng = Math.max(2*mapCenter.lng() - swLL.lng(), neLL.lng());

        var minLatLng = new GLatLng(minLat-marginRatio, minLng-marginRatio);
        var maxLatLng = new GLatLng(maxLat+marginRatio, maxLng+marginRatio);

        bounds.extend(maxLatLng);
        bounds.extend(minLatLng);

        this.map.setZoom(this.map.getBoundsZoomLevel(bounds));
        this.map.setCenter(mapCenter);

    },

    changePanel:function( panel, buttonClick ){
        if( buttonClick ){
            new Fx.Style( $('sbChangeLocation') , 'background-color', {duration: 1000}).set('#ffff00').start( '#ffffff' );
        }
        if( panel == 'location' ){
            // hide local panel
            this.hideLocalPanel();
            this.showLocationPanel();
        }else if( panel == 'local' && !this.localMapDisabled  ){
            this.hideLocationPanel();
            this.showLocalPanel();
        }
    },

    showLocationPanel:function(){

        if( $( 'sbChangeLocation' ) ){
            $( 'sbChangeLocation' ).setStyle( 'display', '' );
            // this.sliderChangeLocation.slideIn();
        }
        if( $( 'locationMapPanel' ) ){
            $( 'locationMapPanel' ).setStyle( 'display', 'block' );
        }

        if( $( 'sbDirectionsContainer') ){
            if( $( 'sbDirectionsContainer').hasClass( 'open' ) ){
                $( 'sbDirectionsContainer').setStyle( 'display', 'none' );
            }
        }

        if( $('currentSbPanelTitle') ){
            //$( 'currentSbPanelTitle' ).setStyle( 'display', '' );
        }

        if( $('sbLocationCloseBtn') && !this.localMapDisabled ){
            $( 'sbLocationCloseBtn' ).setStyle( 'display', '' );
        }

        if( $( 'panelsTitle' ) ){
            //$( 'panelsTitle' ).setStyle( 'display', '' );
        }

        if( $( 'sbMenuFindMe' ) ){
            if( !$( 'sbMenuFindMe' ).hasClass( 'open' ) ){
                $( 'sbMenuFindMe' ).addClass( 'open' );
            }
        }

    },

    hideLocationPanel:function(){

        if( $( 'sbDirectionsContainer') ){
            if( $( 'sbDirectionsContainer').hasClass( 'open' ) ){
                $( 'sbDirectionsContainer').setStyle( 'display', '' );
            }
        }

        if( $( 'sbChangeLocation' ) ){
            $( 'sbChangeLocation' ).setStyle( 'display', 'none' );
            //this.sliderChangeLocation.slideOut();
        }
        if( $( 'locationMapPanel' ) ){
            $( 'locationMapPanel' ).setStyle( 'display', 'none' );
        }

        if( $('currentSbPanelTitle') ){
            $( 'currentSbPanelTitle' ).setStyle( 'display', 'none' );
        }

        if( $('sbLocationCloseBtn') ){
            $( 'sbLocationCloseBtn' ).setStyle( 'display', 'none' );
        }

        if( $( 'panelsTitle' ) ){
            //$( 'panelsTitle' ).setStyle( 'display', 'none' );
        }

        if( $( 'sbMenuFindMe' ) ){
            if( $( 'sbMenuFindMe' ).hasClass( 'open' ) ){
                $( 'sbMenuFindMe' ).removeClass( 'open' );
            }
        }

    },

    showLocalPanel:function(){

        if( $( 'localMapPanel' ) ){
            $( 'localMapPanel' ).setStyle( 'display', '' );
        }

        if( $( 'sbMenuMap' ) ){
            if( !$( 'sbMenuMap' ).hasClass( 'open' ) ){
                $( 'sbMenuMap' ).addClass( 'open' );
            }
        }

    },

    hideLocalPanel:function(){

        if( $( 'localMapPanel' ) ){
            $( 'localMapPanel' ).setStyle( 'display', 'none' );
        }

        if( $( 'sbMenuMap' ) ){
            if( $( 'sbMenuMap' ).hasClass( 'open' ) ){
                $( 'sbMenuMap' ).removeClass( 'open' );
            }
        }

    },

    getUserLocation:function(){
        new Ajax("/js/functions/getMyLocation.php",{
            method:'get',
            onComplete:this.currentLocationResponse.bind(this),
            onFailure:function(){}
        }).request();
    },

    currentLocationResponse:function( response ){
        var location = Json.evaluate( response );
        if( location ){
            if( location.latitude && location.longitude ){
                this.currentLocation = location;
                this.displayYouAreHere();
            }
        }
    },

    displayYouAreHere:function(){
        if( this.currentLocation && !this.marker ){
            var loc = new GLatLng( this.currentLocation.latitude, this.currentLocation.longitude );
            this.map.setCenter(loc, 14);
            this.marker = new GMarker(loc, { icon:this.getIcon(), draggable: true, title: 'You are here!' });
            GEvent.addListener(this.marker,'dragend',function() {
                var lat = this.marker.getPoint().lat();
                var lng = this.marker.getPoint().lng();
                this.updateCurrentPoint( lat, lng );
            }.bind(this));
            this.map.addOverlay( this.marker );
        } else {
            var loc = new GLatLng( this.currentLocation.latitude, this.currentLocation.longitude );
            this.marker.setPoint( loc );
        }
    },

    getIcon:function(){
        if( !this.icon ){
            var icon = new GIcon();
            icon.image = "/images/place_icon.png";
            icon.iconSize = new GSize(61, 53);
            icon.iconAnchor = new GPoint(19, 51);
            icon.infoWindowAnchor = new GPoint(39, 0);
            this.icon = icon;
        }
        return this.icon;
    },

    lokiClick:function( service ){
        if( typeof( service ) == 'undefined' ){
            service = 'Loki';
        }
        // check for loki
        var loki = LokiAPI();
        if (loki) {
            loki.onSuccess = function(location) {
                this.findLocation( location.latitude + ', ' + location.longitude );
            }.bind(this);
            loki.onFailure = function(error) {

                switch( error ){
                    case 1:
                    error = 'Scanner not found!';
                    break;
                    case 2:
                    error = 'WiFi not available!';
                    break;
                    case 3:
                    error = 'No WiFi in range!';
                    break;
                    case 6:
                    error = 'Location cannot be determined!';
                    break;
                    default:
                    error = '';
                    break;
                }

                $('sbLocationResults').empty();
                new Element('p',{'class':'locationResultsError'}).setText( 'We were unable to find your location using ' + service + '. ' + error ).injectInside( $('sbLocationResults') );
                this.sliderResults.slideIn();
            }.bind(this);
            loki.setKey('staging.connectorlocal.com');
            loki.requestLocation(true,loki.FULL_STREET_ADDRESS_LOOKUP);
        } else {
            $('sbLocationResults').empty();
            new Element('p',{'class':'locationResultsError'}).setText( 'We were unable to find the ' + service + ' browser plugin. Please download it and try again.' ).injectInside( $('sbLocationResults') );
            this.sliderResults.slideIn();
        }
    },

    updateCurrentPoint:function( latitude, longitude ){
        if( this.currentLocation ){
            this.showLoader();
            new Ajax("/js/functions/setMyLocation.php",{
                method:'post',
                data:'latitude=' + latitude + '&longitude=' + longitude ,
                onComplete:function( response ){ this.hideLoader(); window.location = window.location; }.bind(this),
                onFailure:function( response ){  this.hideLoader(); }.bind( this )
            }).request();
        }
    },

    initMap:function(){
        if (GBrowserIsCompatible()) {
            this.map = new GMap2($( 'locationMap' ));
            this.map.setCenter(new GLatLng( 54, -100), 2);
            this.map.addControl(new GSmallMapControl());
            this.map.addControl(new GMapTypeControl());
            this.getUserLocation();

            if( $( 'clGlobalSearchFrm' ) ){
                $( 'clGlobalSearchFrm' ).addEvent( 'submit', function( event ){
                    if( $( 'cl_type_select' ) ){
                        if( $( 'cl_type_select' ).value == 'findme' ){
                            new Event( event ).stop();
                            if( $( 'cl_feature_search').value.length > 2 ){
                                if( $( 'location_q' ) ){
                                    this.changePanel( 'location', true );
                                    $( 'location_q' ).value = $( 'cl_feature_search').value;
                                    this.findLocation( $( 'location_q' ).value );
                                }
                            }
                        }
                    }
                }.bind( this ) );
            }

            if( $( 'sbLokibtn' ) ){
                $( 'sbLokibtn' ).addEvent( 'click', function( event ){
                    new Event( event ).stop();
                    this.lokiClick( 'Loki' );
                }.bind( this ) );
            }
             if( $( 'sbGeodebtn' ) ){
                $( 'sbGeodebtn' ).addEvent( 'click', function( event ){
                    new Event( event ).stop();
                    this.lokiClick( 'Geode' );
                }.bind( this ) );
            }
            GEvent.addListener( this.map, "click", function( overlay, latlng ) {
                if( latlng ){
                    this.updateCurrentPoint( latlng.y, latlng.x );
                }
            }.bind( this) );

            if( $( 'localMapPanel' ) && $( 'localMapPanel' ) ){
                if( $( 'location_city_form' ) ){
                    $( 'location_city_form' ).addEvent( 'submit', this.findMe.bind( this ) );
                }
                if( $( 'localMapPanel' ).hasClass( 'disabled') ){
                    this.localMapDisabled = true;
                    if( $('sbLocationCloseBtn') ){
                        $('sbLocationCloseBtn').setStyle( 'display', 'none' );
                    }
                }
                switch( true ){
                    case $( 'localMapPanel' ).hasClass( 'open' ):
                    this.changePanel( 'local' );
                    break;
                    case $( 'localMapPanel' ).hasClass( 'open' ):
                    default:
                    this.changePanel( 'location' );
                    break;
                }
                if( $('sbMenuFindMeBtn') ){
                    $('sbMenuFindMeBtn').addEvent( 'click', function( event ){
                        new Event( event ).stop();
                        this.changePanel( 'location' );
                    }.bind( this ) );
                }
                if( $('sbMenuMapBtn') ){
                    $('sbMenuMapBtn').addEvent( 'click', function( event ){
                        new Event( event ).stop();
                        this.changePanel( 'local' );
                    }.bind( this ) );
                }
            }
        } else{
            alert('Your browser is not compatible with Google Maps.');
        } // end if
    }

});
