var Resultset = function(keys, values) {
    this.init(keys, values);
};

Resultset.prototype = {
    records: [],
    init: function(keys, values) {
		
        if(values) {
            this.records = [];
            for(var i = 0; i < values.length; i++) {
                for(key in keys) {
                    if(!this.records[i])
                        this.records[i] = [];
                    this.records[i][key] = values[i][keys[key]];
                }
            }
        }
        else {
            this.records = keys;
        }
		
        this.readPtr = -1;
        this.pageSize = -1;
        this.curPage = 1;
        this.minAcco = NaN;
        this.maxAcco = NaN;

        this.sortTyp = 0; // 0 = no order, 1 = string, 2 = numeric, 3 = custom1, 4 = custom2, 5 = ...
        this.sortFld = ''; // Field to order
        this.sortAsc = 0; // 0 = asc, 1 = dis
    },

    setPageSize: function(pageSize) {
        this.pageSize = pageSize;
    },
    setSortOptions: function(optTyp, optFld, optAsc){
        this.sortTyp = optTyp;
        this.sortFld = optFld;
        this.sortAsc = optAsc;
    },
    next: function() {
        if(this.pageSize == -1) {
            this.pageSize = this.size();
            this.curPage = 1;
        }

        if( (this.readPtr < this.size() - 1) && (this.readPtr < (this.curPage * this.pageSize) - 1) ) {
            this.readPtr++;
            return true;
        }
        else {
            return false;
        }
    },
	
    previous: function() {
        if(this.readPtr > 0) {
            this.readPtr--;
            return true;
        }
        else {
            return false;
        }		
    },
	
    first: function() {
        if(this.size() > 0) {
            this.readPtr = 0;
            return true;
        }
        else {
            return false;
        }
    },
	
    last: function() {
        if(this.size() > 0) {
            this.readPtr = this.size() - 1;
            return true;
        }
        else {
            return false;
        }
    },
	
    rewind: function() {
        this.readPtr = -1;
    },
	
    getRecord: function() {
        return this.records[this.readPtr];
    },
	
    getField: function(fieldName) {
        return this.records[this.readPtr][fieldName];
    },
	
    getIndex: function(fieldName) {
        if(typeof this.keys[fieldName] != 'undefined') {
            return this.keys[fieldName];
        }
        else {
            return null;
        }
    },
    getMinAccoPrice: function() {
        return this.minAccoPrice;
    },
    getMaxAccoPrice: function() {
        return this.maxAccoPrice;
    },
    applyFilters: function(filterGroups, countMatches) {

        var groupName;
        var filteredArr = [];
        this.minAcco = NaN;
        this.maxAcco = NaN;

        this.rewind();
		
        //Disabilito tutti i filtri e resetto il contatore dei match
        for(groupName in filterGroups) {						
            filterGroups[groupName].disableFilters();
            filterGroups[groupName].resetMatch();
        }
		
        //Applico i filtri a tutti i record nel rs
        while(this.next()) {

            var match = true;
            var group;

            var sValue = "0"; // Caso particolare accoprice
            var value = NaN; // Caso particolare accoprice
			
            for(groupName in filterGroups) {
                group = filterGroups[groupName];				
                if (groupName != 'accoprice') { // Caso particolare accoprice
                    match = match && group.apply(this);
                }
                if(!match) break;
            }

            // Caso particolare accoprice
            //if (match) {
            group = filterGroups['accoprice'];

            if (group) {
                var filters = group.getFilters();
                var filter = filters['accoprice'].filter;
                //Logger.debug('>>> Filter: ' + filter); // Devo risistemare i SUBFILTER e PREZZO
                sValue = this.getRecord().accoprice;
                value = NaN;
                if (sValue) {
                    sValue = sValue.replace(",", "");
                    sValue = sValue.replace(".", "");
                    value = parseFloat(sValue, 10); // tolgo eventuale , che e' per le migliaia... solitamente
                }

                // Calculate real min and max in the resultset.
                if (! isNaN(value)) {
                    if (isNaN(this.minAcco)) {
                        this.minAcco = value;
                    }
                    if (isNaN(this.maxAcco)) {
                        this.maxAcco = value;
                    }
                    if (value > this.maxAcco) {
                        this.maxAcco = value;
                    }
                    if (value < this.minAcco) {
                        this.minAcco = value;
                    }
                }

                match = match && group.apply(this);
            //Logger.debug('>>> AccoPrice: ' + groupName + ' ' +  this.minAcco + ' ' + this.maxAcco); // Devo risistemare i SUBFILTER e PREZZO
            }
            //}
            // END Caso particolare accoprice


            if(match) {
				
                if(countMatches) {
                    for(groupName in filterGroups) {
                        group = filterGroups[groupName];										
                        if(group.evaluateMatch(this)) {
                            group.enable();
                        }
                    }
                }
                Logger.debug('>>> Record: ' + this.getRecord().accocategory);
                filteredArr.push(this.getRecord());		
            }

        }

        // >> PTTCR-287
        if (this.sortTyp > 0) {
            this.sortRS(filteredArr);
        }
        // << PTTCR-287

        // >> BEGIN DARIO - COUNTER
        var counterElem = jQuery('#ajaxitemcount');
        if (counterElem) {
            jQuery('#ajaxitemcount').text(filteredArr.length);
        }
        // << END   DARIO - COUNTER

        var group = filterGroups['accoprice'];

        if (group) {
            var filters = group.getFilters();
            var filter = filters['accoprice'].filter;
            filter.setMinRSValue(this.minAcco);
            filter.setMaxRSValue(this.maxAcco);
            if (this.minAcco > filter.getMinValue())
                filter.setMinValue(this.minAcco);

            if (this.maxAcco < filter.getMaxValue())
                filter.setMaxValue(this.maxAcco);

            filter.setHasPrices(1);
            filter.setMoveHandles(true);
        }

        return new Resultset(filteredArr);
    },
    applySecondPassFilters: function(filterGroups) {

        var groupName;
        this.rewind();

        //Disabilito tutti i filtri e resetto il contatore dei match
        for(groupName in filterGroups) {
            if (groupName != 'accoprice') { // Caso particolare accoprice
                filterGroups[groupName].disableFilters();
            //filterGroups[groupName].resetMatch();
            }
            filterGroups[groupName].resetMatch();
        }

        // Applico i filtri a tutti i record nel rs
        // Per ottimizzazione bisognerebbe fare
        // solo quelli che necessitano del second pass
        while(this.next()) {

            var match = true;
            var group = "";

            for(groupName in filterGroups) {
                if (groupName != 'accoprice') { // Caso particolare accoprice
                    group = filterGroups[groupName];
                    match = match && group.apply(this);
                    if(!match) break;
                }
            }

            if(match) {
                for(groupName in filterGroups) {
                    group = filterGroups[groupName];
                    if(group.evaluateMatch(this)) {
                        //Logger.debug('>>>** applySecondPassFilters: GroupEnable: ' + groupName); // Devo risistemare i SUBFILTER e PREZZO
                        group.enable();
                    }
                }
            }
        }

    },
    sortRS: function(filteredArr) {

        var fldName = this.sortFld;
        
        // String
        if (this.sortTyp == 1) {
            if (this.sortAsc == 0) {
                filteredArr.sort(function (a,b){
                    if (typeof(a[fldName]) != 'undefined') {
                        var nameA=a[fldName].toLowerCase(), nameB=b[fldName].toLowerCase()
                        if (nameA < nameB) return -1;
                        if (nameA > nameB) return 1;
                    }
                    return 0; //default return value (no sorting)
                });

            } else {
                filteredArr.sort(function (a,b){
                    if (typeof(a[fldName]) != 'undefined') {
                        var nameA=a[fldName].toLowerCase(), nameB=b[fldName].toLowerCase()
                        if (nameA < nameB) return 1;
                        if (nameA > nameB) return -1;
                    }
                    return 0; //default return value (no sorting)
                });
            }
        }

        // Numerical
        if (this.sortTyp == 2) {
            if (this.sortAsc == 0) {
                filteredArr.sort(function (a,b){
                    var aVal = 0;
                    var bVal = 0;
                    if (a[fldName] != undefined) {aVal = a[fldName];}
                    if (b[fldName] != undefined) {bVal = b[fldName];}
                    return (aVal - bVal); // Numerically Ascending
                });

            } else {
                filteredArr.sort(function (a,b){
                    var aVal = 0;
                    var bVal = 0;
                    if (a[fldName] != undefined) {aVal = a[fldName];}
                    if (b[fldName] != undefined) {bVal = b[fldName];}
                    return (bVal - aVal); // Numerically Ascending
                });
            }
        }

    // << PTTCR-287: Sort
    },
    // ++ dario ++
    setFieldByPid: function(pid, fieldname, newval) {

        this.rewind();
	
        // Controllo tutti i record nel rs
        while(this.next()) {
            if (this.records[this.readPtr]['pid'] == pid)
                this.records[this.readPtr][fieldname] = newval;
        }
    },
    
    setItemPos: function(newval) {
        this.records[this.readPtr]['itempos'] = this.readPtr - this.pageSize*(this.curPage-1)+1;
       
    //alert(this.records[this.readPtr]['itempos']+ ' - PageSize: ' + this.pageSize + ' - CurPage: ' +this.curPage);
        
    },	
    // -- dario --
	
    size: function() {
        return this.records.length;
    },
    getKeys: function() {

        if(!this.keys) {
            this.keys = [];
            for(key in this.records[0]) {
                this.keys.push(key);
            }
        }
        return this.keys;
		
    },
    incPage: function() {
        var newPtr = this.curPage * this.pageSize - 1;

        if(newPtr < this.size()) {
            this.curPage++;
            this.readPtr = newPtr;
        }
        else {
            this.readPtr = (this.curPage - 1) * this.pageSize - 1;
        }
    },
    decPage: function() {
        if(this.curPage > 1)
            this.curPage--;
        this.readPtr = (this.curPage - 1) * this.pageSize - 1;		
    },
    firstPage: function() {
        this.curPage = 1;
        this.readPtr = -1;
    },
    lastPage: function() {
        this.curPage = this.getTotalPages();
        this.readPtr = (this.curPage - 1) * this.pageSize - 1;
    },
    gotoPage: function(page) {
        if(this.isValidPage(page)) {
            this.curPage = page;
            this.readPtr = (this.curPage - 1) * this.pageSize - 1;
        }
    },
    isFirstPage: function() {
        return this.curPage == 1;
    },
    isLastPage: function() {
        return this.curPage == this.getTotalPages();
    },
    hasMorePages: function() {
        return this.curPage < this.getTotalPages();
    },
    hasPreviousPages: function() {
        return this.curPage > 1;
    },
    isValidPage: function(page) {
        // return ((page > 1 ) && (page < this.getTotalPages()));
        // ++ dario ++
        return ((page >= 1 ) && (page <= this.getTotalPages()));
    // -- dario --
    },
    getCurrentPage: function() {
        return this.curPage;
    },
    getTotalPages: function() {
        return Math.ceil(this.size() / this.pageSize);
    }
}

