//Hack to prevent annoying popup when loading page in firefox.
OpenLayers.Renderer.SVG.prototype.supported = function() {
    var svgFeature = "http://www.w3.org/TR/SVG11/feature#";
    return (document.implementation &&
    (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
    document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
    document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") ));
};

(function($) {
$.fn.createMap = function(easting, northing) {
    var mapDiv = this;
    var lineVectorLayer = new OpenLayers.Layer.Vector("Line Vector Layer");
    var pointVectorLayer = new OpenLayers.Layer.Vector("Point Vector Layer");
    var osMap;
    var lineStyle = {
        strokeColor: "#FF0000",
        strokeOpacity: 0.75,
        strokeWidth: 3
    };
    var movingPoints = false;

    init(easting, northing);
    function init(easting, northing) {
        osMap = new OpenSpace.Map(mapDiv.attr("id"));
        osMap.addLayer(pointVectorLayer);
        osMap.addLayer(lineVectorLayer);

        resizeMap();

        osMap.events.register("click", osMap, function(e) {
            var pt = osMap.getLonLatFromViewPortPx(e.xy);
            gpxGeneratorRoute.addPoint(new Point(pt.lon, pt.lat));
        });

        var modifyFeaturesControl = new OpenLayers.Control.ModifyFeature(lineVectorLayer);
        modifyFeaturesControl.mode = OpenLayers.Control.ModifyFeature.RESHAPE;
        osMap.addControl(modifyFeaturesControl);
        modifyFeaturesControl.activate();
        lineVectorLayer.events.register('featuremodified', lineVectorLayer, function(feature) {
            movingPoints = true;
            var featurePoints = lineVectorLayer.features[0].geometry.components;
            var points = [];
            for (var featurePointsIndex = 0; featurePointsIndex < featurePoints.length; featurePointsIndex++) {
                var currentFeaturePoint = featurePoints[featurePointsIndex];
                points.push(new Point(currentFeaturePoint.x, currentFeaturePoint.y));
            }
            gpxGeneratorRoute.setPoints(points);
            movingPoints = false;
        });

        $(window).resize(resizeMap);
        $(gpxGeneratorRoute).bind("pointsUpdated", drawLine);
        $(gpxGeneratorRoute).bind("allPointsUpdated", zoomTodisplayAllPoints);
        $('#altitudeEnlarge').click(showHideMenu);

        osMap.setCenter(new OpenSpace.MapPoint(easting, northing), 10);
        osMap.zoomTo(7);
    }

    function drawLine() {
        if (!movingPoints) {
            var openLayersPoints = [];
            for(var pointsIndex = 0; pointsIndex < gpxGeneratorRoute.numOfPoints(); pointsIndex++) {
                var point = gpxGeneratorRoute.getPoint(pointsIndex);
                openLayersPoints.push(new OpenLayers.Geometry.Point(point.x, point.y));
            }

            var lineString = new OpenLayers.Geometry.LineString(openLayersPoints);
            var lineFeature = new OpenLayers.Feature.Vector(lineString, null, lineStyle);

            var lineFeatureArray = [lineFeature];
            var pointFeatureArray = [];
            if (gpxGeneratorRoute.numOfPoints() > 0) {
                var startFeature = new OpenLayers.Feature.Vector(openLayersPoints[0]);
                pointFeatureArray.push(startFeature);
            }
            if (gpxGeneratorRoute.numOfPoints() > 1) {
                var endFeature = new OpenLayers.Feature.Vector(openLayersPoints[openLayersPoints.length -1]);
                pointFeatureArray.push(endFeature);
            }

            lineVectorLayer.destroyFeatures();
            lineVectorLayer.addFeatures(lineFeatureArray);
            pointVectorLayer.destroyFeatures();
            pointVectorLayer.addFeatures(pointFeatureArray);
        }
    }

    function resizeMap() {
        var mapHeight = $(window).height() - 60 - $("#altitude").height();

        mapDiv.height(mapHeight);
        osMap.updateSize();
    }

    function zoomTodisplayAllPoints() {
        if (!movingPoints) {
            var bounds = new OpenSpace.MapBounds();
            for (var pointsIndex = 0; pointsIndex < gpxGeneratorRoute.numOfPoints(); pointsIndex++) {
                var point = gpxGeneratorRoute.getPoint(pointsIndex);
                bounds.extend(new OpenSpace.MapPoint(point.x, point.y));
            }

            osMap.zoomToExtent(bounds);
        }
    }

    function showHideMenu() {
        //this should go into its own plugin and resize map gets called but registering for some event
        if ($('#altitudeChartBody:visible').length > 0) {
            $('#altitudeChartBody').toggle('slow', function() {
                var newHeight = $(window).height() - 60 - $("#altitudeHeader").height();
                $("#map").animate({ height: newHeight + "px" }, "slow", "linear", resizeMap);
                $('#altitudeEnlarge').removeClass('ui-icon ui-icon-triangle-1-s').addClass('ui-icon ui-icon-triangle-1-n');
            });
        }
        else {
            var newHeight = $(window).height() - 60 - 150 - $("#altitudeHeader").height();
            $("#map").animate({ height: newHeight + "px" }, "slow", "linear", function() {
                $('#altitudeChartBody').toggle('slow', function() {
                    $('#altitudeEnlarge').removeClass('ui-icon ui-icon-triangle-1-n').addClass('ui-icon ui-icon-triangle-1-s');
                    resizeMap();
                    $(mapDiv).displayAltitudeChart();
                });
            });
        }

        return false;
    }
}

$.fn.numberOfPoints = function() {
    $(gpxGeneratorRoute).bind("pointsUpdated", function(event) {
        $("#numOfPoints").html(gpxGeneratorRoute.numOfPoints());
    });
}

$.fn.deleteLastPoint = function() {
    $("#deleteLastPoint").click(function(event) {
        if (!gpxGeneratorRoute.hasPoints()) {
            return displayError("Sorry you have no points to delete.");
        }
        return gpxGeneratorRoute.removeLastPoint();
    });
}

$.fn.routeLength = function() {
    $(gpxGeneratorRoute).bind("pointsUpdated", function(event) {
        var length = gpxGeneratorRoute.calculateTotalRouteLength();
        var lengthInMiles = convertMetersToMiles(length);
        var roundedLengthInMiles = roundRouteLength(lengthInMiles);
        $("#routeLength").html(roundedLengthInMiles);
    });

    function roundRouteLength(length) {
        var roundedLength;
        if (length == 0) {
            roundedLength = 0;
        }
        else if (length < 10) {
            roundedLength = length.toFixed(2);
        }
        else {
            roundedLength = length.toFixed(1);
        }

        return roundedLength;
    }

    function convertMetersToMiles(length) {
        return ((length / 1000) / 8) * 5;
    }
}

$.fn.displayHeigthGainAndLoss = function() {
    $(gpxGeneratorRoute).bind("altitudesUpdated pointsUpdated", function(event) {
        $("#altitudeGained").html(gpxGeneratorRoute.calculateTotalHeigthChange(true));
        $("#altitudeLoss").html(gpxGeneratorRoute.calculateTotalHeigthChange(false));

    });
}

$.fn.displayAltitudeChart = function() {
    var altitudeChartDiv = $("#altitudeChart");
    $(gpxGeneratorRoute).bind("altitudesUpdated pointsUpdated", function(event) {
        if (gpxGeneratorRoute.numOfPoints() < 2) {
            altitudeChartDiv.html('Need more points to load chart.');
        }
        else {
            var chartPoints = [];
            for (numOfPointsIndex = 0;
                    numOfPointsIndex < gpxGeneratorRoute.numOfPoints() && gpxGeneratorRoute.getPoint(numOfPointsIndex).altitude != null;
                    numOfPointsIndex++) {
                chartPoints[numOfPointsIndex] = [gpxGeneratorRoute.calculateRouteLengthToPoint(numOfPointsIndex), gpxGeneratorRoute.getPoint(numOfPointsIndex).altitude];
            }

            $.plot(altitudeChartDiv, [{data:chartPoints}]);
        }
    });
}
})(jQuery);