var map;	// create the Google map object
var mapErrorText = "";

/////////////////////////////////////////////////////////////////////////////////////////////////
// markermanager.js code starts here
/////////////////////////////////////////////////////////////////////////////////////////////////

function MarkerManager(map, opt_opts) {
  var me = this;
  me.map_ = map;
  me.mapZoom_ = map.getZoom();
  me.projection_ = map.getCurrentMapType().getProjection();

  opt_opts = opt_opts || {};
  me.tileSize_ = MarkerManager.DEFAULT_TILE_SIZE_;

  var mapTypes = map.getMapTypes();
  var mapMaxZoom = mapTypes[0].getMaximumResolution();
  for (var i = 0; i < mapTypes.length; i++) {
    var mapTypeMaxZoom = mapTypes[i].getMaximumResolution();
    if (mapTypeMaxZoom > mapMaxZoom) {
      mapMaxZoom = mapTypeMaxZoom;
    }
  }
  me.maxZoom_  = opt_opts.maxZoom || mapMaxZoom;

  me.trackMarkers_ = opt_opts.trackMarkers;

  var padding;
  if (typeof opt_opts.borderPadding === "number") {
    padding = opt_opts.borderPadding;
  } else {
    padding = MarkerManager.DEFAULT_BORDER_PADDING_;
  }
  // The padding in pixels beyond the viewport, where we will pre-load markers.
  me.swPadding_ = new GSize(-padding, padding);
  me.nePadding_ = new GSize(padding, -padding);
  me.borderPadding_ = padding;

  me.gridWidth_ = [];

  me.grid_ = [];
  me.grid_[me.maxZoom_] = [];
  me.numMarkers_ = [];
  me.numMarkers_[me.maxZoom_] = 0;

  GEvent.bind(map, "moveend", me, me.onMapMoveEnd_);

  // NOTE: These two closures provide easy access to the map.
  // They are used as callbacks, not as methods.
  me.removeOverlay_ = function (marker) {
    map.removeOverlay(marker);
    me.shownMarkers_--;
  };
  me.addOverlay_ = function (marker) {
    map.addOverlay(marker);
    me.shownMarkers_++;
  };

  me.resetManager_();
  me.shownMarkers_ = 0;

  me.shownBounds_ = me.getMapGridBounds_();
}

// Static constants:
MarkerManager.DEFAULT_TILE_SIZE_ = 1024;
MarkerManager.DEFAULT_BORDER_PADDING_ = 100;
MarkerManager.MERCATOR_ZOOM_LEVEL_ZERO_RANGE = 256;


/**
 * Initializes MarkerManager arrays for all zoom levels
 * Called by constructor and by clearAllMarkers
 */
MarkerManager.prototype.resetManager_ = function () {
  var me = this;
  var mapWidth = MarkerManager.MERCATOR_ZOOM_LEVEL_ZERO_RANGE;
  for (var zoom = 0; zoom <= me.maxZoom_; ++zoom) {
    me.grid_[zoom] = [];
    me.numMarkers_[zoom] = 0;
    me.gridWidth_[zoom] = Math.ceil(mapWidth / me.tileSize_);
    mapWidth <<= 1;
  }
};

/**
 * Removes all currently displayed markers
 * and calls resetManager to clear arrays
 */
MarkerManager.prototype.clearMarkers = function () {
  var me = this;
  me.processAll_(me.shownBounds_, me.removeOverlay_);
  me.resetManager_();
};


/**
 * Gets the tile coordinate for a given latlng point.
 *
 * @param {LatLng} latlng The geographical point.
 * @param {Number} zoom The zoom level.
 * @param {GSize} padding The padding used to shift the pixel coordinate.
 *               Used for expanding a bounds to include an extra padding
 *               of pixels surrounding the bounds.
 * @return {GPoint} The point in tile coordinates.
 *
 */
MarkerManager.prototype.getTilePoint_ = function (latlng, zoom, padding) {
  var pixelPoint = this.projection_.fromLatLngToPixel(latlng, zoom);
  return new GPoint(
      Math.floor((pixelPoint.x + padding.width) / this.tileSize_),
      Math.floor((pixelPoint.y + padding.height) / this.tileSize_));
};


/**
 * Finds the appropriate place to add the marker to the grid.
 * Optimized for speed; does not actually add the marker to the map.
 * Designed for batch-processing thousands of markers.
 *
 * @param {Marker} marker The marker to add.
 * @param {Number} minZoom The minimum zoom for displaying the marker.
 * @param {Number} maxZoom The maximum zoom for displaying the marker.
 */
MarkerManager.prototype.addMarkerBatch_ = function (marker, minZoom, maxZoom) {
  var mPoint = marker.getPoint();
  marker.MarkerManager_minZoom = minZoom;
  // Tracking markers is expensive, so we do this only if the
  // user explicitly requested it when creating marker manager.
  if (this.trackMarkers_) {
    GEvent.bind(marker, "changed", this, this.onMarkerMoved_);
  }

  var gridPoint = this.getTilePoint_(mPoint, maxZoom, GSize.ZERO);

  for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
    var cell = this.getGridCellCreate_(gridPoint.x, gridPoint.y, zoom);
    cell.push(marker);

    gridPoint.x = gridPoint.x >> 1;
    gridPoint.y = gridPoint.y >> 1;
  }
};


/**
 * Returns whether or not the given point is visible in the shown bounds. This
 * is a helper method that takes care of the corner case, when shownBounds have
 * negative minX value.
 *
 * @param {Point} point a point on a grid.
 * @return {Boolean} Whether or not the given point is visible in the currently
 * shown bounds.
 */
MarkerManager.prototype.isGridPointVisible_ = function (point) {
  var me = this;
  var vertical = me.shownBounds_.minY <= point.y &&
      point.y <= me.shownBounds_.maxY;
  var minX = me.shownBounds_.minX;
  var horizontal = minX <= point.x && point.x <= me.shownBounds_.maxX;
  if (!horizontal && minX < 0) {
    // Shifts the negative part of the rectangle. As point.x is always less
    // than grid width, only test shifted minX .. 0 part of the shown bounds.
    var width = me.gridWidth_[me.shownBounds_.z];
    horizontal = minX + width <= point.x && point.x <= width - 1;
  }
  return vertical && horizontal;
};


/**
 * Reacts to a notification from a marker that it has moved to a new location.
 * It scans the grid all all zoom levels and moves the marker from the old grid
 * location to a new grid location.
 *
 * @param {Marker} marker The marker that moved.
 * @param {LatLng} oldPoint The old position of the marker.
 * @param {LatLng} newPoint The new position of the marker.
 */
MarkerManager.prototype.onMarkerMoved_ = function (marker, oldPoint, newPoint) {
  // NOTE: We do not know the minimum or maximum zoom the marker was
  // added at, so we start at the absolute maximum. Whenever we successfully
  // remove a marker at a given zoom, we add it at the new grid coordinates.
  var me = this;
  var zoom = me.maxZoom_;
  var changed = false;
  var oldGrid = me.getTilePoint_(oldPoint, zoom, GSize.ZERO);
  var newGrid = me.getTilePoint_(newPoint, zoom, GSize.ZERO);
  while (zoom >= 0 && (oldGrid.x !== newGrid.x || oldGrid.y !== newGrid.y)) {
    var cell = me.getGridCellNoCreate_(oldGrid.x, oldGrid.y, zoom);
    if (cell) {
      if (me.removeFromArray(cell, marker)) {
        me.getGridCellCreate_(newGrid.x, newGrid.y, zoom).push(marker);
      }
    }
    // For the current zoom we also need to update the map. Markers that no
    // longer are visible are removed from the map. Markers that moved into
    // the shown bounds are added to the map. This also lets us keep the count
    // of visible markers up to date.
    if (zoom === me.mapZoom_) {
      if (me.isGridPointVisible_(oldGrid)) {
        if (!me.isGridPointVisible_(newGrid)) {
          me.removeOverlay_(marker);
          changed = true;
        }
      } else {
        if (me.isGridPointVisible_(newGrid)) {
          me.addOverlay_(marker);
          changed = true;
        }
      }
    }
    oldGrid.x = oldGrid.x >> 1;
    oldGrid.y = oldGrid.y >> 1;
    newGrid.x = newGrid.x >> 1;
    newGrid.y = newGrid.y >> 1;
    --zoom;
  }
  if (changed) {
    me.notifyListeners_();
  }
};


/**
 * Searches at every zoom level to find grid cell
 * that marker would be in, removes from that array if found.
 * Also removes marker with removeOverlay if visible.
 * @param {GMarker} marker The marker to delete.
 */
MarkerManager.prototype.removeMarker = function (marker) {
  var me = this;
  var zoom = me.maxZoom_;
  var changed = false;
  var point = marker.getPoint();
  var grid = me.getTilePoint_(point, zoom, GSize.ZERO);
  while (zoom >= 0) {
    var cell = me.getGridCellNoCreate_(grid.x, grid.y, zoom);

    if (cell) {
      me.removeFromArray(cell, marker);
    }
    // For the current zoom we also need to update the map. Markers that no
    // longer are visible are removed from the map. This also lets us keep the count
    // of visible markers up to date.
    if (zoom === me.mapZoom_) {
      if (me.isGridPointVisible_(grid)) {
        me.removeOverlay_(marker);
        changed = true;
      }
    }
    grid.x = grid.x >> 1;
    grid.y = grid.y >> 1;
    --zoom;
  }
  if (changed) {
    me.notifyListeners_();
  }
  me.numMarkers_[marker.MarkerManager_minZoom]--;
};


/**
 * Add many markers at once.
 * Does not actually update the map, just the internal grid.
 *
 * @param {Array of Marker} markers The markers to add.
 * @param {Number} minZoom The minimum zoom level to display the markers.
 * @param {Number} opt_maxZoom The maximum zoom level to display the markers.
 */
MarkerManager.prototype.addMarkers = function (markers, minZoom, opt_maxZoom) {
  var maxZoom = this.getOptMaxZoom_(opt_maxZoom);
  for (var i = markers.length - 1; i >= 0; i--) {
    this.addMarkerBatch_(markers[i], minZoom, maxZoom);
  }

  this.numMarkers_[minZoom] += markers.length;
};


/**
 * Returns the value of the optional maximum zoom. This method is defined so
 * that we have just one place where optional maximum zoom is calculated.
 *
 * @param {Number} opt_maxZoom The optinal maximum zoom.
 * @return The maximum zoom.
 */
MarkerManager.prototype.getOptMaxZoom_ = function (opt_maxZoom) {
  return opt_maxZoom || this.maxZoom_;
};


/**
 * Calculates the total number of markers potentially visible at a given
 * zoom level.
 *
 * @param {Number} zoom The zoom level to check.
 */
MarkerManager.prototype.getMarkerCount = function (zoom) {
  var total = 0;
  for (var z = 0; z <= zoom; z++) {
    total += this.numMarkers_[z];
  }
  return total;
};

/** 
 * Returns a marker given latitude, longitude and zoom. If the marker does not exist, 
 * the method will return a new marker. If a new marker is created, it will NOT be 
 * added to the MarkerManager. 
 * 
 * @param {Number} lat - the latitude of a marker. 
 * @param {Number} lng - the longitude of a marker. 
 * @param {Number} zoom - the zoom level 
 * @return {GMarker} marker - the marker found at lat and lng 
 */ 
MarkerManager.prototype.getMarker = function(lat, lng, zoom) { 
  var me = this; 
  var mPoint = new GLatLng(lat, lng); 
  var gridPoint = me.getTilePoint_(mPoint, zoom, GSize.ZERO); 

  var marker = new GMarker(mPoint); 
  var cellArray = me.getGridCellNoCreate_(gridPoint.x, gridPoint.y, zoom); 
  if(cellArray != undefined){ 
    for (var i = 0; i < cellArray.length; i++) 
    { 
      if(lat == cellArray[i].getLatLng().lat() && 
         lng == cellArray[i].getLatLng().lng()) 
      { 
        marker = cellArray[i]; 
      } 
    } 
  } 
  return marker; 
}; 

/**
 * Add a single marker to the map.
 *
 * @param {Marker} marker The marker to add.
 * @param {Number} minZoom The minimum zoom level to display the marker.
 * @param {Number} opt_maxZoom The maximum zoom level to display the marker.
 */
MarkerManager.prototype.addMarker = function (marker, minZoom, opt_maxZoom) {
  var me = this;
  var maxZoom = this.getOptMaxZoom_(opt_maxZoom);
  me.addMarkerBatch_(marker, minZoom, maxZoom);
  var gridPoint = me.getTilePoint_(marker.getPoint(), me.mapZoom_, GSize.ZERO);
  if (me.isGridPointVisible_(gridPoint) &&
      minZoom <= me.shownBounds_.z &&
      me.shownBounds_.z <= maxZoom) {
    me.addOverlay_(marker);
    me.notifyListeners_();
  }
  this.numMarkers_[minZoom]++;
};

/**
 * Returns true if this bounds (inclusively) contains the given point.
 * @param {Point} point  The point to test.
 * @return {Boolean} This Bounds contains the given Point.
 */


/**
 * Get a cell in the grid, creating it first if necessary.
 *
 * Optimization candidate
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 * @return {Array} The cell in the array.
 */
MarkerManager.prototype.getGridCellCreate_ = function (x, y, z) {
  var grid = this.grid_[z];
  if (x < 0) {
    x += this.gridWidth_[z];
  }
  var gridCol = grid[x];
  if (!gridCol) {
    gridCol = grid[x] = [];
    return (gridCol[y] = []);
  }
  var gridCell = gridCol[y];
  if (!gridCell) {
    return (gridCol[y] = []);
  }
  return gridCell;
};


/**
 * Get a cell in the grid, returning undefined if it does not exist.
 *
 * NOTE: Optimized for speed -- otherwise could combine with getGridCellCreate_.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 * @return {Array} The cell in the array.
 */
MarkerManager.prototype.getGridCellNoCreate_ = function (x, y, z) {
  var grid = this.grid_[z];
  if (x < 0) {
    x += this.gridWidth_[z];
  }
  var gridCol = grid[x];
  return gridCol ? gridCol[y] : undefined;
};


/**
 * Turns at geographical bounds into a grid-space bounds.
 *
 * @param {LatLngBounds} bounds The geographical bounds.
 * @param {Number} zoom The zoom level of the bounds.
 * @param {GSize} swPadding The padding in pixels to extend beyond the
 * given bounds.
 * @param {GSize} nePadding The padding in pixels to extend beyond the
 * given bounds.
 * @return {GBounds} The bounds in grid space.
 */
MarkerManager.prototype.getGridBounds_ = function (bounds, zoom, swPadding, nePadding) {
  zoom = Math.min(zoom, this.maxZoom_);

  var bl = bounds.getSouthWest();
  var tr = bounds.getNorthEast();
  var sw = this.getTilePoint_(bl, zoom, swPadding);
  var ne = this.getTilePoint_(tr, zoom, nePadding);
  var gw = this.gridWidth_[zoom];

  // Crossing the prime meridian requires correction of bounds.
  if (tr.lng() < bl.lng() || ne.x < sw.x) {
    sw.x -= gw;
  }
  if (ne.x - sw.x  + 1 >= gw) {
    // Computed grid bounds are larger than the world; truncate.
    sw.x = 0;
    ne.x = gw - 1;
  }
  var gridBounds = new GBounds([sw, ne]);
  gridBounds.z = zoom;
  return gridBounds;
};


/**
 * Gets the grid-space bounds for the current map viewport.
 *
 * @return {Bounds} The bounds in grid space.
 */
MarkerManager.prototype.getMapGridBounds_ = function () {
  var me = this;
  return me.getGridBounds_(me.map_.getBounds(), me.mapZoom_, me.swPadding_, me.nePadding_);
};


/**
 * Event listener for map:movend.
 * NOTE: Use a timeout so that the user is not blocked
 * from moving the map.
 *
 */
MarkerManager.prototype.onMapMoveEnd_ = function () {
  var me = this;
  me.objectSetTimeout_(this, this.updateMarkers_, 0);
};


/**
 * Call a function or evaluate an expression after a specified number of
 * milliseconds.
 *
 * Equivalent to the standard window.setTimeout function, but the given
 * function executes as a method of this instance. So the function passed to
 * objectSetTimeout can contain references to this.
 *    objectSetTimeout(this, function () { alert(this.x) }, 1000);
 *
 * @param {Object} object  The target object.
 * @param {Function} command  The command to run.
 * @param {Number} milliseconds  The delay.
 * @return {Boolean}  Success.
 */
MarkerManager.prototype.objectSetTimeout_ = function (object, command, milliseconds) {
  return window.setTimeout(function () {
    command.call(object);
  }, milliseconds);
};


/**
 * Refresh forces the marker-manager into a good state.
 * <ol>
 *   <li>If never before initialized, shows all the markers.</li>
 *   <li>If previously initialized, removes and re-adds all markers.</li>
 * </ol>
 */
MarkerManager.prototype.refresh = function () {
  var me = this;
  if (me.shownMarkers_ > 0) {
    me.processAll_(me.shownBounds_, me.removeOverlay_);
  }
  me.processAll_(me.shownBounds_, me.addOverlay_);
  //me.notifyListeners_();
};


/**
 * After the viewport may have changed, add or remove markers as needed.
 */
MarkerManager.prototype.updateMarkers_ = function () {
  var me = this;
  me.mapZoom_ = this.map_.getZoom();
  var newBounds = me.getMapGridBounds_();

  // If the move does not include new grid sections,
  // we have no work to do:
  if (newBounds.equals(me.shownBounds_) && newBounds.z === me.shownBounds_.z) {
    return;
  }

  if (newBounds.z !== me.shownBounds_.z) {
    me.processAll_(me.shownBounds_, me.removeOverlay_);
    me.processAll_(newBounds, me.addOverlay_);
  } else {
    // Remove markers:
    me.rectangleDiff_(me.shownBounds_, newBounds, me.removeCellMarkers_);

    // Add markers:
    me.rectangleDiff_(newBounds, me.shownBounds_, me.addCellMarkers_);
  }
  me.shownBounds_ = newBounds;

  me.notifyListeners_();
};


/**
 * Notify listeners when the state of what is displayed changes.
 */
MarkerManager.prototype.notifyListeners_ = function () {
  GEvent.trigger(this, "changed", this.shownBounds_, this.shownMarkers_);
};


/**
 * Process all markers in the bounds provided, using a callback.
 *
 * @param {Bounds} bounds The bounds in grid space.
 * @param {Function} callback The function to call for each marker.
 */
MarkerManager.prototype.processAll_ = function (bounds, callback) {
  for (var x = bounds.minX; x <= bounds.maxX; x++) {
    for (var y = bounds.minY; y <= bounds.maxY; y++) {
      this.processCellMarkers_(x, y,  bounds.z, callback);
    }
  }
};


/**
 * Process all markers in the grid cell, using a callback.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 * @param {Function} callback The function to call for each marker.
 */
MarkerManager.prototype.processCellMarkers_ = function (x, y, z, callback) {
  var cell = this.getGridCellNoCreate_(x, y, z);
  if (cell) {
    for (var i = cell.length - 1; i >= 0; i--) {
      callback(cell[i]);
    }
  }
};


/**
 * Remove all markers in a grid cell.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 */
MarkerManager.prototype.removeCellMarkers_ = function (x, y, z) {
  this.processCellMarkers_(x, y, z, this.removeOverlay_);
};


/**
 * Add all markers in a grid cell.
 *
 * @param {Number} x The x coordinate of the cell.
 * @param {Number} y The y coordinate of the cell.
 * @param {Number} z The z coordinate of the cell.
 */
MarkerManager.prototype.addCellMarkers_ = function (x, y, z) {
  this.processCellMarkers_(x, y, z, this.addOverlay_);
};


/**
 * Use the rectangleDiffCoords function to process all grid cells
 * that are in bounds1 but not bounds2, using a callback, and using
 * the current MarkerManager object as the instance.
 *
 * Pass the z parameter to the callback in addition to x and y.
 *
 * @param {Bounds} bounds1 The bounds of all points we may process.
 * @param {Bounds} bounds2 The bounds of points to exclude.
 * @param {Function} callback The callback function to call
 *                   for each grid coordinate (x, y, z).
 */
MarkerManager.prototype.rectangleDiff_ = function (bounds1, bounds2, callback) {
  var me = this;
  me.rectangleDiffCoords(bounds1, bounds2, function (x, y) {
    callback.apply(me, [x, y, bounds1.z]);
  });
};


/**
 * Calls the function for all points in bounds1, not in bounds2
 *
 * @param {Bounds} bounds1 The bounds of all points we may process.
 * @param {Bounds} bounds2 The bounds of points to exclude.
 * @param {Function} callback The callback function to call
 *                   for each grid coordinate.
 */
MarkerManager.prototype.rectangleDiffCoords = function (bounds1, bounds2, callback) {
  var minX1 = bounds1.minX;
  var minY1 = bounds1.minY;
  var maxX1 = bounds1.maxX;
  var maxY1 = bounds1.maxY;
  var minX2 = bounds2.minX;
  var minY2 = bounds2.minY;
  var maxX2 = bounds2.maxX;
  var maxY2 = bounds2.maxY;

  var x, y;
  for (x = minX1; x <= maxX1; x++) {  // All x in R1
    // All above:
    for (y = minY1; y <= maxY1 && y < minY2; y++) {  // y in R1 above R2
      callback(x, y);
    }
    // All below:
    for (y = Math.max(maxY2 + 1, minY1);  // y in R1 below R2
         y <= maxY1; y++) {
      callback(x, y);
    }
  }

  for (y = Math.max(minY1, minY2);
       y <= Math.min(maxY1, maxY2); y++) {  // All y in R2 and in R1
    // Strictly left:
    for (x = Math.min(maxX1 + 1, minX2) - 1;
         x >= minX1; x--) {  // x in R1 left of R2
      callback(x, y);
    }
    // Strictly right:
    for (x = Math.max(minX1, maxX2 + 1);  // x in R1 right of R2
         x <= maxX1; x++) {
      callback(x, y);
    }
  }
};


/**
 * Removes value from array. O(N).
 *
 * @param {Array} array  The array to modify.
 * @param {any} value  The value to remove.
 * @param {Boolean} opt_notype  Flag to disable type checking in equality.
 * @return {Number}  The number of instances of value that were removed.
 */
MarkerManager.prototype.removeFromArray = function (array, value, opt_notype) {
  var shift = 0;
  for (var i = 0; i < array.length; ++i) {
    if (array[i] === value || (opt_notype && array[i] === value)) {
      array.splice(i--, 1);
      shift++;
    }
  }
  return shift;
};


/////////////////////////////////////////////////////////////////////////////////////////////////
// markermanager.js code ends here
/////////////////////////////////////////////////////////////////////////////////////////////////

var batch = [];
var mgr;

function getMap(responseJSON, mapDivName, zoomLevel, addressDivName, showPopupDiv, startLocation, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar) {
	//alert(map);
	map = false;
	jsonText = responseJSON.responseText;
	jsonObj = jsonText.parseJSON();

	recCount = (jsonObj.count == null) ? 0 : jsonObj.count;
	countyCount = (jsonObj.counties == null) ? 0 : jsonObj.counties.count;

	if (startLocation == 'true') { // if there is a Start Location specified
		lat = jsonObj.lat;
		lon = jsonObj.lon;
		proximity = jsonObj.proximity;
		map = displayMap(mapDivName, lat, lon, zoomLevel, overviewMap, mapType, mapScale);
	}
	else if (recCount > 0) { // if there is no Start Location specified but there are devices to be displayed
		jsonRec = jsonObj.record[0];
		lat = jsonRec.lat;
		lon = jsonRec.lon;
		address = jsonRec.address;
	  if (showPopupDiv=='true') {
			showWindow(mapDivName);
		}
		map = displayMap(mapDivName, lat, lon, zoomLevel, overviewMap, mapType, mapScale);
	
	}
	else if (countyCount > 0) {
		jsonRec = jsonObj.counties.record[0].record[0].record[0];
		lat = jsonRec.lat;
		lon = jsonRec.lon;
//		address = jsonRec.address;
	  if (showPopupDiv=='true') {
			showWindow(mapDivName);
		}
		map = displayMap(mapDivName, lat, lon, zoomLevel, overviewMap, mapType, mapScale);
	}

	if (map) {
		centerLat = minLat = maxLat = parseFloat(lat);
		centerLon = minLon = maxLon = parseFloat(lon);
		if (startLocation == 'true') {
			if (showLocation == 'true') {
				address = jsonObj.location;
				addDeviceToMap(map, lat, lon, "", "", address, "", address, "", "", "", "", "", "");
			}
			proximity = parseFloat(proximity);
		}
        
		if (recCount > 0) {

			// Add markers for devices
			for (var ctr=0; ctr<recCount; ctr=ctr+1) {

				jsonRec = jsonObj.record[ctr];
				lat = jsonRec.lat;
				lon = jsonRec.lon;
				type = jsonRec.deviceType;
				imageName = jsonRec.imageName;
//				shadowImageName = jsonRec.shadowImageName;
				shadowImageName = "";
				markerTitle = jsonRec.deviceGUID;
				
				statusID = jsonRec.statusID;
				
				var markerHtml = '';
				if(jsonRec.statusTextArray != undefined)
				{
					markerHtml = "<div class='mapInfoWindow' style='padding-top:5px;'><b>"+_('Name')+"</b>:&nbsp;"+jsonRec.deviceName + "<br/>" ;
					markerHtml += "<b>"+_('Address')+"</b>:&nbsp;"+jsonRec.address;
					if(jsonRec.description != undefined && jsonRec.description != '')
					{
						markerHtml += "<br/><b>"+_('Description')+"</b>:&nbsp;"+jsonRec.description;
					}
	
					if(jsonRec.statusTextArray != undefined)
					{
						statusTextArray = jsonRec.statusTextArray;
						for(i = 0 ; i < statusTextArray.length; i++)
						{
							var status = statusTextArray[i];
							if(status.length > 0)
							{
								markerHtml += "&nbsp;<br/><b>"+_('Port')+"&nbsp;"+status[0]+"</b>:&nbsp;"+status[1]+":<i><b>&nbsp;"+status[2]+"</b></i>";
								if(status[3] != '')
								{
									markerHtml += "&nbsp;(" +status[3]+")";
								}
							}			
						}
					}	
	
					hiddenFlag = '';
			
					if(jsonRec.deviceHiddenFlag != undefined)
					{
						hiddenFlag = jsonRec.deviceHiddenFlag;
		
						markerHtml += "<br/>"+hiddenFlag;
					}
				
					markerHtml += "</div>";
				}
				else
				{
				
					fault = "";
				    
					if(jsonRec.statusID_1 != undefined)
					{
						statusID_1		=	jsonRec.statusID_1;
						faultText = (jsonRec.faultText != undefined)?jsonRec.faultText:"";

						if(statusID_1 > 0 && statusID > 0)
						{
							faultPort1 = (faultText[0] != undefined)?(" Port 1 :"+faultText[0]):"";
					
							faultPort2 = (faultText[1] != undefined)?(" Port 2 :"+faultText[1]):"";
						}	
						else
						{
							faultPort1 = (faultText[0] != undefined)?faultText[0]:"";
					
							faultPort2 = (faultText[1] != undefined)?faultText[1]:"";
						}
					
						if(faultPort1 != '' || faultPort2 != '')
						{
							fault = "Fault:"+faultPort1+faultPort2
						}
					}	
					
					hiddenFlag = '';
					
					if(jsonRec.deviceHiddenFlag != undefined)
					{
						hiddenFlag = jsonRec.deviceHiddenFlag;
					}
								
					//chargerlevel = (jsonRec.chargerlevel == null) ? '' : ( jsonRec.chargerlevel );
					address = (jsonRec.address == null) ? '' : ( jsonRec.address );
					numPorts = (jsonRec.numPorts == null) ? '' : ( jsonRec.numPorts );
					port1Status = (jsonRec.port1 == null) ? '' : ( jsonRec.port1 );
					port2Status = (jsonRec.port2 == null) ? '' : ( jsonRec.port2 );
		            port1description = (jsonRec.port1description == null) ? '' : (jsonRec.port1description);
		            port2description = (jsonRec.port2description == null) ? '' : (jsonRec.port2description);
		            description = (jsonRec.description == null) ? '' : ( jsonRec.description );
		            action = (jsonRec.submitButton == null) ? '' : (jsonRec.submitButton) + '<br/>';
		            lastKnown = (jsonRec.lastKnown == null) ? '' : (jsonRec.lastKnown);
                    lastKnownDate = (jsonRec.lastKnownDate == null) ? '' : (jsonRec.lastKnownDate);

		            var portstatuses = '';
		            
		            if (numPorts != '' && numPorts == 2) 
                    {
                        if(port1description != '')
                        {
                            portstatuses += "<br/><b>Port 1: </b>" + port1description + ": <strong><i>" + port1Status + "</i></strong>";
                        }
                        if(port2description != '')
                        {
                            portstatuses += "<br/><b>Port 2: </b>" + port2description + ": <strong><i>" + port2Status + "</i></strong>";
                        }
		            }
		            else if(numPorts != '')
                    {
                        if(port1description != '')
                        {
                            portstatuses += "<br/><b>Port 1: </b>" + port1description + ": <strong><i>" + port1Status + "</i></strong>";
                        }
		            }
		            
					/*markerHtml = "<b>" + jsonRec.DeviceName + "</b><br/>" + jsonRec.address;
					if(jsonRec.statusName != '') {
						markerHtml = markerHtml + "<br/><i>" + jsonRec.statusName + "</i>";
					}
					if(fault != '') {
						markerHtml = markerHtml + "<br/><i>" + fault + "</i>";
					}
					if(hiddenFlag != '') {
						markerHtml = markerHtml + "<br/><i>" + hiddenFlag + "</i>";
					}*/
					//markerHtml = markerHtml + "<br/><b>Charger Level:</b> " + chargerlevel + "<br/><b>No. of ports:</b> " + numPorts + "<br/>" + portstatuses + jsonRec.submitButton + "</div>";
	                //markerHtml = markerHtml + "<br/><b>Charger Level:</b> " + chargerlevel + (numPorts <= 1 ? '' : "<br><b>No. of ports:</b> " + numPorts) + "<br/>" + portstatuses + jsonRec.submitButton + "<br/></div>";
					/* markerHtml = "<b>" + jsonRec.DeviceName + "</b><br/>" + jsonRec.address + "<br/><i>" + jsonRec.statusName + "</i><br/><i>"+fault+"</i><bt/><i>"+hiddenFlag+"</i></div>"; */
					//markerHtml = markerHtml +  portstatuses +"<br/>" + jsonRec.submitButton + "</div>"
		            
		            markerHtml = "<div id='mapInfoWindowNCL'><div class='mapInfoWindow'><b> "+_("Name")+": </b>"+ jsonRec.DeviceName + "<br/> <b> "+_("Address")+": </b>"+ address + "<br/>";
					markerHtml += (description !=''? "<b> "+_("Description")+": </b>" + description +" <br />" : '');
		            
                    /*
                    if (numPorts != '' && numPorts == 2) {
		                markerHtml += "<b>Port 1:</b> " + port1description + ":<strong><i>" + port1Status + "</i></strong><br/>";
		                markerHtml += "<b>Port 2:</b> " + port2description + ":<strong><i>" + port2Status + "</i></strong><br/>";
		            }
		            else if (numPorts != '' && port2Status != '') {
		                markerHtml += "<b>Port 2:</b>" + port2description + ":<strong><i>" + port2Status + "</i></strong><br/>";
		            }
		            else if(numPorts != '') {
		                markerHtml += "<b>Port 1:</b> " + port1description + ":<strong><i>" + port1Status + "</i></strong><br/>";
		            }
		            // markerHtml += action;
		            markerHtml += "</div>";
		            */
		            
		            if(lastKnown != '' && lastKnownDate != '')
                    {
                        markerHtml += "<strong>" + lastKnown + ":</strong> " + lastKnownDate + "<br/>";
                    }
                    
                    if (numPorts == 2) 
                    {
                        
                        if(port1description != '')
                        {
                            markerHtml += "<b>Port 1:</b> " + port1description;
                        }
                        if(port1Status != '')
                            markerHtml += ":<strong><i>" + port1Status + "</i></strong>";
                        markerHtml += "<br/>";
                        
                        markerHtml += "<b>Port 2:</b> " + port2description;
                        if(port2Status != '')
                            markerHtml += ":<strong><i>" + port2Status + "</i></strong>";
                        markerHtml += "<br/>";
                    }
                    else if (port2Status != '') 
                    {
                        if(port2description != '')
                        {
                            markerHtml += "<b>Port 2:</b>" + port2description;
                        }
                        if(port2Status != '')
                            markerHtml += ":<strong><i>" + port2Status + "</i></strong>";
                        markerHtml += "<br/>";
                    }
                    else 
                    {
                        if(port1description != '')
                        {
                            markerHtml += "<b>Port 1:</b> " + port1description;
                        }
                        if(port1Status != '')
                            markerHtml += ":<strong><i>" + port1Status + "</i></strong>";
                        markerHtml += "<br/>";
                    }
                    //markerHtml += action;
                    markerHtml += "</div>";
		            
		            
		            
				}
				markerTooltip = jsonRec.address;//jsonRec.DeviceName;
				statusID = jsonRec.statusID;
				changeStatus = jsonRec.changeStatus;
				modify = jsonRec.modify;
				dimValue = jsonRec.dimValue;
				if (changeStatus != true && modify != true)
					statusID = 0;

				var markerID = "";
				if (dragMarker == "true" || mapSideBar != "")
					markerID = jsonRec.deviceID;

				sideBarImage = "";
				sideBarTitle = "";
				sideBarDesc = "";
								
				if (mapSideBar != "") {
					sideBarImage = iconDir + jsonRec.imageName;
					sideBarTitle = jsonRec.DeviceName;
					sideBarDesc = jsonRec.address + '<br/><i>' + jsonRec.statusName +  "</i><br/><i>"+fault+"</i><bt/><i>"+hiddenFlag+"</i></div>";
				}

				addDeviceToMap(map, lat, lon, imageName, shadowImageName, markerTitle, markerHtml, markerTooltip, markerID, statusID, dimValue, sideBarImage, sideBarTitle, sideBarDesc);
				
				lat = parseFloat(lat);
				lon = parseFloat(lon);
				if (lat < minLat)
					minLat = lat;
				if (lat > maxLat)
					maxLat = lat;
				
				if (lon < minLon)
					minLon = lon;
				if (lon > maxLon)
					maxLon = lon;

			} //end for - add markers to map for each device
				
		} // end if - if there is atleast one device

		// if center and circle should be displayed
		if (centerAddress != '') {
    	centerMap(centerLat, centerLon, proximity);
    }
    else if(minLat!=maxLat || minLon!=maxLon) 
		{
			// Set Center based on all markers
      var centerLat = (minLat + maxLat) / 2;
      var centerLon = (minLon + maxLon) / 2;
      map.setCenter(new GLatLng(centerLat, centerLon), 13);

                  // Set Zoom level so that all markers are visible
      var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
      map.setZoom(map.getBoundsZoomLevel(bds));
    }
    /*
    else {
			// Set Center based on all markers
      var centerLat = (minLat + maxLat) / 2;
    	var centerLon = (minLon + maxLon) / 2;
    	map.setCenter(new GLatLng(centerLat, centerLon), 13);

			// Set Zoom level so that all markers are visible
      var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
      map.setZoom(map.getBoundsZoomLevel(bds));
    }
		*/
		
		if (newMarker == 'true') {
			initPage();
	  }

		if (addressDivName != "") {
	    $(addressDivName).innerHTML = address;
	    setVisible(addressDivName);
	  }
	
	  if (showPopupDiv!='true') {
	    setVisible(mapDivName);
	  }
	  
	  if (mapSideBar!='') {
	    $(mapSideBar).innerHTML = sideBarHTML;
	  }

/// Counties - START
		//showCountyLayer($(mapDivName));
		//addCountyLayers();
		if (countyCount > 0)
			loadCountyPoly(jsonObj.counties, minLat, minLon, maxLat, maxLon);
/// Counties - END

	} // end if - if map has been created
	else {
		map = displayMap(mapDivName, companyLat, companyLon, zoomLevel, overviewMap, mapType, mapScale);
	}
}

function displayMap(mapDivName, lat, lon, zoomLevel, overviewMap, mapType, mapScale) {
  if (GBrowserIsCompatible()) {
    map = new GMap2($(mapDivName));
		map.addControl(new GLargeMapControl());
    if (mapType != 'false')
			map.addControl(new GMapTypeControl());
    if (mapScale != 'false')
			map.addControl(new GScaleControl());
		if (lat != "" && lon != "" && zoomLevel != "")
    	map.setCenter(new GLatLng(lat, lon), zoomLevel);
    
		//if (overviewMap != 'false')
    	//map.addControl(new GOverviewMapControl());

    return map;
  }
}

function addDeviceToMap(map, lat, lon, imageName, shadowImageName, markerTitle, markerHtml, markerTooltip, markerID, statusID, dimValue, sideBarImage, sideBarTitle, sideBarDesc) 
{
	var markerIcon = new GIcon(G_DEFAULT_ICON);

	if (imageName != "") {
		var typeImage = iconDir + imageName;
		markerIcon.image = typeImage;
		markerIcon.iconSize = new GSize(30,30);
		markerIcon.iconAnchor = new GPoint(10,20);
		//markerIcon.shadowSize = new GSize(50,30);
		markerIcon.shadowSize = new GSize(0,0);
		
		if (shadowImageName == "0") {
			markerIcon.shadowSize = new GSize(0,0);
		}
		else if (shadowImageName != "") {
			var shadowImage = iconDir + shadowImageName;
			markerIcon.shadow = shadowImage;
			markerIcon.shadowSize = new GSize(0,0);
		}

	}
	// Set up our GMarkerOptions object
	markerOptions = { icon:markerIcon};

	if (markerTooltip != "") {
		markerOptions.title = markerTooltip;
	}
	if (markerID != "") {
		markerOptions.my_id = markerID;
		markerOptions.draggable= true;
	}
	
	var point = new GLatLng(lat, lon);
	var gmrk = new GMarker(point, markerOptions);
	if (markerHtml != "") {
		GEvent.addListener(gmrk, "click", function() { 
            gmrk.openInfoWindowHtml(markerHtml); 
            //if (Coulomb_slider != undefined && Coulomb_slider == true) { devicemgmtLoad(markerID, statusID, dimValue); } 
            });
		GEvent.addListener(gmrk, "infowindowclose", function() { 
            //if (Coulomb_slider != undefined && Coulomb_slider == true) { devicemgmtUnLoad(markerID); } 
            });
	}
	
	if (markerID != "") {
		GEvent.addListener(gmrk, 'dragend', function() {dragEndHandler(gmrk)});
		my_markers["device"+markerID] = gmrk;
		gmrk.disableDragging();
	}
	map.addOverlay(gmrk);
	if (sideBarTitle != "" || sideBarDesc != "" || sideBarImage != "") {

		if (sideBarTitle != "")
			sideBarHTML = sideBarHTML + '<img src=\"'+sideBarImage+'\" class="iconbottom">&nbsp;' + '<a href=\"javascript:click_sidebar(\'device' + markerID + '\')\"><b>' + sideBarTitle + '<\/b><\/a>';
		if (sideBarDesc != "")
			sideBarHTML = sideBarHTML + '<br />' + sideBarDesc;
		sideBarHTML = sideBarHTML + '<br />';
	}
  //marker.openInfoWindowHtml(address);
	return true;
}

function click_sidebar(idx) {
	GEvent.trigger(my_markers[idx], 'click');
}

function showMap(mapDivName, addressDivName, deviceID, zoomLevel, obj, show, overviewMap, mapType, mapScale)
{
//	var pars = 'mapDivName=' + mapDivName + '&addressDivName=' + addressDivName + '&deviceID=' + deviceID + '&zoomLevel=' + zoomLevel + '&obj=' + obj;
	var pars = 'deviceID=' + deviceID;
	
	if (show == "") {
		show = 'true';
	}
	
	var myAjax = new Ajax.Request(
		deviceURI, 
		{
			method: 'POST', 
			parameters: pars, 
			onComplete: function(response){getMap(response, mapDivName, zoomLevel, addressDivName, show, "", "", "", "", "", overviewMap, mapType, mapScale, "")}
		});
		
		if (obj != "") {
			setDivPos("dhtml_goodies_id1", obj);
		}
	
}



// Loads the URL in the DIV using AJAX
function reLoadDiv2(divName, url, post, startLocation, newMarker, overviewMap, mapType, mapScale) {
	new Ajax.Request (
				url, 
				{
					method:'post',
					postBody:post,
					onComplete: function(response){getMap(response, divName, 13, "", 'false', startLocation, newMarker, "", "", "", overviewMap, mapType, mapScale, "")}
				});
}
function reLoadDiv1(divName, url, post) {
	new Ajax.Updater (divName, url, {method:'post',postBody:post});
}

function reLoadByParam(divName, url, formName, startLocation, showMap, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar)
{
	mapSideBar = (mapSideBar == null) ? "" : mapSideBar;
//  a = typeof(a) != 'undefined' ? a : 42;

	post = $(formName).serialize();
	if (showMap == "true") {
	new Ajax.Request (
				url, 
				{
					method:'post',
					postBody:post,
					onComplete: function(response){isMap(response, divName, 13, "", 'false', startLocation, showMap, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar); }
				});
	}
	else {
	new Ajax.Updater (
				divName, 
				url, 
				{
					method:'post',
					postBody:post
				});
	}
}

function loadDevices(divName, url, formName, map)
{
	post = $(formName).serialize();
	new Ajax.Request (
				url, 
				{
					method:'post',
					postBody:post,
					onComplete: function(response){addIconstoMap(response, map); }
				});
}
function addIconstoMap(responseJSON, map){
	jsonText = responseJSON.responseText;
	jsonObj = jsonText.parseJSON();

	recCount = (jsonObj.count == null) ? 0 : jsonObj.count;
	if (recCount > 0) {
			// Add markers for devices
			for (var ctr=0; ctr<recCount; ctr=ctr+1) {
				jsonRec = jsonObj.record[ctr];
				lat = jsonRec.lat;
				lon = jsonRec.lon;
				//type = jsonRec.deviceType;
				imageName = jsonRec.imageName;
				address = jsonRec.address;
				addDeviceToMap(map, lat, lon, imageName,"0", address, "", address, "", "", "", "", "", "");
			}
		}
	
	//address = jsonObj.location;
	//addDeviceToMap(map, lat, lon, "", "", address, "", address, "", "", "", "", "", "");
}
function reLoadMapByParam(divName, url, formName, startLocation, showTheMap, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar, loadingDiv)
{
	mapSideBar = (mapSideBar == null) ? "" : mapSideBar;
//  a = typeof(a) != 'undefined' ? a : 42;

	post = $(formName).serialize();
	new Ajax.Request (
				url, 
				{
					method:'post',
					postBody:post,
					onComplete: function(response){isMap(response, divName, 13, "", 'false', startLocation, showTheMap, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar, loadingDiv); }
				});
}

function isMap(responseJSON, mapDivName, zoomLevel, addressDivName, showPopupDiv, startLocation, showMap, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar) {

	if (showMap == "true") {
		getMap(responseJSON, mapDivName, zoomLevel, addressDivName, showPopupDiv, startLocation, newMarker, centerAddress, showLocation, dragMarker, overviewMap, mapType, mapScale, mapSideBar);
	}
}

function centerMap(centerLat, centerLon, proximity)
{

	minLat = maxLat = centerLat = parseFloat(centerLat);
	minLon = maxLon = centerLon = parseFloat(centerLon);
	proximity = parseFloat(proximity);

	var d2r = Math.PI / 180;   // degrees to radians
	var r2d = 180 / Math.PI;   // radians to degrees
	var earthsradius = 3963; // 3963 is the radius of the earth in miles

	var points = 80;

	// find the raidus in lat/lon
	var rlat = (proximity / earthsradius) * r2d;
	var rlng = rlat / Math.cos(centerLat * d2r);
	
	var extp = new Array();
	for (var i=0; i < points+1; i++) // one extra here makes sure we connect the
	{
		var theta = Math.PI * (i / (points/2));
		ex = centerLon + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
		ey = centerLat + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
		extp.push(new GPoint(ex, ey));

		if (ey < minLat)
			minLat = ey;
		if (ey > maxLat)
			maxLat = ey;
		
		if (ex < minLon)
			minLon = ex;
		if (ex > maxLon)
			maxLon = ex;

	}
	
	//map.addOverlay(new GPolyline(extp, "#000000", 2));

	// Set Center
	map.setCenter(new GLatLng(centerLat, centerLon), 13);

	// Set Zoom level so that all markers are visible
  var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
  map.setZoom(map.getBoundsZoomLevel(bds));
}

function dragEndHandler(marker) 
{
	try {
		$('Latitude').value=marker.getPoint().lat().toFixed(6);
		$('Longitude').value=marker.getPoint().lng().toFixed(6);
	}
	catch(e) {
		alert('Exception in dragHandler: ' + e);
	}
}

function reverseGeocoder(point, elem)
{
	var rg = new GReverseGeocoder(map);
  // add listners for the results
  GEvent.addListener(rg, "load", function (placemark) {goodresult(placemark, rg, elem);});
  GEvent.addListener(rg, "error", function () {badresult(elem);});
  rg.reverseGeocode(point);
}

// is called with a placemark if the reverse geocode request was successfull
// sets the result div
function goodresult(placemark, rg, elem) {
  elem.value = rg.getPlacemarkProperty(placemark, "address");
}

// is called if the reverse geocode request was unsuccessfull
function badresult(elem) {
  elem.value = "";
}



/****************************************************************
Name			: loadMap
Purpose		: Load the map if valid data is retrieved from the specified URL
Variables	:
1.	requestSettings
 		Datatype	: Array
 		Detail		: AJAX Request related variables
		1.	url
				Datatype 	: string
				Detail		: URL that returns the data to load the map. Devices, Start location, etc.
		2.	formName
				Datatype	: string
				Detail		: Name of the form. 
										Used to retrieve the form elements as POST variables for sending request to the URL
2.	loadingSettings
 		Datatype	: Array
 		Detail		: Map loading related parameters
		1. 	mapDiv
				Datatype	: Object
				Detail		:	Div tag where the map should be displayed
		2. 	sideBarDiv
				Datatype	: Object
				Detail		: Div tag to display Side Bar on the map
										Markers on the map can have their coressponding list in the side bar
3.	mapSettings
 		Datatype	: Array
 		Detail		: Buttons/tools that need to be displayed on the map
		1. 	overviewMap
				Datatype	: Boolean
				Detail		: TRUE - display overviewMap on the map
		2. 	mapLarge
				Datatype	: Boolean
				Detail		: TRUE - display Zoom feature on the map
		3. 	mapType
				Datatype	: Boolean
				Detail		: TRUE - display Map Type buttons on the map
		4. 	mapScale
				Datatype 	: Boolean
				Detail		: TRUE - display the Scale on the map
		5. 	zoomLevel
				Datatype	: integer
				Detail		: Zoom level for the map
4.	startSettings
 		Datatype	: Array
 		Detail		: Settings for Start Address on the map
		1. 	startLocation
				Datatype 	: Boolean
				Detail		: TRUE - if startLocation needs to be displayed with marker on the map
		2. 	showLocation
				Datatype 	: Boolean
				Detail		: TRUE - 
		3. 	centerAddress
				Datatype	: Boolean
				Detail		: TRUE - if the Start Location needs to be centered with a circle displaying the proximity
5.	markerSettings
		Datatype	: Array
		Detail		: Settings for markers	
		1. 	newMarker
				Datatype 	: Boolean
				Detail		: TRUE - if new marker should be allowed to be added by the user to the map
		2. 	dragMarker
				Datatype	: Boolean
				Detail		: TRUE - if the markers need to be set as draggable in the map
****************************************************************/
function loadMap
					(
						requestSettings, 
						loadingSettings, 
						mapSettings, 
						startSettings, 
						markerSettings,
						layerSettings,
						postFunction
					)
{

	// Set default values to parameters if not specified
	//  a = typeof(a) != 'undefined' ? a : 42;
	url = (requestSettings['url'] == null) ? false : requestSettings['url'];
	formName = (requestSettings['formName'] == null) ? false : requestSettings['formName'];

	mapDiv = (loadingSettings['mapDiv'] == null) ? false : loadingSettings['mapDiv'];

	// Check if url or mapDiv is empty
	if ( (!url) || (!mapDiv) ) {
		return false;
	}

	// Set POST variables as serialized if formName is specified
	post = "";
	if (formName) {
		post = $(formName).serialize();
	}
	
	// Set default variables for calling funtion setMap
	var popupSettings = new Array();
	popupSettings['addressDiv'] = false;
	popupSettings['showPopupDiv'] = false;
	
	// Make the AJAX request to retrieve data to load map
	new Ajax.Request 
			(
				url, 
				{
					method:'post',
					postBody:post,
					onComplete: function(response)
												{
													responseText = response.responseText;
													setMap
													(
														responseText, 
														loadingSettings, 
														popupSettings, 
														mapSettings, 
														startSettings, 
														markerSettings,
														layerSettings,
														postFunction
													); 
												}
				}
			);
}


/****************************************************************
Name			: setMap
Purpose		: Display the map along with the markers
Variables	:
1. 	responseJSONText
		Datatype 	: string
		Detail		: JSON containing the data to load the map. Devices, Start location, etc.
2.	loadingSettings
 		Datatype	: Array
 		Detail		: Map loading related parameters
		1. 	mapDiv
				Datatype	: Object
				Detail		:	Div tag where the map should be displayed
		2. 	sideBarDiv
				Datatype	: Object
				Detail		: Div tag to display Side Bar on the map
										Markers on the map can have their coressponding list in the side bar
3.	popupSettings
 		Datatype	: Array
 		Detail		: Popup map related parameters
		1. 	showPopupDiv
				Datatype 	: Boolean
				Detail		: TRUE - if popup map needs to be displayed
	 	2. 	addressDiv
				Datatype 	: object
				Detail		: div tag name where the address needs to be displayed. This is specifically for Popup Maps
4.	mapSettings
 		Datatype	: Array
 		Detail		: Buttons/tools that need to be displayed on the map
		1. 	overviewMap
				Datatype	: boolean
				Detail		: TRUE - display overviewMap on the map
		2. 	mapLarge
				Datatype	: boolean
				Detail		: TRUE - display Zoom feature on the map
		3. 	mapType
				Datatype	: boolean
				Detail		: TRUE - display Map Type buttons on the map
		4. 	mapScale
				Datatype 	: boolean
				Detail		: TRUE - display the Scale on the map
		5. 	zoomLevel
				Datatype	: integer
				Detail		: Zoom level for the map
5.	startSettings
 		Datatype	: Array
 		Detail		: Settings for Start Address on the map
		1. 	startLocation
				Datatype 	: Boolean
				Detail		: TRUE - if startLocation needs to be displayed with marker on the map
		2. 	showLocation
				Datatype 	: Boolean
				Detail		: TRUE - 
		3. 	centerAddress
				Datatype	: Boolean
				Detail		: TRUE - if the Start Location needs to be centered with a circle displaying the proximity
6.	markerSettings
		Datatype	: Array
		Detail		: Settings for markers	
		1. 	newMarker
				Datatype 	: Boolean
				Detail		: TRUE - if new marker should be allowed to be added by the user to the map
		2. 	dragMarker
				Datatype	: Boolean
				Detail		: TRUE - if the markers need to be set as draggable in the map
****************************************************************/
function setMap
					(
						responseJSONText, 
						loadingSettings, 
						popupSettings, 
						mapSettings, 
						startSettings, 
						markerSettings,
						layerSettings,
						postFunction
					) 
{

	 
	// Set default values to parameters if not specified
	responseJSONText = (responseJSONText == null) ? false : responseJSONText;

	mapDiv = (loadingSettings['mapDiv'] == null) ? false : loadingSettings['mapDiv'];
	sideBarDiv = (loadingSettings['sideBarDiv'] == null) ? false : loadingSettings['sideBarDiv'];

	showPopupDiv = (popupSettings['showPopupDiv'] == null) ? false : popupSettings['showPopupDiv'];
	addressDiv = (popupSettings['addressDiv'] == null) ? false : popupSettings['addressDiv'];

	startLocation = (startSettings['startLocation'] == null) ? false : startSettings['startLocation'];
	showLocation = (startSettings['showLocation'] == null) ? false : startSettings['showLocation'];
	centerAddress = (startSettings['centerAddress'] == null) ? false : startSettings['centerAddress'];

	newMarker = (markerSettings['newMarker'] == null) ? false : markerSettings['newMarker'];
	
	isDraggablePropEnable = false;
	
	if(markerSettings['dragMarker'] != undefined)
	{
		isDraggablePropEnable = true;
	}
	 
	dragMarker = (markerSettings['dragMarker'] == null) ? false : markerSettings['dragMarker'];
	resetMarker = (markerSettings['resetMarker'] == null) ? false : markerSettings['resetMarker'];
	toggleMarker = (markerSettings['toggleMarker'] == null) ? false : markerSettings['toggleMarker'];
	markerHtml = (markerSettings['markerHtml'] == null) ? true : markerSettings['markerHtml'];
	markerTooltip = (markerSettings['markerTooltip'] == null) ? true : markerSettings['markerTooltip'];

	showLayer = (layerSettings['showLayer'] == null) ? false : layerSettings['showLayer'];
	zoomLayer = (layerSettings['zoomLayer'] == null) ? false : layerSettings['zoomLayer'];
	hiliteMarkers = (layerSettings['hiliteMarkers'] == null) ? false : layerSettings['hiliteMarkers'];
	
	postFunctionName = (postFunction['name'] == null) ? false : postFunction['name'];
	postFunctionArgs = (postFunction['args'] == null) ? false : postFunction['args'];
	setInfoWindowAnchor = (markerSettings['setInfoWindowAnchor'] != undefined && markerSettings['setInfoWindowAnchor'] != null)?markerSettings['setInfoWindowAnchor']:false;
	
	savePosition = (mapSettings['savePosition'] != undefined && mapSettings['savePosition'] != null)?mapSettings['savePosition']:false;
	
	// Check if Response JSON or mapDiv is empty
	if ( (!responseJSONText) || (!mapDiv) ) {
		return false;
	}

	// set map to FALSE before loading the next map
	map = false;
	mapErrorText = "";
	
	// get the Response JSON text
	jsonText = responseJSONText;

	var recCount = 0;

	if (jsonText == "") {
		mapErrorText = mapErrorText + "Error retrieving devices \n";
		// set startLocation to FALSE
		startLocation = false;
	}
	else {
		// parse the Response JSON as JSON object
		jsonObj = jsonText.parseJSON();
		// check if map coordinates could be retrieved from location address if requested
		var getTheMap = (jsonObj.getMap == null) ? true : jsonObj.getMap;
		
		if (!getTheMap) {
			errorMap(loadingSettings, postFunctionName, postFunctionArgs)
			return false;
		}
	
		// get count of records in the Response JSON
		recCount = jsonObj.Device.count;
	}
	
	// If map has not been created
	if (!map) {

		// if Start Location needs to be displayed on the map
		if (startLocation) { 
			lat = jsonObj.lat;
			lon = jsonObj.lon;
			proximity = jsonObj.proximity;
			
			// set variables
			locationSettings = new Array();
			locationSettings['lat'] = lat;
			locationSettings['lon'] = lon;
			
			// display the map
			map = createMap
							(
								mapDiv, 
								locationSettings,
								mapSettings
							);
		}

		else if (showLayer && jsonObj.Layer.type == 'proximity') {
			
			proximityRec = jsonObj.Layer.record;

			// set variables
			locationSettings = new Array();
			locationSettings['lat'] = proximityRec.lat;
			locationSettings['lon'] = proximityRec.lon;

			// display the map
			map = createMap
							(
								mapDiv, 
								locationSettings,
								mapSettings
							);
			
		}	
		// if Start Location marker is not required, but there are markers to be displayed, set the map at the first marker
		else if (recCount > 0) { 
			jsonRec = jsonObj.Device.record[0];
			lat = jsonRec.lat;
			lon = jsonRec.lon;
			address = jsonRec.address;
			
			// if Popup Map needs to be displayed
		  if (showPopupDiv) {
				showWindow(mapDiv);
			}
	
			// set variables
			locationSettings = new Array();
			locationSettings['lat'] = lat;
			locationSettings['lon'] = lon;
			
			// display the map
			map = createMap
							(
								mapDiv, 
								locationSettings,
								mapSettings
							);
		
		}
	
	}
	
	// if map has been created
	if (map) {
	
		// set the location for the map as the Central location
		centerLat = minLat = maxLat = parseFloat(lat);
		centerLon = minLon = maxLon = parseFloat(lon);
		
		// if Start Location has to be displayed with marker
		if (startLocation) {
			if (showLocation) {
				address = jsonObj.location;
				
				// Set variables to add marker to map
				markerSettings = new Array();
				markerSettings['imageName'] = false; // set default image
				markerSettings['toggleImageName'] = false; // set default image
				markerSettings['shadowImageName'] = false; // set default image
				markerSettings['markerTitle'] = address;
				markerSettings['markerHtml'] = false; // no info window required 
				if (markerTooltip)
					markerSettings['markerTooltip'] = address;
				markerSettings['statusID'] = false;
				markerSettings['dimValue'] = false;
				markerSettings['markerID'] = false;

				sideBarSettings = new Array();
				sideBarSettings['sideBarImage'] = false;
				sideBarSettings['sideBarTitle'] = false;
				sideBarSettings['sideBarClass'] = false;
				// add marker for Start Location
				addMarkerToMap
					(
						locationSettings, 
						markerSettings, 
						markerSettings['markerHtml'],
						sideBarSettings
					);

			}

			proximity = parseFloat(proximity);

		}

		// if records are retrieved
		if (recCount > 0) {

			var sideBarClass = 'trow2';

			// Add markers for devices
			for (var ctr=0; ctr<recCount; ctr=ctr+1) {

				jsonRec = jsonObj.Device.record[ctr];
				lat = jsonRec.lat;
				lon = jsonRec.lon;
				type = jsonRec.deviceType;
				deviceId = jsonRec.deviceID;
				imageName = jsonRec.imageName;
				toggleImageName = (jsonRec.toggleImageName == null)? false : jsonRec.toggleImageName;
				shadowImageName = false;
				//shadowImageName = jsonRec.shadowImageName;
				markerTitle = jsonRec.deviceGUID;
				lastKnown = (jsonRec.lastKnown == null) ? '' : (jsonRec.lastKnown);
                lastKnownDate = (jsonRec.lastKnownDate == null) ? '' : (jsonRec.lastKnownDate);
                
				var markerHtml = "";
				
				if(jsonRec.deviceName!='')
				{
					markerHtml += "<div class='mapInfoWindow' style='padding-top:5px;'><b>"+_('Name')+"</b>:&nbsp;"+jsonRec.deviceName + "<br/>" ;
				}
				if(jsonRec.fleetInfo != undefined && jsonRec.fleetInfo != '')
				{
					markerHtml += "<div class='mapInfoWindow'>"+jsonRec.fleetInfo + "<br/>" ;
				}
				
				if(jsonRec.address != '')
					markerHtml += "<b>"+_('Address')+"</b>:&nbsp;"+jsonRec.address;
	
				if(jsonRec.description != undefined && jsonRec.description != '')
				{
					markerHtml += "<br/><b>"+_('Description')+"</b>:&nbsp;"+jsonRec.description;
				}
                
    	            /* markerHtml += action; */
	            //markerHtml += "</div>";                
	            
	            if(lastKnown != '' && lastKnownDate != '')
                {
                    markerHtml += "<br/><strong>" + lastKnown + ":</strong> " + lastKnownDate + "";
                }
                
	            
				if(jsonRec.statusTextArray != undefined)
				{
					statusTextArray = jsonRec.statusTextArray;
					
					for(i = 0 ; i < statusTextArray.length; i++)
					{
						var status = statusTextArray[i];
						
						if(status.length > 0)
						{
							markerHtml += "&nbsp;<br/><b>"+_('Port')+"&nbsp;"+(status[0])+"</b>:&nbsp;"+status[1]+":&nbsp;<i><b>"+status[2]+"</b></i>";
							if(status[3] != '')
							{
								markerHtml += "&nbsp;(" +status[3]+")";
							}
						}			
					}
				}
				else
				{
				     numPorts = (jsonRec.numPorts == null) ? '' : ( jsonRec.numPorts );
                	 port1Status = (jsonRec.port1 == null) ? '' : ( jsonRec.port1 );
                     port2Status = (jsonRec.port2 == null) ? '' : ( jsonRec.port2 );
	                port1description = (jsonRec.port1description == null) ? '' : (jsonRec.port1description);
	                port2description = (jsonRec.port2description == null) ? '' : (jsonRec.port2description);
	
	                markerHtml += "<br/>";
	                
	                /*
		            if (numPorts != '' && numPorts == 2) {
		                markerHtml += "<b>Port 1:</b> " + port1description + ":<strong><i>" + port1Status + "</i></strong><br/>";
		                markerHtml += "<b>Port 2:</b> " + port2description + ":<strong><i>" + port2Status + "</i></strong><br/>";
		            }
		            else if (numPorts != '' && port2Status != '') {
		                markerHtml += "<b>Port 2:</b>" + port2description + ":<strong><i>" + port2Status + "</i></strong><br/>";
		            }
		            else if(numPorts != '') {
		                markerHtml += "<b>Port 1:</b> " + port1description + ":<strong><i>" + port1Status + "</i></strong><br/>";
		            }
		            */
		            
		            
		            
                    if (numPorts == 2) 
                    {
                        markerHtml += "<b>Port 1:</b> " + port1description;
                        if(port1Status != '')
                            markerHtml += ":<strong><i>" + port1Status + "</i></strong>";
                        markerHtml += "<br/>";
                        
                        markerHtml += "<b>Port 2:</b> " + port2description;
                        if(port2Status != '')
                            markerHtml += ":<strong><i>" + port2Status + "</i></strong>";
                        markerHtml += "<br/>";
                    }
                    else if (port2Status != '') 
                    {
                        markerHtml += "<b>Port 2:</b>" + port2description;
                        if(port2Status != '')
                            markerHtml += ":<strong><i>" + port2Status + "</i></strong>";
                        markerHtml += "<br/>";
                    }
                    else if(port1Status != '')
                    {
                        markerHtml += "<b>Port 1:</b> " + port1description;
                        if(port1Status != '')
                            markerHtml += ":<strong><i>" + port1Status + "</i></strong>";
                        markerHtml += "<br/>";
                    }
                    //markerHtml += action;
                    //markerHtml += "</div>";
		            
					
				}	
	                
				hiddenFlag = '';
			
				if(jsonRec.deviceHiddenFlag != undefined)
				{
					hiddenFlag = jsonRec.deviceHiddenFlag;
		
					markerHtml += "<br/>"+hiddenFlag;
				}
				
				if (markerTooltip)
					markerTooltip = jsonRec.address;
				statusID = jsonRec.statusID;
				
				// storing device status ids for all the devices.
				if(device_status_ids)
					device_status_ids[jsonRec.deviceID] = new Array(statusID, jsonRec.statusID_1, jsonRec.alarmStatus);
				
				changeStatus = jsonRec.changeStatus;
				modify = jsonRec.modify;
				dimValue = jsonRec.dimValue;
				if ( (!changeStatus) && (!modify) )
					statusID = 0;

				markerID = false;
				if (dragMarker || sideBarDiv || resetMarker || toggleMarker)
					markerID = jsonRec.deviceID;

				sideBarImage = false;
				sideBarTitle = false;
				sideBarDesc = false;
				if (sideBarDiv) {
					sideBarImage = iconDir + jsonRec.imageName;
					sideBarTitle = jsonRec.address;
					sideBarClass = (sideBarClass=="trow2")? "trow1": "trow2";
				}

				// Set variables to add marker to map
				locationSettings = new Array();
				locationSettings['lat'] = lat;
				locationSettings['lon'] = lon;

				markerSettings = new Array();
				markerSettings['imageName'] = imageName; // set default image
				if (toggleImageName)
					markerSettings['toggleImageName'] = toggleImageName; // set toggle image
				markerSettings['shadowImageName'] = shadowImageName; // set default image
				markerSettings['markerTitle'] = markerTitle;
				markerSettings['markerHtml'] = markerHtml; // no info window required 
				markerSettings['markerTooltip'] = markerTooltip;
				markerSettings['markerID'] = markerID;
				markerSettings['statusID'] = statusID;
				markerSettings['dimValue'] = dimValue;
				markerSettings['resetMarker'] = resetMarker;
				markerSettings['toggleMarker'] = toggleMarker;
				markerSettings['deviceId'] = deviceId;

				sideBarSettings = new Array();
				sideBarSettings['sideBarImage'] = sideBarImage;
				sideBarSettings['sideBarTitle'] = sideBarTitle;
				sideBarSettings['sideBarClass'] = sideBarClass;
				
				if(isDraggablePropEnable)
				{
					markerSettings['dragMarker'] = dragMarker;
				}
			
				markerSettings['setInfoWindowAnchor'] = setInfoWindowAnchor;
				
				// add marker for Start Location
				addMarkerToMap
					(
						locationSettings, 
						markerSettings, 
						markerSettings['markerHtml'], 
						sideBarSettings
					);
				
				lat = parseFloat(lat);
				lon = parseFloat(lon);
				if (lat < minLat)
					minLat = lat;
				if (lat > maxLat)
					maxLat = lat;
				
				if (lon < minLon)
					minLon = lon;
				if (lon > maxLon)
					maxLon = lon;

			} //end for - add markers to map for each device
				
		} // end if - if there is atleast one device

		var zoomMap = false;
		
		// if center and circle should be displayed
		if (centerAddress) {

			// Set variables to add marker to map
			centerLocation = new Array();
			centerLocation['lat'] = centerLat;
			centerLocation['lon'] = centerLon;

    	drawProximityCircle(centerLocation, proximity);
    	zoomMap = true;
    }
    
    
		// if center and circle should be displayed - Start
		if (showLayer) {

			// Draw Circle
			if (jsonObj.Layer.type == 'proximity') {
			
				proximityRec = jsonObj.Layer.record;

				// set variables
				locationSettings = new Array();
				locationSettings['lat'] = proximityRec.lat;
				locationSettings['lon'] = proximityRec.lon;
				address = proximityRec.location;
				
				// Set variables to add marker to map
				markerSettings = new Array();
				markerSettings['imageName'] = false; // set default image
				markerSettings['shadowImageName'] = false; // set default image
				markerSettings['markerTitle'] = address;
				markerSettings['markerHtml'] = false; // no info window required 
				markerSettings['markerTooltip'] = address;
				markerSettings['statusID'] = false;
				markerSettings['dimValue'] = false;
				markerSettings['markerID'] = false;

				sideBarSettings = new Array();
				sideBarSettings['sideBarImage'] = false;
				sideBarSettings['sideBarTitle'] = false;
				sideBarSettings['sideBarClass'] = false;

				// add marker for Start Location
				addMarkerToMap
					(
						locationSettings, 
						markerSettings, 
						markerSettings['markerHtml'],
						sideBarSettings
					);

				proximity = parseFloat(proximityRec.proximity);

	    	drawProximityCircle(locationSettings, proximity);

			}

			// Draw Polygon
			if (jsonObj.Layer.type == 'polygon') {
    		//polygon = drawPolygon(jsonObj.Layer.record, zoomLayer);


    		polygonJSON = jsonObj.Layer.record;
    	
				pointCount = polygonJSON.count;
			
				var points = new Array();
			
				if (pointCount > 0) {
			
					polyRec = polygonJSON.points[0];
					minLat = maxLat = parseFloat(polyRec.lat);
					minLon = maxLon = parseFloat(polyRec.lon);
			
					// Add markers for devices
					for (var pctr=0; pctr<pointCount; pctr=pctr+1) {
			
						polyRec = polygonJSON.points[pctr];
						lon = polyRec.lon;
						lat = polyRec.lat;
						points.push(new GLatLng(parseFloat(lat),parseFloat(lon)));
			
						// Set Zoom level to display Polygon with maximum zoom
						if (zoomLayer) {
							lat = parseFloat(lat);
							lon = parseFloat(lon);
							if (lat < minLat)
								minLat = lat;
							if (lat > maxLat)
								maxLat = lat;
							
							if (lon < minLon)
								minLon = lon;
							if (lon > maxLon)
								maxLon = lon;
						}
						
					}
					var pointArray = [];
					pointArray.push(points);
					countycolor = "red";
					polylineEncoder = new PolylineEncoder();
					polygon = polylineEncoder.dpEncodeToGPolygon(pointArray, '#0099CC', 0.5 , 0.5 , countycolor, 0.50);
			
					map.addOverlay(polygon);
					
				}
    	}
			if (jsonObj.Layer.type == 'none') {
				polygon = 'none';
			}
			
    	if (polygon && hiliteMarkers) {

    		zoomMap = zoomLayer;

				// Highlight Markers related to polygon
    		if (hiliteMarkers) {
					//highlightMarkers(jsonObj.Layer.markers);
					
					markerJSON = jsonObj.Layer.markers;

					// get count of records in the Response JSON
					recCount = markerJSON.count;
				
					// if records are retrieved
					if (recCount > 0) {
				
						jsonRec = markerJSON.record;
				
						// Add markers for devices
						for (var ctr=0; ctr<recCount; ctr=ctr+1) {
				
							deviceID = jsonRec[ctr].deviceID;
							type = jsonRec[ctr].type;
							imageName = jsonRec[ctr].imageName;
							statusID = jsonRec[ctr].statusID;
				
							markerIcon = my_markers["device"+deviceID];
//							typeImage = iconDir + imageName;
//							markerIcon.setImage(typeImage);

							markerLatLng = markerIcon.getLatLng();
				
							if (polygon != 'none')
								setDeviceToGroup(deviceID, points, markerLatLng);
							//toggleIconImage(deviceID, 1);

							lat = parseFloat(markerLatLng.lat());
							lon = parseFloat(markerLatLng.lng());
							/*
							if (ctr==0) {
								minLat = maxLat = lat;
								minLon = maxLon = lon;
							}
							*/
							if (lat < minLat)
								minLat = lat;
							if (lat > maxLat)
								maxLat = lat;
							
							if (lon < minLon)
								minLon = lon;
							if (lon > maxLon)
								maxLon = lon;
				
						}
						// Set image for each marker - End
						
						// Set Center based on all markers
						var centerLat = (minLat + maxLat) / 2;
						var centerLon = (minLon + maxLon) / 2;
						map.setCenter(new GLatLng(centerLat, centerLon), 13);
						
						// Set Zoom level so that all markers are visible
						var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
						map.setZoom(map.getBoundsZoomLevel(bds));
				
					}
					// If markers are found for polygon - End

				}
			}
    }
		// if center and circle should be displayed - End

    if (!zoomMap) {
    
			// Set Center based on all markers
			var centerLat = (minLat + maxLat) / 2;
			var centerLon = (minLon + maxLon) / 2;
			map.setCenter(new GLatLng(centerLat, centerLon), 13);
			
			// Set Zoom level so that all markers are visible
			var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
			var browserName=navigator.appName; 
			var settempBound =4
			if (browserName=="Microsoft Internet Explorer")
				settempBound =4;
			else
				settempBound =4;
			if(map.getBoundsZoomLevel(bds)!=0) settempBound = map.getBoundsZoomLevel(bds);
			map.setZoom(settempBound);
    }
		if (newMarker) {
			initPage();
	  }
		if (addressDiv) {
	    addressDiv.innerHTML = address;
	    addressDiv.style.visibility = 'visible';
	  }
	  if (showPopupDiv) {
	    mapDiv.style.visibility = 'visible';
	  }
	  if (sideBarDiv) {
	    sideBarDiv.innerHTML = sideBarHTML;
	  }
/// Counties - START
		loadCounty = false; // check has been added by Riju on 9/19/2008 --- not required -- needs to be modified
		if (loadCounty) {
			loadCountyPoly(jsonObj.counties, minLat, minLon, maxLat, maxLon);
		}
/// Counties - END

	} // end if - if map has been created
	else {
		// set variables
		locationSettings = new Array();
		if(jsonObj.lat && jsonObj.lon){
			locationSettings['lat'] = jsonObj.lat;
			locationSettings['lon'] = jsonObj.lon;
			//proximity = 30.00;
			//alert(proximity);
		}
		else{
			locationSettings['lat'] = companyLat;
			locationSettings['lon'] = companyLon;
		}
		// display map with Company location
		map = createMap
						(
							mapDiv, 
							locationSettings,
							mapSettings
						);

		// Set Zoom level so that all markers are visible
    var bds = new GLatLngBounds(new GLatLng(companyLat, companyLon), new GLatLng(companyLat, companyLon));
    map.setZoom(map.getBoundsZoomLevel(bds));

	}

	if (!map) {
		errorMap(loadingSettings, postFunctionName, postFunctionArgs)
		return false;
	}
	
	if (mapErrorText != "") {
		alert(mapErrorText);
	}

	if (postFunctionName) {
		if (postFunctionArgs)
			eval(postFunctionName)(postFunctionArgs);
		else
			eval(postFunctionName)();
	}
	
	mgr = new MarkerManager(map);
	
	mgr.addMarkers(batch,0, 19);
	
	mgr.refresh();
	batch = [];
	
	if(savePosition != undefined && savePosition == true)
	{
		map.savePosition();
	}	
			
	return map;

}

// Reset Markers
function highlightMarkers(markerJSON)
{
	// get count of records in the Response JSON
	recCount = markerJSON.count;

	// if records are retrieved
	if (recCount > 0) {
		jsonRec = markerJSON.record;
		deviceID = jsonRec[0].deviceID;
		markerIcon = my_markers["device"+deviceID];
		var markerLatLng = markerIcon.getLatLng();
		minLat = maxLat = parseFloat(markerLatLng.lat());
		minLon = maxLon = parseFloat(markerLatLng.lng());

		// Add markers for devices
		for (var ctr=0; ctr<recCount; ctr=ctr+1) {

			deviceID = jsonRec[ctr].deviceID;
			type = jsonRec[ctr].deviceType;
			imageName = jsonRec[ctr].imageName;
			statusID = jsonRec[ctr].statusID;

			markerIcon = my_markers["device"+deviceID];
			typeImage = iconDir + imageName;
			markerIcon.setImage(typeImage);

			markerLatLng = markerIcon.getLatLng();

			lat = parseFloat(markerLatLng.lat());
			lon = parseFloat(markerLatLng.lng());
			if (lat < minLat)
				minLat = lat;
			if (lat > maxLat)
				maxLat = lat;
			
			if (lon < minLon)
				minLon = lon;
			if (lon > maxLon)
				maxLon = lon;

		}
		// Set image for each marker - End
		
		// Set Center based on all markers
		var centerLat = (minLat + maxLat) / 2;
		var centerLon = (minLon + maxLon) / 2;
		map.setCenter(new GLatLng(centerLat, centerLon), 13);
		
		// Set Zoom level so that all markers are visible
		var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
		map.setZoom(map.getBoundsZoomLevel(bds));

	}
	// If markers are found for polygon - End
	
}

// Draw Polygon
function drawPolygon(polygonJSON, zoom)
{

	pointCount = polygonJSON.count;

	var points = new Array();

	if (pointCount > 0) {

		polyRec = polygonJSON.points[0];
		minLat = maxLat = parseFloat(polyRec.lat);
		minLon = maxLon = parseFloat(polyRec.lon);

		// Add markers for devices
		for (var pctr=0; pctr<pointCount; pctr=pctr+1) {

			polyRec = polygonJSON.points[pctr];
			lon = polyRec.lon;
			lat = polyRec.lat;
			points.push(new GLatLng(parseFloat(lat),parseFloat(lon)));

			lat = parseFloat(lat);
			lon = parseFloat(lon);
			if (lat < minLat)
				minLat = lat;
			if (lat > maxLat)
				maxLat = lat;
			
			if (lon < minLon)
				minLon = lon;
			if (lon > maxLon)
				maxLon = lon;
		}
		var pointArray = [];
		pointArray.push(points);
		countycolor = "red";
		polylineEncoder = new PolylineEncoder();
		polygon = polylineEncoder.dpEncodeToGPolygon(pointArray, '#0099CC', 0.5 , 0.5 , countycolor, 0.50);
		map.addOverlay(polygon);
		// Set Zoom level to display Polygon with maximum zoom
		if (zoom) {
			// Set Center based on all markers
        var centerLat = (minLat + maxLat) / 2;
    	var centerLon = (minLon + maxLon) / 2;
    	map.setCenter(new GLatLng(centerLat, centerLon), 13);
	    var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
	    map.setZoom(map.getBoundsZoomLevel(bds));
	  }
		return polygon;
	}
}

// Mark County
function loadCountyPoly(countyJSON, minLat, minLon, maxLat, maxLon) {
//	map.clearOverlays();

	countyCount = countyJSON.count;
	polylineEncoder = new PolylineEncoder();

	if (countyCount > 0) {

		// Add polygons for counties
		for (var ctr=0; ctr<countyCount; ctr=ctr+1) {

			countyRec = countyJSON.record[ctr];
			countyid = countyRec.countyid
			countycolor = countyRec.countycolor;

			var actualWidth = (((parseInt(countyRec.actual.actual)/100)*31)+1);
			var sheddableWidth = (((parseInt(countyRec.actual.sheddable)/100)*31)+1);

			var countyHtml = new Array();
			countyHtml['actual'] = "<b>County: " + countyRec.countyname + "<br/><br/>Load:</b>" +
'<div style="width:' + sheddableWidth + 'px;background:blue;border:0px solid white;color:white;font-weight: bold;">'+
'&nbsp;Sheddable - ' + countyRec.actual.sheddable + 
'</div>'+
'<div style="width:' + actualWidth + 'px;background:red;border:0px solid white;color:white;font-weight: bold;">'+
'&nbsp;Actual - ' + countyRec.actual.actual + 
'</div>'+
'<div>'+
'<div style="width:311px;border-top:2px solid;"></div>'+
'<div style="width:30px;height:5px;border-left:1px solid;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;"></div>'+
'<div style="width:15px;height:5px;border-right:0px solid;float:left;text-align:left;">0</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">100</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">200</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">300</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">400</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">500</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">600</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">700</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">800</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">900</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">1000 <b>MW</b></div>'+
'</div>'
+ "<br/><br/>";
			actualWidth = (((parseInt(countyRec.shed.actual)/100)*31)+1);
			sheddableWidth = (((parseInt(countyRec.shed.sheddable)/100)*31)+1);
			countyHtml['shed'] = "<b>County: " + countyRec.countyname + "<br/><br/>Load:</b>" +
'<div style="width:' + actualWidth + 'px;background:red;border:0px solid white;color:white;font-weight: bold;">'+
'&nbsp;Actual - ' + countyRec.shed.actual + 
'</div>'+
'<div>'+
'<div style="width:311px;border-top:2px solid;"></div>'+
'<div style="width:30px;height:5px;border-left:1px solid;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;border-right:1px solid;float:left;"></div>'+
'<div style="width:30px;height:5px;"></div>'+
'<div style="width:15px;height:5px;border-right:0px solid;float:left;text-align:left;">0</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">100</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">200</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">300</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">400</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">500</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">600</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">700</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">800</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">900</div>'+
'<div style="width:31px;height:5px;border-right:0px solid;float:left;text-align:center;">1000 <b>MW</b></div>'+
'</div>'
+ "<br/><br/>";

			areacount = countyRec.count;

			if (areacount > 0) {
	
				// Add markers for devices
				for (var actr=0; actr<areacount; actr=actr+1) {
	
					areaRec = countyRec.record[actr];

					newcountyid = countyid;
					if (actr>0)
					 newcountyid = countyid + actr;

					polycount = areaRec.count;
		
					var points = new Array();
//					var points = new Object();
		
					if (polycount > 0) {
			
						// Add markers for devices
						for (var pctr=0; pctr<polycount; pctr=pctr+1) {

							polyRec = areaRec.record[pctr];
							lon = polyRec.lon;
							lat = polyRec.lat;
							points.push(new GLatLng(parseFloat(lat),parseFloat(lon)));

//							points.push(areaRec.record[pctr]);

//							polyRec = polylineEncoder.pointsToLatLngs(points);
//							lon = polyRec.lon;
//							lat = polyRec.lat;

							lat = parseFloat(lat);
							lon = parseFloat(lon);
							if (lat < minLat)
								minLat = lat;
							if (lat > maxLat)
								maxLat = lat;
							
							if (lon < minLon)
								minLon = lon;
							if (lon > maxLon)
								maxLon = lon;
						}
		
						//map.addOverlay(new GPolyline(points, countycolor, 3, 1));

/****
						var polylines = new Array();
						points.points = areaRec.record[0];
						points.levels = areaRec.record[1];
						points.color = countycolor;
						points.opacity = 0.50;
						points.weight = 0.50;
						points.numLevels = 18;
						points.zoomFactor = 2;
						polylines[0] = points;

						var polylines = new GPolyline.fromEncoded({
														    color: countycolor,
														    opacity: 0.50,
														    weight: 0.50,
														    points: areaRec.record[0],
														    levels: areaRec.record[1],
														    zoomFactor: 2,
														    numLevels: 18
														});
						points[0] = polylines;
						// GPolygon(points,  strokeColor?,  strokeWeight?,  strokeOpacity?,  fillColor?,  fillOpacity?)
						countyPolygon = new GPolygon.fromEncoded(polylines, '#0099CC', 0.5 , 0.5 , countycolor, 0.50);	
*******/
/* */
						// dpEncodeToGPolygon(pointsArray, boundaryColor?, boundaryWeight?, boundaryOpacity?, fillColor?, fillOpacity?, fill?, outline?)
						var pointArray = [];
						pointArray.push(points);
						countyPolygon = polylineEncoder.dpEncodeToGPolygon(pointArray, '#0099CC', 0.5 , 0.5 , countycolor, 0.50);
/* */		
						GEvent.addListener(countyPolygon, "click", function(latlng) { setLatLng(latlng); });
						GEvent.addListener(map, "click", function(overlay, latlng) { checkPolygon(overlay, latlng); });
		
						map.addOverlay(countyPolygon);
		
						polylayers[newcountyid] = countyPolygon;
						polyHtml[newcountyid] = countyHtml;
		
					}

				}
				
			}

		}

    var centerLat = (minLat + maxLat) / 2;
  	var centerLon = (minLon + maxLon) / 2;
  	map.setCenter(new GLatLng(centerLat, centerLon), 13);

		// Set Zoom level so that all markers are visible
    var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
    map.setZoom(map.getBoundsZoomLevel(bds));
		
	}
}

function setLatLng(latlng)
{

	polyLatLng = latlng;

}


function checkPolygon(overlay, latlng)
{

	for(countyid in polylayers) {

		if (polylayers[countyid] == overlay) {
		
			statusID = 'actual';
			if (checkShed)
				statusID = $('vars'+countyid).value;
				
			map.openInfoWindowHtml(polyLatLng, polyHtml[countyid][statusID])
			break;
		}

	}

}

/****************************************************************
Name			: errorMap
Purpose		: Display the map Div with error message
Returns		:	Null
Variables	:
1.	loadingSettings
 		Datatype	: Array
 		Detail		: Map loading related parameters
		1. 	mapDiv
				Datatype	: Object
				Detail		:	Div tag where the map should be displayed
		2. 	sideBarDiv
				Datatype	: Object
				Detail		: Div tag to display Side Bar on the map
										Markers on the map can have their coressponding list in the side bar
****************************************************************/
function errorMap(loadingSettings, postFunctionName, postFunctionArgs)
{
	mapDiv = (loadingSettings['mapDiv'] == null) ? false : loadingSettings['mapDiv'];
	sideBarDiv = (loadingSettings['sideBarDiv'] == null) ? false : loadingSettings['sideBarDiv'];

	if (mapDiv)
		mapDiv.innerHTML = "<div class=\"error\">Map could not be retrieved</div>";
	if (sideBarDiv)
		sideBarDiv.innerHTML = "<div class=\"error\">Data could not be retrieved</div>";
	if (postFunctionName) {
		if (postFunctionArgs)
			eval(postFunctionName)(postFunctionArgs);
		else
			eval(postFunctionName)();
	}
	return;
}
/****************************************************************
Name			: createMap
Purpose		: Display the map with the specified coordinates
Returns		:	Success - map object
						Failure - boolean FALSE
Variables	:
1. 	mapDiv
		Datatype 	: object
		Detail		:	div tag where the map should be displayed
2. 	locationSettings
		Datatype	: Array
		Detail		: Default location geocodes
		1.	lat
				Datatype	: signed decimal
				Detail		: Latitude of the location to be displayed on the map
		2. 	lon
				Datatype	: signed decimal
				Detail		: Longitude of the location to be displayed on the map
3.	mapSettings
 		Datatype	: Array
 		Detail		: Buttons/tools that need to be displayed on the map
		1. 	overviewMap
				Datatype	: boolean
				Detail		: TRUE - display overviewMap on the map
		2. 	mapLarge
				Datatype	: boolean
				Detail		: TRUE - display Zoom feature on the map
		3. 	mapType
				Datatype	: boolean
				Detail		: TRUE - display Map Type buttons on the map
		4. 	mapScale
				Datatype 	: boolean
				Detail		: TRUE - display the Scale on the map
		5. 	zoomLevel
				Datatype	: integer
				Detail		: Zoom level for the map
****************************************************************/
function createMap
					(
						mapDiv, 
						locationSettings,
						mapSettings
					) 
{
	// check if browser can display Google map
  if (GBrowserIsCompatible()) {

		// set default values to parameters
		mapDiv = (mapDiv == null) ? false : mapDiv;

		lat = (locationSettings['lat'] == null) ? false : locationSettings['lat'];
		lon = (locationSettings['lon'] == null) ? false : locationSettings['lon'];

		overviewMap = (mapSettings['overviewMap'] == null) ? false : mapSettings['overviewMap'];
		mapLarge = (mapSettings['mapLarge'] == null) ? false : mapSettings['mapLarge'];
		mapType = (mapSettings['mapType'] == null) ? false : mapSettings['mapType'];
		mapScale = (mapSettings['mapScale'] == null) ? false : mapSettings['mapScale'];
		zoomLevel = (mapSettings['zoomLevel'] == null) ? 13 : mapSettings['zoomLevel'];

		// if mapDiv is empty or latitude or longtidue is not specified
		if ( (!mapDiv) || (!lat) || (!lon) ) {
			return false;
		}

		// show the Divs
		if (mapDiv)
			mapDiv.style.display = 'block';

		// create new map
    map = new GMap2(mapDiv);

		if (map) {

			// set Location to the center of the map
	  	map.setCenter(new GLatLng(lat, lon), zoomLevel);
	
			// display Zoom feature on the map
	    if (mapLarge)
				map.addControl(new GLargeMapControl());
			// display Map Type buttons on the map
	    if (mapType)
				map.addControl(new GMapTypeControl());
			// display the Scale on the map
	    if (mapScale)
				map.addControl(new GScaleControl());
			// display overviewMap on the map
	    //if (overviewMap)
	    	//map.addControl(new GOverviewMapControl());
	  
	  }
		
    return map;

  }

	// return FALSE if map cannot be displayed on the browser
  return false;

}
/****************************************************************
Name			: addMarkerToMap
Purpose		: Add marker to the map
Returns		:	Success - TRUE
						Failure - FALSE
Variables	:
1. 	locationSettings
		Datatype	: Array
		Detail		: Default location geocodes
		1.	lat
				Datatype	: signed decimal
				Detail		: Latitude of the marker to be displayed on the map
		2. 	lon
				Datatype	: signed decimal
				Detail		: Longitude of the marker to be displayed on the map
2. 	markerSettings
		Datatype	: Array
		Detail		: Settings for the marker displayed on the map
		1. 	imageName
				Datatype	: string
				Detail		: Image for the marker
		2. 	shadowImageName
				Datatype	: string
				Detail		: Shadow image for the marker
		3. 	markerTitle
				Datatype	: string
				Detail		: Title for the marker
		4. 	markerHtml
				Datatype	: string
				Detail		: HTML of the info window for the marker
		5. 	markerTooltip
				Datatype	: string
				Detail		: Tooltip for the marker
		6. 	markerID
				Datatype 	: integer
				Detail		: ID for the marker. Will set the marker as draggable if provided
		7. 	statusID
				Datatype 	: integer
				Detail		: Status ID for the marker
		8. 	dimValue
				Datatype 	: integer
				Detail		: Dim Value for the marker if marker is a streetlight
3.	sideBarSettings
		Datatype	: Array
		Detail		: Settings related to the sideBar displaying details of the map
		1. 	sideBarImage
				Datatype 	: string
				Detail		: SideBar Image for the marker
		2. 	sideBarTitle
				Datatype 	: string
				Detail		: SideBar Title for the marker
		3. 	sideBarClass
				Datatype 	: string
				Detail		: CSS Class for the row in the SideBar
****************************************************************/
no_of_markers = 0;

function addMarkerToMap
					(
						locationSettings, 
						markerSettings, 
						markerHtml, 
						sideBarSettings
					) 
{
	
	// set default values to parameters
	lat = (locationSettings['lat'] == null) ? false : locationSettings['lat'];
	lon = (locationSettings['lon'] == null) ? false : locationSettings['lon'];
	
	imageName = (markerSettings['imageName'] == null) ? false : markerSettings['imageName'];
	toggleImageName = (markerSettings['toggleImageName'] == null) ? false : markerSettings['toggleImageName'];
	shadowImageName = (markerSettings['shadowImageName'] == null) ? false : markerSettings['shadowImageName'];
	markerTitle = (markerSettings['markerTitle'] == null) ? false : markerSettings['markerTitle'];
	markerHtml = (markerHtml == null) ? false : markerHtml;
//	markerHtml = (markerSettings['markerHtml'] == null) ? false : markerSettings['markerHtml'];
	markerTooltip = (markerSettings['markerTooltip'] == null) ? false : markerSettings['markerTooltip'];
	var markerID = (markerSettings['markerID'] == null) ? false : markerSettings['markerID'];
	statusID = (markerSettings['statusID'] == null) ? false : markerSettings['statusID'];
	dimValue = (markerSettings['dimValue'] == null) ? false : markerSettings['dimValue'];
	resetMarker = (markerSettings['resetMarker'] == null) ? false : markerSettings['resetMarker'];
	toggleMarker = (markerSettings['toggleMarker'] == null) ? false : markerSettings['toggleMarker'];
	deviceId = (markerSettings['deviceId'] == null) ? false : markerSettings['deviceId'];
	
	sideBarImage = (sideBarSettings['sideBarImage'] == null) ? false : sideBarSettings['sideBarImage'];
	sideBarTitle = (sideBarSettings['sideBarTitle'] == null) ? false : sideBarSettings['sideBarTitle'];
	sideBarClass = (sideBarSettings['sideBarClass'] == null) ? false : sideBarSettings['sideBarClass'];

	// create marker with default icon
	var markerIcon = new GIcon(G_DEFAULT_ICON);
	
	// set icon image if provided
	var typeImage = false;
	if (imageName) {
		typeImage = iconDir + imageName;
		markerIcon.image = typeImage;
		markerIcon.iconSize = new GSize(30,30);
		markerIcon.iconAnchor = new GPoint(10,20);
		markerIcon.infoWindowAnchor = new GPoint(15,10);
		if(markerSettings['setInfoWindowAnchor'] != undefined && markerSettings['setInfoWindowAnchor'] == true)
		{
			markerIcon.infoWindowAnchor = new GPoint(15, 10);
		}
	}

	// set icon image if provided
	var typeToggleImage = false;
	if (toggleImageName) {	
		typeToggleImage = iconDir + toggleImageName;
	}

	markerIcon.shadowSize = new GSize(0,0);
	// set icon image if provided
	if (shadowImageName) {
		var shadowImage = iconDir + shadowImageName;
		markerIcon.shadow = shadowImage;
		markerIcon.shadowSize = new GSize(37,32);
	}

	// Set up our GMarkerOptions object
	markerOptions = { icon:markerIcon};

	if (markerTooltip) {
		markerOptions.title = markerTooltip;
	}

	// add listeners to enable dragging
	if (markerID) {
		markerOptions.my_id = markerID;
		if(markerSettings['dragMarker'] != undefined)
		{
			markerOptions.draggable = markerSettings['dragMarker'];
		}
		else
		{
			markerOptions.draggable = true;
		}	
	}
	
	var point = new GLatLng(lat, lon);
	var gmrk = new GMarker(point, markerOptions);
	
	if (toggleMarker) {
		GEvent.addListener(gmrk, "click", function() { toggleMarkerAction(markerID); });
	}
	else if (markerHtml) {
		if (Coulomb_slider) {
			GEvent.addListener(gmrk, "click", function() { gmrk.openInfoWindowHtml(markerHtml);
            if (typeof(showAddEditDevice) == 'function') {
                showAddEditDevice('view', 'addEditDeviceMap', markerID, true);
            }
			devicemgmtLoad(markerID, statusID, dimValue); });
			GEvent.addListener(gmrk, "infowindowclose", function() { devicemgmtUnLoad(markerID); });
		}
		else {
			GEvent.addListener(gmrk, "click", function() {gmrk.openInfoWindowHtml(markerHtml); 
            if (typeof(showAddEditDevice) == 'function') {
                showAddEditDevice('view', 'addEditDeviceMap', markerID, true);
            }
            });
		}
	}
	
	// add listeners to disable dragging
	if (markerID) {
		GEvent.addListener(gmrk, 'dragend', function() {dragEndHandler(gmrk)});
		my_markers["device"+markerID] = gmrk;
		my_markers_info["device"+markerID] = new Array();
		my_markers_info["device"+markerID]['image'] = typeImage;
		my_markers_info["device"+markerID]['toggleImage'] = typeToggleImage;
		gmrk.disableDragging();
		
	}

	// add the marker
	map.addOverlay(gmrk);
	
	//batch.push(gmrk);
	
	
	if (sideBarTitle || sideBarImage) {

		if (sideBarClass)
			sideBarClass = " class =\"datatable1_tr_" + sideBarClass + "\"";
		else
			sideBarClass = "";

		sideBarHTMLTemp = '<div class=\"datatable1_table\"><div' + sideBarClass + '>';

		if (markerID)
			sideBarHTMLTemp = sideBarHTMLTemp + '<a href=\"javascript:click_sidebar(\'device' + markerID + '\')\">';

		sideBarHTMLTemp = sideBarHTMLTemp + '<div class=\"datatable1_td\">';

		if (sideBarImage)
			sideBarHTMLTemp = sideBarHTMLTemp + '<img src=\"' + sideBarImage + '\" class="iconbottom">&nbsp;';

		if (sideBarTitle)
			sideBarHTMLTemp = sideBarHTMLTemp + sideBarTitle;

		sideBarHTMLTemp = sideBarHTMLTemp + '</div>';

		if (markerID)
			sideBarHTMLTemp = sideBarHTMLTemp + '<\/a>';

		sideBarHTMLTemp = sideBarHTMLTemp + '</div></div>';

		sideBarHTML = sideBarHTML + sideBarHTMLTemp;

	}
	
	if(markerSettings['returnMapRef'])
	{
		return map;
	}
  //marker.openInfoWindowHtml(address);
	return true;

}

function toggleIconImage(markerID, imageType)
{

	var markerIcon = my_markers["device"+markerID];

	// Retrieve Images
	var typeImage = my_markers_info["device"+markerID]['image'];
	var typeToggleImage = my_markers_info["device"+markerID]['toggleImage'];

	var iconImage = (imageType == 0) ? typeImage : typeToggleImage;
	if (iconImage)
		markerIcon.setImage(iconImage);

}

/****************************************************************
Name			: drawProximityCircle
Purpose		: Center map and draw circle with proximity as the radius
Returns		:	Success - TRUE
						Failure - FALSE
Variables	:
1. 	locationSettings
		Datatype	: Array
		Detail		: Default location geocodes
		1.	lat
				Datatype	: signed decimal
				Detail		: Latitude of the marker that needs to be set as the center
		2. 	lon
				Datatype	: signed decimal
				Detail		: Longitude of the marker that needs to be set as the center
2. 	proximity
		Datatype	: integer
		Detail		: Radius of the circle
****************************************************************/
function drawProximityCircle
					(
						locationSettings, 
						proximity
					)

{

	// set default values to parameters
	lat = (locationSettings['lat'] == null) ? false : locationSettings['lat'];
	lon = (locationSettings['lon'] == null) ? false : locationSettings['lon'];

	proximity = (proximity == null) ? false : proximity;
	
	// check values of parameters
	if ( (!lat) || (!lon) || (!proximity) )
		return false;

	minLat = maxLat = centerLat = parseFloat(lat);
	minLon = maxLon = centerLon = parseFloat(lon);
	proximity = parseFloat(proximity);

	var d2r = Math.PI / 180;   // degrees to radians
	var r2d = 180 / Math.PI;   // radians to degrees
	var earthsradius = 3963; // 3963 is the radius of the earth in miles

	var points = 80;

	// find the raidus in lat/lon
	var rlat = (proximity / earthsradius) * r2d;
	var rlng = rlat / Math.cos(centerLat * d2r);
	
	var extp = new Array();
	for (var i=0; i < points+1; i++) // one extra here makes sure we connect the
	{
		var theta = Math.PI * (i / (points/2));
		ex = centerLon + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
		ey = centerLat + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
		extp.push(new GPoint(ex, ey));

		if (ey < minLat)
			minLat = ey;
		if (ey > maxLat)
			maxLat = ey;
		
		if (ex < minLon)
			minLon = ex;
		if (ex > maxLon)
			maxLon = ex;

	}
	
	// draw Circle
	map.addOverlay(new GPolyline(extp, "#000000", 2));

	// Set Center
	map.setCenter(new GLatLng(centerLat, centerLon), 13);

	// Set Zoom level so that all markers are visible
  var bds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon));
  map.setZoom(map.getBoundsZoomLevel(bds));

	return true;
}

function IsPointInPolygon(points, latlong)
{
	// This code adapted from the following URL:
	// http://msdn.microsoft.com/en-us/library/cc451895.aspx
	
	var i;
	var j=points.length-1;
	var inPoly=false;
	var lat = latlong.lat();
	var lon = latlong.lng();
/*
	for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
     		((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
     		&& (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
     		&& (c = !c);
    	return c;
*/
	
	for (i=0; i<points.length; i++) 
	{
		if (points[i].y<lat && points[j].y>=lat ||  points[j].y<lat && points[i].y>=lat) 
		{
			if (points[i].x+(lat-points[i].y)/(points[j].y-points[i].y)*(points[j].x-points[i].x)<lon) 
			{
				inPoly=!inPoly; 
			}
		}
		j=i; 
	}
	
	return inPoly; 
};

function removeMarker(markerID)
{
	map.removeOverlay(my_markers["device" + markerID]);
}