function hbPolyline (latlngs, color, weight, opacity, pane)
{
  this.points = latlngs;
  this.color = color;
  this.weight = weight;
  this.opacity = opacity;
  this.pane = pane;
  this.bounds = null;
  this.mainElem = null;
  this.subElem = null;
  this.map = null;
}

hbPolyline.prototype = new GOverlay ();
hbPolyline.prototype.constructor = hbPolyline;
hbPolyline.prototype.maxId = 0;

hbPolyline.prototype.copy = function ()
{
  return new hbPolyline (this.points, this.color, this.weight, this.opacity, this.pane);
}

hbPolyline.prototype.destroy = function ()
{
  this.remove ();

  this.points = undefined;
  this.color = undefined;
  this.weight = undefined;
  this.opacity = undefined;
  this.bounds = undefined;
  this.pane = undefined;
  this.mainElem = undefined;
  this.subElem = undefined;
  this.map = undefined;
}

hbPolyline.prototype.setPane = function (newPane)
{
  this.pane = newPane;

  if (this.mainElem)
  {
    this.mainElem.parentNode.removeChild (this.mainElem);
    this.map.getPane (this.pane).appendChild (this.mainElem);
  }
}

hbPolyline.prototype.setOpacity = function (newOpacity)
{
  this.opacity = newOpacity;

  if (null != this.subElem)
  {
  /*@cc_on
  @if (@_jscript)
    this.subElem.setAttribute ("opacity", this.opacity);
    this.mainElem.setAttribute ("strokecolor", this.color);
    this.mainElem.setAttribute ("strokeweight", this.weight + "pt");
  @else*/
    this.subElem.setAttribute ("stroke-opacity", this.opacity);
/*@end
  @*/
  }
}

hbPolyline.prototype.getBounds = function ()
{
  if (null == this.bounds)
  {
    if (1 > this.points.length)
    {
      return new GLatLngBounds ();
    }

    var latMin = this.points [0].lat ();
    var latMax = this.points [0].lat ();
    var lngMin = this.points [0].lng ();
    var lngMax = this.points [0].lng ();

    for (var p = 1; p < this.points.length; ++p)
    {
      if (latMin > this.points [p].lat ())
      {
        latMin = this.points [p].lat ()
      }
      else if (latMax < this.points [p].lat ())
      {
        latMax = this.points [p].lat ()
      }

      if (lngMin > this.points [p].lng ())
      {
        lngMin = this.points [p].lng ()
      }
      else if (lngMax < this.points [p].lng ())
      {
        lngMax = this.points [p].lng ()
      }
    }

    this.bounds = new GLatLngBounds (new GLatLng (latMin, lngMin), new GLatLng (latMax, lngMax));
  }

  return this.bounds;
}

hbPolyline.prototype.initialize = function (map)
{
  this.remove ();
  this.map = map;

/*@cc_on
  @if (@_jscript)
    this.mainElem = hbVML.makeCanvas (hbPolyline.prototype.maxId++, 0, 0, 0, 0);
    this.mainElem.style.position = "absolute";
    this.mainElem.style.zIndex = 1000;
    this.mainElem.setAttribute ("unselectable", "on");
    hbVML.addCanvasToParent (this.mainElem, map.getPane (this.pane), 0, 0, 0, 0);
  @else*/
    this.mainElem = hbSVG.makeCanvas (hbPolyline.prototype.maxId++, 0, 0, 0, 0);
    this.mainElem.style.position = "absolute";
    this.mainElem.style.left = "0";
    this.mainElem.style.top = "0";
    this.mainElem.style.zIndex = 1000;
    this.mainElem.setAttribute ("version", "1.1");
    this.mainElem.setAttribute ("overflow", "visible");
    hbSVG.addCanvasToParent (this.mainElem, map.getPane (this.pane), 0, 0, 0, 0, 0, 0);
/*@end
  @*/
}

hbPolyline.prototype.redraw = function (force)
{
  if (false == force)
  {
    return;
  }
/*@cc_on
  @if (@_jscript)
    if (1 < this.points.length)
    {
      var pixelCoord = this.map.fromLatLngToDivPixel (this.points [0]);
      var d = "m" + pixelCoord.x + "," + pixelCoord.y + "l";

      for (var p = 1; p < this.points.length - 1; ++p)
      {
        pixelCoord = this.map.fromLatLngToDivPixel (this.points [p]);
        d = d.concat (pixelCoord.x, ",", pixelCoord.y, ",");
      }

      pixelCoord = this.map.fromLatLngToDivPixel (this.points [p]);
      d = d.concat (pixelCoord.x, ",", pixelCoord.y, "e");

      this.setSubElemAttributes (this.mainElem, d);

      var bounds = this.getBounds ();
      var swPixel = this.map.fromLatLngToDivPixel (bounds.getSouthWest ());
      var nePixel = this.map.fromLatLngToDivPixel (bounds.getNorthEast ());

      var left = swPixel.x - this.weight;
      var top = nePixel.y - this.weight;
      var width = nePixel.x - left + this.weight;
      var height = swPixel.y - top + this.weight;

      hbVML.transformCanvas (this.mainElem,
          left,
          top,
          width,
          height);
    }
  @else*/
    if (1 < this.points.length)
    {
      var pixelCoord = this.map.fromLatLngToDivPixel (this.points [0]);
      var d = "M " + pixelCoord.x + "," + pixelCoord.y;

      for (var p = 1; p < this.points.length; ++p)
      {
        pixelCoord = this.map.fromLatLngToDivPixel (this.points [p]);
        d = d.concat (" L ", pixelCoord.x, ",", pixelCoord.y);
      }

      if (null == this.subElem)
      {
        this.subElem = document.createElementNS (hbSVG.ns, "path");
        this.setSubElemAttributes (this.subElem, d);
        this.mainElem.appendChild (this.subElem);
      }
      else
      {
        this.setSubElemAttributes (this.subElem, d);
      }

      var bounds = this.getBounds ();
      var swPixel = this.map.fromLatLngToDivPixel (bounds.getSouthWest ());
      var nePixel = this.map.fromLatLngToDivPixel (bounds.getNorthEast ());

      var left = swPixel.x - this.weight;
      var top = nePixel.y - this.weight;
      var width = nePixel.x - left + this.weight;
      var height = swPixel.y - top + this.weight;

      this.mainElem.style.left = left;
      this.mainElem.style.top = top;
      hbSVG.transformCanvas (this.mainElem,
          left,  // left
          top,  // top
          width,  // pixelWidth
          height,  // pixelHeight
          width,  // userWidth
          height); // userHeight
    }
/*@end
  @*/
}

hbPolyline.prototype.remove = function ()
{
  if ((this.mainElem) && (this.mainElem.parentNode))
  {
    GEvent.clearNode (this.mainElem);
    this.mainElem.parentNode.removeChild (this.mainElem);
    this.subElem = null;
  }
}

hbPolyline.prototype.setSubElemAttributes = function (elem, d)
{
/*@cc_on
  @if (@_jscript)
    elem.setAttribute ("filled", "f");
    elem.setAttribute ("strokecolor", this.color);
    elem.setAttribute ("strokeweight", this.weight + "pt");
    elem.setAttribute ("path", d);

    if (null == this.subElem)
    {
      this.subElem = document.createElement ("v:stroke");
      this.subElem.setAttribute ("opacity", this.opacity);
      this.subElem.setAttribute ("joinstyle", "round");
      this.subElem.setAttribute ("endcap", "round");
      this.mainElem.appendChild (this.subElem);
    }
    else
    {
      this.subElem.setAttribute ("opacity", this.opacity);
      this.subElem.setAttribute ("joinstyle", "round");
      this.subElem.setAttribute ("endcap", "round");
    }
  @else*/
    elem.setAttribute ("d", d);
    elem.setAttribute ("fill", "none");
    elem.setAttribute ("stroke", this.color);
    elem.setAttribute ("stroke-width", this.weight + "px");
    elem.setAttribute ("stroke-opacity", this.opacity);
    elem.setAttribute ("stroke-linejoin", "round");
    elem.setAttribute ("stroke-linecap", "round");
/*@end
  @*/
}
