﻿// Create our "house" marker icon
var HOUSE_ICON = {};
HOUSE_ICON.image = _appPath + "/images/map_house.gif";
HOUSE_ICON.size = {width:32, height:31};
HOUSE_ICON.iconAnchor = new Microsoft.Maps.Point(16, 15);
HOUSE_ICON.infoWindowAnchor = new Microsoft.Maps.Point(16, 1);

// numbered house icons
var HOUSE_ICONS = [];
for(var i=1;i<=20;i++){
    HOUSE_ICONS[i] = {};
    HOUSE_ICONS[i].image = _appPath + "/images/search/map_house" +i.toString() + ".gif";
    HOUSE_ICONS[i].size = {width:32, height:31};
    HOUSE_ICONS[i].iconAnchor = new Microsoft.Maps.Point(15, 30);
    HOUSE_ICONS[i].infoWindowAnchor = new Microsoft.Maps.Point(16, 1);
}
// MiniHouse Icon
var MINIHOUSE_ICON = {};
MINIHOUSE_ICON.image = _appPath + "/images/mapIcons/markerdiamond.png";
MINIHOUSE_ICON.size = {width:11, height:11};
MINIHOUSE_ICON.iconAnchor = new Microsoft.Maps.Point(5, 5);
MINIHOUSE_ICON.infoWindowAnchor = new Microsoft.Maps.Point(5, 5);

// city icon
var CITY_ICON = {};
CITY_ICON.image = _appPath + "/images/search/cityhouses.gif";
CITY_ICON.size = {width:26, height:24};
CITY_ICON.iconAnchor = new Microsoft.Maps.Point(13, 12);
CITY_ICON.infoWindowAnchor = new Microsoft.Maps.Point(13, 0);

// numbered icons
var NUMBERED_ICONS = [];
for(var i=1;i<=99;i++){
    NUMBERED_ICONS[i] = {};
    NUMBERED_ICONS[i].image = _appPath + '/images/mapIcons/marker' + i.toString() + '.png';
    NUMBERED_ICONS[i].size = {width:20, height:34};
    NUMBERED_ICONS[i].iconAnchor = new Microsoft.Maps.Point(10, 32);
    NUMBERED_ICONS[i].infoWindowAnchor = new Microsoft.Maps.Point(10, 0);
}
// Amenity Icon
var AMENITY_ICON = {};
AMENITY_ICON.image = _appPath + "/images/mapIcons/bluesquare.png";
AMENITY_ICON.size = {width:9, height:9};
AMENITY_ICON.iconAnchor = new Microsoft.Maps.Point(5, 5);
AMENITY_ICON.infoWindowAnchor = new Microsoft.Maps.Point(5, 5);

// Building Icon
var BUILDING_ICON = {};
BUILDING_ICON.image = _appPath + "/images/mapIcons/building.png";
BUILDING_ICON.size = {width:9, height:19};
BUILDING_ICON.iconAnchor = new Microsoft.Maps.Point(5, 5);
BUILDING_ICON.infoWindowAnchor = new Microsoft.Maps.Point(19, 5);
/*
 options 
 containerId - id of the container
 centerLat - latitude for the center of the map
 centerLng - longitude for the center of the map
 zoom - start zoom for the map
 showControls - boolean to display a map with no overlay controls
*/
function WDCMap(containerId, centerLat, centerLng, zoom, controlType){

    this.container = null;
    this.layer = null;   
    this.map = null;   
    this.wait = null;
    this.popup = null;
    this.popupBody = null;
    this.popupOffset = 0;
    this.mapOffset;
    //initialize the control
    this.origLatLong = new Microsoft.Maps.Location(centerLat,centerLng);
    this.origzoom = zoom;
    this.mapMoveCallbacks = [];
    this.tooltipText = null;
    this.tooltip = null;
    
    this.markers = {};
    
    this.mapTypeControl = null;
    this.mapControls = null;
    this.mapControlType = controlType;
    
    this.enableMapMoveCallback = true;
    this.oneTimeMapMoveCallback = null;
    
    //used for png fix
    this.isIE6 = (navigator.userAgent.toLowerCase().indexOf("msie 6.") != -1);
    
    this.init(containerId, centerLat, centerLng, zoom);
    __maps.push(this);
}

WDCMap.prototype.init = function (mapid, latitude, longitude, zoom) {
    var oThis = this;
    this.container = document.getElementById(mapid);
   
    this.layer = document.createElement("div");
    this.layer.id = "map_" + mapid
    this.layer.style.position = "absolute";
    this.layer.style.width = this.container.offsetWidth + 'px';
    this.layer.style.height = this.container.offsetHeight + 'px'; 
    this.container.appendChild(this.layer);
    
    this.tooltip = document.createElement('div');
    this.tooltip.style.position = 'absolute';
    this.tooltip.style.visibility = 'hidden';
    this.tooltip.style.zIndex = 10000;
    this.tooltip.className = 'mapTooltip';
    var tooltipBg = document.createElement('div');
    tooltipBg.className = 'mapTooltipBg';
    this.tooltip.appendChild(tooltipBg);
    this.tooltipText = document.createElement('p');
    this.tooltipText.className = 'mapTooltipText';
    this.tooltip.appendChild(this.tooltipText);
    document.body.appendChild(this.tooltip);
    
    this.popup = createTag('div', {'id': mapid + 'popup', 'class':'mapInfoBox mapInfoBox-left', 'style' : 'visibility:hidden;'});
    var popupContainer = createTag('div', {'class':'container'});
    this.popup.appendChild(popupContainer);
    var popupClose = createTag('div', {'class':'close'});
    popupClose.onclick = function(){oThis.hideMarkerPopup();};
    var popupMain = createTag('div', {'class':'main'});
    this.popupBody = createTag('div', {'id' : mapid + '_popup_body', 'class':'body'});
    popupContainer.appendChild(this.popupBody);
    popupContainer.appendChild(popupClose);
    popupContainer.appendChild(popupMain);
    popupContainer.appendChild(createTag('div', {'class':'shadow'}));
    var beak = createTag('div', {'class':'beak'})
    popupContainer.appendChild(beak);
    popupContainer.appendChild(createTag('div', {'class':'beakShadow'}));
    document.body.appendChild(this.popup);  
    this.popupOffset = Math.abs(popupContainer.offsetLeft) + beak.offsetWidth/2;

    //create the wait div and assign styles
    this.wait = document.createElement("div");
    this.wait.className = "wait";
    this.wait.style.visibility = "hidden";
    this.wait.style.width = this.layer.offsetWidth + 'px';
    this.wait.style.height = this.layer.offsetHeight + 'px'; 
    var strMsg;
    strMsg = "<table border='0' cellpadding='0' cellspacing='0' align='center' height='100%'>";
    strMsg += "<tr valign='center'><td align='center'>";
    strMsg += "<div><img src='" + _appPath + "/images/loading.gif' />&nbsp;&nbsp;<b>Please Wait...</b></div></td></tr></table>";
    this.wait.innerHTML = strMsg;
    this.container.appendChild(this.wait);

    this.showWait();

    var options = {
                    credentials:__key,
                    enableClickableLogo: false,
                    enableSearchLogo: false,
                    showCopyright: false,
                    showScalebar: false,
                    showDashboard: true
                  };
    
    if(this.mapControlType == "small" || this.mapControlType == "tiny" || this.mapControlType == "none")
    {
        options.showDashboard = false;
    }
    
    this.map = new Microsoft.Maps.Map(document.getElementById(this.layer.id), options);
    this.map.setView({center: new Microsoft.Maps.Location(latitude, longitude), zoom : zoom, mapTypeId: Microsoft.Maps.MapTypeId.road });
    this.setMapType(getCookie("searchMapType"));
    Microsoft.Maps.Events.addHandler(this.map, "viewchangeend",function(e) {
        oThis.doMapMoveCallback();
    });
    
    Microsoft.Maps.Events.addHandler(this.map, "maptypechanged",function() {
        var type = oThis.getMapType();
        setCookie("searchMapType", oThis.getMapType(), null, '/');
    });
    
    Microsoft.Maps.Events.addHandler(this.map, "mousemove",function(e) {
                                        oThis.tooltip.style.left = (e.pageX -(oThis.tooltip.offsetWidth/2)+5).toString() + 'px';
                                        oThis.tooltip.style.top = (e.pageY -oThis.tooltip.offsetHeight-10).toString() + 'px';
    });

    Microsoft.Maps.Events.addHandler(this.map, "viewchangestart", function(e) { 
                                        oThis.hideMarkerPopup();
                                    });
    Microsoft.Maps.Events.addHandler(this.map, "viewchangeend", function(e) { 
                                        oThis.mapOffset = findPos(oThis.container);
                                    });
//    Microsoft.Maps.Events.addHandler(this.map, "onresize", function(e) { 
//        oThis.mapOffset = findPos(oThis.container);
//        oThis.hideMarkerPopup();
//    });

    //disable mousewheel zoom
    Microsoft.Maps.Events.addHandler(this.map, 'mousewheel', function(e) {
        e.handled = true;
    });


    addEvent(window,'resize',function(){oThis.mapOffset = findPos(oThis.container);oThis.hideMarkerPopup();});
    this.mapOffset = findPos(this.container);

    this.hideWait();  
    
};
WDCMap.prototype.dispose = function () {
    if(this.map){
        this.map.dispose();
    }
    this.hideMouseTooltip();
    this.hideWait();
    this.hideMarkerPopup();
};

WDCMap.prototype.showMouseTooltip = function(text){
    if(text&&text!=''&&this.popup.style.visibility!='visible'){
        this.tooltipText.innerHTML = text;
        this.tooltip.style.visibility = 'visible';
    }
};
WDCMap.prototype.hideMouseTooltip = function(){
    this.tooltip.style.visibility = 'hidden';
};

WDCMap.prototype.addMapMoveCallback = function( name, callback ) {
    this.mapMoveCallbacks.push({"name":name,"callback":callback});
};

WDCMap.prototype.removeMapMoveCallback = function(name) {
     for(var i=0; i<this.mapMoveCallbacks.length; i++){
        if(this.mapMoveCallbacks[i].name==name){
            this.mapMoveCallbacks.splice(i,1);
            i--;
        }
    }   
};

WDCMap.prototype.doMapMoveCallback = function(){
    if(this.enableMapMoveCallback){
        for(var i=0; i<this.mapMoveCallbacks.length; i++){
            var callback = this.mapMoveCallbacks[i].callback;
            var t=setTimeout(callback,10);
        }
    }
    if(this.oneTimeMapMoveCallback){
            var t=setTimeout(this.oneTimeMapMoveCallback,10);
    }
};

WDCMap.prototype.setMapType = function (type) {
    var style;
    switch(type){
        case 'road':
            style = Microsoft.Maps.MapTypeId.road;
            break;
        case 'aerial':
            style = Microsoft.Maps.MapTypeId.aerial;
            break;
        case 'birdseye':
        case 'hybrid':
            style = Microsoft.Maps.MapTypeId.birdseye;
            break;
        default:
            style = Microsoft.Maps.MapTypeId.road;
            break;
    }
    if(style!=this.map.getMapTypeId()){
        this.map.setMapType({mapTypeId:style});
    }
};

WDCMap.prototype.getMapType = function () {
    var style = this.map.getMapTypeId();
    switch(style){
        case Microsoft.Maps.MapTypeId.road:
            return 'road';
        case Microsoft.Maps.MapTypeId.aerial:
            return 'aerial';
        case Microsoft.Maps.MapTypeId.birdseye:
            return 'birdseye';
        default:
            return 'road';
    }
};

WDCMap.prototype.showWait = function() {
    this.wait.style.visibility = "visible";
};

WDCMap.prototype.hideWait = function() {
    this.wait.style.visibility = "hidden";
};

WDCMap.prototype.reset = function() {
    this.map.setView({center:this.origLatLong, zoom:this.origzoom});
    this.doMapMoveCallback()
};

WDCMap.prototype.checkResize = function() {
    var height = this.container.offsetHeight;
    var width = this.container.offsetWidth;
    this.layer.style.width = width + 'px';
    this.layer.style.height = height + 'px'; 
    this.wait.style.width = this.layer.offsetWidth + 'px';
    this.wait.style.height = this.layer.offsetHeight + 'px'; 
    
    var center = this.map.getCenter();
    this.map.setOptions({width:width,height:height});
    this.map.setView({center:center});  
};

WDCMap.prototype.setLocation = function(latitude, longitude, zoom) {
    if( !zoom || zoom <= 0 ){
        this.map.setView({center: new Microsoft.Maps.Location(latitude, longitude)});
    } else {
        this.map.setView({center: new Microsoft.Maps.Location(latitude, longitude), zoom: zoom});
    }
};

WDCMap.prototype.setLocationFromText = function( location ) {
    if( location != "" )
    {
        var address = location;
        var geocoder = new WDCGeocoder();
        var oThis = this;
        if (geocoder) {
            this.showWait();
            geocoder.getLatLng(
                address,
                function(point) {
                   if (!point) {
                        alert("'" + address + "' is not a valid location.");
                    } else {
                        oThis.hideMarkerPopup();
                        oThis.map.setView({center:point,zoom: 13});
                        oThis.doMapMoveCallback()
                    }
                    oThis.hideWait();
                }
            );
        }
    }
};

WDCMap.prototype.getMarker = function(id, group){
    if(this.markers[group]){
        return this.markers[group][id];
    } else {
        return null;
    }
};

WDCMap.prototype.setMarker = function( info ) {
    this.createMarker(info);
    this.map.entities.push(marker);
};

WDCMap.prototype.createMarker = function( info ) {
    var marker = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(info.lat,info.lng));
    if(info.icon){
        var options = {};
        //if ie6 and png image apply filter
        if(this.isIE6&&info.icon.image.indexOf('.png', info.icon.image.length - 4) !== -1){
            var background = 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=\'true\', sizingMethod=\'fixed\', src=\'' + info.icon.image + '\');'
            var image = String.format('<div style="cursor:pointer;height:{0}px;width:{1}px;{3};"></div>', info.icon.size.height, info.icon.size.width, background);
            options.icon = image;
        } else {
            options.icon = info.icon.image;
        }
        options.anchor = info.icon.iconAnchor;
        options.height = info.icon.size.height;
        options.width = info.icon.size.width;
    }
    if(info.z){options.zIndex = info.z;}
    marker.setOptions(options);
//    if(info.title){marker.SetTitle(info.title);}
//    if(info.desc){marker.SetDescription(info.desc);}
    if(info.tooltip){marker.tooltip = info.tooltip;}
    marker.info = info;

    var oThis = this;    
    Microsoft.Maps.Events.addHandler(marker, "mouseover", function(e) { 
                                                oThis.showMouseTooltip(e.target.tooltip);
                                                oThis.map.getRootElement().style.cursor = 'pointer';
                                                return true;  
                                            });
                                            
    Microsoft.Maps.Events.addHandler(marker, "mouseout", function(e) { 
                                                oThis.hideMouseTooltip();
                                                oThis.map.getRootElement().style.cursor = 'url(http://ecn.dev.virtualearth.net/mapcontrol/v7.0/cursors/grab.cur), move';
                                                return true;  
                                            });
                                            
    Microsoft.Maps.Events.addHandler(marker, "click", function(e) { 
                                                if(e.target.info&&e.target.info.onclick){
                                                    e.target.info.onclick(oThis,e.target);
                                                } else if(e.target.info&&e.target.info.url) {
                                                    document.location = e.target.info.url;
                                                } else {
                                                    oThis.showMarkerPopup(oThis,e.target);
                                                }
                                            });
    return marker;
};

WDCMap.prototype.isPointVisible = function( point ) {
    var bounds = this.map.getBounds();

    var topLeft = bounds.getNorthwest();
    var bottomRight = bounds.getSoutheast();
    return ( topLeft.latitude > point.latitude && point.latitude > bottomRight.latitude &&
             topLeft.longitude < point.longitude && point.longitude < bottomRight.longitude)
};

WDCMap.prototype.showMarkerPopup = function( context, marker ) {
    context.hideMarkerPopup();
    if(marker.info){
        //if(marker.info.title!=marker.GetTitle()){marker.SetTitle(marker.info.title);}
        if(marker.info.desc&&marker.info.desc!=''){
            var center = this.map.getCenter()
            var point = marker.getLocation();
            if(!context.isPointVisible(point)){
                context.map.setView({center:point});
                context.enableMapMoveCallback = true;
                context.oneTimeMapMoveCallback = function(){
                    context.showMarkerPopup(context,marker);
                    context.oneTimeMapMoveCallback = null;
                    context.enableMapMoveCallback = true;
                }
                return;
            }            
        
            var pixel = this.map.tryLocationToPixel(marker.getLocation(),Microsoft.Maps.PixelReference.control);
            if(pixel.x + this.popupOffset > this.popupBody.offsetWidth){
                this.popup.className = 'mapInfoBox mapInfoBox-right';
            } else {
                this.popup.className = 'mapInfoBox mapInfoBox-left';
            }
            var offsetX = marker.info.icon.iconAnchor.x - marker.info.icon.infoWindowAnchor.x;
            var offsetY = marker.info.icon.infoWindowAnchor.y - marker.info.icon.iconAnchor.y;
            var left = pixel.x + this.mapOffset.left + offsetX;
            var top = pixel.y + this.mapOffset.top + offsetY;
            this.popup.style.left = left + 'px';
            this.popup.style.top = top + 'px';
            this.popupBody.innerHTML = marker.info.desc;
            this.popup.style.visibility = 'visible';
            this.hideMouseTooltip();
        }
    }
};

WDCMap.prototype.hideMarkerPopup = function(){
    //this.map.HideInfoBox();    
    this.popup.style.visibility = 'hidden';
}

WDCMap.prototype.clearMarkers = function(group) {
    if(this.markers!=null){
        if(group){
            if(this.markers[group]){
                for(var k in this.markers[group]){
                    this.map.entities.remove(this.markers[group][k]);
                }
                this.markers[group]={};
            }
        } else {
            this.map.entities.clear();
            this.markers={};
        }
    }
};

WDCMap.prototype.addMarkers = function( markerInfoList, bestFit ) {
    var group;
    var locs = [];
    if(markerInfoList){
        for( var i=0; i<markerInfoList.length;i++ ) {
            var marker = this.createMarker(markerInfoList[i]);

            var id = markerInfoList[i].id;
            group = markerInfoList[i].group;
            if(group==null){group=0;}
            if(!this.markers[group]){this.markers[group]={};}
            if(id!=null){
                this.markers[group][id] = marker;
            } else {
                this.markers[group].push(marker);
            }
            this.map.entities.push(marker);
            locs.push(new Microsoft.Maps.Location(markerInfoList[i].lat,markerInfoList[i].lng));
        }
    }
    if( bestFit == true) {
        this.map.setView({bounds: Microsoft.Maps.LocationRect.fromLocations(locs)});
        this.origLatLong = this.map.getTargetCenter();
        this.origzoom = this.map.getTargetZoom();
    }
};

WDCMap.prototype.addPlaces = function(places){
    var place;
    var polygon;
    for(var i=0;i<places.length;i++){
        place = new WDCMapPlace(places[i]);
        for(var j=0;j<place.polygons.length;j++){
            polygon = place.polygons[j];
            if(place.polygons.length>1){
                polygon.parentList = place.polygons;
            }
            polygon.setOptions({fillColor: new Microsoft.Maps.Color(0,0,0,0),
                                strokeColor: new Microsoft.Maps.Color(100,255,0,0),
                                strokeThickness: 2
            });
            polygon.tooltip = place.info.name;
            this.attachPolygonEvents(polygon);
            this.map.entities.push(polygon);
        }
    }
}

WDCMap.prototype.attachPolygonEvents = function(polygon){
    var oThis = this;
    Microsoft.Maps.Events.addHandler(polygon, "mouseover", function(e) { 
                                if(oThis.map.getZoom()<15){
                                    if(e.target.parentList){
                                        for(var i=0;i<e.target.parentList.length;i++){
                                            e.target.parentList[i].setOptions({fillColor: new Microsoft.Maps.Color(100,35,80,135)});
                                        }
                                    } else {
                                        e.target.setOptions({fillColor: new Microsoft.Maps.Color(100,35,80,135)});
                                    }
                                }
                                oThis.showMouseTooltip(e.target.tooltip);
                                return true;
                            });
    Microsoft.Maps.Events.addHandler(polygon, "mouseout", function(e) { 
                                e.target.setOptions({fillColor: new Microsoft.Maps.Color(0,0,0,0)});
                                oThis.hideMouseTooltip();
                                return true;
                            });
}

WDCMap.prototype.getMapBounds = function(maxLatDelta, maxLngDelta) {
    var bounds = this.map.getBounds();
    var sw = new Microsoft.Maps.Location(bounds.getSouth(), bounds.getWest());
    var ne = new Microsoft.Maps.Location(bounds.getNorth(),bounds.getEast());
    var center = this.map.getCenter();
    if(maxLatDelta!=null&&Math.abs(ne.latitude-sw.latitude)>maxLatDelta){
        sw = new Microsoft.Maps.Location(center.latitude-(maxLatDelta/2), sw.longitude);
        ne = new Microsoft.Maps.Location(center.latitude+(maxLatDelta/2), ne.longitude);
    }
    if(maxLngDelta!=null&&Math.abs(ne.longitude-sw.longitude)>maxLngDelta){
        sw = new Microsoft.Maps.Location(sw.latitude, center.longitude-(maxLngDelta/2));
        ne = new Microsoft.Maps.Location(ne.latitude, center.longitude+(maxLngDelta/2));
    }
    return {"sw":sw,"ne":ne};
}

WDCMap.prototype.getBounds = function(maxLatDelta, maxLngDelta) {
    var bounds = this.getMapBounds(maxLatDelta, maxLngDelta);
    var sw = bounds.sw;
    var ne = bounds.ne;
    return sw.latitude.toString() + ',' + sw.longitude.toString() + ',' + ne.latitude.toString() + ',' + ne.longitude.toString();
};

WDCMap.prototype.getZoom = function() {
    this.map.getZoom();
};

WDCMap.prototype.getMapInfo = function(maxLatDelta, maxLngDelta) {
    var bounds = this.getMapBounds(maxLatDelta, maxLngDelta);
    var zoom = this.map.getZoom();
    var center = this.map.getCenter();
    var info = "sw=" + bounds.sw.latitude.toString() + ',' + bounds.sw.longitude.toString();
    info = info + "&ne=" + bounds.ne.latitude.toString() + ',' + bounds.ne.longitude.toString();
    info = info + "&c=" + center.latitude.toString() + ',' + center.longitude.toString();
    info = info + "&z=" + zoom;
    return info;
};

WDCMap.prototype.openMarkerWindow = function(id,group){
    if(!group){group=0;}
    if(this.markers[group]){
        if(this.markers[group][id]){
            this.showMarkerPopup(this,this.markers[group][id]);
        }
    }
};

////////////////////////////
//WDCGeocoder
//implemented using Bing's restful location service
//Note: could not use xmlHTTP for some reason so I am using
//      the JSONP protocol supported by bing
////////////////////////////
function WDCGeocoder(){
}

WDCGeocoder.prototype.makeRequest = function(location, callback){
    var callbackId = this.getUniqueCallbackId();
    //create a unique instance of the passed in callback function
    window[callbackId] = callback;
    
    var request = 'http://dev.virtualearth.net/REST/v1/Locations/' + location + '?key=' + __key + '&jsonp=' + callbackId;
    var script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.setAttribute("src", request);
    _geo=this;
    document.body.appendChild(script);
};
WDCGeocoder.prototype.getUniqueCallbackId = function(){
    var callbackId;
    do{
    callbackId = 'wdcGeocoder_' + Math.floor(Math.random()*100000).toString();
    }while(window[callbackId]);
    return callbackId;
};

WDCGeocoder.prototype.getLatLng = function (location, callback) {
     this.makeRequest(location.trim(),function(result){
            if(result &&
               result.resourceSets &&
               result.resourceSets.length > 0 &&
               result.resourceSets[0].resources &&
               result.resourceSets[0].resources.length > 0){
               var latlong = new Microsoft.Maps.Location(result.resourceSets[0].resources[0].point.coordinates[0], result.resourceSets[0].resources[0].point.coordinates[1]);
               callback(latlong);                     
            } else {
                callback(null);
            }
        });
};

WDCGeocoder.prototype.getLocations = function(location, callback){
    var context = this;
    this.makeRequest(location.trim(),function(result){
                var places = [];
                try{
                    if( result &&
                        result.resourceSets &&
                        result.resourceSets.length > 0 &&
                        result.resourceSets[0].resources &&
                        result.resourceSets[0].resources.length > 0) {
                      
                        var place;
                        for(var i=0;i<result.resourceSets[0].resources.length;i++){
                            try{
                                place = context.processLocation(result.resourceSets[0].resources[i]);
                            } catch(e) {
                            alert(e);
                                place = null;
                            }
                            if(place!=null){
                                places.push(place);
                            }
                        }
                   }
                } catch(err) {
                    //alert(err.message);
                    places=null;
                }
                if(callback){callback(places);}
        });
};

WDCGeocoder.prototype.processLocation = function(place){
    var p = new Microsoft.Maps.Location(place.point.coordinates[0], place.point.coordinates[1]);
    var c = place.confidence;
    var addr = '';
    var display = '';
    var city = '';
    var state = '';
    var zip = '';
    var country = place.address.countryRegion;
    if(place.entityType=='Address'&&(country=="United States"||country=="US"||country=="USA")){
        addr = place.address.addressLine;
        state = place.address.adminDistrict;
        city = place.address.locality;
        zip = place.address.postalCode;
        display = place.address.formattedAddress;
    }else {
        return null;
    }
    return {"p":p,"c":c,"display":display,"addr":addr,"city":city,"state":state,"zip":zip};
}


////////////////////////////
//WDCMapPlace
////////////////////////////
function WDCMapPlace(info){
    this.info = info;
    this.polygons = null;
    this.init();
}
WDCMapPlace.prototype.init = function(){
    this.polygons = [];
    var shape;
    var points;
    var polygon;
    for(var i=0;i<this.info.shapes.length;i++){
        shape = this.info.shapes[i];
        points = this.decodePoints(shape.encoded);
        if(points&&points.length>0){
            polygon = new Microsoft.Maps.Polygon(points);
            this.polygons.push(polygon);
        }        
    }
};
WDCMapPlace.prototype.decodePoints = function(encoded){
    // Decode an encoded string into a list of VE lat/lng.
    var len = encoded.length;
    var index = 0;
    var array = [];
    var lat = 0;
    var lng = 0;
    try
    {
        while (index < len) {
            var b;
            var shift = 0;
            var result = 0;
            do {
                  b = encoded.charCodeAt(index++) - 63;
                  result |= (b & 0x1f) << shift;
                  shift += 5;
            } while (b >= 0x20);
            var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                  b = encoded.charCodeAt(index++) - 63;
                  result |= (b & 0x1f) << shift;
                  shift += 5;
            } while (b >= 0x20);
            var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            array.push(new Microsoft.Maps.Location((lat * 1e-5), (lng * 1e-5)));
        }
    } catch(ex)
    {
        //error in encoding.
    }
    return array;
};

function CreateMap(mapId, mapData, places, lat, lng, zoom, location, onReadyCallback,controlType,mapType,smartView){
    if(location!==null&&location!==""){
        var geocoder = new WDCGeocoder(); 
        geocoder.getLatLng(location, function(point) {
                                      var map;
                                      if (!point) { map = new WDCMap(mapId,lat,lng,zoom,controlType);}
                                      else {map = new WDCMap(mapId,point.latitude,point.longitude,zoom,controlType,mapType);}
                                      map.addMarkers(mapData,smartView);
                                      map.addPlaces(places);
                                      if(mapType){map.setMapType(mapType);}
                                      if(onReadyCallback){
                                        window.setTimeout(function(){onReadyCallback(map);},1000);
                                      }
                                    } );
    }
    else{
        var map = new WDCMap(mapId,lat,lng,zoom,controlType);
        map.addMarkers(mapData,smartView);
        map.addPlaces(places);
        if(mapType){map.setMapType(mapType);}
        if(onReadyCallback){window.setTimeout(function(){onReadyCallback(map);},1000);}
    }
}

var __maps = [];
function WDCUnloadMaps(){
    for(var i=0;i<__maps.length;i++){
        __maps[i].dispose();
    }
}

