// GPolygon preview
// This is code that's been ripped from the 2.49 version
// of the api. It's mostly functional.
// Chris Smoak - 3 May 2006

// For this script to work correctly, you will need to use
// maps2.49.api.js. To do this, specify the 'v' parameter 
// of the api javascript url to be 2.49:
//   <script src="http://maps.google.com/maps?file=api&v=2.49&key=abc123" type="text/javascript"></script>


// In order to use a different API version, you will need
// to update the following functions with their current
// obfuscated name. You can find these through careful
// inspection of the api javascript. The names I have
// given these methods are probably innacurate:

GMap2.prototype.getDivPixelCenter = GMap2.prototype.u;
GMap2.prototype.fromDivPixelsToLatLngBounds = GMap2.prototype.pd;
GPolyline.prototype.getVectors = GPolyline.prototype.Za;
GPolyline.prototype.getPoints = GPolyline.prototype.Xa;
GPolyline.prototype.getSomething = GPolyline.prototype.Ya;



// XUserAgent is a copy of the user agent code in maps.10.js

// user agent types
XUserAgent.IE = 1;
XUserAgent.MOZILLA = 2;
XUserAgent.SAFARI = 3;
XUserAgent.OPERA = 4;

// user agent OSes
XUserAgent.WIN = 0;
XUserAgent.NIX = 1;
XUserAgent.MAC = 2;

function XUserAgent(type, version, os) { this.type = type; this.version = version; this.os = os };

XUserAgent.instance = function() {
    var userAgent = new XUserAgent(0, 0, null);
    var userAgentName = navigator.userAgent.toLowerCase();
    if (userAgentName.indexOf("opera") != -1) {
        userAgent.type = XUserAgent.OPERA;
        if (userAgentName.indexOf("opera/7") != -1 || userAgentName.indexOf("opera 7") != -1) {
            userAgent.version = 7
        } else if (userAgentName.indexOf("opera/8") != -1 || userAgentName.indexOf("opera 8") != -1) {
            userAgent.version = 8
        }
    } else if (userAgentName.indexOf("msie") != -1 && document.all) {
        userAgent.type = XUserAgent.IE;
        if (userAgentName.indexOf("msie 5")) { userAgent.version = 5 }
    } else if (userAgentName.indexOf("safari") != -1) { userAgent.type = XUserAgent.SAFARI }
    else if (userAgentName.indexOf("mozilla") != -1) { userAgent.type = XUserAgent.MOZILLA }
    if (userAgentName.indexOf("x11;") != -1) { userAgent.os = XUserAgent.NIX }
    else if (userAgentName.indexOf("macintosh") != -1) { userAgent.os = XUserAgent.MAC }

    return userAgent;
}();

// Turns on SVG polylines
_mSvgForced = true;
_mSvgEnabled = true;

XUserAgent.prototype.supportsSvg = function() {
  if (false && !_mSvgForced) {
    if (this.os == XUserAgent.WIN) { return false }
    if (this.type != XUserAgent.SAFARI) { return false }
  }
  if (document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#SVG","1.1")) { return true }
  return false
};


// from maps2.49.api.js

function GPolygon(polylines, fill, color, opacity, outline) {
  this.polylines = polylines || []; // t
  this.fill = fill != null ? fill : true; // od
  this.color = color || "#0055ff"; // A
  this.opacity = opacity || 0.25; // B
  this.outline = outline != null ? outline : true // ge
}

GPolygon.prototype.initialize = function(map) {
  this.map = map; // a
  for (var i = 0; i < this.polylines.length; i++) {
    this.polylines[i].initialize(map)
  }
}

GPolygon.prototype.remove = function() {
  for (var i = 0; i < this.polylines.length; ++i) {
    this.polylines[i].remove()
  }
  var elem = this.element;
  if (elem) {
    elemRemove(elem);
    this.element = null;
    // TODO: s(this, 'remove')
  }
}

GPolygon.prototype.copy = function() {
  return new GPolygon(this.polylines, this.fill, this.color, this.opacity, this.outline)
}

GPolygon.prototype.redraw = function(force) {
  redrawLinearOverlay(this, 3, force)
};

GPolygon.prototype.getSomething = function() { // Ya
  var min = 100; // a
  for (var i = 0; i < this.polylines.length; i++) {
    var c = this.polylines[i].getSomething();
    if (min > c) { min = c }
  }
  return min
};

GPolygon.prototype.getVectors = function(latLngBounds, b) { // Za
  var c = [];
  for (var i = 0; i < this.polylines.length; i++) {
    c.push(this.polylines[i].getVectors(latLngBounds, b))
  }
  return c
};

GPolygon.prototype.getPoints = function(vectors, points, extent) {
  for (var i = 0; i < this.polylines.length; i++) {
    var pts = [];
    this.polylines[i].getPoints(vectors[i], pts, extent);
    points.push(pts)
  }
  return points
}

GPolygon.prototype.rgba = function() {
  var color = this.color;
  if (color.charAt(0) == '#') {
    color = color.substring(1);
  }
  var r = parseInt(color.substring(0, 2), 16);
  var g = parseInt(color.substring(2, 2), 16);
  var b = parseInt(color.substring(4, 2), 16);
  return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + this.opacity;
}

GPolygon.prototype.createElement = function(imageBounds, latLngBounds, pane, svg) { // cd
  var e = this.getSomething();
  var vectors = this.getVectors(latLngBounds, e); // f, Za
  var points = []; // g
  var extent = new GBounds(); // h
  this.getPoints(vectors, points, extent); // Xa
  var element = null; // i
  if (points.length > 0 && this.fill) {
    if (svg) {
      var width = imageBounds.max().x - imageBounds.min().x; // l
      element = document.createElementNS($svgNamespaceUrl, "svg");
      var poly = document.createElementNS($svgNamespaceUrl, "polygon"); // n
      this.poly = poly;
      element.appendChild(poly);
      elemSetPosition(element, new GPoint(extent.min().x, extent.min().y));
      element.setAttribute("version", "1.1");
      element.setAttribute("width", (width + 10) + 'px');
      element.setAttribute("height", (width + 10) + 'px');
      element.setAttribute("viewBox", extent.min().x + " " + extent.min().y + " " + width + " " + width);
      element.setAttribute("overflow", "visible");
      var pointsString = pointsToSvgString(points); // p
      poly.setAttribute("points", pointsString);
      poly.setAttribute("fill-rule", "evenodd");
      poly.setAttribute("fill", this.color);
      poly.setAttribute("fill-opacity", this.opacity);
/*
      // my attempt at a mouseover effect. doesn't always work--don't know why.

      poly.style.zIndex = 100000;
      var _this = this;
      poly.addEventListener('mouseover', function() {
        _this.opacity = 0.5;
        _this.poly.setAttribute('fill-opacity', _this.opacity);
      }, false);
      poly.addEventListener('mouseout', function() {
        _this.opacity = 0.25;
        _this.poly.setAttribute('fill-opacity', _this.opacity);
      }, false);
*/
      pane.appendChild(element)
    } else {
      var center = this.map.getDivPixelCenter(); // q
      element = createVmlElement("v:shape", pane, center, new GSize(1, 1));
      element.unselectable = "on";
      element.coordorigin = center.x + " " + center.y;
      element.coordsize = "1 1";
      var pointsString = pointsToVmlString(points);
      element.path = pointsString;
      var fill = createVmlElement("v:fill", element);
      fill.color = this.color;
      fill.opacity = this.opacity;
      var stroke = createVmlElement("v:stroke", element);
      stroke.opacity = 0
    }
  }
  return element
};

function redrawLinearOverlay(obj, type, force) { // od
  var map = obj.map; // d
  var size = map.getSize(); // i
  var center = map.getDivPixelCenter(); // f // u
  if (!force) {
    var left = center.x - Math.round(size.width / 2); // g
    var top = center.y - Math.round(size.height / 2); // h
    var bounds = new GBounds([new GPoint(left, top), new GPoint(left + size.width, top + size.height)]); // i
    if (obj.bounds.containsBounds(bounds)) { return } // ya
  }
  var ie = XUserAgent.instance.type == XUserAgent.IE; // l, w, 1
  var svg = XUserAgent.instance.supportsSvg(); // n
  var maxSize = 900; // p
  var width, height;
  if (ie || svg) {
    width = Math.max(1000, screen.width); // q
    height = Math.max(1000, screen.height) // u
  } else {
    width = Math.min(size.width, maxSize);
    height = Math.min(size.height, maxSize)
  }
  var bl = new GPoint(center.x - width, center.y + height); // y
  var tr = new GPoint(center.x + width, center.y - height); // C
  var imageBounds = new GBounds([tr, bl]); // E
  obj.bounds = imageBounds; // tf
  obj.remove();
  var latLngBounds = map.fromDivPixelsToLatLngBounds(bl, tr); // J
  var pane = map.getPane(0); // L, E
  if(svg || ie) {
    obj.element = obj.createElement(imageBounds, latLngBounds, pane, svg) // D, cd
  } else {
    if (type == 3) {
      // TODO: ie?
    } else if (type == 2) {
// not needed for polygon
//      obj.D = obj.lf(E, J, L)
    }
  }
  if (type == 3 && obj.outline) {
    for (var i = 0; i < obj.polylines.length; i++) {
      obj.polylines[i].redraw(force)
    }
  }
}


function pointsToSvgString(points) { // pe
  var string = "";
  for (var i = 0; i < points.length; i++) {
    string += points[i].join(" ") + " "
  }
  return string
}

function pointsToVmlString(points) {
  var parts = [];
  for (var i = 0; i < points.length; i++) {
    var vml = encodeVmlPoints(points[i]);
    parts.push(vml.substring(0, vml.length - 1))
  }
  parts.push("e");
  return parts.join(" ")
}

function encodeVmlPoints(a) {
  var b = [];
  var c;
  var d;
  for (var e = 0; e < a.length; ) {
    var f = a[e++];
    var g = a[e++];
    var h = a[e++];
    var i = a[e++];
    if (g != c || f != d) {
      b.push("m");
      b.push(f);
      b.push(g);
      b.push("l")
    }
    b.push(h);
    b.push(i);
    c = i;
    d = h
  }
  b.push("e");
  return b.join(" ")
}


function elemSetPosition(element, position) {
  var style = element.style;
  style.position = "absolute";
  style.left = (position.x) + 'px';
  style.top = (position.y) + 'px'
}


function elemOwnerDocument(elem) {
  return (elem ? elem.ownerDocument : null) || document
}

function elemSetSize(elem, size) {
  var style = elem.style;
  style.width = (size.width) + 'px';
  style.height = (size.height) + 'px'
}

function createVmlElement(name, parent, position, size) { // Kb
  var vml = elemOwnerDocument(parent).createElement(name);
  if (parent) { parent.appendChild(vml) }

  vml.style.behavior = "url(#default#VML)";

  if (position) { elemSetPosition(vml, position) }
  if (size) { elemSetSize(vml, size) }
 
  return vml
}

function elemRemove(elem) { // Z
  if (elem.parentNode) {
    elem.parentNode.removeChild(elem);
    // TODO: clean up listeners : ae(elem, wc)
  }
}

var $svgNamespaceUrl = "http://www.w3.org/2000/svg";

/*

// this is code to clean up events after the element has been
// removed--I wasn't able to recreate this b/c certain
// functions are hid within the api code and are not accessible here.
// *sad*

function ae(a, b, c) {
  if (b) { b.call(null,a) }
  for (var d = a.firstChild; d; d = d.nextSibling) {
    if (d.nodeType == 1) {
      arguments.callee.call(this, d, b, c)
    }
  }
  if (c) { c.call(null, a) }
}

function wc(a) {
  s(a, 'clearlisteners');
  bb(ed(a), function() {
    this.remove();
    zb(Ua, this)
  })
}

  
function ed(a){var b=[];if(a["__e_"]){Jb(b,a["__e_"])}return b}
  


function zb(a,b,c){var d=0;for(var e=0;e<a.length;++e){if(a[e]===b||c&&a[e]==b){a.splice(e--,1);d++}}return d}

*/

/*
function s(a, b, c, d) {
  var e = [];
  Jb(e, arguments, 2);
  bb(yc(a), function() {
    if (this.Vd(b)) {
      try {
        this.apply(a,e)
      } catch (f) { }
    }
  }
)}

function Jb(a,b,c,d){var e=c||0;var f=d||b.length;for(var g=e;g<f;++g){a.push(b[g])}}

function bb(a,b){for(var c=0;c<a.length;++c){b.call(a[c])}}

function yc(a,b){var c=a["__e_"];if(!c){if(b){c=(a["__e_"]=[])}else{c=[]}}return c}

*/

