fcf.module({
  name: "fcf:NFSQL/NFilter/Filter.js",
  dependencies: [],
  module: function() {
    var NFilter = fcf.prepareObject(fcf, "NFSQL.NFilter");

    NFilter._filters = {};


    NFilter.getFilter = function(a_type) {
      if (a_type in NFilter._filters){
        return NFilter._filters[a_type].filter;
      } else {
        return NFilter._defaultFilter;
      }
    }

    NFilter.Filter = class Filter {

      constructor(a_options){
        this._type = a_options && a_options.type ? a_options.type : {type: "text"};
        this.comparisons = { };
        this.enableOrder = true;
      }

      isTranslateField(a_fieldDescription) {
        return !!a_fieldDescription.translate;
      }

      validate(a_description, a_dstErrors) {

      }

      friendly(a_view, a_value){
        return a_value.toString();
      }

      availableComparison(a_operation, a_mode){
        if (this.comparisons[a_mode])
          return fcf.find(this.comparisons[a_mode], a_operation) != undefined;
        else if (this.comparisons["*"])
          return fcf.find(this.comparisons["*"], a_operation) != undefined;
        else 
          return false;
      }

      comparison(a_cmpType, a_left, a_right) {
        switch(a_cmpType) {
          case "=":
            return a_left == a_right;
          case "<":
            return a_left < a_right;
          case ">":
            return a_left > a_right;
          case "<=":
            return a_left <= a_right;
          case ">=":
            return a_left >= a_right;
          case "like":
            var search = fcf.replaceAll(a_right, "%", ".*");
            var re  = new RegExp(search, "gi");
            return fcf.str(a_left).search(re) != -1;
        };
      }

      getRealFields(a_projection, a_fieldAlias){
        let rf = fcf.clone(a_projection.fieldsMap[a_fieldAlias]);
        if (rf.alias == a_projection.key)
          rf.primary = true;
        return [rf];
      }

      equalRealFields(a_left, a_right){
        let res = a_left.field     ==  a_right.field &&
                  a_left.type      ==  a_right.type &&
                  a_left.min       ==  a_right.min &&
                  a_left.max       ==  a_right.max &&
                  a_left.defaultDB ==  a_right.defaultDB;

        if (!a_left.primary && !a_right.primary){
          let leftNotNull  = !!a_left.notEmpty || !!a_left.notNull;
          let rightNotNull = !!a_right.notEmpty || !!a_right.notNull;

          res &= leftNotNull == rightNotNull;
          res &= !!a_left.unique    ==  !!a_right.unique;
        }

        if (a_left.primary && a_right.primary && (!!a_left.autoIncrement != !!a_right.autoIncrement))
          res = false;

        return !!res;
      }

      getDependences(a_projection, a_fieldAliasOrType){
        return [];
      }

      checkStructure(a_projection, a_field){

      }

      validate(a_description, a_dstErrors) {
      }

      processOutputField(a_taskInfo, a_info){
      }

      postProcessOutputField(a_taskInfo, a_info){
      }

      processWhereField(a_taskInfo, a_info){
      }

      processUpdateField(a_taskInfo, a_info){
      }

      processInsertField(a_taskInfo, a_info){
      }

      processDeleteField(a_taskInfo, a_info){
      }

    }

    NFilter._defaultFilter = new NFilter.Filter();

    return NFilter.Filter;
  }
});
