<?PHP

  /** Generator for HTML form fields
   * \nosubgrouping
   */
class FormField {

    # ---- PUBLIC INTERFACE --------------------------------------------------

    /** @name Setup/Initialization */
    /*@{*/

    /**
     * Object Constructor.
     * @param Name Internal name for this field, used in the HTML for id=
     * @param IsRequired 
     * @param Label Display label for this field, shown to the user
     * @param ValidFunc A function to check the validity of input to this field
     *  The function should return 0 for valid input
     * @param ValidMsgs An array of error messages, corresponding to the error
     *    codes returned by ValidFunc
     */
    function FormField($Name, $IsRequired, $Label, $ValidFunc, $ValidMsgs)
    {
        # save field info
        $this->MyName = $Name;
        $this->MyIsRequired = $IsRequired;
        $this->MyLabel = $Label;
        $this->MyValidFunc = $ValidFunc;
        $this->MyValidMsgs = $ValidMsgs;

        # attempt to set value if available
        if (isset($_POST[$this->MyName]))
        {
            $this->MyValue = $_POST[$this->MyName];
        }
        elseif (isset($_GET[$this->MyName]))
        {
            $this->MyValue = $_GET[$this->MyName];
        }
    }
    /*@}*/

    /** @name Accessors */
    /*@{*/
    
    /**
     * Get or set Name (internal name for id=)
     * @param NewVal New value for the object's name (OPTIONAL)
     * @return The objects current name
     */ 
    function Name($NewVal = NULL) {  return $this->GetOrSet("MyName", $NewVal);  }

    /** Get/set IsRequired @see Name */
    
    /**
     * Get or set IsRequired
     * @param NewVal (OPTIONAL)
     * @return current value of IsRequired
     */
    function IsRequired($NewVal = NULL) {  return $this->GetOrSet("MyIsRequired", $NewVal);  }
    
    /** Get or set the Label (display name in generated HTML)
     * @param NewVal (OPTIONAL)
     * @return current label
     */
    function Label($NewVal = NULL) {  return $this->GetOrSet("MyLabel", $NewVal);  }

    /**
     * Get or set the field's value
     * @param NewVal (OPTIONAL)
     * @return current form value
     */
    function Value($NewVal = NULL) {  return $this->GetOrSet("MyValue", $NewVal);  }
    
    /**
     * Determine if this field is a password fild
     * @return TRUE for password fields, FALSE otherwise
     */
    function IsPassword() {  return method_exists($this, "PasswordFormField");  }
    
    /*@}*/
    
    /** @name Display */
    /*@{*/
    
    /**
     * Print the label and generate input tags for this object
     * @param DisplayErrorIndicator TRUE to display errors with this
     *    field (OPTIONAL, default=FALSE)
     */
    function PrintField($DisplayErrorIndicator = FALSE)
    {
        $this->PrintLabel($DisplayErrorIndicator);
        $this->PrintInput($DisplayErrorIndicator);
    }

    /**
     * Print the label for this field without generating the input tags
     * @param DisplayErrorIndicator TRUE to display errors with this
     *    field (OPTIONAL, default=FALSE)
     */
    function PrintLabel($DisplayErrorIndicator = FALSE)
    {
        # print label
        print(($DisplayErrorIndicator ? "<span style=\"color: red;\"" : "")
            ."<label for=\"".$this->MyName."\">".$this->MyLabel."</label>"
            .($DisplayErrorIndicator ? "</span>" : "")
            ."\n");
    }
    /*@}*/

    /** @name Error Checking */
    /*@{*/
    
    /**
     * Check the validity of the field's value.
     * @return (int) non-zero for invalid input
     */
    function IsInvalidValue($Value)
    {
        # assume value is valid
        $ErrorCode = 0;

        # if custom validation function supplied
        if ($this->MyValidFunc)
        {
            # call custom function and return code
            $ValidFunc = $this->MyValidFunc;
            $ErrorCode = $ValidFunc($this->MyName, $Value);
        }
        else
        {
            # if value is required and none is set
            if ($this->MyIsRequired && !strlen($Value) 
                    && !method_exists($this, "PasswordFormField"))
            {
                # return code indicating missing value
                $ErrorCode = 1;
            }
        }

        # return error code (if any) to caller
        return $ErrorCode;
    }

    /**
     * Map an error code from IsInvalidValue to an error message.
     * @param ErrorCode the error code assumed to come from IsInvalidValue()
     * @return a text string corresponding to the given error code
     */
    function GetInvalidValueMessage($ErrorCode)
    {
        $Messages = array(
                0 => "This value is valid.",
                1 => "%L is a required value.",
                );
        if (isset($this->MyValidMsgs[$ErrorCode]))
        {
            $Message = $this->MyValidMsgs[$ErrorCode];
        }
        else
        {
            $Message = isset($Messages[$ErrorCode]) 
                    ? $Messages[$ErrorCode] : 
                            "INTERNAL ERROR - Invalid Error Code (Field = %N, Code = %C)";
        }
        return $Message;
    }

    /*@}*/
    
    # ---- PRIVATE INTERFACE -------------------------------------------------

    protected $MyName;
    protected $MyIsRequired;
    protected $MyLabel;
    protected $MyValue;
    protected $MyValidFunc;
    protected $MyValidMsgs;

    # convenience function to handle getting and setting of values
    private function GetOrSet($ValueName, $NewValue)
    {
        if ($NewValue !== NULL)
        {
            $this->{$ValueName} = $NewValue;
        }
        return $this->{$ValueName};
    }
}


?>
