/**
  * The most important function of ValidForm Builder library.
  *
  * This function handles all the server-side field validation logic.
  * @internal
  * @param integer $intDynamicPosition Using the intDynamicPosition parameter, you can validate a specific dynamic
  * field, if necessary.
  * @return boolean True if the current field validates, false if not.
  */
 public function validate($intDynamicPosition = 0)
 {
     // Reset the internal errors array
     $this->__errors = array();
     // *** Get the value to validate from either the global request variable or the cached __validvalues array.
     $value = $this->getValue($intDynamicPosition);
     // *** Get required an visible states from condition and overwrite values for validation purposes
     $objCondition = $this->__field->getConditionRecursive("required");
     if (is_object($objCondition)) {
         if ($objCondition->isMet($intDynamicPosition)) {
             $this->__required = $objCondition->getValue();
         } else {
             $this->__required = !$objCondition->getValue();
         }
     }
     $objCondition = $this->__field->getConditionRecursive("enabled");
     if (is_object($objCondition)) {
         if ($objCondition->isMet($intDynamicPosition)) {
             $this->__required = $objCondition->getValue() ? $this->__required : false;
         } else {
             $this->__required = $objCondition->getValue() ? false : $this->__required;
         }
     }
     $objCondition = $this->__field->getConditionRecursive("visible");
     if (is_object($objCondition)) {
         if ($objCondition->isMet($intDynamicPosition)) {
             $this->__required = $objCondition->getValue() ? $this->__required : false;
         } else {
             $this->__required = $objCondition->getValue() ? false : $this->__required;
         }
     }
     // Check if parent element is an area.
     // If so, check if it's an active area that is selected
     $objParent = $this->__field->getMeta("parent", null);
     if (!is_null($objParent) && get_class($objParent) === "ValidFormBuilder\\Area") {
         if ($objParent->isActive() && !$objParent->getValue($intDynamicPosition)) {
             $this->__required = false;
         }
     }
     // *** Check "required" option.
     if (is_array($value)) {
         $blnEmpty = true;
         $intCount = 0;
         foreach ($value as $valueItem) {
             if (strlen($valueItem) > 0) {
                 $blnEmpty = false;
                 break;
             }
             $intCount++;
         }
         if ($blnEmpty) {
             if ($this->__required) {
                 unset($this->__validvalues[$intDynamicPosition]);
                 $this->__errors[$intDynamicPosition] = $this->__requirederror;
             } else {
                 $this->__validvalues[$intDynamicPosition] = "";
                 return true;
             }
         }
     } elseif (strlen($value) == 0) {
         if ($this->__required && $intDynamicPosition == 0) {
             // *** Only the first dynamic field has a required check. We asume by design that "real" dynamic fields are not required.
             unset($this->__validvalues[$intDynamicPosition]);
             $this->__errors[$intDynamicPosition] = $this->__requirederror;
         } else {
             unset($this->__validvalues[$intDynamicPosition]);
             if (empty($this->__matchwith)) {
                 return true;
             }
         }
     }
     // *** Check if value is_null and not required. No other checks needed.
     if (!$this->__required && is_null($value)) {
         return true;
     }
     // *** Check if value is hint value.
     if (!$this->__hasError($intDynamicPosition)) {
         $strHint = $this->__field->getHint();
         if (!empty($strHint) && !is_array($value)) {
             if ($strHint == $value) {
                 if ($this->__required) {
                     // *** If required then it's an error.
                     unset($this->__validvalues[$intDynamicPosition]);
                     $this->__errors[$intDynamicPosition] = $this->__hinterror;
                 } else {
                     // *** If optional then empty value and return true.
                     unset($this->__validvalues[$intDynamicPosition]);
                     return true;
                 }
             }
         }
     }
     // *** Check minimum input length.
     if (!$this->__hasError($intDynamicPosition)) {
         if ($this->__minlength > 0 && is_array($value)) {
             if (count($value) < $this->__minlength) {
                 unset($this->__validvalues[$intDynamicPosition]);
                 $this->__errors[$intDynamicPosition] = sprintf($this->__minlengtherror, $this->__minlength);
             }
         } elseif ($this->__minlength > 0 && strlen($value) < $this->__minlength) {
             unset($this->__validvalues[$intDynamicPosition]);
             $this->__errors[$intDynamicPosition] = sprintf($this->__minlengtherror, $this->__minlength);
         }
     }
     // *** Check maximum input length.
     if (!$this->__hasError($intDynamicPosition)) {
         if ($this->__maxlength > 0 && is_array($value)) {
             if (count($value) > $this->__maxlength) {
                 unset($this->__validvalues[$intDynamicPosition]);
                 $this->__errors[$intDynamicPosition] = sprintf($this->__maxlengtherror, $this->__maxlength);
             }
         } elseif ($this->__maxlength > 0 && strlen($value) > $this->__maxlength) {
             unset($this->__validvalues[$intDynamicPosition]);
             $this->__errors[$intDynamicPosition] = sprintf($this->__maxlengtherror, $this->__maxlength);
         }
     }
     // *** Check matching values.
     if (!$this->__hasError($intDynamicPosition)) {
         if (!empty($this->__matchwith)) {
             $matchValue = $this->__matchwith->getValue();
             if (empty($matchValue)) {
                 $matchValue = null;
             }
             if (empty($value)) {
                 $value = null;
             }
             if ($matchValue !== $value) {
                 unset($this->__validvalues[$intDynamicPosition]);
                 $this->__errors[$intDynamicPosition] = $this->__matchwitherror;
             } elseif (is_null($value)) {
                 return true;
             }
         }
     }
     // *** Check specific types.
     if (!$this->__hasError($intDynamicPosition)) {
         switch ($this->__field->getType()) {
             case ValidForm::VFORM_CUSTOM:
             case ValidForm::VFORM_CUSTOM_TEXT:
                 $blnValidType = Validator::validate($this->__validation, $value);
                 break;
             default:
                 $blnValidType = Validator::validate($this->__field->getType(), $value);
         }
         if (!$blnValidType) {
             unset($this->__validvalues[$intDynamicPosition]);
             $this->__errors[$intDynamicPosition] = $this->__typeerror;
         } else {
             if (is_array($value) && is_array($value[0])) {
                 //*** Set the value directly when the value is a nested array.
                 $this->__validvalues = $value;
             } else {
                 $this->__validvalues[$intDynamicPosition] = $value;
             }
         }
     }
     // *** Override error.
     if (isset($this->__overrideerrors[$intDynamicPosition]) && !empty($this->__overrideerrors[$intDynamicPosition])) {
         unset($this->__validvalues[$intDynamicPosition]);
         $this->__errors[$intDynamicPosition] = $this->__overrideerrors[$intDynamicPosition];
     }
     return !isset($this->__validvalues[$intDynamicPosition]) ? false : true;
 }
 /**
  * Check if an element should be visible according to an optionally attached "visible" condition.
  *
  * @param Base $objElement
  * @param $intDynamicCount
  * @return bool|true
  */
 protected function elementShouldDisplay(Base $objElement, $intDynamicCount = 0)
 {
     $blnReturn = true;
     $objCondition = $objElement->getConditionRecursive("visible");
     if (is_object($objCondition)) {
         if ($objCondition->isMet($intDynamicCount)) {
             $blnReturn = $objCondition->getValue();
         } else {
             $blnReturn = !$objCondition->getValue();
         }
     }
     return $blnReturn;
 }