/**
 * This class handles request to display or hide circuits (via kml).
 * It calls the server to request circuits extent and to
 * position circuits marker (used to control de infowindow).
 */
bqc.Circuits = Class.create({

    justInitialized: true,

    initialize: function(map, parameters) {
        this.map = map;
        this.param = parameters;
        this.kml = {
            id: {},
            combined: {},
            overlay: {},
            urls: {}
        };
        this.marker = {
            overlay: {},
            images: {},
            fiches: {},
            initialized: false
        };
        this.reset();
        this.listener = null;
        this.listenMap();
        this.projection = G_NORMAL_MAP.getProjection();
        this.configure();
    },

    configure: function(){
        var me = this;
        new Ajax.Request('circuitsConfiguration.do', {
            method: 'get',
            evalJSON: true,
            onSuccess: function(transport){
                var response = transport.responseJSON;
                me.kml.urls = response.urls;
                me.kml.combined = response.combined;
                me.marker.images = response.marker.images;
                me.marker.fiches = response.marker.fiches;
                if (me.param.init != null && me.param.init.length > 0) {
                    me.load(me.param.init);
                }
            }
        });
    },

    proximitySearch: function(id, callback) {
        if (this.kml.id == this.kml.combined) {
            this.load(id, callback);
        } else {
            callback(id);
        }
    },

    listenMap: function(){
        if(this.listener == null){
            var me = this;
            this.listener = GEvent.addListener(this.map, 'moveend', function(){
                me.remark();
            });
        }
    },

    stopListeningMap: function() {
        if (this.listener != null) {
            GEvent.removeListener(this.listener);
            this.listener = null;
        }
    },

    load: function(id, callback) {
        if(this.kml.id != null){
            this.unload();
        }
        this.kml.id = id != null ? id : this.kml.combined;
        this.applyOverlay(callback);
    },

    applyOverlay: function(callback){
        if($("loadingPanel")){
            bqc.showLoading();
        }
        var url = this.param.kmlPath + "/" + this.kml.urls[this.kml.id]+"?v=3";
        var that = this;
        this.kml.overlay = new GGeoXml(url, function() {
            if (that.kml.id != that.kml.combined && !that.param.noMarker) {
                that.kml.overlay.gotoDefaultViewport(that.map);
            }
            that.postLoad(callback);
             if($("loadingPanel")){
                 bqc.hideLoading();
             }
        });
        this.map.addOverlay(this.kml.overlay);
    },

    unload: function(){
        if(this.kml.id != null){
            this.map.removeOverlay(this.kml.overlay);
            this.release();
        }
    },

    release: function() {
        this.kml.overlay = {};
        this.kml.id = {};
        this.destroyMarkers();
    },

    initMark: function(callback) {
        if (this.kml.id.length > 0 && !this.param.noMarker) {
            if(bqc.searchManager.isProximity){
                bqc.searchManager.tooltipManager.resetProximity();
                bqc.searchManager.clearReferenceMarker();
                bqc.searchManager.clearAll();
                bqc.resultList.clear();
            }
            this.mark(false, callback);
        }
    },

    centerSearching: function() {
        this.reset();
    },

    proximitySearching: function() {
        this.postLoad = function(callback) {
            bqc.searchManager.clearReferenceMarker();
            bqc.searchManager.clearSearch();
            this.initMark(callback);
            bqc.resultList.hide();
            if($("loadingPanel")){
                bqc.resultList.showLoading();
            }
        }
    },

    reset: function() {
        this.postLoad = this.initMark;
    },

    viewEntire: function() {
        var me = this;
        new Ajax.Request('circuitExtent.do', {
            method: 'get',
            evalJSON: true,
            parameters: {
                id: this.kml.id,
                r: Math.random()
            },
            onSuccess: function(transport){
                var extent = transport.responseJSON;
                var bounds = new GLatLngBounds(new GLatLng(extent.ymin,extent.xmin), new GLatLng(extent.ymax,extent.xmax));
                me.map.setCenter(
                    bounds.getCenter(),
                    me.map.getBoundsZoomLevel(bounds));
                me.mark(false);
            }
        });
    },

    remark: function(){
        if(this.marker.initialized && this.marker.overlay != {}){
            this.mark(true);
        }
    },

    getReducedBounds: function() {
        return getReducedBounds(this.map, bqc.circuitMarkerAnchor.x,
            bqc.circuitMarkerAnchor.y, bqc.circuitMarkerAnchor.x);
    },

    mark: function(update, callback) {
        var center = this.map.getCenter();
        var bounds = this.getReducedBounds();
        var p = {
            x: center.lng(),
            y: center.lat(),
            xmin: bounds.getSouthWest().lng(),
            ymin: bounds.getSouthWest().lat(),
            xmax: bounds.getNorthEast().lng(),
            ymax: bounds.getNorthEast().lat()
        };
        // do not send special combined id to circuitMarket servlet.
        if(this.kml.id != this.kml.combined){
            p.id = this.kml.id;
        }
        var me = this;
        new Ajax.Request('circuitMarker.do', {
            method: 'get',
            evalJSON: true,
            parameters: p,
            onSuccess: function(transport){
                var response = transport.responseJSON;
                me.marker.coordinates = response;
                if(update){
                    me.updateMarkers();
                } else {
                    me.createMarkers();
                }
                if (callback != null) {
                    callback(me.kml.id);
                }
            }
        });
    },

    updateMarkers: function(){
        for (var id in this.marker.coordinates){
            var overlay = this.marker.overlay[id];
            if (overlay == null) {
                this.createMarker(id);
            } else {
                overlay.marker.setLatLng(new GLatLng(this.marker.coordinates[id].lat, this.marker.coordinates[id].lon));
            }
        }
    },

    createMarker: function(id) {
        var coordinate = this.marker.coordinates[id];
        coordinate.img = this.param.contextPath + "/" + this.marker.images[id];
        coordinate.id = id;
        var marker = new bqc.CircuitMarker(coordinate, this.map, bqc.searchManager);
        this.marker.overlay[id] = marker;
        if (id == this.kml.id && this.justInitialized) {
            this.justInitialized = false;
            this.map.savePosition();
        }
    },

    createMarkers: function(){
        for (var id in this.marker.coordinates) {
            this.createMarker(id);
        }
        this.marker.initialized = true;
    },

    destroyMarkers: function(){
        for (var id in this.marker.overlay){
            this.marker.overlay[id].remove();
        }
        this.marker.overlay = {};
        this.marker.initialized = false;
    }
});
