ns('Carib.Order.Validation.Rules');

/**
 * Validation rules
 * 
 * @version $Id: rules.js 865 2010-03-19 17:01:03Z  $
 */

Carib.Order.Validation.Rules.BaseRule = function(config) {
  // configurable {
  this.msg = null; // message to override default one
  // }
  
  if(config)
    $.extend(this, config);
}

Carib.Order.Validation.Rules.BaseRule.prototype = {
  validate: function(source, errors) {
    
  },
  
  _addError: function(errors, field, msg) {
    errors.add(field, this.msg ? this.msg : msg);
  }
}


/**
 * Base rule to validate only one field
 * 
 * @param {Object} config
 */
Carib.Order.Validation.Rules.BaseFieldRule = function(config) {
  // configurable {
  this.name = ''; // required field name
  // }
  this.errors = null;
  this.source = null;
  
  Carib.Order.Validation.Rules.BaseFieldRule.superclass.constructor.call(this, config);  
}

utils.extend(Carib.Order.Validation.Rules.BaseFieldRule, Carib.Order.Validation.Rules.BaseRule, {
  validate: function(source, errors) {
    this.errors = errors;
    this.source = source;

    var value = source.getValue(this.name);
    if(value || value === 0)
      this._validateValue(value);
  },
  
  _validateValue: function(value) {
    
  },
  
  _addFieldError: function(msg) {
    this._addError(this.errors, this.name, msg);
  }
});


/**
 * Required rule
 * 
 * @param {Object} config
 */
Carib.Order.Validation.Rules.Required = function(config) {
  Carib.Order.Validation.Rules.Required.superclass.constructor.call(this, config);
}

utils.extend(Carib.Order.Validation.Rules.Required, Carib.Order.Validation.Rules.BaseFieldRule, {
  validate: function(source, errors) {
    this.errors = errors;
    this.source = source;

    var value = source.getValue(this.name);
    if(value)
      value = $.trim('' + value);
      
    if(!value && value !== 0)
      this._addFieldError('Поле должно быть заполнено');
  }
});


/**
 * Rule to validate if value greater of passed one
 */
Carib.Order.Validation.Rules.Greater = function(config) {
  // configurable {
  this.value = 0; // value for validation
  // }
  
  Carib.Order.Validation.Rules.Greater.superclass.constructor.call(this, config);
}

utils.extend(Carib.Order.Validation.Rules.Greater, Carib.Order.Validation.Rules.BaseFieldRule, {
  _validateValue: function(value) {
    if(value <= this.value) {
      this._addFieldError('Значение должно быть больше ' + this.value);
    } 
  }  
});


/**
 * Rule to validate email for correct
 */
Carib.Order.Validation.Rules.Email = function(config) {
  config = $.extend({
    name: 'email'
  }, config);
  
  Carib.Order.Validation.Rules.Email.superclass.constructor.call(this, config);
}

utils.extend(Carib.Order.Validation.Rules.Email, Carib.Order.Validation.Rules.BaseFieldRule, {
  _validateValue: function(value) {
    var re = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;
    if(!re.test(value)) {
      this._addFieldError('Неверный e-mail');
    } 
  }  
});


/**
 * Rule to validate date interval
 * 
 * @param {Object} config
 */
Carib.Order.Validation.Rules.DatesInterval = function(config) {
  // configurable {
  this.start_date = null; // name of start date
  this.end_date = null; // name of end date
  // }
  
  Carib.Order.Validation.Rules.DatesInterval.superclass.constructor.call(this, config);
}

utils.extend(Carib.Order.Validation.Rules.DatesInterval, Carib.Order.Validation.Rules.BaseRule, {
  validate: function(source, errors) {
    var start_date = source.getValue(this.start_date);
    var end_date = source.getValue(this.end_date);
    
    if(!start_date || !end_date)
      return;
      
    if(start_date.getTime() > end_date.getTime()) {
      this._addError(errors, this.start_date, 'Дата начала больше даты завершения');
    }
  }
});


/**
 * Rule to validate source with callback function
 * @param {Object} config
 */
Carib.Order.Validation.Rules.Callback = function(config) {
  // configurable {
  this.callback = null; // required callback function 
  this.scope = window; // the scope (this reference) in which the callback function is executed.
  // }
  
  Carib.Order.Validation.Rules.Callback.superclass.constructor.call(this, config);
}

utils.extend(Carib.Order.Validation.Rules.Callback, Carib.Order.Validation.Rules.BaseRule, {
  validate: function(source, errors) {
    this.callback.call(this.scope, source, errors);
  }
});

