var HtmlFilters = {
    SLIDER:			'slider',
    CHECKBOX:		'checkbox',
    DROPDOWN:		'dropdown',
    TEXTBOX:		'textbox',
    SUBFILTER:      'subfilter'
};

var Operators = {
    EQ:		1,
    NEQ:	2,
    GTE:	3,
    GT:		4,
    LTE:	5,
    LT:		6,
    LIKE:	7
};

var Filter = function(filterName, operator, filterValue) {
    this.init(filterName, operator, filterValue);
};

Filter.prototype = {
    init: function(filterName, operator, filterValue) {
        
        //Logger.debug('Filter: init: ' + filterName + operator +filterValue );

        this.filterName = filterName;
        this.filterValue = filterValue;
        this.operator = operator;
		
        this.active = false;
		
        this.matches = 0;
    },

    setValue: function(value) {
        this.filterValues[0] = value;
    },
    /**
	 * Applica il filtro alla riga corrente del resultset
	 */
    apply: function(rset) {
       
        var match = false;
		
        try {
            //Estrae il valore del campo relativo al filtro nel resultset
            var value = rset.getField(this.filterName);
            if(typeof(value) != 'object')
                value = [value];
	
            for(var v = 0; v < value.length; v++) {
				
                if(this.operator != Operators.EQ && this.operator != Operators.NEQ && this.operator != Operators.LIKE ) {
                    var intVal1 = parseInt(value[v], 10);
                    var intVal2 = parseInt(this.filterValue, 10);
                }
				
                switch(this.operator) {
                    case Operators.EQ:
                        match = match || (this.filterValue == value[v]);
                        break;
                    case Operators.NEQ:
                        match = match || (this.filterValue != value[v]);
                        break;
                    case Operators.LIKE:
                        match = match || (value[v].toLowerCase().indexOf(this.filterValue.toLowerCase()) > -1);
                        break;
                    case Operators.GTE:
                        match = match || (intVal1 >= intVal2);
                        break;
                    case Operators.GT:
                        match = match || (intVal1 > intVal2);
                        break;
                    case Operators.LTE:
                        match = match || (intVal1 <= intVal2);
                        break;
                    case Operators.LT:
                        match = match || (intVal1 < intVal2);
                        break;
                }

                if(match)
                    return true;
            }
        } catch(e) {
            Logger.debug(e);
        }
		
        return match;
    },
    evaluateMatch: function(rset) {
        if(this.apply(rset)) {
            this.matches++;
            return true;
        }
        return false;
    },
    getMatches: function() {
        return this.matches;
    },
    hasMatches: function() {
        return this.matches > 0;
    },
    resetMatch: function() {
        this.matches = 0;
    },
    activate: function() {
        this.active = true;
    },
    deactivate: function() {
        this.active = false;
    },
    isActive: function() {
        return this.active;
    },
    enable: function() {
        this.enabled = true;
    },
    disable: function() {
        this.enabled = false;
    },
    isEnabled: function() {
        return this.enabled;
    },
    getFilterName: function() {
        return this.filterName;
    }
};

/**
 * Filtro di tipo dropdown
 */
var DropdownFilter = function(filterName, operator, filterValue) {
    this.init(filterName, operator, filterValue);
};

Ext.extend(DropdownFilter, Filter, {
	
    init: function(filterName, operator, filterValues) {
        this.filterName = filterName;
        this.filterValues = filterValues;
        this.operator = operator;
		
        this.active = false;
        this.selectedValue = null;
        this.matches = {};
    },
	
    apply: function(rset) {
        var match = false;
        try {

            var fieldValue = rset.getField(this.filterName);
			
            if(typeof(fieldValue) != 'object')
                fieldValue = [fieldValue];
	
            var filterValue = this.selectedValue;
	
            for(var v = 0; v < fieldValue.length; v++) {
                if(this.operator != Operators.EQ && this.operator != Operators.NEQ && this.operator != Operators.LIKE ) {
                    var intVal1 = parseInt(fieldValue[v], 10);
                    var intVal2 = parseInt(filterValue, 10);
                }
				
                switch(this.operator) {
                    case Operators.EQ:
                        match = match || (filterValue == fieldValue[v]);
                        break;
                    case Operators.NEQ:
                        match = match || (filterValue != fieldValue[v]);
                        break;
                    case Operators.LIKE:
                        match = match || (fieldValue[v].toLowerCase().indexOf(filterValue.toLowerCase()) > -1);
                        break;
                    case Operators.GTE:
                        match = match || (intVal1 >= intVal2);
                        break;
                    case Operators.GT:
                        match = match || (intVal1 > intVal2);
                        break;
                    case Operators.LTE:
                        match = match || (intVal1 <= intVal2);
                        break;
                    case Operators.LT:
                        match = match || (intVal1 < intVal2);
                        break;
                }
			
                if(match)
                    return true;
            }
        } catch(e) {}
		
        return match;
    },
	
    evaluateMatch: function(rset) {
        try {

            var fieldValue = rset.getField(this.filterName);
			
            if(typeof(fieldValue) != 'object')
                fieldValue = [fieldValue];
	
            var fltValuesLength = this.filterValues.length;
            var fldValuesLength = fieldValue.length;
	
            for(var i = 0; i < fltValuesLength; i++) {
				
                var match = false;
				
                for(var v = 0; v < fldValuesLength; v++) {
					
                    var filterValue = this.filterValues[i];
					
                    if(this.operator != Operators.EQ && this.operator != Operators.NEQ && this.operator != Operators.LIKE ) {
                        var intVal1 = parseInt(fieldValue[v], 10);
                        var intVal2 = parseInt(filterValue, 10);
                    }
					
                    switch(this.operator) {
                        case Operators.EQ:
                            match = match || (filterValue == fieldValue[v]);
                            break;
                        case Operators.NEQ:
                            match = match || (filterValue != fieldValue[v]);
                            break;
                        case Operators.LIKE:
                            match = match || (fieldValue[v].toLowerCase().indexOf(filterValue.toLowerCase()) > -1);
                            break;
                        case Operators.GTE:
                            match = match || (intVal1 >= intVal2);
                            break;
                        case Operators.GT:
                            match = match || (intVal1 > intVal2);
                            break;
                        case Operators.LTE:
                            match = match || (intVal1 <= intVal2);
                            break;
                        case Operators.LT:
                            match = match || (intVal1 < intVal2);
                            break;
                    }

                }

                if(!this.matches[filterValue])
                    this.matches[filterValue] = 0;
				
                if(match) {
                    this.matches[filterValue]++;
                }
            }
        } catch(e) {}
		
        return match;
    },
    setSelectedValue: function(value) {
        this.selectedValue = value;
    },
    getMatches: function(filterValue) {
        return this.matches[filterValue] ? this.matches[filterValue] : 0;
    },
    hasMatches: function() {
        for(val in this.matches) {
            if(this.matches[val] > 0)
                return true;
        }
        return false;
    },
    resetMatch: function() {
        this.matches = {};
    }
});


/**
 * SubFilter, filtro per tipologia e categoria.
 * Utilizza lo stesso motore non gerarchico per i filtri, il match
 * viene fatto come filterParent AND filterName
 */
var SubFilter = function(filterName, operator, filterValue, fieldSubName, filterSubValues, filterCtrlID) {
    this.init(filterName, operator, filterValue, fieldSubName, filterSubValues, filterCtrlID);
};

Ext.extend(SubFilter, Filter, {

    init: function(filterName, operator, filterValue, fieldSubName, filterSubValues, filterCtrlID) {
        this.filterName = filterName;
        this.fieldSubName = fieldSubName;
        this.filterValue = filterValue;
        this.filterSubValues = filterSubValues;
        this.filterCtrlID = filterCtrlID;
        this.active = false;
        this.selectedValue = null;
        this.selectedSubValue = null;
        this.matches = 0;
        this.subMatches = {};
    },

    apply: function(rset) {
 
        var match = false;
        var match1 = false;
        var match2 = false;
        
        try {

            var fieldValue = rset.getField(this.filterName);
            var fieldSubValue = rset.getField(this.fieldSubName);
            var selectedSubValue = this.selectedSubValue;
            
            if(typeof(fieldValue) != 'object') {
                fieldValue = [fieldValue];
            }

            var filterValue = this.filterValue;

            for(var v = 0; v < fieldValue.length; v++) {
                match1 = match1 || (filterValue == fieldValue[v]);
            }

            if (match1) {

                if (selectedSubValue) {
                    if(typeof(selectedSubValue) != 'object') {
                        selectedSubValue = selectedSubValue.split(','); // Convert CSV into array
                    }
                    if (selectedSubValue.length > 0) {
                        selItemField = this.filterCtrlID + '_' + fieldSubValue;
                        for (var v1=0; v1<selectedSubValue.length; v1++){
                            selItemSubValue = selectedSubValue[v1];
                            if (selItemSubValue == selItemField) {
                                this.subMatches[selItemField] = 1;
                                match2 = true;
                            }
                        }
                    } else {
                        match2 = true; // in this case if zero selected is like all selected...
                    }
                } else {
                    match2 = true;
                }
            }

        } catch(e) {}

        match = match1 && match2;

        return match;
    },
    evaluateMatch: function(rset) {
        if(this.apply(rset)) {
            this.matches++;
            return true;
        }
        return false;
    },
    setSelectedSubValue: function(value) {
        this.selectedSubValue = value;
    },
    getMatches: function() {
        return this.matches;
    },
    getSubMatches: function(filterValue) {
        return this.subMatches[filterValue];
    }
    ,
    hasMatches: function() {
        if(this.matches > 0) {
            return true;
        }
        return false;
    },
    resetMatch: function() {
        this.matches = 0;
        this.subMatches = {};
    }
});



/**
 * Filtro di tipo range, che puņ essere visualizzato come uno slider o come una coppia di valori (min e max)
 */
var RangeFilter = function(filterName, minValue, maxValue) {
    this.init(filterName, minValue, maxValue);
};

Ext.extend(RangeFilter, Filter, {
	
    init: function(filterName, minValue, maxValue) {
        this.filterName = filterName;
        this.minValue = minValue;
        this.maxValue = maxValue;

        this.rsMoveHandles = true;

        this.rsMinValue = Number.NaN;
        this.rsMaxValue = Number.NaN;

        this.iPriceFound = 0;
		
        this.active = true;
        this.matches = 0;
    },
	
    apply: function(rset) {

        var match = false;

        try {

            var fieldValue = rset.getField(this.filterName);

            //Logger.debug('===== RangeSlider: apply: fieldValue='+fieldValue + ', this.minValue='+this.minValue + ', this.maxValue='+this.maxValue);

            if(typeof(fieldValue) != 'object')
                fieldValue = [fieldValue];
	
            for(var v = 0; v < fieldValue.length; v++) {
                var sValue = fieldValue[v];
                var value = NaN;
                if (sValue) {
                    sValue = sValue.replace(",", "");
                    sValue = sValue.replace(".", "");
                    value = parseFloat(sValue, 10); // tolgo eventuale , che e' per le migliaia... solitamente
                }
                

                match = match || (((value >= this.minValue) && (value <= this.maxValue)) || isNaN(value));

                if(match)
                    return true;
            }
        } catch(e) {}
		
        return match;
    },


	
    evaluateMatch: function(rset) {

        var match = this.apply(rset);
		
        if(match)
            this.matches++;
		
        return match;
    },
    setValue: function(values) {
        this.minValue = values.min;
        this.maxValue = values.max;
    },
    getMinValue: function() {
        return this.minValue;
    },
    setMinValue: function(minValue) {
        this.minValue = minValue;
    },
    getMaxValue: function() {
        return this.maxValue;
    },
    setMaxValue: function(maxValue) {
        this.maxValue = maxValue;
    },
    getMinRSValue: function() {
        return this.rsMinValue;
    },
    getMaxRSValue: function() {
        return this.rsMaxValue;
    },
    setMinRSValue: function(value) {
        this.rsMinValue = value;
    },
    setMaxRSValue: function(value) {
        this.rsMaxValue = value;
    },
    getMoveHandles: function() {
        return this.rsMoveHandles;
    },
    setMoveHandles: function(handleValue) {
        this.rsMoveHandles = handleValue;
    },
    hasMatches: function() {
        return this.matches > 0;
    },
    resetMatch: function() {
        this.matches = 0;
    },
    hasPrices: function() {
        return this.iPriceFound > 0;
    },
    setHasPrices: function(value) {
        this.iPriceFound = value;
    },
    hasEQMinMax: function() {
        if (this.rsMaxValue == this.rsMinValue) {
            return true;
        } else {
            return false;
        }
    }
});
