var Path = {
  conditionalTriggers: (new Array()),
  
  requestedSkipOffer: false,
  validSubmission: true,
  
  skipOffer: function() {
    this.requestedSkipOffer = true;
    return true;
  },
  
  _isOriginalEvent: function(e) {
    // if no event - it is not the original
    if (e == undefined) return false
    return (
        (jQuery.browser.msie && (e.returnValue == undefined)) ||
        (jQuery.browser.safari) ||
        (e.cancelable)
        );
  },
  
  _isElementVisible: function(elementId) {
    var key = 'e' + elementId;
    if (this.conditionalTriggers[key] && (Object.size(this.conditionalTriggers[key]) != 0)) {
      return true
    }
    return false;
  },
  
  _setElementTrigger: function(elementId, triggerValue, needToShow) {
    var elementWasVisible = this._isElementVisible(elementId);

    var key = 'e' + elementId;
    if (needToShow) {
        if (!this.conditionalTriggers[key]) this.conditionalTriggers[key] = new Array();
        this.conditionalTriggers[key]['t' + triggerValue] = true;
    } else {
        if (!elementWasVisible) return false;
        delete this.conditionalTriggers[key]['t' + triggerValue];
    }
    return elementWasVisible;
  },
  
  _clearFormValues: function(elementId) {
    var offerEngine = this;
    jQuery('#e' + elementId + '-wrapper').find('input,select').each( function() { offerEngine._clearFormValue(this); } ).change();
  },
  
  _clearFormValue: function(domElement) {
    switch (domElement.nodeName) {
      case 'INPUT' :
      switch (domElement.type) {
        case 'checkbox' :
        case 'radio'    : domElement.checked = false; break;
        case 'password' :
        case 'text'     : domElement.value = ''; break;
      }
      break;
      case 'SELECT' : domElement.selectedIndex = 0; break;
    }
    
  },
  
  _processChange: function(conditionalElementIdsString, needToShow, triggerElementValue) {
    if (conditionalElementIdsString == undefined || conditionalElementIdsString == null || conditionalElementIdsString.length < 1) return;

    var conditionalElementIds = conditionalElementIdsString.split(',');
    
    for (var index=0; index<conditionalElementIds.length; index++) {
      var elemId = conditionalElementIds[index];
      var domId = "e" + elemId;
      
      var elementWasAlreadyVisible = this._setElementTrigger(elemId, triggerElementValue, needToShow);
      var elementIsNowVisible = this._isElementVisible(elemId);

      if (needToShow && elementIsNowVisible) {
        jQuery('#e' + elemId + '-wrapper').slideDown(250);
        jQuery('#e' + elemId + '-is-visible').val(true);
        
      } else if (!needToShow && !elementIsNowVisible) {
        jQuery('#e' + elemId + '-wrapper').slideUp(250);
        jQuery('#e' + elemId + '-is-visible').val(false);
        this._clearErrors('e' + elemId)
        this._clearFormValues(elemId);
      }
    }
  },
  
  handleEvent: function(triggerEvent, triggerElement, triggerElementId, conditionalElementIdsString) {
    if (triggerElement.type == 'checkbox') {
      this._processChange(conditionalElementIdsString, triggerElement.checked, triggerElement.value);
      
    } else if (triggerElement.type == 'radio') {
      if (this._isOriginalEvent(triggerEvent)) {
        triggerEvent.returnValue = true; // needed for IE
        this._processChange(conditionalElementIdsString, triggerElement.checked, triggerElement.value);
        
        // Now loop through all other radio buttons and fire the onchange for them
        jQuery('#e' + triggerElementId + '-options input').not(triggerElement).each(function(){
          this.onchange();
        });
        
      } else {
        this._processChange(conditionalElementIdsString, triggerElement.checked, triggerElement.value);
      }
    }
    return true;
  },
  
  handleSelectChange: function(selectElement) {
    offerEngine = this;
    jQuery(selectElement).find('option').each(function(){ offerEngine._processChange(jQuery(this).attr('conditionalElements'), this.selected, this.value) });
    return true;
  },
  
  addConditionalTrigger: function(elementId, triggerValue) {
    this._setElementTrigger(elementId, triggerValue, true)
  },
  
  
  
  
  
  
  
  elementValidations: (new Array()),
  
  addValidation: function(elementId, valType, valMessage) {
    var key = 'e' + elementId;
    if (Path.elementValidations[key] == undefined) this.elementValidations[key] = new Object();
    
    var valParams = [];
    for( var i = 3; i < arguments.length; i++ ) {
      valParams.push(arguments[i])
    }
    
    Path.elementValidations[key][valType] = {valMessage: valMessage, valParams: valParams};
  },
  
  _isBlankString: function(s) {
    var blankRE = /^[\s]+jQuery/;
    return (s == "" || blankRE.test(s));
  },
  
  _formValueFor: function(elemIdString) {
    var offerEngine = this;
    var curVal = '';
    
    jQuery('#' + elemIdString + '-wrapper').find('input:not(:hidden,:image),select,textarea').each( function() {
      switch (this.nodeName) {
        case 'INPUT' :
        switch (this.type) {
          case 'checkbox' :
          case 'radio'    : if (this.checked) curVal += this.value; break;
          case 'password' :
          case 'text'     : curVal = this.value; break;
        }
        break;
        case 'SELECT' : curVal = jQuery(this).val(); break;
        case 'TEXTAREA' : curVal = jQuery(this).val(); break;
      }
    });
    
    return curVal;
  },



  _clearErrors: function(elemIdString) {
    var posWrapper = jQuery('#' + elemIdString + '-wrapper .positioning-wrapper')
    posWrapper.removeClass('error-wrapper')

    posWrapper.find('p.error').remove()

    posWrapper.find('.field-with-errors').removeClass('field-being-fixed field-with-errors')
  },


  
  validateForm: function() {
    if (this.requestedSkipOffer) return true;
    
    var validSubmission = true;
    
    for (var elemIdString in this.elementValidations) {
      if (elemIdString != 'size') {
        var jqWrapper = jQuery('#' + elemIdString + '-wrapper');
        
        var errorMessages = new Array();
        
        var container = jqWrapper.parents('.offer-container')
        var containerIsVisible = (container.length == 0 || container.is(':visible'))
        if (!containerIsVisible) {continue}

        var isVisible = (jQuery('#' + elemIdString + '-is-visible').val() == 'true');
        if (!isVisible) {continue;};

        var curVal = this._formValueFor(elemIdString);
        var isBlank = this._isBlankString(curVal);
        
        var validations = this.elementValidations[elemIdString]
        var val;

        // Required
        val = validations['RequiredValidation'];
        if (val != undefined && isBlank) {
          errorMessages.push(val.valMessage);
        }
        
        // Date
        val = validations['DateValidation'];
        if (!isBlank && val != undefined) {
          var d = parseDate(curVal);
          if (!d) errorMessages.push(val.valMessage);
        }
        
        // Number
        val = validations['NumberValidation'];
        var numberRe = /^[+-]?[0-9]+$/
        if (!isBlank && val != undefined) {
          if (!numberRe.test(curVal)) errorMessages.push(val.valMessage);
        }

        // MinimumLength
        val = validations['MinimumLengthValidation'];
        var minLengthRe = /^\S{6,}$/
        if (!isBlank && val != undefined) {
          if (!minLengthRe.test(curVal)) errorMessages.push(val.valMessage);
        }
        
        // Regexps
        var revals = ['EmailValidation', 'PhoneValidation', 'ZipValidation', 'RegexpValidation'];
        for (var i=0; i<revals.length; i++) {
          val = validations[revals[i]];
          if (!isBlank && val != undefined) {
            var re = new RegExp(val.valParams[0], val.valParams[1]);
            if (!re.test(curVal)) errorMessages.push(val.valMessage);
          }
        }
        
        var jqPosWrapper = jqWrapper.find('.positioning-wrapper')

        if (errorMessages.length == 0) {
          this._clearErrors(elemIdString)

        } else {
          validSubmission = false

          jqPosWrapper.addClass('error-wrapper')
          var jqErrorMessageContainer = jqPosWrapper.find('p.error')

          if (jqErrorMessageContainer.length == 0) {
            jqPosWrapper.prepend('<p class="error"></p>')
            jqErrorMessageContainer = jqPosWrapper.find('p.error')
          }

          jqErrorMessageContainer.html(errorMessages[0])

          jqWrapper.find('input:not(:hidden,:image),select,textarea')
            .addClass('field-with-errors')
            .removeClass('field-being-fixed')
        }
        
      }
    }


    if (!validSubmission) {
      this.validSubmission = false;
      alert('There were some problems with the submitted information.\n\nPlease look over the form and correct the issues before continuing.')
      return false;
    }

    this.validSubmission = true;
    return true;
  }
}
