bqc.WAIT_TIME = 350;
bqc.CAT_COUNT = 12;
bqc.PAGE_SIZE = 10;
bqc.CHECKBOX_CIRCUIT = 'headerCat6';
bqc.SEARCH_MAXCHAR = 60;
bqc.HOSTS = [1, 2, 3, 4, 5];
bqc.ATTRACTS = [7, 8, 9, 10];

bqc.SearchManager = Class.create({

    initialize: function(map, tooltipManager) {
        this.map = map;
        this.categories = {};
        this.tooltipManager = tooltipManager;
        this.clusters = [];
        this.markedMarkers = [];
        this.unmarkedMarkers = [];
        this.listener = null;
        this.moveStartListener=null;
        this.zoomListener=null;
        this.currentSearch = null;
        this.previousSearch = null;
        this.referenceMarker = null;
        this.options = {
            p_mode: bqc.params.p_mode,
            p_fromSite: bqc.params.p_fromSite
        }
        this.searchText = $('searchText');
        if (this.searchText != null) {
            this.searchText.value = bqc.locale.search.inputValue;
            this.categories = this.createCategories();
        }
        $('regions').selectedIndex = 0;
        this.categoryUpdateTicket = null;
        this.markerOffset = 0;
        this.jsonResult = null;
        this.addIdToMarker = {};
        this.isProximity = false;
        this.searchSeq = 0;
        this.lastSeq = 0;
        this.setCategoriesCount = 0;
    },

    setOptions: function(options) {
        if (options.p_addId != null) {
            var that = this;
            this.getMarkers(options.p_addId, function(json) {
                if (json.marked.length > 0) {
                    that.isProximity = true;
                    var reference = {
                        json: json.marked[0],
                        map: that.map,
                        searchManager: that
                    };
                    if (options.p_searchNow != null) {
                        that.handleSearchNow(options, reference);
                    } else {
                        that.showReferenceMarker(reference, true);
                        that.referenceMarker.clickHandler();
                        that.map.savePosition();
                    }
                }
            }, true);
        }
    },

    handleSearchNow: function(options, reference) {
        var type = reference.json.type;
        if (this.isHost(type)) {
            this.setCategories(options, bqc.ATTRACTS);
        } else {
            this.setCategories(options, bqc.HOSTS);
            if (options.p_mode == 'partner') {
                options.p_reservable = 'Y';
            }
        }
        this.proximitySearch(options.p_addId, options, null,
            reference, null, null, true);
    },

    isHost: function(type) {
        for (var i = 0; i < bqc.HOSTS.length; ++i) {
            if (type == bqc.HOSTS[i]) {
                return true;
            }
        }
        return false;
    },

    isAttract: function(type) {
        for (var i = 0; i < bqc.ATTRACTS.length; ++i) {
            if (type == bqc.ATTRACTS[i]) {
                return true;
            }
        }
        return false;
    },

    setCategories: function(options, catArray) {
        for (var i = 0; i < catArray.length; ++i) {
            options['searchCategory-' + catArray[i]] = 'visible';
        }
    },

    hasCategory: function(options) {
        for (var i = 1; i <= bqc.CAT_COUNT; ++i) {
            if (options['searchCategory-' + i] != null) {
                return true;
            }
        }
        return false;
    },

    uncheck: function(el) {
        if (el != null) {
            el.checked = false;
        }
    },

    uncheckFathers: function() {
        this.uncheck($('accommodationFather'));
        this.uncheck($('attractionFather'));
    },

    createCategories: function() {
        this.uncheckFathers();
        for (var i = 1; i <= bqc.CAT_COUNT; ++i) {
            var el = $('headerCat' + i);
            el.checked = false;
            this.categories[el.id] = {
                el: el,
                name: 'searchCategory-' + el.value,
                value: el.value
            };
            if (el.id != bqc.CHECKBOX_CIRCUIT) {
                el.onclick = this.createCategoryHandler(this.categories, i);
            }
        }
        return this.categories;
    },

    createCategoryHandler: function(categories, id) {
        var that = this;
       
        return function() {
             if( categories[this.id].el.checked){
                bqc.gaLogger.log(bqc.params.p_mode_org, bqc.GAnalyticsStrings.level2.categorySearch, categories[this.id].el.value);
             }
            if (id <= 5) {
                if (!bqc.accommodationFatherClicked) {
                    unMarkFather(this, 'accommodationFather');
                }
            } else if (id <= 10) {
                if (!bqc.attractionFatherClicked) {
                    unMarkFather(this, 'attractionFather');
                }
            }
            that.updateCategory(categories[this.id]);
        };
    },

    updateCategory: function(cat) {

        if (cat.el.checked) {
            if(bqc.catsClicked == ""){
                bqc.catsClicked += cat.el.value;
            }else{
                bqc.catsClicked += "," + cat.el.value;
            }
            this.options[cat.name] = 'visible';
            ++this.setCategoriesCount;
  
        } else {
            delete this.options[cat.name];
            --this.setCategoriesCount;
        }
        var that = this;
        var requestTicket = Math.random();
        this.categoryUpdateTicket = requestTicket;
        window.setTimeout(function() {
            if (that.categoryUpdateTicket == requestTicket) {
               
                that.tryCenterSearch(
                    bqc.advInputBox.getValue(that.searchText), true, false);
            }
        }, 100);
    },

    listenMap: function() {
        if(this.isProximity){
            return;
        }
        var that = this;
        var zoomendded = false;
        if (this.listener == null) {
            this.listener = GEvent.addListener(this.map, 'moveend', function() {
                if (!zoomendded) {
                    that.searchAgain();
                } else {
                    zoomendded = false;
                }
            });
        }
        if (this.moveStartListener == null) {
            this.moveStartListener = GEvent.addListener(this.map, 'movestart', function() {
                that.tooltipManager.hideTooltip();
                that.clearAll();
            });
        }
        if (this.zoomListener == null) {
            this.zoomListener = GEvent.addListener(this.map, 'zoomend', function() {
                zoomendded = true;
                that.zoomend();
            });
        }
    },

    zoomend: function() {
        this.tooltipManager.hideTooltip();
        this.clearAll();
        var time = new Date().getTime();
        this.previousSearch = time;
        var that = this;
        window.setTimeout(function() {
            if (time == that.previousSearch) {
                that.searchAgain();
            }
        }, bqc.WAIT_TIME);
    },

    stopListeningMap: function() {
        if (this.listener != null) {
            GEvent.removeListener(this.listener);
            this.listener = null;
        }
        if (this.moveStartListener != null) {
            GEvent.removeListener(this.moveStartListener);
            this.moveStartListener = null;
        }
        if (this.zoomListener != null) {
            GEvent.removeListener(this.zoomListener);
            this.zoomListener = null;
        }

        
    },

    addClusterParams: function(options, addIds, dontCluster) {
        var bounds = getReducedBounds(this.map, bqc.markedIconAnchor.x, bqc.markedIconAnchor.y, bqc.markedIconAnchor.x);
        var sw = bounds.getSouthWest();
        var ne = bounds.getNorthEast();

        var swLng = sw.lng(), swLat = sw.lat(), neLng = ne.lng(), neLat = ne.lat();

        options.p_xmin = (swLng >= -180 && swLng <= 0) ? swLng : -180;
        options.p_ymin = (swLat >= 0 && swLat <= 90) ? swLat : 0;
        options.p_xmax = (neLng >= -180 && neLng <= 0) ? neLng : 0;
        options.p_ymax = (neLat >= 0 && neLat <= 90) ? neLat : 90;

        options.p_centerX = this.map.getCenter().lng();
        options.p_centerY = this.map.getCenter().lat();


        options.p_deltaX = this.getDeltaX(swLng, neLng);
        options.p_deltaY = this.getDeltaY(swLat, neLat);
        

        options.p_isClustedSearch = (bqc.conf.zoomToDisableCLuster>=this.map.getZoom()) && dontCluster != true;
        if (addIds) {
            options.p_add_ids=addIds;
        }
        options.catsClicked = bqc.catsClicked;
        return options;
    },

    clearReferenceMarker: function() {
        if (this.referenceMarker != null) {
            this.referenceMarker.remove();
            this.referenceMarker = null;
        }
    },

    showReferenceMarker: function(marker, setZoom) {
        if (marker != null) {
            this.referenceMarker = new bqc.ReferenceMarker(marker);
            if (setZoom) {
                this.map.setCenter(this.referenceMarker.marker.getLatLng(), bqc.conf.zoomToReference);
            }
        }
    },

    initProximitySearch: function(isNew, setPage) {
        bqc.resultList.showList();
        if (isNew) {
            bqc.router.remove();
            this.isProximity = true;
            bqc.resultList.isProximity = true;
            bqc.resultList.showLoading();
            this.setPage = setPage;
        }
        this.clearReferenceMarker();
        this.clearSearch();
        this.listenMap();
    },

    endProximitySearch: function(transport, callback, isSetPage,savePos) {
        this.showMarkers(transport.responseJSON, isSetPage);
        this.showAllMarked(savePos);
        if (callback != null) {
            callback(transport.responseJSON);
        }
    },

    circuitProximitySearch: function(options, callback, offset) {
        this.initProximitySearch(offset == null, this.createCircuitProximitySetPage(options));
	bqc.circuits.proximitySearching();
        bqc.proximityName = bqc.locale.circuits[options.p_parcours_id];
        var that = this;
        if (offset != null) {
            options.p_offset = offset;
        }
        new Ajax.Request('circuitProximity.do', {
            method: 'post',
            evalJSON: true,
            parameters: options,
            onSuccess: function(transport) {
                 if (transport.responseJSON.nbtotal<1) {
                    that.handleCircuitProximNoResult();
                }else{
                    that.endProximitySearch(transport, callback, offset != null);
                }
                
            }
        });
    },

    proximitySearch: function(addId, options, callback, marker, isSetPage, catsChecked,savePos) {

        this.initProximitySearch(!isSetPage, this.createProximitySetPage(addId, options, marker));
        
        var proximityName=marker.json.name;
        if(marker.json.poiName!=""){
            proximityName=proximityName+" - "+marker.json.poiName
        }
       bqc.proximityName=proximityName;

        var that = this;
        options.p_addId = addId;
        options.catsChecked = catsChecked;
        new Ajax.Request('proximitySearch.do', {
            method: 'post',
            evalJSON: true,
            parameters: options,
            onSuccess: function(transport) {
                bqc.circuits.unload();
                that.showReferenceMarker(marker);
                 if (transport.responseJSON.nbtotal<1) {
                    that.handleProximNoResult();
                }else{  
                    that.endProximitySearch(transport, callback, isSetPage,savePos);
                }
            }
        });
    },

    tryCenterSearch: function(text, fromCategory, isFromHeader) {
        this.searchCriterions = this.formatedResult();

        text = (text == null || text.length > bqc.SEARCH_MAXCHAR) ? '' : bqc.trim(text);
        if (!fromCategory && text.length == 0 && this.setCategoriesCount == 0) {
            return;
        }

        bqc.resultList.showList();
        if (text.length > 0 && text.length < 3 && !fromCategory) {
            bqc.resultList.showError(bqc.locale.search.errCharacter);
            return;
        }
        this.options.searchCriterion = text;
        if (isFromHeader === true) {
            bqc.gaLogger.log(bqc.params.p_mode_org, bqc.GAnalyticsStrings.level2.textSearch, text);
        }
        this.centerSearch(true, text, true);
        this.searchCriterions=this.formatedResult();
    },

    hasResult: function() {
        return this.clusters.length > 0 || this.unmarkedMarkers.length > 0 ||
        this.markedMarkers.length > 0;
    },

    formatedResult:function() {
        var text = this.options.searchCriterion;
        if (text == null) {
            text = '';
        }
        for (var id in this.categories) {
            var category = this.categories[id];
            if (this.options[category.name] != null) {
                if (text.length > 0) {
                    text += ', '
                }
                text += bqc.locale.search.categories[category.value - 1];
            }
        }
        return text;
    },

    handleProximNoResult: function() {
        if(bqc.params.p_unit=="mi"){
        bqc.resultList.showError(bqc.locale.search.errProxNoResult+bqc.locale.search.errProxDistanceMiles);
      }else{
          bqc.resultList.showError(bqc.locale.search.errProxNoResult+bqc.locale.search.errProxDistanceKm);
      }

    },
    handleCircuitProximNoResult: function() {
        if(bqc.params.p_unit=="mi"){
        bqc.resultList.showError(bqc.locale.search.errProxNoResult+bqc.locale.search.errCircuitsDistanceMiles);
      }else{
          bqc.resultList.showError(bqc.locale.search.errProxNoResult+bqc.locale.search.errCircuitsDistanceKm);
      }

    },

    handleNoResult: function() {
        var text = this.options.searchCriterion;
        if (text == null) {
            text = '';
        }
        for (var id in this.categories) {
            var category = this.categories[id];
            if (this.options[category.name] != null) {
                if (text.length > 0) {
                    text += ', '
                }
                text += bqc.locale.search.categories[category.value - 1];
            }
        }
        if (text.length == 0) {
            bqc.resultList.clear();
        } else {
            bqc.resultList.showError(bqc.locale.search.errNoResult.replace('%s', text));
        }
        bqc.circuits.reset();
    },

    centerSearch: function(isNew, text, initial) {
        bqc.resultList.showLoading();
        if (isNew) {
            bqc.resultList.isProximity = false;
            this.setPage = this.setCenterSearchPage;
        }
        bqc.circuits.centerSearching();
        var that = this;
        this.tooltipManager.resetProximity();
        this.clearReferenceMarker();
        this.currentSearch = function() {
            that.centerSearch();
        };
        this.options.p_offset = this.markerOffset = 0
        this.listenMap();
        if(typeof text != "undefined"){
            this.options.textSearched = text;
        }else{
            this.options.textSearched = "";
        }
        if(typeof initial != "undefined" && initial){
            this.options.initial = initial;
        }else{
            this.options.initial = false
        }
        var seq = ++this.searchSeq;
                new Ajax.Request('centerSearch.do', {
            method: 'post',
            evalJSON: true,
            parameters: this.addClusterParams(this.options),
            onSuccess: function(transport) {


                if(transport.responseJSON.extend){
                    var center = this.map.getCenter();
                    var bounds = new GLatLngBounds ();
                    bounds.extend(center);
                    bounds.extend(new GLatLng(transport.responseJSON.point.lat, transport.responseJSON.point.lng));
                    this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));
                    bounds = getIncreasedBounds(this.map, bqc.markedIconAnchor.x, bqc.markedIconAnchor.y, bqc.markedIconAnchor.x);
                    this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));

                }else{
                    bqc.catsClicked = "";
                    if (seq > that.lastSeq) {
                        that.lastSeq = seq;

                        that.jsonResult = transport.responseJSON;
                        that.showMarkers(transport.responseJSON);

                        if (!that.hasResult()) {
                            that.handleNoResult();
                        }
                    }
                }
            }
        });

        
        /*new Ajax.Request('centerSearch.do', {
            method: 'post',
            evalJSON: true,
            parameters: this.addClusterParams(this.options),
            onSuccess: function(transport) {
                bqc.catsClicked = "";
                if (seq > that.lastSeq) {
                    that.lastSeq = seq;

                    that.jsonResult = transport.responseJSON;
                    that.showMarkers(transport.responseJSON);

                    if (!that.hasResult()) {
                        that.handleNoResult();
                    }
                }
            }
        });*/
    },

    getMarkers: function(addIds, callback, dontCluster) {
        new Ajax.Request('reSearch.do', {
            method: 'post',
            evalJSON: true,
            parameters: this.addClusterParams(this.options, addIds, dontCluster),
            onSuccess: function(transport) {
                callback(transport.responseJSON);
            }
        });
    },
    
    multiResultSearch: function(addIds, isUpdate) {
        bqc.resultList.showLoading();

        var that = this;
        if (!isUpdate) {
            bqc.resultList.isProximity = false;
            this.setPage = this.setCenterSearchPage;
            this.currentSearch = function() {
                that.multiResultSearch(addIds, true);
            }
        }
        this.tooltipManager.resetProximity();
        this.clearReferenceMarker();
        this.markerOffset = 0;
        this.listenMap();
        this.getMarkers(addIds, function(json) {
            that.jsonResult = json;
            that.showMarkers(json);
        });
    },

    selectHosts: function() {
        this.options['searchCategory-1'] = 'visible';
        this.options['searchCategory-2'] = 'visible';
        this.options['searchCategory-3'] = 'visible';
        this.options['searchCategory-4'] = 'visible';
        this.options['searchCategory-5'] = 'visible';
    },

    hostsSearch: function() {
        this.options.p_reservable= 'Y';
        this.options.searchCriterion = '';
        this.selectHosts();
        this.tryCenterSearch(null, true, false);
    },
    
    getDeltaX: function(left, right) {
        var delta = (right > left) ? 
            (right - left) :
            (180 - left + right + 180);
        return delta / (this.map.getSize().width / bqc.conf.clusterGridPixelSize);
    },

    getDeltaY: function(bottom, top) {
        var delta = (top > bottom) ?
            (top - bottom) :
            (90 - bottom + top + 90);
        return delta / (this.map.getSize().height / bqc.conf.clusterGridPixelSize);
    },

    showAllMarked: function(savePos) {
        if (this.markedMarkers.length > 0) {
            var xmin, ymin, xmax, ymax;
            if (this.referenceMarker != null) {
                xmin = this.referenceMarker.getLatLng().lng();
                ymin = this.referenceMarker.getLatLng().lat();
                xmax = xmin;
                ymax = ymin;
            } else {
                xmin = Number.MAX_VALUE;
                ymin = Number.MAX_VALUE;
                xmax = Number.NEGATIVE_INFINITY;
                ymax = Number.NEGATIVE_INFINITY;
            }
            for (var i = 0; i < this.markedMarkers.length; ++i) {
                var latlng = this.markedMarkers[i].marker.getLatLng();
                xmin = Math.min(xmin, latlng.lng());
                ymin = Math.min(ymin, latlng.lat());
                xmax = Math.max(xmax, latlng.lng());
                ymax = Math.max(ymax, latlng.lat());
            }
            var bounds = new GLatLngBounds(
                new GLatLng(ymin, xmin),
                new GLatLng(ymax, xmax));
            this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));
            bounds = getIncreasedBounds(this.map, bqc.markedIconAnchor.x, bqc.markedIconAnchor.y, bqc.markedIconAnchor.x);
            this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));
            if(savePos){
                this.map.savePosition();
            }
        }
    },

    showMarker: function(addId) {
        var marker = this.addIdToMarker[addId];
        if (marker != null) {
            marker.showMiniFiche();
        }
    },

    showMarkers: function(json,update) {
        bqc.spider.clearSpidered();
        this.clearAll();

        if (json.grouped != null) {
            var totalGrouped = 0;
            for (var i = 0; i < json.grouped.length; ++i) {
                this.clusters.push(new bqc.ClusterMarker(json.grouped[i], this.map, this));
                totalGrouped = totalGrouped + json.grouped[i].nb;
            }
            var markers = json.marked.concat(json.unmarked);
            var mrk;
            for (i = 0; i < this.markerOffset; ++i) {
                mrk = new bqc.Marker(markers[i], this.map, this);
                this.unmarkedMarkers.push(mrk);
                bqc.GMarkers.push(mrk.marker);
                this.addIdToMarker[mrk.json.addId] = mrk;
            }
            var markedIndex = 0;
            for (i = this.markerOffset; i < markers.length &&
                markedIndex < bqc.PAGE_SIZE; ++i, ++markedIndex) {
                mrk=new bqc.MarkedMarker(markers[i], this.map, this, markedIndex);
                this.markedMarkers.push(mrk);
                bqc.GMarkers.push(mrk.marker);
                this.addIdToMarker[mrk.json.addId] = mrk;
            }
            for (; i < markers.length; ++i) {
                mrk=new bqc.Marker(markers[i], this.map, this);
                this.unmarkedMarkers.push(mrk);
                bqc.GMarkers.push(mrk.marker);
                this.addIdToMarker[mrk.json.addId] = mrk;
            }

            if(this.referenceMarker){
                bqc.GMarkers.push(this.referenceMarker.marker);
            }
            bqc.spider.setMarkers(bqc.GMarkers)

            if(update == undefined || !update){
                bqc.resultList.fillList(markers,json.marked,json.nbtotal,null,json.nbtotal+totalGrouped);
            }
        }
    },

    getOffset: function(page) {
        return (page - 1) * bqc.PAGE_SIZE;
    },

    setMarkerOffset: function(page) {
        this.markerOffset = this.getOffset(page);
    },

    setPage: null, // See setCenterSearchPage or setProximitySearchPage

    setCenterSearchPage: function(page) {
        this.setMarkerOffset(page);
        this.showMarkers(this.jsonResult,true);
    },

    createProximitySetPage: function(addId, options, marker) {
        var that = this;
        return function(page, callback) {
            options.p_offset = this.getOffset(page);
            that.proximitySearch(addId, options, callback, marker, true);
        }
    },

    createCircuitProximitySetPage: function(options) {
        var that = this;
        return function(page, callback) {
            that.circuitProximitySearch(options, callback, this.getOffset(page));
        }
    },

    clearCategories: function() {
        this.uncheckFathers();
        this.setCategoriesCount = 0;
        for (var id in this.categories) {
            if (id != bqc.CHECKBOX_CIRCUIT) {
                var cat = $(id);
                cat.checked = false;
                delete this.options[this.categories[cat.id].name];
            }
        }
    },

    clearSearch: function() {
        this.currentSearch = null;
        this.clearCategories();
        this.stopListeningMap();
        this.clearAll();
    },

    clearAll: function() {
        bqc.spider.clearSpidered();
        this.clearArray(this.clusters);
        this.clearArray(this.markedMarkers);
        this.clearArray(this.unmarkedMarkers);
        this.addIdToMarker = {};
        bqc.GMarkers=new Array();
    },

    clearArray: function(array) {
        while (array.length > 0) {
            array.pop().remove();
        }
    },

    searchAgain: function() {
        if (this.currentSearch != null) {
            this.currentSearch();
        }
    }
});

