// Subclassed VML/SVG Polyline
//
// Bill Chadwick May 2007
//
// Free for any use
//
// Adds 
//  click, mouseover and mouseout events
//  tooltip
//  dot or dash styling
//  dynamic setting of colour, opacity, weight and dash style  

var BDCCPolylineId; //counter for unique DOM Ids

// Constructor params exactly as GPolyline then a tooltip and dash which must be one of "dot" or "dash" or "solid"

function BDCCPolyline(points, color, weight, opacity, tooltip, dash) {

    this.tooltip = tooltip;
    this.dash = (dash != null) ? dash : "solid";
    this.color = color;
    this.weight = weight;
    this.opacity = opacity;
    this.lineStyle = 'single';

    //make a unique DOM id for this polyline
    if (BDCCPolylineId == null)
        BDCCPolylineId = 0;
    else
        BDCCPolylineId += 1;
    this.domid = "BDCCPolylineId" + BDCCPolylineId.toString();

    this.usesVml = (navigator.userAgent.indexOf("MSIE") != -1);

    GPolyline.call(this, points, color, weight, opacity, {"clickable":false, "geodesic":true}); //call super class constructor 
}
BDCCPolyline.prototype = new GPolyline(new Array(new GLatLng(0, 0))); //subclass from GPolyline

// According to the GMap docs, GPolyline implements the GOverlay interface
// That is it implements the functions initialize, remove, copy and redraw
// Here we add to GPolyline's own implementation of these functions
//

BDCCPolyline.prototype.initialize = function(map) {
    GPolyline.prototype.initialize.call(this, map); //super class
    //Initialise cant be used to cache the SVG path node or its parent svg node as both are recreated in redraw
    //For VML the shape node is recreated in redraw and all shapes have a common parent       
    this.map = map;
}

BDCCPolyline.prototype.remove = function() {
    GPolyline.prototype.remove.call(this); //super class
}

BDCCPolyline.prototype.copy = function(map) {
    return new BDCCPolyline(this.points, this.color, this.weight, this.opacity, this.tooltip, this.dash);
}

BDCCPolyline.prototype.redraw = function(force) {

    GPolyline.prototype.redraw.call(this, force); //super class
    var dom = null;
    var i = 1;
    var prnt;

    if (this.usesVml) {
        try {
            var shps = document.getElementsByTagName("shape");
            i = shps.length - 1;

            //You could omit parent node checking if you only have one map per document
            //Doing so will give a performance improvement	  	    
            this.map.getPane(G_MAP_MAP_PANE).parentNode.id = "Cntnr" + this.domid;

            while ((dom == null) && (i >= 0)) {

                dom = shps[i]; //assume ours is the most recently added by the superclass redraw
                prnt = dom.parentNode;
                while (prnt != null) {
                    if (prnt.id == "Cntnr" + this.domid)
                        break;
                    else
                        prnt = prnt.parentNode;
                }
                if (prnt == null) {
                    i -= 1;
                    dom = null;
                }
                else
                    break;
            }

            if (dom != null) {
                //we found our VML node
                if (this.tooltip != null) {
                    dom.style.cursor = "help"; //to show mouseover 
                    dom.title = this.tooltip;
                }
                dom.id = this.domid; //assign unique DOM id so we can modify attributes later   
            }
        }
        catch (ex) {
            if (BDCCPolylineId == 0)
                alert("The designer of this Google Maps web page has attempted to use VML graphics without including the necessary header material.");
        }
    }
    else {
        var shps = document.getElementsByTagName("path");
        i = shps.length - 1;

        //You could omit parent node checking if you only have one map per document
        //Doing so will give a performance improvement	  	    
        this.map.getPane(G_MAP_MAP_PANE).parentNode.setAttribute("id", "Cntnr" + this.domid);

        while ((dom == null) && (i >= 0)) {

            dom = shps[i]; //assume ours is the most recently added by the superclass redraw
            prnt = dom.parentNode;
            while (prnt != null) {
                if (prnt.id == "Cntnr" + this.domid)
                    break;
                else
                    prnt = prnt.parentNode;
            }
            if (prnt == null) {
                i -= 1;
                dom = null;
            }
            else
                break;
        }

        if (dom != null) {
            //we found our SVG node

            if (this.tooltip != null) {
                dom.style.cursor = "help"; //to show mouseover 
                dom.setAttribute("title", this.tooltip);
            }
            dom.setAttribute("id", this.domid); //assign unique DOM id so we can modify attributes later
            dom.setAttribute("pointer-events", "stroke"); //only click on the line, not its bounding rectangle
        }
    }

    if (this.dredraw)
        window.clearTimeout(this.dredraw);

    if (dom != null) {

        //set up the appearance of our polyline
        this.setColor(this.color);
        this.setDash(this.dash);
        this.setOpacity(this.opacity);
        this.setWeight(this.weight);
        this.setLineStyle(this.lineStyle);

        //set up event handlers
        var cclick = GEvent.callback(this, this.onClick);
        var cover = GEvent.callback(this, this.onOver);
        var cout = GEvent.callback(this, this.onOut);

        GEvent.clearInstanceListeners(dom); //safety 
        GEvent.addDomListener(dom, "click", function(event) { cclick(); });
        GEvent.addDomListener(dom, "mouseover", function() { cover(); });
        GEvent.addDomListener(dom, "mouseout", function() { cout(); });
    }
    else {
        //we could not paint because GMaps has not done its drawing yet, try a bit later
        var credraw = GEvent.callback(this, this.redraw);
        this.dredraw = window.setTimeout(function(force) { credraw(true); }, 200); //the true here is vital
    }
}

//event handlers
BDCCPolyline.prototype.onClick = function() {
    GEvent.trigger(this, "click");
}
BDCCPolyline.prototype.onOver = function() {
    GEvent.trigger(this, "mouseover");
}
BDCCPolyline.prototype.onOut = function() {
    GEvent.trigger(this, "mouseout");
}

//once the shape has been drawn, we can modify it with these setX functions;

BDCCPolyline.prototype.setColor = function(color) {
    this.color = color;
    var dom = document.getElementById(this.domid);
    if (!dom)
        return;
    if (this.usesVml) {
        dom.stroke.color = this.color;
    }
    else {
        dom.setAttribute("stroke", this.color);
    }
}
BDCCPolyline.prototype.getColor = function() {
    return this.color;
}
BDCCPolyline.prototype.setDash = function(dash) {
    this.dash = dash;
    var dom = document.getElementById(this.domid);
    if (!dom)
        return;
    if (this.usesVml) {
        if (this.dash == "dash")
            dom.stroke.dashstyle = "dash";
        else if (this.dash == "dot")
            dom.stroke.dashstyle = "dot";
        else
            dom.stroke.dashstyle = "";
    }
    else {
        if (this.dash == "dash")
            dom.setAttribute("stroke-dasharray", "10,10");
        else if (this.dash == "dot")
            dom.setAttribute("stroke-dasharray", "3,17");
        else
            dom.setAttribute("stroke-dasharray", "");
    }
}
BDCCPolyline.prototype.getDash = function() {
    return this.dash;
}
//for VML only, use single, thinthin, thinthick, thickthin, thickbetweenthin
BDCCPolyline.prototype.setLineStyle = function(ls) {
    this.lineStyle = ls;
    var dom = document.getElementById(this.domid);
    if (!dom)
        return;
    if (this.usesVml) {
        dom.stroke.linestyle = ls;
    }
}
BDCCPolyline.prototype.getLineStyle = function() {
    return this.lineStyle;
}


BDCCPolyline.prototype.setWeight = function(weight) {
    this.weight = weight;
    var dom = document.getElementById(this.domid);
    if (!dom)
        return;
    if (this.usesVml) {
        dom.stroke.weight = this.weight.toString() + "px";
    }
    else {
        dom.setAttribute("stroke-width", this.weight.toString() + "px");
    }
}
BDCCPolyline.prototype.getWeight = function() {
    return this.weight;
}
BDCCPolyline.prototype.setOpacity = function(opacity) {
    this.opacity = opacity;
    var dom = document.getElementById(this.domid);
    if (!dom)
        return;
    if (this.usesVml) {
        dom.stroke.opacity = this.opacity;
    }
    else {
        dom.setAttribute("stroke-opacity", this.opacity);
    }
}
BDCCPolyline.prototype.getOpacity = function() {
    return this.opacity;
}
