eval(dashfly.namespace);

var mainMapObj = null;
var application = null;
var mouseClickListener = null;
var selectedType = 1;
var routePointIndex = 0;
var distanceCalulator;
var directionObj;
var isMLS = false;
var ajax = null;
var ROUTE_CUTOVER = 200; // Make large so it never cuts in

var needToWaitForResults = false;
var waitingEvent = null;
var maxWaitingSeries = 100;
var currentWaitingSeries = 0;
var currentWaitingCalculateRouteSeries = 0;
var showAddressNeedToWaitForResults = false;
var showAddressCurrentWaitingSeries = 0;

var ajaxcall = "././ajaxcall/";

function getMaximumPoints() {
   var max = 5;
   var postContent = '';
   jQuery.ajax( { 
      url:  ajaxcall + "getMaximumPoints.php",
      async : false,
      success : function(result) {
         max = parseInt(result, 10);
      }
   });

   return max;
}

var help_text_screen1 = 'Let us optimize your route. Enter a starting address and up to ' + (getMaximumPoints() - 1) + ' stops.  Click <strong>Create Route</strong> and we\'ll provide you the most efficient route to all your stops and back home.  The green star represents your starting and ending address for a round trip route.  If you are creating a one-way route, the orange star will represent your ending address.  If an address marker is displayed in <span style="color:red;">red</span>, please double check that your address is entered correctly.';
var help_text_screen2 = 'Now you can customize your route by <strong>dragging and dropping</strong> any of the addresses below to fit your needs.  Simply drag an address to a new spot, drop it, and click <strong>Reroute</strong> to update the directions.  If you would like to add a new stop, modify, or delete an address in this route, click <strong>Edit</strong> to make the changes.';
var help_text_screen3 = 'Now you can customize your route by dragging and dropping any of the addresses below to fit your needs. <div style="text-align: center; margin-top: 10px">';
var help_address = [ 'Starting Ending address', 'First stop address', 'Second stop address', 'Third stop address',
        'Fourth stop address', 'Fifth stop address', 'Sixth stop address', 'Seventh stop address',
        'Eighth stop address', 'Ninth stop address', 'Tenth stop address', 'Eleventh stop address',
        'Twelfth stop address', 'Thirteenth stop address', 'Fourteenth stop address', 'Fifteenth stop address',
        'Sixteenth stop address', 'Seventeenth stop address', 'Eighteenth stop address', 'Nineteeth stop address',
        'Twentieth stop address', 'Twenty first stop address', 'Twenty second stop address',
        'Twenty third stop address', 'Twenty fourth stop address', 'Twenty fifth stop address',
        'Twenty sixth stop address', 'Twenty seventh stop address', 'Twenty eighth stop address',
        'Twenty ninth stop address' ];
var isShowMyRoute = false;
var routeParam = null;
var routeDistance = 0;
var routeTime = 0;
var iscalculate = false;
var local = [];
var searchText = null;
var addressLabel = '';
var errorStateOnGeocoding = false;

var taskQueue = new Queue();
var priorityTaskQueue = new Queue();

var queueIsRunning = false;
var priorityQueueIsRunning = false;
var mustDelay = 0;

try {
    var console = {
        log : function() {
            return;
        },
        debug : function() {
            return;
        },
        info : function() {
            return;
        },
        warn : function() {
            return;
        },
        error : function() {
            return;
        },
        "assert" : function() {
            return;
        },
        dir : function() {
            return;
        },
        dirxml : function() {
            return;
        },
        trace : function() {
            return;
        },
        group : function() {
            return;
        },
        groupEnd : function() {
            return;
        },
        time : function() {
            return;
        },
        timeEnd : function() {
            return;
        },
        profile : function() {
            return;
        },
        profileEnd : function() {
            return;
        },
        count : function() {
            return;
        }
    };
}

catch (e) {
}

function Log(text) {
    //console.log(text); // For Firebug logging
}

function ltrim(s) {
    var l = 0;
    while (l < s.length && s[l] == ' ') {
        l++;
    }
    return s.substring(l, s.length);
}

function rtrim(s) {
    var r = s.length - 1;
    while (r > 0 && s[r] == ' ') {
        r -= 1;
    }
    return s.substring(0, r + 1);
}

function trim(s) {
    return rtrim(ltrim(s));
}

function IsNumeric(sText) {
    var ValidChars = "0123456789";
    var IsNumber = true;
    var Char;
    for (i = 0; i < sText.length && IsNumber === true; i++) {
        Char = sText.charAt(i);
        if (ValidChars.indexOf(Char) == -1) {
            IsNumber = false;
        }
    }
}

function  isPrintModeActive() {
   return typeof isInPrintMode !== 'undefined';
}

function replaceToString(htmlStr) {
    //  alert(htmlStr);
    var str = htmlStr.replace(/&apos;/g, "'");
    str = str.replace(/&comma;/g, ",");
    str = str.replace(/&nbsp;/g, " ");
    return str;
}

function replaceToHTML(str) {
    var htmlStr = str.replace(/\'/g, "&apos;");
    htmlStr = htmlStr.replace(/,/g, "&comma;");
    htmlStr = htmlStr.replace(/ /g, "&nbsp;");
    return htmlStr;
}

function addressInAddList(add) {
    var flag = false;
    for (i = 0; i < addList.length; i++) {
        if (addList[i] !== undefined && addList[i] !== null && addList[i].GetAddress() == add) {
            flag = true;
        }
    }
    return flag;
}

function setText(elm, txt) {
    if (document.getElementById(elm) !== undefined && document.getElementById(elm) !== null &&
            document.getElementById(elm) != 'undefined') {
        document.getElementById(elm).innerHTML = txt;
    }
}

function showElement(elm) {
    if (document.getElementById(elm) !== undefined && document.getElementById(elm) !== null && 
           document.getElementById(elm) != 'undefined') {
        document.getElementById(elm).style.visibility = 'visible';
        document.getElementById(elm).style.display = 'block';
    }
}

function hideElement(elm) {
    if (document.getElementById(elm) !== undefined && document.getElementById(elm) !== null &&
            document.getElementById(elm) != 'undefined') {
        document.getElementById(elm).style.visibility = 'hidden';
        document.getElementById(elm).style.display = 'none';
    }

}

function getCurrentTier() {
    var myAjax = new Ajax.Request(ajaxcall + "getCurrentTier.php", {
        method :'get',
        parameters :'',
        asynchronous :false
    });
    var max = myAjax.transport.responseText;
  return parseInt(max, 10);
}

function centerMap() {
    var pts = [];
    for ( var i = 0; i < addList.length; i++) {
        if (addList[i] !== undefined && addList[i] !== null) {
            pts.push(addList[i].GetLatLng());
        }
    }
    if (routeDestination !== undefined && routeDestination !== null) {
        pts.push(routeDestination.GetLatLng());
    }

    line = new GPolyline(pts);
    zoomlevel = mainMapObj.getBoundsZoomLevel(line.getBounds());
    mainMapObj.setCenter(line.getBounds().getCenter(), parseInt(zoomlevel - 2, 10));
    // alert("Bounds : " + line.getBounds());
}

function removedelimeter(str) {
    var address = str;
    if (str.indexOf(":") > 0) {
        address = str.substring(str.indexOf(":") + 1);
        Log("address after removing label " + address + "<br>");
    }
    return address;
}

function isAllAddresssSame() {
    var flag = true;
    Log("Length of address list = " + addList.length);
    for ( var i = 0; i < addList.length; i++) {
        var ccode = String.fromCharCode(65 + i);
        var obj = document.getElementById('route' + ccode);
        if (addList[i] !== undefined && addList[i] !== null) {
            Log("isAlladdresssame " + addList[i].GetAddress() + " " + removedelimeter(obj.value));
            if (addList[i].GetAddress() != removedelimeter(obj.value)) {
                if (obj.value.length !== 0 && isAddrExists(help_address, obj.value) === false) {
                    flag = false;
                }
            }
        }
    }
    Log("Returning from isaddresssame : " + flag + "<br>");
    return flag;
}

function onShowInfoWindow(marker, event, html) {
    GEvent.addListener(marker, event, function() {
        marker.openInfoWindowHtml(html);
    });
}

function getIcon(marker_str) {
    var blueIcon = new GIcon();
    blueIcon.image = IMAGEPATH + marker_str + ".png";
    blueIcon.shadow = IMAGEPATH + "marker_shadow.png";
    blueIcon.iconSize = new GSize(22, 35);
    blueIcon.shadowSize = new GSize(37, 35);
    blueIcon.iconAnchor = new GPoint(9, 34);
    blueIcon.infoWindowAnchor = new GPoint(9, 2);
    blueIcon.infoShadowAnchor = new GPoint(18, 25);
    blueIcon.transparent = "http://www.google.com/intl/en_ALL/mapfiles/markerTransparent.png";
    return blueIcon;
}

function createMarker(point, html) {
    var marker = new GMarker(point, getIcon("poi"));
    onShowInfoWindow(marker, "mouseover", html);
    return marker;
}

function doLocalSearch() {
    // alert(document.getElementById('searchTxtbox').value);
    searchText = document.getElementById('searchTxtbox').value;
    // alert(searchText);

    var localURL = ajaxcall + "local.php?query=";
    var center = mainMapObj.getCenter();
    localURL += escape(searchText) + "&lat=" + center.lat() + "&lng=" + center.lng();

    for ( var i = 0; i < local.length; i++) {
        if (local[i].GetMarker() !== undefined && local[i].GetMarker() !== null) {
            mainMapObj.removeOverlay(local[i].GetMarker());
        }
    }

    local = [];

    GDownloadUrl(encodeURI(localURL), function(data, responseCode) {
        // alert(data);
            var xml = GXml.parse(data);
            results = xml.documentElement.getElementsByTagName("Result");
            Log("Result from local is : " + results.length);
            for ( var i = 0; i < results.length; i++) {
                var title;
                if (results[i].getElementsByTagName("Title")[0].hasChildNodes()) {
                    title = results[i].getElementsByTagName("Title")[0].firstChild.nodeValue;
                }

                var address;
                if (results[i].getElementsByTagName("Address")[0].hasChildNodes()) {
                    address = results[i].getElementsByTagName("Address")[0].firstChild.nodeValue;
                }

                var city;
                if (results[i].getElementsByTagName("City")[0].hasChildNodes()) {
                    city = results[i].getElementsByTagName("City")[0].firstChild.nodeValue;
                }

                var state;
                if (results[i].getElementsByTagName("State")[0].hasChildNodes()) {
                    state = results[i].getElementsByTagName("State")[0].firstChild.nodeValue;
                }

                var lat = results[i].getElementsByTagName("Latitude")[0].firstChild.nodeValue;
                var lng = results[i].getElementsByTagName("Longitude")[0].firstChild.nodeValue;
                // yahoo does not provide accuracy setting
                var accuracy = 8; //results[i].getElementsByTagName("Accuracy")[0].firstChild.nodeValue;
                var point = new GLatLng(lat, lng);
                Log(address + ", " + city + ", " + state + " " + lat + " " + lng + "<br>");
                dashadd = new DashFlyAddress();
                dashadd.SetAddress(address + ", " + city + ", " + state);
                dashadd.SetLatLng(point);
                dashadd.SetAccuracy(accuracy);
                dashadd.SetAddressLabel(title + ":" + address + ", " + city + ", " + state);
                var html = "<div style='width: 270px; height: 110px'><strong>" + title + "</strong><br />" + address +
                        "<br >" + city + ", " + state + "<br /><a href='javascript:addSearchToRoute(" + i +
                        ")'>Add to route</a></div>";

                dashadd.SetMarker(createMarker(point, html));
                // alert("Label: " + dashadd.GetAddressLabel());
            local[i] = dashadd;
            mainMapObj.addOverlay(dashadd.GetMarker());
        }
        if (local.length > 0) {
            var pts = [];
            for ( var ii = 0; ii < local.length; ii++) {
                pts.push(local[ii].GetLatLng());
            }
            line = new GPolyline(pts);
            zoomlevel = mainMapObj.getBoundsZoomLevel(line.getBounds());
            mainMapObj.setCenter(line.getBounds().getCenter(), parseInt(zoomlevel - 1, 10));
        }
    });

}

function formatAddressLabel(address, pad) {
    var label = address.GetAddressLabel().replace(/^(.*):(.*)/, '<strong>$1</strong><br>$2<br>');
    if (address.GetAccuracy() != 8){
        label += '<div style="font-weight:bold;color:red;">Warning, please verify the accuracy of this address</div>';
        label += '<br/>Google mapped it to the following Address:';
        label += '<br/>' + address.GetActualAddress();
    }
    if (pad) {
        label = '<div style="width: 280px; height: 100px">' + label + '</div>';
    }
    return label;
}

function onShowAddressInfo(marker, event, address) {
    return onShowInfoWindow(marker, event, formatAddressLabel(address, true));
}

function displayUpgradeDialog(message) {
    var currentTier = getCurrentTier();

    if (currentTier > 0 && currentTier < 32) {
        alert(message);
        jQuery("#accountUpdate").dialog("open"); //.load("updateDialog");
    } else if (currentTier === 0) {
        alert("We're sorry, but you've reached maximum number of addresses or saved routes. Please register to upgrade your account.");
    } else {
        alert("We're sorry, but you've reached maximum number of addresses or saved routes.");
    }
}

function reconcileAddresses() {
    dashfly.addTaskToQueue( new reconcileAddressesBody() );
}

reconcileAddressesBody = function() {
    
    return function() {
        // We need to loop over the various text entries, and if they aren't
        // in addList, and aren't in the default text, we need to add them & geocode them.
    
        var lookingForAddresses = false;
        var textElement;
        var addressText;
        // We look for id's with routeA, routeB, ...
        for ( var i = 0; i < routePointIndex; i++) {
            Log("reconcile with i = " + i);
            var pointId = "route" + String.fromCharCode(64 + i + 1);
            textElement = document.getElementById(pointId);
    
            if (textElement !== undefined && textElement !== null) {
                addressText = textElement.value;
    
                // Is this default text?
                if (trim(addressText).length !== 0 && !isAddrExists(help_address, addressText)) {
                    if (!addressInAddList(addressText)) {
                        // Geocode & show this, adding it to addList.
                        Log(" will do showaddress for " + pointId);
                        lookingForAddresses = true;
                        showAddress(textElement);
                        break; // Should only have 1 unknown.
                    }
                }
            }
        }

        // Now handle the case of the end point.
        var rtElement = document.getElementById("roundtrip");
        if (rtElement.checked === false) // i.e., one-way trip
        {
            textElement = document.getElementById("routeDestination");
            if (textElement !== undefined && textElement !== null) {
                addressText = textElement.value;
    
                if (routeDestination === undefined || routeDestination === null || routeDestination.GetAddress() != addressText) {
                    Log(" will do showaddress for endpoint.");
                    showAddress(textElement);
                    lookingForAddresses = true;
                }
            }
        }
    
        return lookingForAddresses;
    }
};

//Forces an onchange event call to the given element
function postAutoCompleteAddress(element, selectedItem) {
 element.onchange();
}

function addRoutePoint() {
    var currentMaximum = getMaximumPoints();
    if (routePointIndex + (document.getElementById('roundtrip').checked ? 0 : 1) <= currentMaximum) {
        reconcileAddresses();
        var ccode = String.fromCharCode(64 + routePointIndex);
        var parentdiv = document.getElementById('additionalRoutePoints');
        var textboxdiv = document.createElement('div');
        textboxdiv.id = "textdiv_route" + ccode;

        // Commented by DB, is this necessary?
        // textboxdiv.setAttribute('id','routePoint'+routePointIndex);
        textboxdiv.innerHTML = "<img src=\"" + IMAGEPATH + "stop" + (routePointIndex - 1) +
                ".png\" /> <input id=\"route" + ccode + "\" type=\"text\" name='" + (routePointIndex - 1) +
                "' value='" + help_address[routePointIndex - 1] +
                "' onfocus=textfocus(this) class=\"inputtext\"  onchange=\"showAddress(this);\" tabindex=\"" +
                routePointIndex + "\"/><input type=\"image\" src=\"" + IMAGEPATH + "addressbook.png\" id=\"address" +
                ccode + "\" onclick=\"openAddressBook('route" + ccode + "');\"/>";
        parentdiv.appendChild(textboxdiv);
        routePointIndex++;
        //new Autocompleter.Local("route" + ccode, 'cachedAddressList', cachedAddresses, {
        //    afterUpdateElement :postAutoCompleteAddress
        //});
    } else {
        displayUpgradeDialog("We're sorry ... to add more than " + (currentMaximum - 1) +
                " stops, you must upgrade your service.");
    }
}

function addSearchToRoute(index) {
    // alert(index);
    if (addList.length > 0) {
        var ccode = String.fromCharCode(65 + addList.length);
        var obj = document.getElementById('route' + ccode);
        if (obj === undefined || obj === null) {
            addRoutePoint();
            obj = document.getElementById('route' + ccode);
            if (obj === undefined || obj === null) {
                return;
            }
        }
        obj.value = local[index].GetAddressLabel();
        obj.style.color = '#000000';
    } else {
        document.getElementById('routeA').value = local[index].GetAddressLabel();
    }
    // alert(local[index].GetAddress());
    // alert(local[index].GetAddress());
    // alert(local[index].GetAddressLabel());
    // alert(local[index].GetAddressLabel());
    // alert(local[index].GetLatLng());
    // alert(addList.length);

    dashadd = new DashFlyAddress();
    dashadd.SetAddress(local[index].GetAddress());
    dashadd.SetActualAddress(local[index].GetAddress());
    dashadd.SetAddressLabel(local[index].GetAddressLabel());
    dashadd.SetLatLng(local[index].GetLatLng());
    dashadd.SetAccuracy(local[index].GetAccuracy());
    var marker_str = (addList.length === 0) ? "star" : addList.length;
	if (dashadd.GetAccuracy() != 8){
		marker_str += "warn";
		alert('Warning, the address \"' + dashadd.GetAddress() + '\" does not have an exact match.  Please recheck address');
	}
    var marker = new GMarker(local[index].GetLatLng(), getIcon(marker_str));
    dashadd.SetMarker(marker);
    onShowAddressInfo(marker, "click", dashadd);
    addList.push(dashadd);
    mainMapObj.addOverlay(marker);

    Log("marker added " + local[index].GetAddress() + " " + local[index].GetLatLng() + "<br>");

    for ( var i = 0; i < local.length; i++) {
        if (local[i].GetMarker() !== undefined && local[i].GetMarker() !== null) {
            mainMapObj.removeOverlay(local[i].GetMarker());
        }
    }
}

//Sets a cooked with the name, value and expire time
//This will be immediatly available to the page
function setCookie(c_name, value, expiredays) {
 var exdate = new Date();
 exdate.setDate(exdate.getDate() + expiredays);
 document.cookie = c_name + "=" + escape(value) + ((expiredays === undefined || expiredays === null) ? "" : ";expires=" + exdate.toGMTString());
}

function getCookie(c_name) {
   if (document.cookie.length>0) {
     c_start=document.cookie.indexOf(c_name + "=");
     if (c_start!=-1) {
       c_start=c_start + c_name.length+1;
       c_end=document.cookie.indexOf(";",c_start);
       if (c_end==-1) { 
          c_end=document.cookie.length;
       }
       return unescape(document.cookie.substring(c_start,c_end));
     }
   }
   return "";
}

function ProcessCachedAddresses(response) {
    setCookie('addresses', response, 7);
}

//makes and ajax call to encode the addresses
function updateCachedAddresses(addresses) {
    var postContent = '';
    for ( var i = 0; i < addresses.length; i++) {
        if (addresses[i] !== undefined && addresses[i] !== null) {
            postContent += "add[]" + "=" + encodeURIComponent(addresses[i]) + "&";
        }
    }
    jQuery.post(ajaxcall + "updateCachedAddresses.php", postContent, ProcessCachedAddresses);
}

/**
 * Returns true if data is contained in the array
 */
function contains(arr, data) {
    for (j = 0; j < arr.length; j++) {
        if (arr[j] == data) {
            return true;
        }
    }
    return false;
}

//...
function DelGmnoprint() {
    var sd = document.getElementsByTagName('svg');
    for ( var n = 0; n < sd.length; n++) {
        if (sd[n].parentNode.className == 'gmnoprint') {
            sd[n].parentNode.className = '';
        }
        setTimeout(DelGmnoprint, 100);
    }
}

function prepareDragAddress() {
    parentdiv = document.getElementById('stops');
    // Log("Child length : " + parentdiv.childNodes.length+"<br>");
    for ( var ii = parentdiv.childNodes.length; ii >= 0; ii--) {
        child = document.getElementById('stops').childNodes[ii];
        // Log("child : " + ii + " " + child +"<br>");
        if (child !== undefined && child !== null) {
            parentdiv.removeChild(child);
        }
    }

    var additionalCount = 1;
    if (routeDestination === undefined || routeDestination === null) {
        additionalCount = 0;
    }
    for ( var i = 0; i < addList.length + additionalCount; i++) {

        var tempAddress;
        if (i != addList.length) {
            tempAddress = addList[i];
        } else {
            tempAddress = routeDestination;
        }

        if (tempAddress !== undefined && tempAddress !== null) {
            // actually build a table for each entry.
            lielm = document.createElement('li');

            tblelm = document.createElement('table');
            tblBodyElm = document.createElement('tbody');

            trelm = document.createElement('tr');
            trelm.id = "stop_number_" + i;

            tdelm = document.createElement('td');

            imgelm = document.createElement('img');
            // imgelm.setAttribute('class','stops_img');
            // imgelm.className = 'stops_img';
            imgelm.src = "";
            if (i === 0) {
                // imgelm.setAttribute('src','template/html/images/star_bullet.png');
                imgelm.src = IMAGEPATH + "star_bullet.png";
            } else if (i < addList.length) {
                // imgelm.setAttribute('src','template/html/images/stop' + i +
                // '.png');
                imgelm.src = IMAGEPATH + 'stop' + i + '.png';
            } else {
                imgelm.src = IMAGEPATH + "dest_star_bullet.png";
            }

            tdelm.appendChild(imgelm);
            trelm.appendChild(tdelm);

            tdelm = document.createElement('td');
            if (tempAddress.GetAddressLabel().indexOf(':') > 0) {
                tmparr = tempAddress.GetAddressLabel().split(':');
                tdelm.innerHTML = tmparr[0] + '<br>' + tmparr[1];
            } else {
                tdelm.innerHTML = tempAddress.GetAddressLabel();
            }
            trelm.appendChild(tdelm);
            tblBodyElm.appendChild(trelm);
            tblelm.appendChild(tblBodyElm);
            lielm.appendChild(tblelm);
            parentdiv.appendChild(lielm);
        }
    }

    Sortable.create("stops", {
        dropOnEmpty :true,
        containment : [ "stops" ],
        constraint :false
    });
}

function SortedDirectionLoad() {
    var parntElm;
    var tblElm;
    var tblBodyElm;
    mainMapObj.clearOverlays();
    var numofRoutes = directionObj.getNumRoutes();

    if (numofRoutes > 0) {
        routeParam = "Total distance is " + directionObj.getDistance().html + " and travel time is " +
                directionObj.getDuration().html;
        routeDistance = directionObj.getDistance().meters;
        routeTime = directionObj.getDuration().seconds;
        addDiv('directionPanel', routeParam);
        parntElm = document.getElementById('directionPanel');
        tblElm = document.createElement('table');
        tblElm.cellSpacing = '0';
        tblElm.cellPadding = '0';
        tblElm.width = '100%';
        tblElm.border = '0';
        tblElm.setAttribute('cellspacing', '0');
        tblElm.setAttribute('cellpadding', '0');
        tblElm.setAttribute('id', 'directionTable');
        tblBodyElm = document.createElement('tbody');
    }
    // var counter =0;
    var additional = 1;
    if (routeDestination === undefined || routeDestination === null) {
        additional = 0;
    }

    var tempAddress;
    var marker_str;
    for ( var i = 0; i < numofRoutes + additional; i++) {
        var marker;

        if (i == numofRoutes) {
            marker_str = "dest_star";
            tempAddress = routeDestination;
        } else {
            marker_str = (i === 0) ? "star" : i;
            tempAddress = addList[i];
        }

        if (tempAddress.GetAccuracy() != 8){
    		marker_str += "warn";
    		alert('Warning, the address \"' + tempAddress.GetAddress() + '\" does not have an exact match.  Please recheck address');
    	}

        marker = new GMarker(directionObj.getMarker(i).getLatLng(), getIcon(marker_str));
        onShowAddressInfo(marker, "click", tempAddress);
        mainMapObj.addOverlay(marker);
        route = directionObj.getRoute(i);

        addrLabel = formatAddressLabel(tempAddress);

        if (route !== undefined && route !== null) {
            tblBodyElm.appendChild(addressRow(IMAGEPATH + marker_str + ".png", addrLabel, tempAddress.GetAddress(),
                    tempAddress.GetNotes(), i, route.getDistance().html + " - about " + route.getDuration().html));

            for ( var k = 0; k < route.getNumSteps(); k++) {
                step = route.getStep(k);
                tblBodyElm.appendChild(directionRow((k + 1), step.getDescriptionHtml(), step.getDistance().html));
            }
        }
        // counter++;
    }
    if (numofRoutes > 0) {
        if (routeDestination === undefined || routeDestination === null) {
            tempAddress = addList[0];
            marker_str = "star.png";
        } else {
            tempAddress = routeDestination;
            marker_str = "dest_star.png";
        }

        if (tempAddress.GetAddressLabel().indexOf(':') > 0) {
            tmparr = tempAddress.GetAddressLabel().split(':');
            addrLabel = tmparr[0] + '<br>' + tmparr[1];
        } else {
            addrLabel = tempAddress.GetAddressLabel();
        }

        tblBodyElm.appendChild(lastAddressRow(addrLabel, marker_str));

        mainMapObj.addOverlay(directionObj.getPolyline());
        zoomlevel = mainMapObj.getBoundsZoomLevel(directionObj.getPolyline().getBounds());
        mainMapObj.setCenter(directionObj.getPolyline().getBounds().getCenter(), zoomlevel);
        prepareDragAddress();
        showElement("saveRoutePanel");
        showElement("dragPanel");
        hideElement("routePointPanel");
        hideElement("searchPanel");
        hideElement("localSearch");

        if (isShowMyRoute) {
            showElement('routeTitlebar');
            // isShowMyRoute = false;
        }
        tblElm.appendChild(tblBodyElm);
        parntElm.appendChild(tblElm);
    }

    isShowMyRoute = true;
    if (typeof(_mSvgEnabled) != "undefined" && _mSvgEnabled) {
        setTimeout(DelGmnoprint, 500);
    }
}

function GErrorOccured() {
    var code = directionObj.getStatus().code;
    var reason = "Code " + code;
    if (reasons[code]) {
        reason = reasons[code];
    }
    alert("Failed to obtain directions, " + reason);
}

//Find route will call direction object and create a route
//it will use global var addList to create a route
function FindRoute() {
 iscalculate = false;
 // clear route and direction text
 mainMapObj.clearOverlays();
 document.getElementById("directionPanel").innerHTML = "";

 // find route and direction text
 addarr = [];
 for ( var i = 0; i < addList.length; i++) {
     if (addList[i] !== undefined && addList[i] !== null) {
         addarr.push(addList[i].GetLatLng());
     }
 }
 // add start address as end address
 if (routeDestination === undefined || routeDestination === null) {
     addarr.push(addarr[0]);
 } else {
     addarr.push(routeDestination.GetLatLng());
 }

 for ( var ii = 0; ii < addarr.length; ii++) {
     Log("Route " + ii + " " + addarr[ii] + "<br>");
 }
 Log("Finding route now : <br>");
 directionObj = new GDirections(null, null, {
     getSteps :true,
     getPolyline :true
 });
 directionObj.loadFromWaypoints(addarr, {
     getSteps :true,
     getPolyline :true,
     preserveViewport :false
 });
 GEvent.addListener(directionObj, "load", SortedDirectionLoad);
 GEvent.addListener(directionObj, "error", GErrorOccured);
}

function DoTheFindRoute(newAddList) {
    //Log("Route = " + newAddList );
    Log("From optimized routing, doing the FindRoute method.");
    addList = newAddList;
    FindRoute();
    jQuery("#routeGenerationProgressBarDialog").dialog("close");
    //   jQuery("#routeGenerationProgressBarDialog").dialog("open");
    //   jQuery('#routeGenerationProgressBarDialog').jqmShow();

}

function populateTextBoxes() {
    routePointIndex = addList.length + 1;
    var marker_str;
    var marker;
    for ( var i = 0; i < addList.length; i++) {
        // add markers to map
        // alert(i + " " + addList[i]);
        if (addList[i] !== undefined && addList[i] !== null) {
            // mainMapObj.addOverlay(addList[i].GetMarker());
            marker_str = (i === 0) ? "star" : i;
        	if (addList[i].GetAccuracy() != 8){
        		marker_str += "warn";
        		alert('Warning, the address \"' + addList[i].GetAddress() + '\" does not have an exact match.  Please recheck address');
        	}
            marker = new GMarker(addList[i].GetLatLng(), getIcon(marker_str));
            mainMapObj.removeOverlay(marker);
            onShowAddressInfo(marker, "click", addList[i]);
            addList[i].SetMarker(marker);
            mainMapObj.addOverlay(marker);
            centerMap();
            obj = document.getElementById("route" + String.fromCharCode(65 + i));
            if (obj !== undefined && obj !== null) {
                if (i < addList.length) {
                    obj.value = addList[i].GetAddressLabel();
                    obj.style.color = '#000000';
                } else {
                    obj.value = help_address[i];
                    obj.style.color = '#999999';
                }
            } else {
                var ccode = String.fromCharCode(65 + i);
                var parentdiv = document.getElementById('additionalRoutePoints');
                var textboxdiv = document.createElement('div');

                textboxdiv.innerHTML = "<img src=\"" +
                        IMAGEPATH +
                        "stop" +
                        (i) +
                        ".png\" /> <input id=\"route" +
                        ccode +
                        "\" type=\"text\" name='" +
                        (i) +
                        "' value='" +
                        addList[i].GetAddress() +
                        "' onkeyup='handleSubmit(event)' onfocus=textfocus(this) class=\"inputtext\"  onchange=\"showAddress(this);\" tabindex=\"" +
                        i + "\"/><input type=\"image\" src=\"" + IMAGEPATH + "addressbook.png\" id=\"address" + ccode +
                        "\" \" onclick=\"openAddressBook('route" + ccode + "');\"/><br>\n";
                parentdiv.appendChild(textboxdiv);
                obj = document.getElementById("route" + String.fromCharCode(65 + i));
                obj.style.color = '#000000';
            }
        }
    }

    var checkbox;
    if (routeDestination === undefined || routeDestination === null) // round trip
    {
        obj = document.getElementById('routeDestination');
        obj.value = (addList[0] === undefined || addList[0] === null ? "" : addList[0].GetAddressLabel());
        // obj.style.color = '#999999';
        obj.disabled = true;
        checkbox = document.getElementById('roundtrip');
        checkbox.checked = true;
    } else {
        obj = document.getElementById('routeDestination');
        obj.value = routeDestination.GetAddressLabel();
        // obj.style.color = '#000000';
        obj.disabled = false;
        checkbox = document.getElementById('roundtrip');
        checkbox.checked = false;

        marker_str = "dest_star";
    	if (routeDestination.GetAccuracy() != 8){
    		marker_str += "warn";
    	}
        marker = new GMarker(routeDestination.GetLatLng(), getIcon(marker_str));
        mainMapObj.removeOverlay(marker);
        onShowInfoWindow(marker, "click", routeDestination);
        routeDestination.SetMarker(marker);
        mainMapObj.addOverlay(marker);
        centerMap();
    }

    // JWW
    // clear additional address if present
    var currentMaximum = getMaximumPoints();
    for ( var ii = addList.length; ii < currentMaximum; ii++) {
        var cccode = String.fromCharCode(65 + ii);
        obj = document.getElementById('route' + cccode);
        if (obj !== undefined && obj !== null) {
            obj.value = help_address[ii];
            obj.style.color = '#999999';
            routePointIndex++;
        }
    }
}

function geocodeAndFindRoute(address, ccode) {
    Log("Geocode and find route.");
    geoCoderObj = new GClientGeocoder();
    // alert(address);
    mustDelay = mustDelay + 1;
    geoCoderObj.getLocations(address, function(result) {
        if (result.Status.code == G_GEO_SUCCESS) {
            var addressElement;
            var tempAddress;
            if (ccode != "routeDestination") {
                addressElement = document.getElementById('route' + ccode);
                tempAddress = addList[addressElement.name];
            } else {
                addressElement = document.getElementById('routeDestination');
                tempAddress = routeDestination;
            }

            if (addList.length > 0 && tempAddress !== undefined && tempAddress !== null &&
                    tempAddress.GetMarker() !== undefined && tempAddress.GetMarker() !== null) {
                mainMapObj.removeOverlay(tempAddress.GetMarker());
            }
            var coord = result.Placemark[0].Point.coordinates;
            var lat = coord[1];
            var lng = coord[0];
            Log("geocodeAndFindRoute Place mark : " + result.Placemark[0].address + "<br>");
            Log(lat + " : " + lng + "<br>");
            dashadd = new DashFlyAddress();
            dashadd.SetAddress(address);
            if (addressLabel.length > 0) {
                dashadd.SetAddressLabel(addressLabel);
            } else {
                dashadd.SetAddressLabel(address);
            }

            dashadd.SetActualAddress(result.Placemark[0].address);
            dashadd.SetLatLng(new GLatLng(lat, lng));
            dashadd.SetAccuracy(result.Placemark[0].AddressDetails.Accuracy);

            var marker_str;
            if (ccode != "routeDestionation") {
                addList[addressElement.name] = dashadd;
                marker_str = (parseInt(addressElement.name, 10) === 0) ? "star" : addressElement.name;
            } else {
                routeDestination = dashadd;
                marker_str = "dest_star";
            }
        	if (dashadd.GetAccuracy() != 8){
        		marker_str += "warn";
        		alert('Warning, the address \"' + dashadd.GetAddress() + '\" does not have an exact match.  Please recheck address');
        	}

            // create marker
            var marker = new GMarker(new GLatLng(lat, lng), getIcon(marker_str));
            mainMapObj.removeOverlay(marker);
            onShowAddressInfo(marker, "click", dashadd);
            dashadd.SetMarker(marker);
            mainMapObj.addOverlay(marker);
            centerMap();
            if (document.getElementById("optimizeRoute").checked === false) {
                if (addList.length < ROUTE_CUTOVER) {
                    googdistanceCalulator = new DistanceByGoogle(addList, routeDestination, true, DoTheFindRoute);
                    googdistanceCalulator.GetOptimizedAddress();
                } else {
                    distanceCalulator = new DistanceByAir(addList, true);
                    // overwrite global addList variable so we have sorted
                    // address global
                    addList = distanceCalulator.GetOptimizedAddress();
                    FindRoute();
                }
            } else {
                FindRoute();
            }
        } else {
            if (result.Status.code == G_GEO_TOO_MANY_QUERIES) {
                alert("Not able to geocode : " + address + "<br>");
                document.getElementById('route' + ccode).focus();
            } else if (result.Status.code == G_GEO_UNKNOWN_ADDRESS) {
                alert("Unknown address " + address + "<br>");
                document.getElementById('route' + ccode).focus();
            } else {
                var reason = "Code " + result.Status.code;
                if (reasons[result.Status.code]) {
                    reason = reasons[result.Status.code];
                }
                alert("Fail to obtain geocode " + reason + " " + address);
                document.getElementById('route' + ccode).focus();
            }
        }
        
        mustDelay = mustDelay - 1;
    });
}

function showAddress( e ) {
    dashfly.addPriorityTaskToQueue( new showAddressBody(e) );
}

// Following function will geocode given address and raise the error if not able
// to geocode it
showAddressBody = function (e) {

    return function() {
        // Log("Entering showaddress with errorstate = " + errorStateOnGeocoding);
        // if( errorStateOnGeocoding == true)
        // {
        // return;
        // }
        if (e == 'showroute') {
    
            // reset text, etc, so allow geocoding again.
            errorStateOnGeocoding = false;
    
            Log('showroute in show address<br>');
            iscalculate = true;
            Log("Checking all address same<br>");
            if (isAllAddresssSame()) {
                // check last address
                var ccode = String.fromCharCode(65 + addList.length);
                var obj = document.getElementById('route' + ccode);
                Log("ccode : " + ccode + "<br>");
                // alert(obj);
                if ((obj !== undefined && obj !== null && obj.value.length !== 0 && isAddrExists(help_address, obj.value) === false)) {
                    Log("dont find route");
                    FindRoute();
                } else {
                    Log("Find route from all address same<br>");
                    if (document.getElementById("optimizeRoute").checked === false) {
                        if (addList.length < ROUTE_CUTOVER) {
                            if (addList.length > 5) {
                                jQuery("#routeGenerationProgressBarDialog").dialog("open");
                            }
                            googdistanceCalulator = new DistanceByGoogle(addList, routeDestination, true, DoTheFindRoute);
                            googdistanceCalulator.GetOptimizedAddress();
                        } else {
                            distanceCalulator = new DistanceByAir(addList, true);
                            // overwrite global addList variable so we have sorted
                            // address global
                            addList = distanceCalulator.GetOptimizedAddress();
                            FindRoute();
                        }
                    } else {
                        FindRoute();
                    }
                }
            }
            // FindRoute();
            return;
        } else {
            Log("Setting need to wait to true");
            showAddressNeedToWaitForResults = true;
    
            Log("Show Address Geo coding address " + e.name + " " + e.value + "<br>");
            e.value = e.value.replace(/\t/g, " ");
            var address = removedelimeter(e.value);
            Log("Address is " + address);
            addressLabel = e.value;
            var existingAddress = null;
            if (e.name == "routeDestination") {
                existingAddress = routeDestination;
            } else {
                existingAddress = addList[e.name];
            }
    
            // reset text, etc, so allow geocoding again.
            errorStateOnGeocoding = false;
    
            if (address.length === 0) {
                Log("Show Address Returning because address length is 0" + "<br>");
                if (existingAddress !== undefined && existingAddress !== null) {
                    mainMapObj.removeOverlay(existingAddress.GetMarker());
                    if (e.name == "routeDestination") {
                        routeDestination = null;
                        existingAddress = null;
                    } else {
                        addList[e.name] = null;
                        existingAddress = null;
                        addList.splice(e.name, 1);
                    }
                    mainMapObj.clearOverlays();
                    populateTextBoxes();
                    Log("is calculate route : " + iscalculate);
                }
                return;
            } else {
                if (addList.length > parseInt(e.name, 10)) {
                    if (existingAddress !== undefined && existingAddress !== null &&
                            existingAddress.GetAddress() !== undefined && existingAddress.GetAddress() !== null &&
                            existingAddress.GetAddress().length > 0 &&
                            existingAddress.GetAddress() == removedelimeter(e.value)) {
                        Log("Show Address RETURNING because already having address" + "<br>");
                        Log("is calculate route : " + iscalculate + "<br>");
                        return;
                    }
                }
            }
    
            Log("Show Address Geocoding started " + "<br>");
            geoCoderObj = new GClientGeocoder();
            Log("Show Address Geocoding object created " + "<br>");
            mustDelay = mustDelay + 1;
            geoCoderObj.getLocations(address, function(result) {
                if (iscalculate) {
                    Log("returning because is calculate : " + "<br>");
                    var geocodeKey = "";
                    if (e.name == "routeDestination") {
                        geocodeKey = e.name;
                    } else {
                        geocodeKey = String.fromCharCode(65 + parseInt(e.name, 10));
                    }
    
                    geocodeAndFindRoute(removedelimeter(e.value), geocodeKey);
                    showAddressNeedToWaitForResults = false;
                    errorStateOnGeocoding = false;
    
                    return;
                }
                if (result.Status.code == G_GEO_SUCCESS) {
                    if (addList.length > 0 && existingAddress !== undefined && existingAddress !== null &&
                            existingAddress.GetMarker() !== undefined && existingAddress.GetMarker() !== null) {
                        Log("Show Address Removing : " + existingAddress.GetAddress());
                        mainMapObj.removeOverlay(existingAddress.GetMarker());
                    }
                    var coord = result.Placemark[0].Point.coordinates;
                    var lat = coord[1];
                    var lng = coord[0];
                    Log("Show Address Place mark : " + result.Placemark[0].address + "<br>");
                    Log("Show Address  " + lat + " : " + lng + "<br>");
                    dashadd = new DashFlyAddress();
                    dashadd.SetAddress(address);
                    if (addressLabel.length > 0) {
                        dashadd.SetAddressLabel(addressLabel);
                    }
                    else {
                        dashadd.SetAddressLabel(address);
                    }
                    addressLabel = '';
                    dashadd.SetActualAddress(result.Placemark[0].address);
                    dashadd.SetLatLng(new GLatLng(lat, lng));
                    dashadd.SetAccuracy(result.Placemark[0].AddressDetails.Accuracy);
//                    alert(result.Placemark[0].AddressDetails.Accuracy);
                    // trim the string
                    ca = address.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
                    // If at least 15 characters long and unique
                    if (ca.length > 15 && !contains(cachedAddresses, ca)) {
                        cachedAddresses[cachedAddresses.length] = ca;
                        updateCachedAddresses(cachedAddresses);
                    }

                    var marker_str;
                    if (e.name == "routeDestination") {
                        routeDestination = dashadd;
                        marker_str = "dest_star";
                    } else {
                        addList[parseInt(e.name,10)] = dashadd;
                        marker_str = (parseInt(e.name,10) === 0) ? "star" : e.name;
                    }
                	if (dashadd.GetAccuracy() != 8){
                		marker_str += "warn";
                		e.style.color = "red";
                		alert('Warning, the address \"' + dashadd.GetAddress() + '\" does not have an exact match.  Please recheck address');
                	}
                    // create marker
                    var marker = new GMarker(new GLatLng(lat, lng), getIcon(marker_str));
                    mainMapObj.removeOverlay(marker);
                    onShowAddressInfo(marker, "click", dashadd);
                    dashadd.SetMarker(marker);
                    mainMapObj.addOverlay(marker);
    
                    Log("Show Address Geocoding completed successfully " + "<br>");
                    centerMap();
                    errorStateOnGeocoding = false;
                } else {
                    if (result.Status.code == G_GEO_TOO_MANY_QUERIES) {
                        alert("Not able to geocode at this time; please resubmit this address: " + address);
                        e.focus();
                    } else if (result.Status.code == G_GEO_UNKNOWN_ADDRESS) {
                        alert("Unknown address: " + address);
                        e.focus();
                    } else if (result.Status.code == G_GEO_SERVER_ERROR) {
                        alert("The geocoding server has an error; please resubmit this address: " + address);
                        e.focus();
                    } else {
                        var reason = "Code " + result.Status.code;
                        if (reasons[result.Status.code]) {
                            reason = reasons[result.Status.code];
                        }
                        alert(reason + " " + address);
                        e.focus();
                    }
                    errorStateOnGeocoding = true;
                }
                Log("Setting need to wait to false");
                mustDelay = mustDelay - 1;
            });
        }
    };
};

calculateRouteBody = function() {
    return function() {
        Log("************ in calculate route ***************");
    
        if (errorStateOnGeocoding === true) {
            return;
        }
    
        if (addList.length > 0 && addList[0] !== undefined && addList[0] !== null &&
                isAddrExists(help_address, addList[0].GetAddress()) === false) {
            if (base == 'login_id') {
                setText('helper', help_text_screen3);
            } else {
                setText('helper', help_text_screen2);
            }
            iscalculate = true;
            // hide login_id route and save route
            hideElement('saveRouteInputPanel');
            showAddress('showroute');
        } else {
            alert("Starting address is required");
            document.getElementById('routeA').focus();
        }
    }
};

function calculateRoute() {
    dashfly.addTaskToQueue( new reconcileAddressesBody() );
    dashfly.addTaskToQueue( new calculateRouteBody() );
}



function isVisible(elm) {
    flag = false;
    if (document.getElementById(elm) !== undefined && document.getElementById(elm) !== null) {
        if ((document.getElementById(elm).style.visibility == 'visible') ||
                (document.getElementById(elm).style.display == 'block')) {
            flag = true;
        }
        else {
            flag = false;
        }
    }
    return flag;
}

function reroute() {
    if (isVisible("dragPanel")) {
        temparr = addList.copy();
        var oldRouteDestination = routeDestination;

        addList = [];
        routeDestination = null;

        if (document.getElementById("stops").childNodes.length > 0) {
            var addressNodes = document.getElementById("stops").getElementsByTagName("tr");

            for ( var i = 0; i < addressNodes.length; i++) {
                var id = addressNodes[i].id; // works with IE & FireFox
                var addressNumber = id.substring(id.lastIndexOf("_") + 1);

                // not setting the ending address, so use addList
                if (i != temparr.length) {
                    if (addressNumber == temparr.length) {
                        addList[i] = oldRouteDestination;
                        // doing end address
                    } else {
                        addList[i] = temparr[addressNumber];
                    }
                } else {
                    if (addressNumber == temparr.length) {
                        routeDestination = oldRouteDestination;
                        // doing end address
                    } else {
                        routeDestination = temparr[addressNumber];
                    }
                }
            }
            FindRoute();
        }
    }
}

function removeLastEmptyRoutePoint() {
    var ccode = String.fromCharCode(64 + routePointIndex - 1);
    var possibleElement = document.getElementById("route" + ccode);

    if (possibleElement.value === '' || possibleElement.value == help_address[routePointIndex - 2]) {
        var parentdiv = document.getElementById('additionalRoutePoints');
        var element = document.getElementById('textdiv_route' + ccode);
        if (element !== undefined && element !== null) {
            parentdiv.removeChild(element);
            routePointIndex--;
        }
        Log("routepointindex = " + routePointIndex);
    }
}


function AddViewAllLnk() {
    parentdiv = document.getElementById('savedRouteList');
    
    if( !!parentdiv && parentdiv !== null ) {
       lielm = document.createElement('li');
       divelm = document.createElement('a');
       divelm.setAttribute('href', "/routes");
       divelm.innerHTML = 'View All';
   
       lielm.appendChild(divelm);
       parentdiv.appendChild(lielm);
    }
}

function AppendMyRoute(routeName, link) {
    var parentdiv = document.getElementById('savedRouteList');
    
    if( !!parentdiv && parentdiv !== null ) {
       lielm = document.createElement('li');
   
       divelm = document.createElement('a');
       divelm.setAttribute('href', "javascript:DeleteMyRoute('" + link + "')");
       divelm.setAttribute('title', "Delete this route");
       divelm.name = link;
       divelm.innerHTML = "<img src='" + IMAGEPATH + "delete_small.png' border='0'>";
       lielm.appendChild(divelm);
   
       divelm = document.createElement('span');
       divelm.innerHTML = '&nbsp;&nbsp;';
       lielm.appendChild(divelm);
   
       divelm = document.createElement('a');
       divelm.setAttribute('href', "javascript:ShowMyRoute('" + link + "','" + routeName + "')");
       divelm.innerHTML = replaceToString(routeName);
   
       lielm.appendChild(divelm);
       parentdiv.appendChild(lielm);
    }
}

function ProcessMyroute(response) {
    if (response !== undefined && response !== null && response.length > 0) {
        routearr = response.split("###");
        for ( var i = 0; i < routearr.length; i++) {
            rtdata = routearr[i].split(",");
            if (rtdata.length == 2) {
                AppendMyRoute(rtdata[0], rtdata[1]);
            }
        }
        // add view all link
        if (routearr.length > 0) {
            AddViewAllLnk();
        }
    }
}

function RefreshMyrouteList() {
    jQuery.get(ajaxcall + "myroute.php", '', ProcessMyroute);
}

function handleResize() {
    if (document.getElementById("map") != 'undefined' && document.getElementById("map") !== undefined &&
            document.getElementById("map") !== null) {
        var leftPanelSizeTxt = document.getElementById("left").style.width;
        var leftPanelSize = 268;

        if (leftPanelSizeTxt !== '') {
            leftPanelSize = parseInt(leftPanelSizeTxt, 10) + 20;
        }

        document.getElementById("map").style.width = (document.body.clientWidth - leftPanelSize) + 'px';
        document.getElementById("resizablemap").style.width = (document.body.clientWidth - leftPanelSize) + 'px';
    }
    mainMapObj.checkResize();
}

function init() {
    jQuery("#accountUpdate").addClass('dashflydialog').dialog( {
        modal :true,
        overlay : {
            opacity :0.5,
            background :"black"
        },
        width :880,
        height :670,
        autoOpen :false
    });

    jQuery("#accountUpdate").css("position", "relative");
    jQuery("#accountUpdate").css("left", "0px");
    jQuery("#accountUpdate").css("right", "0px");

    RefreshMyrouteList();

    if (addList.length > 0) {

        showElement("saveRoutePanel");
        showElement("dragPanel");
        hideElement("routePointPanel");
        hideElement("searchPanel");

        // routePointIndex = addList.length;
        routePointIndex = addList.length + 1;

        mainMapObj = new GMap2(document.getElementById("map"));
        
        mainMapObj.enableScrollWheelZoom();
        mainMapObj.addControl(new GLargeMapControl());
        mainMapObj.addControl(new GMapTypeControl());
        mainMapObj.setCenter(new GLatLng(36.778038, -96.80603), 10);
        for ( var i = 0; i < addList.length; i++) {
            // add markers to map
            if (addList[i] !== undefined && addList[i] !== null) {
                // mainMapObj.addOverlay(addList[i].GetMarker());
                var marker_str = (i === 0) ? "star" : i;
            	if (addList[i].GetAccuracy() != 8){
            		marker_str += "warn";
            	}
                var marker = new GMarker(addList[i].GetLatLng(), getIcon(marker_str));
                mainMapObj.removeOverlay(marker);
                onShowAddressInfo(marker, "click", addList[i]);
                addList[i].SetMarker(marker);
                mainMapObj.addOverlay(marker);
            }
        }
        // if(parseInt(addList.length) > 6) {
        // routePointIndex = parseInt(addList.length) + 1;
        // }
        if (base !== undefined && base !== null && base == 'route') {
            hideElement("localSearch");
            setText('helper', help_text_screen2);
            isShowMyRoute = true;
            FindRoute();
            setText('routeTitlebar', replaceToString(rname));
            showElement('routeTitlebar');
        } else if (base !== undefined && base !== null && base == 'login_id') {
            hideElement("localSearch");
            setText('routeTitlebar', replaceToString(rname));
            hideElement('routeTitlebar');
            hideElement('saveRouteLinkPanel');
            hideElement('savedRoutePanel');
            isShowMyRoute = false;
            setText('helper', help_text_screen3);
            FindRoute();
        }
        
        // If we're not in print mode, don't install a resize handler
        if( !isPrintModeActive() ) {
           window.onresize = handleResize;
        }
        handleResize();
    } else {
        var minpoints = 5;
        var currentMax = getMaximumPoints();
        if (minpoints > currentMax) {
            minpoints = currentMax;
        }
        routePointIndex = minpoints + 1;

        for ( var ii = 0; ii < minpoints; ii++) {
            document.getElementById("route" + String.fromCharCode(64 + ii + 1)).value = help_address[ii];
            document.getElementById("route" + String.fromCharCode(64 + ii + 1)).style.color = '#999999';
        }
        mainMapObj = new GMap2(document.getElementById("map"));
        mainMapObj.enableScrollWheelZoom();
        mainMapObj.addControl(new GLargeMapControl());
        mainMapObj.addControl(new GMapTypeControl());
        // Set default center in case invalid zip code
        // Also set first so we can correctly center map on browser load
        // or resize
        mainMapObj.setCenter(new GLatLng(36.778038, -98.80603), 4);

        showElement("routePointPanel");
        // Focus the starting address
        document.getElementById("routeA").focus();
        // Display helper text for screen 1
        setText('helper', help_text_screen1);
        // document.getElementById("helper").innerHTML = help_text_screen1;
        // Handle map width resizing based on browser width
        // If we're not in print mode, don't install a resize handler
        if( !isPrintModeActive() ) {
           window.onresize = handleResize;
        }

        handleResize();

        geoCoderObj = new GClientGeocoder();
        geoCoderObj.getLocations(zipcode + ", " + country, function(result) 
        {
            if (result.Status.code == G_GEO_SUCCESS && zipcode != "0") 
            {
                var coord = result.Placemark[0].Point.coordinates;
                var lat = coord[1];
                var lng = coord[0];
                // alert(lat + ":" + lng);
                mainMapObj.setCenter(new GLatLng(lat, lng), 10);
            }
        });
    }

    // If we are NOT in print mode, start the gas app stuff; this prevents undefineds from occurring.
    if( !isPrintModeActive() ) {
       application = new Application().start();
    }
}

function unload() {
    // if (application) application.stop();
    GUnload();
}


function printSetup() {
   var addresses = addList.slice(0);
   var isRoundTrip = ( typeof routeDestination === 'undefined' || routeDestination === null );
   if( !isRoundTrip ) {
      addresses.push( routeDestination );
   }
   dashflyprint.doPrint( addresses,  isRoundTrip );
}

function ProcessShowMyRoute(response) {
    routeDestination = null;

    if (response.length > 0) {
        addr = response.split('###');
        addList = [];
        for ( var i = 0; i < addr.length - 1; i++) {
            addNote = addr[i].split('@@@');
            if (addNote.length == 2) {
                tempArr = addNote[1].split(',');
                adr = new DashFlyAddress();
                temp = addNote[0].split('???');
                var1 = temp[0].split('___');
                adr.SetAddress(var1[0]);
                if (var1[1] !== undefined && var1[1] !== null && var1[1].length > 0) {
                    adr.SetAddressLabel(var1[1]);
                } else {
                    adr.SetAddressLabel(var1[0]);
                }
                temp2 = temp[1].split('$$$');
                adr.SetActualAddress(temp2[0]);
                temp3 = temp2[1].split(',');
                tempLng = temp3[1].split('+++')[0];
                adr.SetLatLng(new GLatLng(temp3[0], tempLng));
                adr.SetNotes(tempArr);
                temp4 = temp2[1].split('+++');
                adr.SetAccuracy(temp4[1]);

                var marker_str = (i === 0) ? "star" : i;
            	if (adr.GetAccuracy() != 8){
            		marker_str += "warn";
            	}
                var marker = new GMarker(new GLatLng(temp3[0], temp3[1]), getIcon(marker_str));
                onShowAddressInfo(marker, "click", adr);
                adr.SetMarker(marker);

                addList.push(adr);
                tempArr = [];
            }
        }
        if (addr[addr.length - 1] == "true") {
            // round trip
            routeDestination = null;
        } else {
            // one way
            routeDestination = addList[addList.length - 1];
            addList = addList.splice(0, addList.length - 1);
        }

        setRoutePointIndex = addr.length;
        setText('helper', help_text_screen2);
        FindRoute();
    }
}

function ShowMyRoute(id, name) {
    rname = name;
    hideElement('saveRouteInputPanel');
    setText('routeTitlebar', replaceToString(name));
    isShowMyRoute = true;
    var postContent = '';
    postContent += "id" + "=" + id;
    jQuery.post(ajaxcall + "myrouteaddress.php", postContent, ProcessShowMyRoute);
}

function AddMyRoute(routeName, link) {
    // alert('after save show link');
    parentdiv = document.getElementById('savedRouteList');

    lielm = document.createElement('li');

    divelm = document.createElement('a');
    divelm.setAttribute('href', "javascript:DeleteMyRoute('" + link + "')");
    divelm.name = link;
    divelm.innerHTML = "<img src='" + IMAGEPATH + "delete_small.png' border='0'>";
    lielm.appendChild(divelm);

    divelm = document.createElement('span');
    divelm.innerHTML = '&nbsp;&nbsp;';
    lielm.appendChild(divelm);

    divelm = document.createElement('a');
    divelm.setAttribute('href', "javascript:ShowMyRoute('" + link + "','" + replaceToHTML(routeName) + "')");
    divelm.innerHTML = replaceToString(routeName);

    lielm.appendChild(divelm);
    // alert("Lenght : " +parentdiv.childNodes.length );
    if (parentdiv.childNodes.length > 0) {
        if (parentdiv.childNodes.length > 5) {
            parentdiv.removeChild(parentdiv.childNodes[parentdiv.childNodes.length - 2]);
        }
        parentdiv.insertBefore(lielm, parentdiv.childNodes[0]);

    } else {
        parentdiv.appendChild(lielm);
        AddViewAllLnk();
    }
    ShowMyRoute(link, routeName);
}

function ProcessSaveRoute(response) {
    if (parseInt(response, 10) > 0) {
        setText('routeTitlebar', document.getElementById("saveroute").value);
        AddMyRoute(document.getElementById("saveroute").value, response);
        document.getElementById("saveroute").value = "";
        hideElement('saveRouteInputPanel');
        showElement('routeTitlebar');
    } else if (parseInt(response, 10) == -1) {
        displayUpgradeDialog("We're sorry ... to save more routes, you must upgrade your service.");
    } else {
        alert("Not able to save route...");
    }
}

function saveRoute() {
    obj = document.getElementById("saveroute");
    if (obj !== undefined && obj !== null && obj.value.length > 0) {
        var postContent = '';
        for ( var i = 0; i < (addList.length); i++) {
            if (addList[i] !== undefined && addList[i] !== null) {
                postContent += "add[]" + "=" + encodeURIComponent(addList[i].GetAddress()) + "&";
                postContent += "actadd[]" + "=" + encodeURIComponent(addList[i].GetActualAddress()) + "&";
                postContent += "addlbl[]" + "=" + encodeURIComponent(addList[i].GetAddressLabel()) + "&";
                postContent += "latlng[]" + "=" +
                    encodeURIComponent(addList[i].GetLatLng().lat() + "," + addList[i].GetLatLng().lng()) + "&";
                postContent += "accuracy[]" + "=" + encodeURIComponent(addList[i].GetAccuracy()) + "&";

            }
        }
        var roundTrip = 'y';

        // If it's NOT a round trip, we have to add on the ending destination
        if (routeDestination !== undefined && routeDestination !== null) {
            roundTrip = 'n';
            postContent += "add[]" + "=" + encodeURIComponent(routeDestination.GetAddress()) + "&";
            postContent += "actadd[]" + "=" + encodeURIComponent(routeDestination.GetActualAddress()) + "&";
            postContent += "addlbl[]" + "=" + encodeURIComponent(routeDestination.GetAddressLabel()) + "&";
            postContent += "latlng[]" + "=" +
                encodeURIComponent(routeDestination.GetLatLng().lat() + "," + routeDestination.GetLatLng().lng()) + "&";
                postContent += "accuracy[]" + "=" + encodeURIComponent(routeDestination.GetAccuracy()) + "&";
        }

        postContent += "rname" + "=" + obj.value + "&";
        postContent += "distance" + "=" + routeDistance + "&";
        postContent += "time" + "=" + routeTime + "&";
        postContent += "roundTrip" + "=" + roundTrip;
        Log(postContent + "<br>");
        jQuery.post(ajaxcall + "saveroute.php", postContent, ProcessSaveRoute);
    } else {
        alert("Please enter route name..");
    }
}

function handleSubmit(e) {
    var code = e.keyCode;
    if (code == 13) {
        if (isVisible('saveRouteInputPanel')) {
            saveRoute();
        }
        else if (isVisible('addNoteInputPanel')) {
            addNotes();
        }
        // else {
        // if(isVisible('routePointPanel'))
        // calculateRoute();
        // }
    }
}

function changeAddress() {
    obj = document.getElementById('changeaddress');
    if (obj.value.length > 0) {
        hideElement('addressChanger');
        // JWW ??
        addList[distanceCalulator.geoCoderCounter].SetAddress(obj.value);
        distanceCalulator.CaculateRoute();
    } else {
        alert("please change the address");
    }
}

function downloadGPX() {
    queryString = "";
    var arrTmp = [];
    addresslist = document.getElementById("waypoints").value;
    var waypt = arrTmp.concat(document.getElementById("waypoints").value.split("\n"));

    for ( var i = 0; i < waypoints.length; i++) {
        if (i === 0) {
            queryString = "?wapt[]=" + addList[i] + "&waptl[]=" + waypoints[i].lat() + "," + waypoints[i].lng();
        } else {
            queryString = queryString + "&wapt[]=" + addList[i] + "&waptl[]=" + waypoints[i].lat() + "," +
                    waypoints[i].lng();
        }
    }
    window.open("gpxfile.php" + queryString);
}

function textfocus(txt) {
    if (isAddrExists(help_address, txt.value)) {
        txt.value = '';
    }
    // txt.className='inputtextactive';
    txt.style.color = '#333333';
}

function goBack() {
    isMLS = false;
    isShowMyRoute = false;
    hideElement("dragPanel");
    hideElement("routeTitlebar");
    hideElement('saveRouteInputPanel');

    showElement("routePointPanel");
    showElement("searchPanel");
    showElement("localSearch");

    // clear all map overlay
    mainMapObj.clearOverlays();
    // clear direction panel
    document.getElementById("directionPanel").innerHTML = "";

    // Display helper text for screen 1
    document.getElementById("helper").innerHTML = help_text_screen1;
    populateTextBoxes();
}

function showSaveRoutePanel() {
    showElement('saveRouteInputPanel');
    document.getElementById("saveroute").focus();
}

function DeleteMyRouteElement(id) {
    parentdiv = document.getElementById('savedRouteList');
    for ( var i = parentdiv.childNodes.length - 1; i >= 0; i--) {
        child = document.getElementById('savedRouteList').childNodes[i];
        parentdiv.removeChild(child);
    }
    RefreshMyrouteList();
}

function ProcessDeleteMyRoute(response) {
    if (parseInt(response, 10) > 0) {
        DeleteMyRouteElement(response);
    } else {
        alert('Error occured while deleting route');
    }
}

function DeleteMyRoute(routeid) {
    if (confirm("Are you sure you want to delete this route?")) {
        var postContent = '';
        postContent += "id" + "=" + routeid;
        jQuery.get(ajaxcall + "deletemyroute.php", postContent, ProcessDeleteMyRoute);
    }
}

function ProcessGetNotes(response) {
    if (response !== undefined && response !== null && response.length > 0) {
        notesList = response.split('###');
        for ( var i = 0; i < addList.length; i++) {
            if (notesList[i] !== undefined && notesList[i] !== null && notesList[i].length > 0) {
                notes = notesList[i].split(',');
                addList[i].SetNotes(notes);
            }
        }
    }
    sortNFindRoute(sorNFindRouteFlag, isgeocodingFlag);
    document.getElementById("helper").innerHTML = help_text_screen2;
}

function getNotesFromServer() {
    var postContent = '';
    for ( var i = 0; i < addList.length; i++) {
        postContent += "add[]" + "=" + encodeURIComponent(addList[i].GetAddress()) + "&";
    }
    jQuery.post(ajaxcall + "getNotes.php", postContent, ProcessGetNotes);
}

function editRoute() {
    routePointIndex = 0;
    for ( var i = 0; i < document.getElementById("stops").childNodes.length; i++) {
        routePointIndex++;
        var ccode = String.fromCharCode(64 + i + 1);
        var parentdiv = document.getElementById('editRoutePanel');
        var textboxdiv = document.createElement('div');
        // Commented by DB, is this necessary?
        // textboxdiv.setAttribute('id','routePoint'+routePointIndex);
        if (i === 0) {
            textboxdiv.innerHTML = "<img src=\"" + IMAGEPATH + "star_bullet.png\" /> <input id=\"route" + ccode +
                    "\" type=\"text\" name='route" + ccode + "' value='" +
                    document.getElementById("stops").childNodes[i].childNodes[0].innerHTML +
                    "' onfocus=textfocus(this) class=\"inputtext\" tabindex=\"1\"/><br>";
        }
        else {
            textboxdiv.innerHTML = "<img src=\"" + IMAGEPATH + "stop" + i + ".png\" /> <input id=\"route" + ccode +
                    "\" type=\"text\" name='route" + ccode + "' value='" +
                    document.getElementById("stops").childNodes[i].childNodes[0].innerHTML +
                    "' onfocus=textfocus(this) class=\"inputtext\" tabindex=\"" + i + "\"/><br>";
        }
        parentdiv.appendChild(textboxdiv);
    }

    for ( var ii = (document.getElementById("stops").childNodes.length - 1); ii >= 0; ii--) {
        document.getElementById("stops").removeChild(document.getElementById("stops").childNodes[ii]);
    }
}

function dragAddRoutePoint() {
    if (document.getElementById('stops').childNodes.length > 0) {
        routePointIndex = document.getElementById('stops').childNodes.length;
    }
    else {
        routePointIndex = (document.getElementById('editRoutePanel').childNodes.length - 1);
    }
    // alert('lenght of add : ' + routePointIndex);
    routePointIndex += document.getElementById('dragAdditionalRoutePoints').childNodes.length;
    if (routePointIndex <= 11) {
        var ccode = String.fromCharCode(64 + routePointIndex);
        var parentdiv = document.getElementById('dragAdditionalRoutePoints');
        var textboxdiv = document.createElement('div');
        // Commented by DB, is this necessary?
        // textboxdiv.setAttribute('id','routePoint'+routePointIndex);
        textboxdiv.innerHTML = "<img src=\"" + IMAGEPATH + "stop" + (routePointIndex + 1) +
                ".png\" /> <input id=\"route" + ccode + "\" type=\"text\" name='route" + ccode + "' value='" +
                help_address[routePointIndex + 1] + "' onfocus=textfocus(this) class=\"inputtext\"/><br>";
        parentdiv.appendChild(textboxdiv);
        routePointIndex++;
    }
}

//function GetAddressFromMLS() {
//    var postContent = '';
//    for ( var i = 0; i < addList.length; i++) {
//        if (i == (addList.length - 1)) {
//            postContent += "add[]" + "=" + encodeURI(addList[i].GetMLS());
//        }
//        else {
//            postContent += "add[]" + "=" + encodeURI(addList[i].GetMLS()) + "&";
//        }
//    }
//    jQuery.get(ajaxcall + "getmls.php", postContent, ProcessMLSAddress);
//}
//
//function ProcessMLSAddress(response) {
//    addarr = response.split("###");
//    tempArr = addList.copy();
//    addList = [];
//    for ( var i = 0; i < tempArr.length; i++) {
//        addr = new DashFlyAddress();
//        if (IsNumeric(tempArr[i])) {
//            addr.SetAddress(addarr[i]);
//            addr.SetMLS(tempArr[i]);
//        } else {
//            addr.SetAddress(tempArr[i]);
//        }
//        addList.push(addr);
//    }
//    if (document.getElementById("optimizeRoute").checked === true) {
//        sorNFindRouteFlag = false;
//    }
//    else {
//        sorNFindRouteFlag = true;
//    }
//
//    getNotesFromServer();
//}

function displayDrag(e) {
    e.firstChild.style.visibility = 'visible';
}

function hideDrag(e) {
    e.firstChild.style.visibility = 'hidden';
}

function GetMLS(addArr, add) {
    for ( var i = 0; i < addArr.length; i++) {
        if (addArr[i].GetAddress() == add) {
            return addArr[i].GetMLS();
        }
    }

}

function GetActualAddress(addArr, add) {
    for ( var i = 0; i < addArr.length; i++) {
        if (addArr[i].GetAddress() == add) {
            return addArr[i].GetActualAddress();
        }
    }

}

function GetDashAddObj(arr, add) {
    for ( var i = 0; i < arr.length; i++) {
        //alert(arr[i].GetAddressLabel() + "+++" + add);
        if (arr[i].GetAddressLabel() == add.replace(/&amp;/g, "&")) {
            //alert("same");
            return arr[i];
        }
    }
}


// Add an action object to the queue. If the queue isn't currently running, it will be started.
// We expect that the actionObject will have an execute() method; any parameters
// should be set within the actionObject.

dashfly.addTaskToQueue = function( actionObject ) {
    taskQueue.enqueue( actionObject );
    if( !queueIsRunning ) {
        dashfly.startQueue();
    }
};

dashfly.addPriorityTaskToQueue = function( actionObject ) {
    priorityTaskQueue.enqueue( actionObject );
    if( !priorityQueueIsRunning ) {
        dashfly.startPriorityQueue();
    }
};

dashfly.doNextTask = function() {
    if( taskQueue.isEmpty() === false) {
        if( mustDelay <= 0 && priorityTaskQueue.isEmpty() === true ) {
            var action = taskQueue.dequeue();
            action();
        }
        dashfly.startQueue();
    } else {
        queueIsRunning = false;
    }
};

dashfly.startQueue = function() {
    queueIsRunning = true;
    setTimeout( dashfly.doNextTask, 50 );
};

dashfly.startPriorityQueue = function() {
    priorityQueueIsRunning = true;
    setTimeout( dashfly.doPriorityNextTask, 50 );
};

dashfly.doPriorityNextTask = function() {
    if( priorityTaskQueue.isEmpty() === false) {
        if( mustDelay <= 0 ) {
            var action = priorityTaskQueue.dequeue();
            action();
        }
        dashfly.startPriorityQueue();
    } else {
        priorityQueueIsRunning = false;
    }
};
