/*global mapping, console, OpenLayers, document, $*/

Array.prototype.last = function () {
    return this.slice(-1)[0];
};

var monitor = {
    indicId: null,
    indic: null,
    queueLength: 0,
    init: function () {
        this.indic = $("#" + this.indicId);
        this.refresh();
    },
    queue: function () {
        //console.log("q++");
        this.queueLength++;
        this.refresh();
    },
    dequeue: function () {
        //console.log("q--");
        this.queueLength--;
        this.refresh();
    },
    refresh: function () {
        if (this.queueLength > 0) {
            if (this.indic.is(":hidden")) {
                this.indic.fadeIn("fast");
            }
        } else {
            if (!this.indic.is(":hidden")) {
                this.indic.fadeOut("fast");
            }
        }
    },
    reset: function () {
        this.queueLength = 0;
        this.refresh();
    }
};

var mapping = {
    wmsURI: "http://eryr.net/tilecache",
    wfsURI: document.baseURI + "/loilayerwfs",
    bounds: new OpenLayers.Bounds(146597, 192627, 229380, 250139),
    resolutions: [122, 86, 60, 25, 5, 2.5],
    mapOptions: {},
    map: null,
    baseLayer: null,
    segmentLayer: null,
    POILayer: null,
    mapControls: [
        new OpenLayers.Control.Navigation(),
        new OpenLayers.Control.PanZoomBar()
    ],
    currentZoomedFeature: null,
    selectControl: null,
    popUpClass: "poiPopUp",
    popUp: null,
    tabList: null,
    tabs: [],
    nextBtn: null,
    prevBtn: null,
    popLock: false,
    baseStyle: OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']),
    routeStyle: null,
    highlightStyle: null,
    wfsStyle: null,

    init: function () {
/*
        if (!console) {
            console = {log: function (msg) {}};
        }
*/
        OpenLayers.ImgPath = "/";
        this.baseStyle.strokeWidth = 4;
        this.routeStyle = OpenLayers.Util.extend({}, this.baseStyle);
        this.routeStyle.strokeColor = "#A024AE";
        this.highlightStyle = OpenLayers.Util.extend({}, this.baseStyle);
        this.highlightStyle.strokeColor = "#FFA4E9";
        this.wfsStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
        this.wfsStyle.externalGraphic = "pin1.png";
        this.popUp = $("." + this.popUpClass).hide();
        monitor.indicId = "monitor";
        monitor.init();
        this.tabList = $("#tabs");
        this.tabs = $("#tabs li");
        var tabClickBound = this.tabClick.bind(this);
        this.tabs.click(function () {
            tabClickBound($(this));
        });
        var nextBound = this.nextTab.bind(this);
        this.nextBtn = $("#showNext");
        this.nextBtn.click(nextBound);
        var prevBound = this.prevTab.bind(this);
        this.prevBtn = $("#showPrevious");
        this.prevBtn.click(prevBound);
        this.baseLayer = new OpenLayers.Layer.WMS("Base WMS", this.wmsURI, {layers: 'planed-os', format: 'image/png'});
        this.segmentLayer = new OpenLayers.Layer.Vector("Route", {style: this.routeStyle});
        this.POILayer = new OpenLayers.Layer.WFS("POI", this.wfsURI, {}, {style: this.wfsStyle, extractAttributes: true});
/*
        this.POILayer.events.register("loadend", this, function (e) {
            console.log("loadend");
            monitor.dequeue();
        });
        this.POILayer.events.register("loadcancel", this, function (e) {
            console.log("loadcancel");
            monitor.dequeue();
        });

        this.POILayer.events.register("loadstart", this, function (e) {
            console.log("loadstart");
            monitor.queue();
        });
*/


        this.POILayer.events.register("beforefeatureadded", this, function (e) {
            return !!e.feature.geometry && !!e.feature.geometry.CLASS_NAME && e.feature.geometry.CLASS_NAME === "OpenLayers.Geometry.Point";
        }); //Prevents features with null geometry being added
        var selFBound = this.selF.bind(this);
        var unselFBound = this.unselF.bind(this);
        this.selectControl = new OpenLayers.Control.SelectFeature([this.segmentLayer, this.POILayer], {onSelect: selFBound, onUnselect: unselFBound, hover: true});
        this.mapControls.push(this.selectControl);
        this.mapOptions = {
            maxExtent : this.bounds,
            restrictedExtent: this.bounds,
            resolutions : this.resolutions,
            projection : 'EPSG:27700',
            tileSize : new OpenLayers.Size(256, 256),
            controls : this.mapControls
        };
        this.map = new OpenLayers.Map("map", this.mapOptions);
/*
         this.map.events.register("move", this, function (e) {
                    console.log("mapMove", e);
            });
*/
        this.map.addLayers([this.baseLayer, this.segmentLayer, this.POILayer]);

        this.map.zoomToExtent(this.bounds);

        this.selectControl.activate();
        var mousePos = new OpenLayers.Control.MousePosition();
        this.map.addControl(mousePos);
        $("#" + mousePos.div.id.replace(/\./g, "\\\\\\\.")).hide();
        this.map.events.register("mousemove", this.map, function (e) {
            if (!mapping.popLock) {
                var cssObj = {left: mousePos.lastXy.x + 16, top: mousePos.lastXy.y};
                $("#OBSmapPop").css(cssObj);
            }
        });
        $("#OBSmapPop").hide();


        this.getTabBodies();

        this.segment();

    },

    popClose: function () {
        this.popLock = false;
        $(".popToggle").hide();
        $("#OBSmapPop").hide().removeClass("OBSMapPopActive");
    },

    tabClick: function (t) {
        this.tabs.removeClass("selected");
        t.addClass("selected");
        this.getTabBodies();
    },

    getTabBodies: function () {
        var tl = this.tabs.length;
        for (var i = 0; i < tl; i++) {
            var t = $(this.tabs[i]);
            var bodyId = $(this.tabs[i])[0].id.split("tab-")[1];
            if (t.hasClass("selected")) {
                $("#" + bodyId).show();
            } else {
                $("#" + bodyId).hide();
            }
        }
        this.setMapToFeature($("#tabs li.selected")[0].id.split("tab-section")[1]);
    },

    nextTab: function () {
        var nt = $("#tabs li.selected").next();
        if (nt.length) {
            this.tabClick(nt);
        }
    },

    prevTab: function () {
        var pt = $("#tabs li.selected").prev();
        if (pt.length) {
            this.tabClick(pt);
        }
    },

    setMapToFeature: function (ftidx) {

        if (ftidx) {
            this.zoomToFeature(this.segmentLayer.features[ftidx - 1]);
            this.highlightFeature(this.segmentLayer.features[ftidx - 1]);
        } else if (!!this.map && !!this.segmentLayer.features[0]) {
            this.map.zoomToExtent(mapping.segmentLayer.features[0].geometry.parent.getBounds());
            this.highlightFeature(false);
        }

    },

    highlightFeature: function (f) {
        for (var i = 0, l = this.segmentLayer.features.length ; i < l; i++) {
            this.segmentLayer.features[i].style = this.routeStyle;
        }
        if (!!f) {
            f.style = this.highlightStyle;
        }
        this.segmentLayer.redraw();
    },

    selF: function (f) {
        if (!!f.layer) {
            switch (f.layer.name) {
            case "Route":
                break;
            case "POI":
                this.POIHover(f);
                break;
            default :
                break;
            }
        }
    },

    unselF: function (f) {
        if (!this.popLock) {
            $("#OBSmapPop").hide();
        }
    },

    featureClick: function () {
        if (mapping.popLock) {
            mapping.popClose();
        } else {
            mapping.popLock = true;
            $(".popToggle").show();
            $("#OBSmapPop").addClass("OBSMapPopActive");
        }
    },

    onFeatureUnhover: function (feature) {
        if (!this.popLock) {
            $("#OBSmapPop").hide();
        }
    },

    POIHover: function (f) {
        if (!this.popLock) {
            var thisFeature = f;
            var jQString = "#" + thisFeature.geometry.id.replace(/\./g, "\\\\\\\.");
            var featureTitleText;
            if (thisFeature.data.portal_type === "SiopImage") {
                featureTitleText = "<img src='" + thisFeature.data.url + "/image_header' />";
            } else {
                featureTitleText = thisFeature.data.title;
            }
            var featureDescriptionText;
            if (thisFeature.data.description) {
                featureDescriptionText = thisFeature.data.description;
            } else {
                featureDescriptionText = "";
            }
            var popLink;
            if (thisFeature.data.url) {
                popLink = "<p class='popToggle'><a href='" + thisFeature.data.url + "'>Read more...</a></p>";
            } else {
                popLink = "";
            }
            $(jQString).unbind();
            if (thisFeature.data.portal_type === "SiopImage") {
                $("a[rel*='lightbox']").attr({href: thisFeature.data.url + "/image_preview", title: "<a href='" + thisFeature.data.url + "'>" + thisFeature.data.title + " by " + thisFeature.data.creator + " " + thisFeature.data.rights + "</a>"});
                $(jQString).click(function () {
                    $("a[rel*='lightbox']").lightBox().click();
                });
                $("#OBSmapPop")[0].innerHTML = "<div id='miniImagePop'><div id='miniSpin'><img src='spinner.gif' /></div><div id='miniImage'><img src='" + thisFeature.data.url + "/image_header' /></div></div>";
            } else {
                var fcB = this.featureClick.bind(this);
                $(jQString).click(fcB);
                $("#OBSmapPop")[0].innerHTML = "<div id='popClose' class='popToggle' onclick='mapping.popClose()'></div><p class='popTitle'><b>" + featureTitleText + "</b></p><p class='popToggle'>" + featureDescriptionText + "</p>" + popLink;
                $(".popToggle").hide();
            }
            $("#OBSmapPop").show();
        }
    },

    geomToFeature: function (geom) {
        var f = new OpenLayers.Feature.Vector(geom.clone());
        f.attributes.classes = {};
        f.addNext = function (nextFeature) {
            this.next = nextFeature;
            nextFeature.prev = this;
        };

        return f;
    },

    addF: function (evt) {

        if (!!evt.feature.geometry && evt.feature.geometry.CLASS_NAME === "OpenLayers.Geometry.MultiLineString" && !!evt.feature.attributes.classes) {
            this.map.zoomToExtent(evt.feature.geometry.getBounds());
            var newFeatures = [];
            for (var fc = 0, fcl = evt.feature.geometry.components.length ; fc < fcl ; fc++) {
                newFeatures.push(this.geomToFeature(evt.feature.geometry.components[fc]));
            }
            for (var i = 0, il = evt.feature.attributes.classes.length ; i < il; i++) {
                var c = evt.feature.attributes.classes[i];
                var thisClassType = c.classType;
                var thisClassMembers = c.members;
                for (var j = 0, m = thisClassMembers.length; j < m ;j++) {
                    for (var k = 0, n = thisClassMembers[j].segments.length; k < n; k++) {
                        var thisSeg = thisClassMembers[j].segments[k];
                        newFeatures[thisSeg].attributes.classes[thisClassType] = thisClassMembers[j].type;
                        newFeatures[thisSeg].attributes.index = thisSeg;
                    }
                }
            }
            for (var l = 0, p = newFeatures.length - 1; l < p; l++) {
                newFeatures[l].addNext(newFeatures[l + 1]);
                newFeatures[l].attributes.group = newFeatures;
            }
            newFeatures.last().group = newFeatures;
            if (newFeatures[0].geometry.components[0].equals(newFeatures.last().geometry.components.last())) {
                newFeatures.last().addNext(newFeatures[0]);
            }
            this.segmentLayer.addFeatures(newFeatures);
            evt.feature.destroy();

            return false;
        } else {

            return true;
        }
    },

    rrange: function (min, max) {
        var range = max - min;
        return min + range * Math.random();
    },

    segment: function () {
        var geomURI = document.baseURI + "/getGeometry";
        this.segmentLayer.events.register("beforefeatureadded", this, this.addF);
        var WKTcallback = this.addGeom.bind(this);
        OpenLayers.Request.issue({
            callback: WKTcallback,
            method: "get",
            url: geomURI
        });
    },

    addGeom: function (response) {
        console.log(response);
        if (response.status === 200) {
            var WKTFormat = new OpenLayers.Format.WKT();
            var wktText = response.responseText;
            var ft = WKTFormat.read(wktText);
            ft.attributes.classes = [{
                classType: "day",
                members: [{type: "Day 1", segments: []}]
            }];
            this.segmentLayer.addFeatures([ft]);
        }
    },

    zoomToFeature: function (f) {
        if (!f) {
            if (this.currentZoomedFeature) {
                this.currentZoomedFeature = this.currentZoomedFeature.next;
            } else {
                this.currentZoomedFeature = this.segmentLayer.features[0];
            }
            f = this.currentZoomedFeature;
        }
        if (!!f) {
            this.map.zoomToExtent(f.geometry.getBounds());
        }
    }
};

$(document).ready(function () {
    mapping.init();
});

