/**
 * @name LabeledMarker
 * @version 1.3
 * @author Mike Purvis (http://uwmike.com)
 * @copyright (c) 2007 Mike Purvis (http://uwmike.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function LabeledMarker(latlng, opt_opts) {
  this.opts_ = opt_opts;
  this.labelText_ = opt_opts.labelText || "";
  this.labelClass_ = opt_opts.labelClass || "LabeledMarker_markerLabel";
  this.labelOffset_ = opt_opts.labelOffset || new GSize(0, 0);
  this.id = opt_opts.id;
  this.clickable_ = opt_opts.clickable || true;
  this.title_ = opt_opts.title || "";
  this.labelVisibility_ = true;
  this.ownVisibility_ = true;
  this.div_ = document.createElement("div");
  this.div_.id = this.id;
  this.div_.className = this.labelClass_;
  this.div_.innerHTML = this.labelText_;
  this.div_.style.position = "absolute";
  this.div_.style.cursor = "pointer";
  this.div_.title = this.title_;
  if (opt_opts.draggable) {opt_opts.draggable = false;}
  GMarker.apply(this, arguments);
}


LabeledMarker.prototype = new GMarker(new GLatLng(0, 0));
LabeledMarker.prototype.initialize = function (map) {
  GMarker.prototype.initialize.apply(this, arguments);
  this.map_ = map;
  if (!this.ownVisibility_) {this.hide();}
  this.applyLabelVisibility_();
  map.getPane(G_MAP_MARKER_PANE).appendChild(this.div_);
  if (this.clickable_) {
    var eventPassthrus = ['click', 'dblclick', 'mousedown', 'mouseup','mouseover', 'mouseout'];
    for (var i = 0; i < eventPassthrus.length; i++) {
      var name = eventPassthrus[i];
      GEvent.addDomListener(this.div_, name,GEvent.callback(GEvent, GEvent.trigger,this, name, this.getLatLng()));
    }
  }
};


LabeledMarker.prototype.redraw = function (force) {
  GMarker.prototype.redraw.apply(this, arguments);
  this.redrawLabel_();
};


LabeledMarker.prototype.redrawLabel_ = function () {
  var p = this.map_.fromLatLngToDivPixel(this.getLatLng());
  var z = GOverlay.getZIndex(this.getLatLng().lat());
  this.div_.style.left = (p.x + this.labelOffset_.width) + "px";
  this.div_.style.top = (p.y + this.labelOffset_.height) + "px";
  this.div_.style.zIndex = z; // in front of the marker
};


LabeledMarker.prototype.remove = function () {
  GEvent.clearInstanceListeners(this.div_);
  if (this.div_.outerHTML) {
    this.div_.outerHTML = ""; 
  }
  if (this.div_.parentNode) {
    this.div_.parentNode.removeChild(this.div_);
  }
  this.div_ = null;
  GMarker.prototype.remove.apply(this, arguments);
};


LabeledMarker.prototype.copy = function () {
  var newMarker = new LabeledMarker(this.getLatLng(), this.opts_);
  newMarker.labelVisibility_ = this.labelVisibility_;
  newMarker.ownVisibility_ = this.ownVisibility_;
  return newMarker;
};


LabeledMarker.prototype.show = function () {
  GMarker.prototype.show.apply(this, arguments);
  this.ownVisibility_ = true;
  this.applyLabelVisibility_();
};


LabeledMarker.prototype.hide = function () {
  GMarker.prototype.hide.apply(this, arguments);
  this.ownVisibility_ = false;
  this.applyLabelVisibility_();
};


LabeledMarker.prototype.setLabelVisibility = function (visibility) {
  this.labelVisibility_ = visibility;
  this.applyLabelVisibility_();
};


LabeledMarker.prototype.getLabelVisibility = function () {
  return this.labelVisibility_;
};


LabeledMarker.prototype.applyLabelVisibility_ = function () {
  if ((!this.isHidden()) && this.labelVisibility_) {
    this.div_.style.display = 'block';
  } else {
    this.div_.style.display = 'none';
  }
};


LabeledMarker.prototype.setLabelText = function (text) {
  this.labelText_ = text;
  this.div_.innerHTML = text;
  this.opts_.labelText = text;
};

function createLMarker(point, markerOptions, desc)
{
var marker = new LabeledMarker(point, markerOptions);
return marker;
}

var mrkFeat = [];
var bounds = new GLatLngBounds();
function AddMarkers(mark, color, latTab, lngTab, desc)
{
for (var m = 0; m < latTab.length; m++)
{
var mm = mrkFeat.length;
if(lngTab[m] > 0){lngTab[m] = -lngTab[m];}
var icon = new GIcon();icon.image = 'http://pics3.city-data.com/images/' + color.replace('#', 'm') +'.png';icon.iconSize = new GSize(16, 16);icon.iconAnchor = new GPoint(8, 8);
var mrk = createLMarker(new GLatLng(latTab[m], lngTab[m]), {hide:true, title:desc[m],labelText: String.fromCharCode(mark.charCodeAt(0)+m), labelClass: color.replace('#', 'm'), id : 'lm' + mm, icon: icon, labelOffset: new GSize(-3, -6)}, desc[m]);
mrk.color = color;
mrkFeat.push(mrk);
bounds.extend(new GLatLng(latTab[m], lngTab[m]));
}
}

function showHideBoundaries()
{
var overTab = overHashTab['featMAP'];
for (o = 0; o < overTab.length; o++){if (!overTab[o].isHidden()) {overTab[o].hide();} else {overTab[o].show();}}
}

function showHide(color)
{
for (var m = 0; m < mrkFeat.length; m++)
{
var mrk = mrkFeat[m];
if ((mrk.color == color) && mrk.isHidden()) {mrk.show();ms = document.getElementById('lm' + m).style;ms.display='block';ms.visibility='visible';}
else if ((mrk.color == color) && !mrk.isHidden()) {mrk.hide();ms = document.getElementById('lm' + m).style;ms.display='none';ms.visibility='hidden';}
else {mrk.hide();ms = document.getElementById('lm' + m).style;ms.display='none';ms.visibility='hidden';}
}
}

var gmapHashTab = [];
var overHashTab = [];
var safariFix = (navigator.userAgent.indexOf('Safari') != -1);
var firefoxFix = (navigator.userAgent.indexOf('Firefox') != -1);
var operaFix = (navigator.userAgent.indexOf('Opera') != -1);


function DecodeGMapPoints(encoded) {
    var len = encoded.length;
    var index = 0;
    var array = [];
    var lat = 0;
    var lng = 0;

    while (index < len) {
        var b;
        var shift = 0;
        var result = 0;
        do {
            b = encoded.charCodeAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lat += dlat;

        shift = 0;
        result = 0;
        do {
            b = encoded.charCodeAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lng += dlng;

        array.push(new GLatLng(parseFloat(lat) * 1e-5, parseFloat(lng) * 1e-5));
    }

    return array;
}

function ShowGMapPolyEnc(encTab, encNumTab, mapID, style, descs, labels, uControls) {
    var polyt = [];
    var overTab = [];
    var bounds = new GLatLngBounds();
    for (var p = 0; p < encTab.length; p++) 
    {
        points = DecodeGMapPoints(encTab[p]);
        poly = eval("new GPolygon(points,'#0000FF', 2, 1,'#0000FF',0.20)");
        bounds.extend(poly.getBounds().getSouthWest());
        bounds.extend(poly.getBounds().getNorthEast());
        polyt.push(poly);
    }

    var gmap = new GMap2(document.getElementById(mapID));
    gmap.addControl(new GMapTypeControl(1));
    gmap.addControl(new GSmallMapControl());
    gmap.addControl(new GScaleControl());
    gmap.setCenter(bounds.getCenter(), gmap.getBoundsZoomLevel(bounds));

    for (p = 0; p < polyt.length; p++) 
    {
        var gOver = polyt[p];
        gmap.addOverlay(gOver);
        overTab.push(gOver);
    }
    gmapHashTab[mapID] = gmap;
    overHashTab[mapID] = overTab;

    if (safariFix && (typeof borderCol != 'undefined') ) {
        var strokeStyle = { 'color': borderCol[mapID], 'opacity': 1.0, 'weight': 2 };
        for (o = 0; o < overTab.length; o++) { overTab[o].setStrokeStyle(strokeStyle); }
    }    
}






if (typeof loadFeaturesReal == 'function') { loadFeaturesReal(); }
