﻿//Author:   rebecca.mccay
//Created:  11/16/2009 10:41:41 AM

        
var Locator = {

    InitialZoom: 4,
    InitialCentre: new MapDS.LatLng( -28, 135),
    PoiSearchBuffer: 200000, // metres from the location.
    PoiSearchRecordLimit: 5, // max number of POIs to find.
    
    Strings: {
        InvalidSearch: 'Please enter a Town/Suburb or Postcode.',
        InvalidSuburb: 'The value of Suburb is not valid.',
        InvalidPostcode: 'The value of Postcode is not valid.',
        MultipleAddressDialogTitle: 'Multiple Address Matches Found.',
        MultipleAddressPrompt: 'Choose an address:',
        Searching: 'Searching...',
        POIsFound: '{0} match{1} found'
    },
    
    Images: {
        Loading: './images/loading-circle-black.gif'
    },
    
    ElementIDs: {
        Map: 'map',
        MultipleAddressDialog: 'multipleAddressDialog',
        MultipleAddresses: 'ddlMultipleAddresses',
        ExceptionDialog: 'exceptionDialog',
        NoResultDialog: 'noLocationsFound',
        Search: 'search',
        SearchStreet: 'txtStreet',
        SearchSuburb: 'txtSuburb',
        SearchState: 'ddlState',
        SearchPostcode: 'txtPostcode',
        SearchButton: 'btnSearch',
        ResetButton: 'btnReset',
        ApplyFiltersButton: 'btnApply',
        //DrivingDirections: 'drivingDirections',
        DirectionsButton: 'btnDirections',
        DrivingDirectionsList: 'drivingDirectionsList',
         DrivingDirectionsWrapper: 'drivingDirectionsWrapper',
        POIsButton: 'btnPointsOfInterest',
        ResultsButton: 'ResultButtons', 
        POIsWrapper: 'pointsOfInterestWrapper',
        POIsList: 'pointsOfInterestList',
        POIsFound: 'pointsOfInterestFound',
        FiltersButton: 'btnFilters',
        FiltersList: 'filtersList',
        StartTitle: 'startTitle',
        EndTitle: 'endTitle'
    },
    
    /// Reset the search fields back to default values.
    /// Here we set the textfields to the value in the title attribute and then call the blur method to
    /// trigger jQuery hint code.
    resetSearchFields: function() {
       $( this.getElementID( this.ElementIDs.Search ) + ' input[title!=""]').attr("value","").blur();
       $( this.getElementID( this.ElementIDs.Search ) + ' input[type="checkbox"]').attr("checked","");
       $( this.getElementID( this.ElementIDs.SearchState ) ).attr( "selectedIndex", 0 );
        $(this.getElementID(this.ElementIDs.POIsButton)).css({'display':'none', 'height' : '0px'} );
       $(this.getElementID(this.ElementIDs.DirectionsButton)).css({'display':'none', 'height' : '0px'} );
    },
    
    /// This method is used to validate the search fields. The following function has code
    /// to perform validation on the standard address fields. Use it as a guide for your
    /// custom search fields.
    validateSearchFields: function() {
        var haveValidSuburb = false;
        var haveValidPostcode = false;
        var txtSuburb = $( this.getElementID( this.ElementIDs.SearchSuburb ) );
        var txtPostcode = $( this.getElementID( this.ElementIDs.SearchPostcode ) );
        
        if (txtSuburb.attr("value") != '' && txtSuburb.attr("value").toLowerCase() != txtSuburb.attr("title").toLowerCase()) {
        haveValidSuburb = true;
  } 
        
        if ( !haveValidSuburb && !haveValidPostcode ) {
            this.displayException( this.Strings.InvalidSearch );
            return false;
        }
        
        return true;
    },
    
    /// Builds a MapDS.Address representation of the address to be geocoded.
    /// This method is automatically called.
    buildAddressSearch: function() {
        if(this.DebugMode){Logger.info('buildAddressSearch');}
        
         // load street information
        var txtStreet = $( this.getElementID( this.ElementIDs.SearchStreet ) );
        var street = txtStreet.attr("value");
        if( txtStreet.attr("value").toLowerCase() == txtStreet.attr("title").toLowerCase() ) {
            street = '';
        }
        
        // load suburb information
        var txtSuburb = $( this.getElementID( this.ElementIDs.SearchSuburb ) );
        var suburb = txtSuburb.attr("value");
        if( txtSuburb.attr("value").toLowerCase() == txtSuburb.attr("title").toLowerCase() ) {
            suburb = '';
        }
        
        // load postcode information
        var txtPostcode = $( this.getElementID( this.ElementIDs.SearchPostcode ) );
        var postcode = txtPostcode.attr("value");
        if( txtPostcode.attr("value").toLowerCase() == txtPostcode.attr("title").toLowerCase() ) {
            postcode = '';
        }
        
        // load selected state value
        var state = '';
        var ddlState = $( this.getElementID( this.ElementIDs.SearchState ) );
        if( ddlState.attr("selectedIndex") != 0 ) {
            state = ddlState.attr("value");
        }
        
        var address = new MapDS.Address(street, suburb, postcode, null, state);

        return address;

    },
    
    /// Builds a string representation of the search filters available.
    /// MUST return either an object or null. Last line should always be "return null;"
    /// instead of removing, return your object before this line.
    getSearchFiltersString: function() {
    
    return null;

    },
    
    
     setmapcentre: function( lat, lng)
           
   {
      //this.map.setCentre(new MapDS.LatLng(lat, lng), Locator.map.getZoom() );
            this.map.setCentre(new MapDS.LatLng(lat, lng), 16 );
   },
   
   refreshmap: function(cMW, cMH){
   var _SELF = this;

   var mW = $(_SELF.getElementID(_SELF.ElementIDs.Map)).width();
   var mH = $(_SELF.getElementID(_SELF.ElementIDs.Map)).height();

	     if(mW !== cMW || mH !== cMH ) {
		    currentMapWidth = mW;
		    currentMapHeight = mH;
		 }   
   }, 
    
    /// This method is called from within findNearest. The purpose of this function is to allow
    /// for control of how the marker is created and how the extra POI information is displayed.
    processPOI: function(id,poi) {
        if(this.DebugMode){Logger.debug(poi);}
        var _SELF = this;
      
        
        poi.position = new MapDS.LatLng(Number(poi.properties.Ref_Y), Number(poi.properties.Ref_X));
        
        var size = new MapDS.Size( 22, 33 );  
        var offset = new MapDS.Pixel( -11, -33 );  
        var icn = new MapDS.Maps.Icon( './images/markers/{0}.png'.format( id ), size, offset );          
        var mkr = new MapDS.Maps.Marker( poi.position, {icon:icn} );
          
        mkr.setPopupContent( '<div class="popup-content"><h6>{0}</h6><p>{1}</p><p>{2}{3}{4}{5}</p><p>{8}</p><p>{9}</p><p>{10}</p><p><a href="#" class="directions" onclick="Locator.getDirections({6});return false;">Get Directions</a> {11}</p></div>'.format( 
            (poi.properties.DisplayName?poi.properties.DisplayName:'undefined'),   
            ( ( poi.properties.Shop_Unit_No != '' && !_SELF.isUndefined( poi.properties.Shop_Unit_No ) ) ? poi.properties.Shop_Unit_No + ', ' : '' ),
            ( ( poi.properties.Street != '' && !_SELF.isUndefined( poi.properties.Street ) ) ? poi.properties.Street + ', ' : '' ), 
            ( ( poi.properties.Suburb != '' && !_SELF.isUndefined( poi.properties.Suburb ) ) ? poi.properties.Suburb + ', ' : '' ),
            ( ( poi.properties.Postcode != '' && !_SELF.isUndefined( poi.properties.Postcode ) ) ? poi.properties.Postcode + ', ' : '' ),
            poi.properties.State, id, (poi.properties.distance?_SELF.formatDistance(poi.properties.distance):''), 
            ( ( poi.properties.Phone1 != '' && !_SELF.isUndefined( poi.properties.Phone1 ) ) ? '<b>Phone:</b> ' + poi.properties.Phone1 + ' ' : '' ),
            ( ( poi.properties.Fax != '' && !_SELF.isUndefined( poi.properties.Fax ) ) ? '<b>Fax:</b> ' + poi.properties.Fax + ' ' : '') , 
            ( ( poi.properties.Email != '' && !_SELF.isUndefined( poi.properties.Email ) ) ? '<b>Email:</b> <a href="mailto:' + poi.properties.Email + '">' + poi.properties.Email + ' </a> ' : '' ),
            '<a href="javascript:Locator.setmapcentre(' + poi.position.Latitude() + ',' + poi.position.Longitude() + ');"> Zoom in</a>'
        ) );

        
        var listItem = $( '<li style="background: url(./images/markers/{0}.png) no-repeat 3px 3px;" />'.format( id ) ).html( '<span class="printAddressLineOne"><h6>{0}</h6><p>{1}</p><p>{2}{3}{4}{5}</p></span><p>{6}</p><p>{7}</p><p>{8}</p>'.format( 
                (poi.properties.DisplayName?poi.properties.DisplayName:'undefined'),
                ( ( poi.properties.Shop_Unit_No != '' && !_SELF.isUndefined( poi.properties.Shop_Unit_No ) ) ? poi.properties.Shop_Unit_No + ', ' : '' ),
                ( ( poi.properties.Street != '' && !_SELF.isUndefined( poi.properties.Street ) ) ? poi.properties.Street + ', ' : '' ), 
                ( ( poi.properties.Suburb != '' && !_SELF.isUndefined( poi.properties.Suburb ) ) ? poi.properties.Suburb + ', ' : '' ),
                ( ( poi.properties.Postcode != '' && !_SELF.isUndefined( poi.properties.Postcode ) ) ? poi.properties.Postcode + ', ' : '' ),
                poi.properties.State,
                ( ( poi.properties.Phone1 != '' && !_SELF.isUndefined( poi.properties.Phone1 ) ) ? '<b>Phone:</b> ' + poi.properties.Phone1 + ' ' : '' ),
                ( ( poi.properties.Fax != '' && !_SELF.isUndefined( poi.properties.Fax ) ) ? '<b>Fax:</b> ' + poi.properties.Fax + ' ' : '') , 
                ( ( poi.properties.Email != '' && !_SELF.isUndefined( poi.properties.Email ) ) ? '<b>Email:</b> <a href="mailto:' + poi.properties.Email + '">' + poi.properties.Email + ' </a> ' : '' )
            ) ).click( function() {
                    _SELF.map.setCentre( mkr.getPoint(), 16 );  
                    if(!$( _SELF.getElementID( _SELF.ElementIDs.POIsWrapper ) ).is(":hidden")) { _SELF.toggleDropdown(2); }
                    mkr.showPopup();
                }).appendTo( _SELF.getElementID( _SELF.ElementIDs.POIsList ) );

        $('<img src="./images/car.png" class="drivingLink" height="16px" width="16px" alt="Driving Directions" title="Driving Directions" />').click( function() {
            _SELF.getDirections(id);return false;
        }).appendTo( listItem );
        
       
        
        return mkr;
    },
    
    /// This method is called from within findNearest. The purpose of this function is to allow
    /// for control of how the searched location marker is created and how the extra information is displayed.
    processLocationPOI: function(poi, pt) {
        if(this.DebugMode){Logger.debug(poi);}
        
        var _SELF = this;
        var size = new MapDS.Size( 29, 36 );  
        var offset = new MapDS.Pixel( -3, -35 );
        var locicn =  new MapDS.Maps.Icon( './images/poi_home.png', size, offset);
        var searchLocation = ''; 
        var postalCode = '';
        poi.position = new MapDS.LatLng( pt.Latitude(), pt.Longitude() );
        
        
        var txtSuburb = $( this.getElementID( this.ElementIDs.SearchSuburb ) );
         if ((txtSuburb.attr("value").length > 10 && txtSuburb.attr("value").split(",").length - 1 == 2) ) {
                 searchLocation = ( ( poi.Locality != '' && !_SELF.isUndefined(poi.Locality ) ) ? poi.Locality() + ' ' : '' );
                 
            }else {  
                 searchLocation = ( ( poi.Locality != '' && !_SELF.isUndefined(poi.Locality ) ) ? poi.Locality + ' ' : '' ); 
                 postalCode =  poi.PostalCode;
            }
        
        
        
        var mkr = new MapDS.Maps.Marker( poi.position, {icon:locicn} );
        mkr.setPopupContent( '<div class="popup-content search-location"><h4>Your searched location</h4><p>{0}{1}{2}</p></div>'.format( 
                ( poi.AddressLine!='' ? poi.AddressLine() + ' ' : '' ), 
                ( searchLocation!='' ? searchLocation + ' ' : '' ),
                ( postalCode!='' ? postalCode + ' ' : '' )
 
            ) 
        );
        this.map.addOverlay( mkr );
        
        // DO NOT REMOVE THE FOLLOWING LINE - It is needed for routing purposes.
        this.locationMarker = mkr;
    }, 
     

    /// Start of core Locator code

    map: null, // object that contains the QuickMap instance
    geocoder: new MapDS.Maps.Geocoder(),
    directionsHelper: null,
    RouteMode: 1, // eventually this will be a setting that can change therefore it will move to the top of the script file.
    locationMarker: null,
    DebugMode: false,
    
    _foundLocations: null, // private
    _lastSearchedLocation: null, // private
    _pois: [], // private
    _lastFieldFocussed: null, // private, the last search field to have focus
    
    /// Returns true if object is undefined
    isUndefined: function(object) { return typeof object === "undefined"; },
    
    /// Private method
    /// Returns true if object is an Image
    /// IE doesn't support "instanceof Image" so instead we test that the object is in the DOM then test the tagName is 'IMG'
    isImage: function(object) { return this.isHTMLElement( object, 'IMG' ); },

    /// Returns true if object is an HTML Element
    /// {type} is a string that represents the type of HTML element that the object should be.
    ///      for example. if [type] is "div" then the element should be a div.
    isHTMLElement: function(object, type) { if ( !type || !( typeof type === "string" ) ) { return false; } if ( object && object.nodeType ) { return (object.tagName===type.toUpperCase() ? true : false); } return false; },
    
    /// Returns true if input is a number
    isNumeric: function(input) { return (input - 0) == input && input.length > 0; },
    
    /// Returns true if object is a function
    isFunction: function(object) { return typeof object === "function"; },
    
    /// Returns the id string asked for, will prepend # unless the second parameter is false.
    getElementID: function( id, withHash ) { if( this.isUndefined( withHash ) ) { withHash = true; } return ( withHash ? "#" : "" ) + id; },

    /// Will fire a call to load up the exception dialog, the HTML will be set using the message parameter.
    displayException: function( errorMessage ) { $( this.getElementID( this.ElementIDs.ExceptionDialog ) ).html( errorMessage ).dialog( 'open' ); },

    /// Will save a POI as the last location.
    saveLocationPOI: function(poi) { this._lastSearchedLocation = poi; },
    
    /// Formats a distance into a string representation.
    formatDistance: function(d) {
        d = parseInt(d,10);
        if(d<1000) { return d + ' metres'; }
        d = d / 1000;
        return d + ' kilometres';
    },

    /// Resets everything! 
    reset: function() {
        this._foundLocations = null;
        this._lastSearchedLocation = null;
        this.locationMarker = null;
        this._pois = [];
        this.resetDropdowns();
        if(this.map instanceof MapDS.Maps.Map){
            this.map.clearOverlays();
            this.map.setCentre( this.InitialCentre, this.InitialZoom );
        }
        // User defined method
        this.resetSearchFields();
    },
    
    /// Resets the content of the POIs and Direction dropdowns.
    resetDropdowns: function() {
        $( this.getElementID( this.ElementIDs.DrivingDirectionsList ) ).html('<p>Please perform a search.</p>');
        $( this.getElementID( this.ElementIDs.POIsFound ) ).html('');
        $( this.getElementID( this.ElementIDs.POIsList ) ).html('<p>Please perform a search.</p>');
        if(!$( this.getElementID( this.ElementIDs.DrivingDirectionsList ) ).is(":hidden")) { this.toggleDropdown(3); }
        if(!$( this.getElementID( this.ElementIDs.POIsWrapper ) ).is(":hidden")) { this.toggleDropdown(2); }
        if(!$( this.getElementID( this.ElementIDs.FiltersList ) ).is(":hidden")) { this.toggleDropdown(1); }
    },
    
    /// Performs a call to geocode in order to geocode an address. 
    findAddress: function() {
        if(!this.validateSearchFields()) {return;}
        
        // lock down the find button
//        $( this.getElementID( this.ElementIDs.SearchButton ) ).attr('disabled', 'true');
        
        var _SELF = this;
        
        
        
//        $( this.getElementID( this.ElementIDs.SearchButton ) ).attr('enabled', 'true');
                
         var txtSuburb = $( this.getElementID( this.ElementIDs.SearchSuburb ) );
        
        //check autocomplete option has been selected
            if ((txtSuburb.attr("value").length > 10 && txtSuburb.attr("value").split(",").length - 1 == 2) ) {
               address = this.buildAddressSearch();
                this.findNearest(address);
               }else {
                this.geocode(this.buildAddressSearch(), function(address){_SELF.findNearest(address);}  );
                
                }
    },
    
    /// Performs a call to Geocode an address. If a single match is found then the method 
    /// will automatically call findNearest. Multiple matches are displayed within a 
    /// dialog for the user to select.
    geocode: function(addressToGeocode, loadAddressCallBack) {
        if(this.DebugMode){Logger.info('geocode');}
        
        // make jQuery Ajax call...
        var _SELF = this;
        _SELF.geocoder.getLocations(addressToGeocode, function(result) {
            if(this.DebugMode){Logger.log(result);}

            if (result.Code === 1) {
                loadAddressCallBack(result.Locations[0]);
            } else if (result.Code === 100) {
                _SELF._foundLocations = result.Locations;

                $(_SELF.getElementID(_SELF.ElementIDs.MultipleAddressDialog)).find(
                        _SELF.getElementID(_SELF.ElementIDs.MultipleAddresses)).html('');

                $("<option/>").attr('value', '0').html(_SELF.Strings.MultipleAddressPrompt).appendTo(
                        $(_SELF.getElementID(_SELF.ElementIDs.MultipleAddressDialog)).find(
                        _SELF.getElementID(_SELF.ElementIDs.MultipleAddresses)));

                $.each(result.Locations, function(i, address) {
                    $("<option/>").html((address.AddressLine != '' ? address.AddressLine + ', ' : '') +
                        address.Locality + ', ' + address.Region + ', ' + address.PostalCode).appendTo(
                        $(_SELF.getElementID(_SELF.ElementIDs.MultipleAddressDialog)).find(
                        _SELF.getElementID(_SELF.ElementIDs.MultipleAddresses)));
                });

                $(_SELF.getElementID(_SELF.ElementIDs.MultipleAddressDialog)).dialog('open');
                
            } else if (result.Code === 110) {
            
                 _SELF.displayException("We were unable to find the location specified. Please try new information");
                
                
            } else if (result.Code > 100) {
                _SELF.displayException(result.Message);
            }

        });
    },
    
    /// Calls findnearest.ashx passing X/Y and search filters. Results are displayed.
    findNearest: function(address) {
        
        var _SELF = this;
            var txtSuburb = $( this.getElementID( this.ElementIDs.SearchSuburb ) );
        
            if ((txtSuburb.attr("value").length > 10 && txtSuburb.attr("value").split(",").length - 1 == 2) ) {
                var coords = $("#coords").val().split(",");
                var pt = new MapDS.LatLng(Number(coords[0]), Number(coords[1])); 

            }else {
                 var pt = new MapDS.LatLng( address.Position.Latitude, address.Position.Longitude );
            
        }
        //get this from the hidden field which is populated when an item selected from autocomplete
   
       var featuresClient = new MapDS.Features.ServiceClient();
       
       
       
       var p = new MapDS.Features.PointsQuery(pt, { buffer: _SELF.PoiSearchBuffer, items: _SELF.PoiSearchRecordLimit, sortby: "distance"});
       featuresClient.getFeatures(p, "GEMONEYBRANCHES", function(results) {
            
            // TODO: handle any errors from the service
       if  ( results.features.length<1){          
                 $(_SELF.getElementID(_SELF.ElementIDs.NoResultDialog)).dialog('open');      
       } else { 
            
            _SELF._pois=[];
            _SELF.resetDropdowns();
            _SELF.map.clearOverlays();
            
            
            // build the search caption
            var searchedAddress = new String( 
                ( address.Locality!='' ? address.Locality + ', ' : '' ) + 
                ( address.Region!='' ? address.Region + ', ' : '' ) + 
                ( address.PostalCode!='' ? address.PostalCode + ', ' : '' ) 
            );
            searchedAddress = searchedAddress.substr( 0, searchedAddress.lastIndexOf( ', ' ) );
                        
            if ( results.features.length > 0 ) {
                $( _SELF.getElementID( _SELF.ElementIDs.DrivingDirectionsList ) ).html(' ');
                $( _SELF.getElementID(_SELF.ElementIDs.DirectionsButton)).css({'display':'none'} ); 
                $( _SELF.getElementID( _SELF.ElementIDs.POIsList ) ).html('');
                
                
                $.each(results.features, function(i,poi){
                

                    
                    var id = i+1;
                    poi.Marker = _SELF.processPOI( id, poi )
                    _SELF._pois.push( poi );
                    _SELF.map.addOverlay( poi.Marker );
                });
                
                Logger.log (address);
                
                _SELF.processLocationPOI( address, pt );
                
                Logger.log (address);
                _SELF.saveLocationPOI( address );
                
                }
                if($( _SELF.getElementID( _SELF.ElementIDs.POIsWrapper ) ).is(":hidden")) { _SELF.toggleDropdown(2); $(_SELF.getElementID(_SELF.ElementIDs.POIsButton)).css({'display':'inline-block', 'height' : '20px'} ); $(_SELF.getElementID(_SELF.ElementIDs.ResultsButton)).css({'display':'inline-block', 'height' : '10px'} );}      
  
            }    
        });
    },
    
    /// Gets a string summary representation of the selected filters.
    getFriendlySearchFiltersString: function() {

        // the following return should always remain and be the last line.
        return '';
    },
    
    /// Executes a request for driving directions for the given POI id.
    getDirections: function(id) {
        var _SELF = this;
         
        if(_SELF.map.hasVisiblePopup()) {_SELF.map.removePopups();}
        
        if ( ! _SELF.isUndefined( _SELF._pois ) && _SELF._pois.length >= id ) {
            id -= 1; // decrement to get array position
            _SELF.directionsHelper.clear();
            
            var stSuburb = '';
            var stPostcode = '';
            var st = _SELF._lastSearchedLocation.position;
            var ed = ( _SELF._pois[id].position instanceof MapDS.LatLng ? _SELF._pois[id].position : new MapDS.LatLng( _SELF._pois[id].Position.Latitude, _SELF._pois[id].Position.Longitude ) );
            
            
            
            if ( this.RouteMode === 1 ) {
             var stTitle = $( _SELF.getElementID( _SELF.ElementIDs.StartTitle ) );
             var stAddress =  ( ( _SELF._lastSearchedLocation.AddressLine != '' && !_SELF.isUndefined(_SELF._lastSearchedLocation.AddressLine  ) ) ? _SELF._lastSearchedLocation.AddressLine() + ', ' : '' );
                
            var txtSuburb = $( this.getElementID( this.ElementIDs.SearchSuburb ) );
            if ((txtSuburb.attr("value").length > 10 && txtSuburb.attr("value").split(",").length - 1 == 2) ) {
                 stSuburb = ( ( _SELF._lastSearchedLocation.Locality != '' && !_SELF.isUndefined(_SELF._lastSearchedLocation.Locality  ) ) ? _SELF._lastSearchedLocation.Locality() + ' ' : '' );
            }else {  
                 stSuburb = ( ( _SELF._lastSearchedLocation.Locality != '' && !_SELF.isUndefined(_SELF._lastSearchedLocation.Locality  ) ) ? _SELF._lastSearchedLocation.Locality + ' ' : '' ); 
                 stPostcode =  ( ( _SELF._lastSearchedLocation.PostalCode != '' && !_SELF.isUndefined(_SELF._lastSearchedLocation.PostalCode  ) ) ? _SELF._lastSearchedLocation.PostalCode + ' ' : '' ); 
            }
                
                
               
            stTitle.html ( $( '<h4 />'.format( id ) ).html( 'Start: {0}{1}{2}'.format( 
              stAddress,
              stSuburb,
              stPostcode   
            ) )); 
                
            var edTitle = $( _SELF.getElementID( _SELF.ElementIDs.EndTitle ) );
             edTitle.html ( $( '<h4 />'.format( id ) ).html( 'End: {0}{1}{2}{3}{4}'.format( 
                ( ( _SELF._pois[id].properties.DisplayName != '' && !_SELF.isUndefined(_SELF._pois[id].properties.DisplayName  ) ) ? _SELF._pois[id].properties.DisplayName + ', ' : '' ),
                ( (_SELF._pois[id].properties.Street != '' && !_SELF.isUndefined(_SELF._pois[id].properties.Street  ) ) ? _SELF._pois[id].properties.Street + ', ' : '' ),
                ( ( _SELF._pois[id].properties.Suburb != '' && !_SELF.isUndefined( _SELF._pois[id].properties.Suburb  ) ) ?  _SELF._pois[id].properties.Suburb + ', ' : '' ),
                ( (  _SELF._pois[id].properties.Postcode != '' && !_SELF.isUndefined(_SELF._pois[id].properties.Postcode  ) ) ? _SELF._pois[id].properties.Postcode + ', ' : '' ),
                ( (  _SELF._pois[id].properties.State != '' && !_SELF.isUndefined(_SELF._pois[id].properties.State  ) ) ? _SELF._pois[id].properties.State + ', ' : '' )
            ) ));
                      
                var dd = $( _SELF.getElementID( _SELF.ElementIDs.DrivingDirectionsList ) );
                dd.html('<p><img src="./images/loading-circle-black.gif" alt="Loading" height="16px" width="16px" /> Loading</p>');
                _SELF.directionsHelper.buildFromWaypoints([ st, ed ]);
                if(dd.is(":hidden")) { _SELF.toggleDropdown(3); }                                      
            }
        }
    },
    
  
    /// Toggles the directions dropdown
    toggleDropdown: function(dropDown) {
        var _SELF = this;
        var A = null;
        var B = null;
        if(dropDown===1) {
            // Filters
            if(!$( _SELF.getElementID( _SELF.ElementIDs.DrivingDirectionsList ) ).is(":hidden")) { _SELF.toggleDropdown(3); }
            if(!$( _SELF.getElementID( _SELF.ElementIDs.POIsWrapper ) ).is(":hidden")) { _SELF.toggleDropdown(2); }
            A = $( _SELF.getElementID( _SELF.ElementIDs.FiltersList ) );
		    B = $( _SELF.getElementID( _SELF.ElementIDs.FiltersButton ) );
        } else if(dropDown===2) {
            // POIs
            if(!$( _SELF.getElementID( _SELF.ElementIDs.DrivingDirectionsList ) ).is(":hidden")) { _SELF.toggleDropdown(3); }
            if(!$( _SELF.getElementID( _SELF.ElementIDs.FiltersList ) ).is(":hidden")) { _SELF.toggleDropdown(1); }
            A = $( _SELF.getElementID( _SELF.ElementIDs.POIsWrapper ) );
		    B = $( _SELF.getElementID( _SELF.ElementIDs.POIsButton ) );
		        $(_SELF.getElementID(_SELF.ElementIDs.POIsButton)).css({'display':'inline-block'} );    
		        $( _SELF.getElementID( _SELF.ElementIDs.Map ) ).toggleClass('mapResultsOpen');
        } else if(dropDown===3) {
            // Directions
            if(!$( _SELF.getElementID( _SELF.ElementIDs.POIsWrapper ) ).is(":hidden")) { _SELF.toggleDropdown(2); }
            if(!$( _SELF.getElementID( _SELF.ElementIDs.FiltersList ) ).is(":hidden")) { _SELF.toggleDropdown(1); }
            A = $( _SELF.getElementID( _SELF.ElementIDs.DrivingDirectionsList ) );
		    B = $( _SELF.getElementID( _SELF.ElementIDs.DirectionsButton ) ); 
		        $( _SELF.getElementID(_SELF.ElementIDs.DirectionsButton)).css({'display':'inline-block'} ); 
		        $( _SELF.getElementID( _SELF.ElementIDs.StartTitle ) ).toggleClass('menu-open');
		        $( _SELF.getElementID( _SELF.ElementIDs.EndTitle ) ).toggleClass('menu-open'); 
		        $( _SELF.getElementID( _SELF.ElementIDs.Map ) ).toggleClass('mapResultsOpen');  
		                     
        }
        if(!A || !B) {return;}
          
        var currentMapWidth = $(_SELF.getElementID(_SELF.ElementIDs.Map)).width();
        var currentMapHeight = $(_SELF.getElementID(_SELF.ElementIDs.Map)).height();
		var C = B.offset();
		A.css();
		B.toggleClass("menu-open");A.toggle();
		_SELF.refreshmap(currentMapWidth, currentMapHeight  );
		_SELF.map.loadBestView(null,true);	
    },
    
    
    PrinterFriendly: function(){
        var _SELF = this;  
        var newWin;
        newWin =window.open("PrintPage.aspx","kid",'resizable=yes,menubar=1,toolbar=1,scrollbars=yes,width=900,height=650,toolbar=no');    
    },

    /// This method is hooked into the window.onload within the init method.
    initMap: function( lat, lng, zoom ) {
        this.map = new MapDS.Maps.Map( this.getElementID( this.ElementIDs.Map, false ), { zoom:this.InitialZoom, centre:this.InitialCentre } );
        this.directionsHelper = new MapDS.Maps.Directions( this.map, ( this.ElementIDs.DrivingDirectionsList ? document.getElementById( this.ElementIDs.DrivingDirectionsList ) : null ) );
   
    },
    
    /// The main initialisation method for the Locator object.
    init: function() {
        var _SELF = this;
        $().ready(function() {
            
            
            // Grab all anchor elements on the page that have an href and target is external. Set their target to blank.
            $( 'a[rel="external"]' ).filter( '[href!=""]' ).each( function() { this.target = "_blank"; } );
            
            $( _SELF.getElementID( _SELF.ElementIDs.SearchButton ) ).click( function() { _SELF.findAddress(); });
            $( _SELF.getElementID( _SELF.ElementIDs.ApplyFiltersButton ) ).click( function() { _SELF.findAddress(); });
            $( _SELF.getElementID( _SELF.ElementIDs.ResetButton ) ).click( function() { _SELF.reset(); });
            $( _SELF.getElementID( _SELF.ElementIDs.DirectionsButton ) ).click(function(){ _SELF.toggleDropdown(3); });
            $( _SELF.getElementID( _SELF.ElementIDs.POIsButton ) ).click(function(){ _SELF.toggleDropdown(2); });
            $( _SELF.getElementID( _SELF.ElementIDs.FiltersButton ) ).click(function(){ _SELF.toggleDropdown(1); });
            
            // need to have the current text blanked on focus, reset on blur...
            $( _SELF.getElementID( _SELF.ElementIDs.Search ) + ' input[title!=""]').keypress( function(evt) { _SELF._lastFieldFocussed = this; if (evt.keyCode == 13 ) { $( _SELF.getElementID( _SELF.ElementIDs.SearchButton ) ).click(); } }).hint();
            // ensure that Enter presses on the form don't cause a submit
            $( "form" ).keypress( function(e) { if (e.keyCode == 13) { return false; } });
            
            // attach the exception dialog
            $( _SELF.getElementID( _SELF.ElementIDs.ExceptionDialog ) ).dialog({
                bgiframe: true,
                modal: true,
                draggable: false,
                resizable: false,
                autoOpen: false,
                zIndex: 99999,
                close: function( evt, ui ) {
                        if( _SELF._lastFieldFocussed ) {
                            _SELF._lastFieldFocussed.focus();
                        }
                    },
                buttons: {OK: function() { $(this).dialog('close'); }}
            });
            
            
            // attach the No Locations dialog
            $( _SELF.getElementID( _SELF.ElementIDs.NoResultDialog ) ).dialog({
                bgiframe: true,
                modal: true,
                draggable: false,
                resizable: false,
                autoOpen: false,
                zIndex: 99999,
                close: function( evt, ui ) {
                        if( _SELF._lastFieldFocussed ) {
                            _SELF._lastFieldFocussed.focus();
                        }
                    },
                buttons: {OK: function() { $(this).dialog('close'); }}
            });
            
            // attach the multiple results dialog.
		    $( _SELF.getElementID( _SELF.ElementIDs.MultipleAddressDialog ) ).dialog({
			    bgiframe: true,
			    height: 300,
			    width: 400,
			    modal: true,
                draggable: false,
                resizable: false,
                autoOpen: false,
                zIndex: 99999,
			    buttons: {
				    'Use Address': function() {
                        var idx = $(this).find( _SELF.getElementID( _SELF.ElementIDs.MultipleAddresses ) ).attr('selectedIndex');
                        if (idx!=0) {
                            // go back one to get correct array location.
                            idx--;
                            // Call FindNearest....
                            _SELF.findNearest(_SELF._foundLocations[idx]);
                        }
					    $(this).dialog('close');
				    },
				    Cancel: function() { $(this).dialog('close'); }
			    }
		    });
		    
		    
		    // handle the resizing of the browser window.
		    var currentMapWidth = $(_SELF.getElementID(_SELF.ElementIDs.Map)).width();
		    var currentMapHeight = $(_SELF.getElementID(_SELF.ElementIDs.Map)).height();
            $(window).wresize(function() {
                /*var w = $( window );
                var H = w.height();
                var W = w.width();*/
		        var mW = $(_SELF.getElementID(_SELF.ElementIDs.Map)).width();
		        var mH = $(_SELF.getElementID(_SELF.ElementIDs.Map)).height();
		        if(mW !== currentMapWidth || mH !== currentMapHeight) {
		            currentMapWidth = mW;
		            currentMapHeight = mH;
                    if (_SELF.map instanceof MapDS.Maps.Map) {
                        _SELF.map.setCentre(_SELF.map.getCentre(), _SELF.map.getZoom(), true);
                    }
                }
            });
		    
		    _SELF.reset();
		    
            // need to wrap the call in a function so we can maintain scope
            window.onload = function() { _SELF.initMap.apply(_SELF);
              
                       window.locationCoords = [];


//                    Change to this url when live:
                   $('#txtSuburb').autocomplete('http://data.nowwhere.com.au/features/features.svc/AutoCompleteSuburbsAU0911.json?key=i6fWYdQkvsBIbnIinfyJRDstt3UpGY3YlyuokQeA', { minChars: 3, width: 262, parseMethod: function(jsondata) {
                


                        var suburbPostcode;
                        if (jsondata.features && jsondata.features.length && jsondata.features[0].properties) {
                            for (i = 0; i < jsondata.features.length; i++) {
                                            
                                if (jsondata.features[i].properties.DisplayName) {
                                    suburbPostcode = suburbPostcode + "\n" + jsondata.features[i].properties.DisplayName;
                                    if (jsondata.features[i].geometry.coordinates) {
//                                        $("#coords").data(jsondata.features[i].properties.DisplayName, jsondata.features[i].geometry.coordinates);
                                        window.locationCoords.push([jsondata.features[i].properties.DisplayName, jsondata.features[i].geometry.coordinates]);
//                                         var coords = $("#coords").val();
  
                                    
                                    }
                                }
                            }
                            suburbPostcode = suburbPostcode.replace('undefined', '');
                            suburbPostcode = suburbPostcode.replace(/^(\s*)/, "\n");
                        }

                        return suburbPostcode;
                    }
                    });   
            
             };
            
            
        });
    }
    
};
Locator.init();
