﻿

var _developmentMap = null;

var DevelopmentMap = Class.create();

DevelopmentMap.prototype = {
    ///<summary>
    /// A helper object to render a basic google map for Developments.
    /// The Map will center on development by address and provides the ability to get
    /// directions to that development from a starting postcode.
    //</summary>

    // ID of the map element
    mapElementID : null,
    
    // ID of the derections element
    directionsElementID : null,
        
    // map object
    map : null,
    
    // geo-coder object
    geoCoder : null,

    //
    startAddress : null,

    // development street address (i.e. 10 Some Road)
    _streetAddress : null,
    
    // development city name
    _city : null,
    
    // development postcode
    _postcode : null,
    
    // development lat
    _lat : null,
    
    // development lng
    _lng : null,
    
    // complete development address
    address : null,
    
    // gmap development point
    developmentPoint : null,
    
    // directions object
    directions : null,
        
    // default center lat (Edinburgh-ish)
    centerLat : 55.9584,
    
    // default center lng (Edinburgh-ish)
    centerLng : -3.19702,
    
    // default zoom level
    zoom : 13,
    
    // geo-coder retry delay
    delay : 100,
    
    // enable map dragging 
    enableDrag : true,
    
    // enable map info window
    enableInfoWindow : true,
    
    // enable double click zooming
    enableDoubleClickZoom : true,
        
    // enable scroll wheel zooming
    enableScrollWheelZoom : true,
    
    // google maps not compatible with browser message
    notCompatibleMessage : "Sorry, the Google Maps API is not compatible with this browser",
    
    // address search address not found message
    addressNotFoundMessage : "Development address not found",
    
    // directions, no start address
    noStartAddress : "No address supplied",
    
    // collection of geo-coder failure result codes (currently not implemented)
    geoCoderReasons : [],
    
    // current development icon
    currentIcon : null,
    
    // current development icon graphic
    currentIconImage: '/Miller.HomesWeb/img/GIcons/current_icon1.png',
    currentIconImage_IE: '/Miller.HomesWeb/img/GIcons/current_icon1.gif',
    
    // current icon shadow
    currentIconImageShadow : '/Miller.HomesWeb/img/GIcons/shadow1.png',
    
    // future development icon
    futureIcon : null,
    
    // future development icon graphic
    futureIconImage: '/Miller.HomesWeb/img/GIcons/future_icon1.png',
    futureIconImage_IE: '/Miller.HomesWeb/img/GIcons/future_icon1.gif',
    
    // future icon shadow
    futureIconImageShadow : '/Miller.HomesWeb/img/GIcons/shadow1.png',
    
    
    initialize: function(elMap, elDirections) {
        ///<summary>Object initialiser</summary>
        this.mapElementID = elMap;
        this.directionsElementID = elDirections;
        _developmentMap = this;
        this._initIcons();
        this.geoCoder = new GClientGeocoder();
        this._loadGeoCoderReasons();
        
        document.getElementById(elDirections).innerHTML = '';
    },

    is_ie6: function() {
        return (navigator.userAgent.toLowerCase().indexOf('msie 6') != -1);
    },
    
    _loadGeoCoderReasons : function() {
        ///<summary>Load the GeoCoder message array</summary>
        this.geoCoderReasons[G_GEO_SUCCESS]            = "Success";
        this.geoCoderReasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
        this.geoCoderReasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
        this.geoCoderReasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
        this.geoCoderReasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
        this.geoCoderReasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
        this.geoCoderReasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
        this.geoCoderReasons[403]                      = "Error 403: Probably an incorrect error caused by a bug in the handling of invalid JSON.";
    },
    
    _initIcons : function() {
        ///<summary>Initialise icons</summary>
        ///<remarks>Internal method</remarks>

        var baseIcon = new GIcon();

        baseIcon.iconSize = new GSize(28, 28);
        
        if (this.is_ie6())
            baseIcon.shadowSize = null;
        else
            baseIcon.shadowSize = new GSize(36, 36);
            
        baseIcon.iconAnchor=new GPoint(12,16);
        baseIcon.infoWindowAnchor=new GPoint(8,4);   
        
        // create the current icon based on the base icon properties
        this.currentIcon = new GIcon(baseIcon);
        if (this.is_ie6())
            this.currentIcon.image = this.currentIconImage_IE;
        else
            this.currentIcon.image = this.currentIconImage;
        if (this.is_ie6())
            this.currentIcon.shadow = null;
        else
            this.currentIcon.shadow = this.currentIconImageShadow;
        
        // create the future icon based on the base icon properties
        this.futureIcon = new GIcon(baseIcon);
        if (this.is_ie6())
            this.futureIcon.image = this.futureIconImage_IE;
        else
            this.futureIcon.image = this.futureIconImage;

        if (this.is_ie6())
            this.futureIcon.shadow = null;
        else
            this.futureIcon.shadow = this.futureIconImageShadow;
        
    },
    
    load : function(lat, lng) {
        ///<summary>Load the google map for a development at a specified address</summary>
        ///<param name="streetAddr">(Optional) Development house number and street name</param>
        ///<param name="city">(Optional) Development city name</param>
        ///<param name="postcode">(Required) Development postcode</param>
        
        if(!this.mapElementID)
            throw "Map element ID not specified";
        
        if (GBrowserIsCompatible()) {                            
        
            // init map
            this.map = new GMap2(document.getElementById(this.mapElementID));
            
            // prep for directions
            this.directions = new GDirections(this.map, document.getElementById(this.directionsElementID));
            GEvent.addListener(this.directions, 'load', this.onDirectionsLoaded);
            GEvent.addListener(this.directions, 'error', this.onDirectionsError);
            
            // pan\zoom control
            this.map.addControl(new GLargeMapControl());
            
            if(!this.enableDrag)
                this.map.disableDragging();
                
            if(!this.enableInfoWindow)
                this.map.disableInfoWindow()
                
            if(!this.enableDoubleClickZoom)
                this.map.enableDoubleClickZoom()
                
            if(this.enableScrollWheelZoom)
                this.map.enableScrollWheelZoom();
                                
            // plot point on map
            this._lat = lat;
            this._lng = lng;
                       
            var point = new GLatLng(lat,lng);
            
            var marker = new GMarker(point,_developmentMap.currentIcon);
            
            _developmentMap.map.setCenter(point, _developmentMap.zoom);
            _developmentMap.map.addOverlay( marker );
            _developmentMap.developmentPoint = point;
            
        } else {
            alert(notCompatibleMessage);
        }
    },
    
    
    getDirections : function(startAddress) {
        ///<summary>Get directions from a start address to the marked development</summary>
        ///<param name="startAddress">The address to create directions from</summary>
        
        if(startAddress == null) {
            // alert(this.noStartAddress);
        } else {
        
            this.startAddress = startAddress;
        
            document.getElementById(elAddr).value = this.startAddress;
                
            this.directions.load("from: " + startAddress + " to: " + this.developmentPoint.lat() + ',' + this.developmentPoint.lng(),{ "locale": "en_GB" });
        }
    },
    
    onDirectionsLoaded : function() {
        ///<summary>Return method</summary>
        // loaded succesfuly - nothing to do
    },
    
    onDirectionsError : function() {
        ///<summary>Directions error handler<summary>
        
        // ensure the start address ends with ',UK' and try again
        if(_developmentMap.startAddress.indexOf(',UK') < 1) {
        
            _developmentMap.startAddress += ',UK';
            _developmentMap.getDirections(_developmentMap.startAddress);
            
        } else {
        
           if (_developmentMap.directions.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
	         alert('Address unknown error');
    	     
	       else if (_developmentMap.directions.getStatus().code == G_GEO_SERVER_ERROR)
	         alert('Geo server error');
    	   
	       else if (_developmentMap.directions.getStatus().code == G_GEO_MISSING_QUERY)
	         alert('Bad query error');

	       else if (_developmentMap.directions.getStatus().code == G_GEO_BAD_REQUEST)
	         alert('Bad request error');
    	    
	       else 
	        alert("An unknown error occurred.");
	    }
    }
       
};

