var _currLeg = null;  
var _tmpline = null;
var _one = null;

function GDrawLine(map, options) {
    this.map_     = map;
    this.options_ = options;
    
    this.seg_     = {};
    this.seg_.start   = null; // _one 
    this.seg_.line    = null;
    
    this.points_ = [];
    this.polyline_ = null;
    this.totalDistance_ = 0;
    
    this.currPoint_ = null;
    
    this.working_ = false;
    
    GEvent.bind(this.map_, 'click', this, this.addPoint_);
    GEvent.bind(this.map_, 'mousemove', this, this.moveSeg_);
}

// ============================================================ addPoint_
GDrawLine.prototype.addPoint_ = function(overlay, point) {
    if (!this.working_) return;

    if (!point) {	// When drawing, a click registers as a click on the actual line graphic overlay, not the map 
    	point = this.currPoint_;
	}
    
    ll = new GLatLng(point.y, point.x);
    this.seg_.start = ll;
    
    var legd = 0;
    if ( this.options_.modifyStart() ) {
        if ( this.points_.length > 0) legd = ll.distanceFrom(this.points_[0]);
        this.points_.unshift(ll);
    } else {
        if ( this.points_.length > 0) legd = ll.distanceFrom(this.points_[this.points_.length-1]);
        this.points_.push(ll);
    }
    this.totalDistance_ += legd;
    this.redrawRoute_();
    if ( typeof(this.options_.onAddPoint) == 'function' ) {
        this.options_.onAddPoint(ll, legd, this.totalDistance_);
    }
}

// ============================================================ moveSeg_ 
GDrawLine.prototype.moveSeg_ = function(point) {
	this.currPoint_ = point;

    if (this.seg_.start == null || !this.working_) return;

	if ( this.seg_.line != null ) {
		this.map_.removeOverlay(this.seg_.line);
	}
	var pts = new Array(this.seg_.start, new GLatLng(point.y, point.x));
	
	this.seg_.distance = this.seg_.start.distanceFrom(pts[1]);
    
    if ( typeof(this.options_.onCurrDist) == 'function' ) {
        this.options_.onCurrDist(this.seg_.distance);
	}
	this.seg_.line = new GPolyline(pts, '#ee0000', 3, .7);
	this.map_.addOverlay(this.seg_.line);
}

// ============================================================ redrawRoute_
GDrawLine.prototype.redrawRoute_ = function() {
    if ( this.polyline_ != null ) {
	    this.map_.removeOverlay(this.polyline_);
	}

    if ( this.points_.length < 2 ) return;
	
	this.polyline_ = new GPolyline(this.points_, '#cc3300', 3, .7);
	this.map_.addOverlay(this.polyline_);    
}

// ============================================================ removePoint 
GDrawLine.prototype.removePoint = function() {
    if ( this.points_.length < 1 ) return;

    this.map_.removeOverlay(this.seg_.line);

    var legd = 0;
    if ( this.options_.modifyStart() ) {
        pt = this.points_.shift();
        if ( this.points_.length > 0) {
            legd = pt.distanceFrom(this.points_[0]);
            this.seg_.start = this.points_[0];
        }
    } else {
        pt = this.points_.pop();
        if ( this.points_.length > 0) {
            legd = pt.distanceFrom(this.points_[this.points_.length-1]);
            this.seg_.start = this.points_[this.points_.length-1];
        }
    }
    if (legd != 0) this.totalDistance_ -= legd;
    this.redrawRoute_();
    if ( typeof(this.options_.onRemovePoint) == 'function' ) {
        this.options_.onRemovePoint(pt, legd, this.totalDistance_);
    }
}

// ============================================================ clearRoute 
GDrawLine.prototype.clearRoute = function() {
    this.map_.clearOverlays();
    this.points_ = [];
    delete this.seg_.start;
    this.seg_.start = null;
    this.totalDistance_ = 0;
}

// ============================================================ changeWorkEnd 
GDrawLine.prototype.changeWorkEnd = function() {
	if (this.seg_.line) this.map_.removeOverlay(this.seg_.line);

    if ( this.options_.modifyStart() ) {
        this.seg_.start = this.points_[0];
    } else {
        this.seg_.start = this.points_[this.points_.length-1];
    }
}

// ============================================================ toggleWorking 
GDrawLine.prototype.toggleWorking = function() {
    if (this.working_) {
    	if (this.seg_.line) this.map_.removeOverlay(this.seg_.line);
        this.working_ = false;
    } else {
        this.changeWorkEnd();
        this.working_ = true;
    }
    return this.working_;
}






// ======================================================================== mouseMover 
function mouseMover(point) {
	//$("debug").innerHTML = (point.y).toFixed(6) + ', ' + (point.x).toFixed(6);

	if ( _one == null ) return;
	
	if ( _tmpline != null ) {
		_map.removeOverlay(_tmpline);
	}
	pts=new Array();
	pts.push(_one);
	two = new GLatLng(point.y, point.x);
	pts.push(two);
	
	d = _one.distanceFrom(two)/1609.344;
	$('tmpRoute').innerHTML = "Current leg: " + d.toFixed(4);
	
	_tmpline = new GPolyline(pts, '#ee0000', 3, .7);
	_map.addOverlay(_tmpline);
}

// ======================================================================== addPoint
function addPoint(point) {
	var ll = new GLatLng(point.y, point.x);
	_one = ll;
	
	if ( !_currLeg  ) { 
		_currLeg = new Data_Leg(); 
		$("stoproute").style.display = "inline";
	}
	
	if ( document.getElementById("addtostart").checked ) {
		_currLeg.addPointToStart(ll);
	} else {
    	_currLeg.addPointToEnd(ll);
	}
    redrawPoly();
    
    /*
	if ( _currLeg.points.length == 1 ) {
		var marker = createMarker(ll, _startIcon, "Start Marker");
		_currLeg.setStartMarker(marker);
		_map.addOverlay(marker);
	}
    */
}

// ======================================================================== removePoint
function removePoint() {
	if ( !_currLeg ) return;

	if ( document.getElementById("addtostart").checked ) {
        _currLeg.removeStartPoint();
	} else {
		_currLeg.removeEndPoint();
	}

	redrawPoly();
}
// ======================================================================== redrawPoly
function redrawPoly() {
	
	if ( !_currLeg ) return;
	
	if ( _currLeg.polyline ) {
		_map.removeOverlay(_currLeg.polyline);
	}
	
	if ( _currLeg.points.length > 1 ) {
		_currLeg.polyline = new GPolyline(_currLeg.points, '#cc3300', 3, .7);
		_map.addOverlay(_currLeg.polyline);
		updateInfo();
	}	
}

// ======================================================================== clearPoly
function clearPoly() {
	_map.clearOverlays();
    if ( _one ) delete _one;
	_one = null;
	
    if ( _currLeg) {
        _currLeg.points.length = 0;
        delete _currLeg.polyline;
        _currLeg = null;
    }
    
    _currRoute = null;
    
    //$("routesContent").innerHTML = "Click map to start line.";
   	//$('tmpRoute').innerHTML = "Current leg: 0 ";
}

// ======================================================================== updateInfo
function updateInfo() {
	var html = "";
    var perleg = _currLeg.distance/_currLeg.points.length;

	html += "Last Leg: " + (_currLeg.lastleg).toFixed(4) + "<br>";
	html += "Total Distance: " + (_currLeg.distance).toFixed(3) + " miles<br>";
	html += "Leg Count: " + _currLeg.points.length + " (" + perleg.toFixed(4) + ")<br>";	
	$("routesContent").innerHTML = html;
}
	
// ======================================================================== startstopRoute 
function startstopRoute() {
	if ($("stoproute").value == "stop route") {
		delete _one;
		_one = null;
		_map.removeOverlay(_tmpline);
		$("stoproute").value = "continue route";
	} else {
		if ( _currLeg.points.length > 0 ) {
			_one = _currLeg.points[_currLeg.points.length-1]
			$("stoproute").value = "stop route";
		}
	}
}

// ======================================================================== refreshRoute
function refreshRoute(rid) {
	_currRoute = _routes[rid];
	$("polyname").value = _currRoute.name;
	
	var html = "";	
	html += "<strong>" + _currRoute.name + "</strong><br>";
	html += "<a href=\"javascript: panZoomTo('start');\">zoom start</a> | ";
	html += "<a href=\"javascript: panZoomTo('end');\">zoom end</a> | ";
	html += "<a href=\"javascript: savePoly(" + i + ");\">save</a> ";

	$("route").innerHTML = html;
}

// ======================================================================== panZoomTo 
function panZoomTo(se) {
	if ( se == "start" ) {
		pt = _currLeg.getStartPoint();
	} else {
		pt = _currLeg.getEndPoint();
	}
	if ( pt != null ) {
		_map.setZoom(16);
		_map.panTo(pt);
	}
}

// ======================================================================== showRoute 
function showRoute(rid) {
    clearPoly();
	refreshRoute(rid);
	
	console.log(_currRoute);

    _currLeg = new Data_Leg(); 

	var ptary = _currRoute.data.split(",");
	for (i=0;i<ptary.length;i++) {
		pt = ptary[i].split(" ");
		
		point = new GLatLng(parseFloat(pt[0]), parseFloat(pt[1]));
		if ( i==0 ) {
			marker = createMarker(point, _startIcon, "Start Marker");
			_map.addOverlay(marker);
		}
        _currLeg.addPointToEnd(point);
	}
	marker = createMarker(point, _endIcon, "End Marker");
	_map.addOverlay(marker);
	
	bndcent = getCenterBounds(_currLeg.points);
	_map.setCenter(bndcent.center, _map.getBoundsZoomLevel(bndcent.bounds));

    redrawPoly();
}



function Data_Leg(id) {
	this.id = id;
}
Data_Leg.prototype = {
	points: [],
	polyline: null,
	distance: 0,
	lastleg: 0,
	
	addPointToEnd: function(point) {
		this.points.push(point);
		if (this.points.length > 1) {
			lastpoint = this.points[this.points.length-2];
			this.lastleg = point.distanceFrom(lastpoint)/1609.344;  // meters to miles 
			this.distance += this.lastleg;
		}
	},
    
    removeEndPoint: function() {
        return this.points.pop();
    },

	addPointToStart: function(point) {
		this.points.unshift(point);
		if (this.points.length > 1) {
			lastpoint = this.points[this.points.length-2];
			this.lastleg = point.distanceFrom(lastpoint)/1609.344;  // meters to miles 
			this.distance += this.lastleg;
		}
	},

    removeStartPoint: function() {
        return this.points.shift();
    },
	
	getStartPoint: function() {
		if ( this.points.length == 0 ) return null;
		return this.points[0];
	},
	
	getEndPoint: function() {
		if ( this.points.length == 0 ) return null;
		return this.points[this.points.length-1];
	},		

	getStartMarker: function() {
		if (this.startMarker) return this.startMarker;
	},
	setStartMarker: function(marker) {
		this.startMarker = marker;
	},
	getEndMarker: function() {
		if (this.endMarker) return this.endMarker;
	},
	setEndMarker: function(marker) {
		this.endMarker = marker;
	}
	
}  
