<?PHP

/**
* Display a resource field value for editing.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param CWUser $User The user to use as context. The current user will be used
*       if this value isn't given.
* @param string $Context The context in which the field will be printed. This
*       can be "EDIT" or "AUTHOR".
*/
function PrintResourceFieldValueForEditing(
    Resource $Resource,
    MetadataField $Field,
    CWUser $User=NULL,
    $Context="EDIT")
{
    # use the current user for context if one wasn't specified
    if (is_null($User))
    {
        $User = $GLOBALS["G_User"];
    }

    # print nothing if the user isn't allowed to view the field
    if ($Context == "EDIT" && !$Resource->UserCanViewField($User, $Field))
    {
        return;
    }

    # make sure the necessary JavaScript files get included
    $GLOBALS["AF"]->RequireUIFile("jquery-ui.js");
    $GLOBALS["AF"]->RequireUIFile("CW-Keyboard.js");
    $GLOBALS["AF"]->RequireUIFile("CW-QuickSearch.js");
    # CKEditor setup
    require_once($GLOBALS["AF"]->GUIFile("CKEditorSetup.php"));

    # check privileges based on context
    $CanEdit = $Resource->UserCanModifyField($User, $Field);

    # just print the value instead of a form element if the user is not allowed
    # to edit the field
    if (!$CanEdit || !$Field->Editable())
    {
        PrintResourceFieldValue($Resource, $Field);
        return;
    }

    # get the value unmodified by any plugins
    $RawValue = $Resource->Get($Field, TRUE);

    # allow plugins to modify the value
    $SignalResult = $GLOBALS["AF"]->SignalEvent(
        "EVENT_PRE_FIELD_EDIT_FILTER", array(
            "Field" => $Field,
            "Resource" => $Resource,
            "Value" => $RawValue));
    $Value = $SignalResult["Value"];

    # display each field type differently
    switch ($Field->Type())
    {
        case MetadataSchema::MDFTYPE_TEXT:
        case MetadataSchema::MDFTYPE_NUMBER:
        case MetadataSchema::MDFTYPE_URL:
            DisplayResourceFieldValueWithTextInput($Resource, $Field, $Value);
            break;

        case MetadataSchema::MDFTYPE_PARAGRAPH:
            DisplayResourceFieldValueWithTextarea($Resource, $Field, $Value);
            break;

        case MetadataSchema::MDFTYPE_DATE:
            DisplayResourceFieldValueWithTextInput(
                $Resource,
                $Field,
                $Value->Formatted());
            break;

        case MetadataSchema::MDFTYPE_TIMESTAMP:
            DisplayTimestampResourceFieldValueForEditing(
                $Resource,
                $Field,
                $Value);
            break;

        case MetadataSchema::MDFTYPE_FLAG:
            DisplayResourceFieldValueWithRadioOption(
                $Resource, $Field, 1, $Field->FlagOnLabel(), $Value);
            DisplayResourceFieldValueWithRadioOption(
                $Resource, $Field, 0, $Field->FlagOffLabel(), !$Value);
            break;

        case MetadataSchema::MDFTYPE_TREE:
        case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
            $ValueCount = $Field->GetCountOfPossibleValues();
            $OptionListThreshold = $Field->OptionListThreshold();
            $AjaxThreshold = $Field->AjaxThreshold();

            # display the options using checkboxes if below the threshold
            if ($ValueCount < $OptionListThreshold)
            {
                DisplayResourceFieldValueTermsWithCheckboxOptions(
                    $Resource,
                    $Field,
                    $Value);
            }

            # above the option threshold but below the AJAX threshold
            else if ($ValueCount < $AjaxThreshold)
            {
                DisplayResourceFieldValueTermsWithSelectBoxes(
                    $Resource,
                    $Field,
                    $Value);
            }

            # use AJAX search because it's above all of the thresholds
            else
            {
                DisplayResourceFieldValueTermsWithSearch(
                    $Resource,
                        $Field,
                        $Value);
            }
            break;

        case MetadataSchema::MDFTYPE_OPTION:
            # show checkboxes if multiple values are allowed
            if ($Field->AllowMultiple())
            {
                DisplayResourceFieldValueTermsWithCheckboxOptions(
                    $Resource,
                    $Field,
                    $Value);
            }

            # show radio buttons otherwise
            else
            {
                DisplayResourceFieldValueTermsWithRadioOptions(
                    $Resource,
                    $Field,
                    $Value);
            }
            break;

        case MetadataSchema::MDFTYPE_USER:
            $ValueCount = $Field->GetCountOfPossibleValues();
            $InterfaceToggleThreshold = 45;

            # use search if above the threshold
            if ($ValueCount > $InterfaceToggleThreshold)
            {
                DisplayResourceFieldValueWithSearch(
                    $Resource,
                    $Field,
                    $User->Id(),
                    $User->Get("UserName"));
            }

            # use select boxes otherwise
            else
            {
                DisplayResourceFieldValueWithSelectBox(
                    $Resource,
                    $Field,
                    $User->Id());
            }
            break;

        case MetadataSchema::MDFTYPE_POINT:
            DisplayPointResourceFieldValueForEditing($Resource, $Field, $Value);
            break;

        case MetadataSchema::MDFTYPE_REFERENCE:
            DisplayResourceFieldValueTermsWithSearch($Resource, $Field, $Value);
            break;

        case MetadataSchema::MDFTYPE_IMAGE:
            DisplayImageFieldValueForEditing($Resource, $Field, $Value);
            break;

        case MetadataSchema::MDFTYPE_FILE:
            DisplayFileFieldValueForEditing($Resource, $Field, $Value);
            break;
    }

    # get extra HTML to display if any print it
    $Context = $GLOBALS["AF"]->GetPageName() == "EditResourceComplete"
        ? "EDIT_COMPLETE_DISPLAY" : "EDIT";
    $SignalResult = $GLOBALS["AF"]->SignalEvent(
        "EVENT_APPEND_HTML_TO_FIELD_DISPLAY",
        array(
            "Field" => $Field, "Resource" => $Resource,
            "Context" => $Context, "Html" => NULL));
    print $SignalResult["Html"];
}

/**
* Display a field value using a text input form element.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param string $Value The resource field value.
*/
function DisplayResourceFieldValueWithTextInput(
    Resource $Resource,
    MetadataField $Field,
    $Value)
{
    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName());
    $SafeMaxLength = defaulthtmlentities($Field->MaxLength());
    $SafeTextFieldSize = defaulthtmlentities($Field->TextFieldSize());
    $SafeValue = defaulthtmlentities($Value);
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-value cw-field-text_input cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         type="text"
         name="<?PHP print $SafeFormFieldName; ?>"
         size="<?PHP print $SafeTextFieldSize; ?>"
         maxlength="<?PHP print $SafeMaxLength; ?>"
         value="<?PHP print $SafeValue; ?>" />
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a field value using a textarea form element.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param string $Value The resource field value.
*/
function DisplayResourceFieldValueWithTextarea(
    Resource $Resource,
    MetadataField $Field,
    $Value)
{
    # determine if the WYSIWYG editor should be used
    $UsesWysiwygEditor = $Field->UseWysiwygEditor();

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName());
    $SafeParagraphRows = defaulthtmlentities($Field->ParagraphRows());
    $SafeParagraphCols = defaulthtmlentities($Field->ParagraphCols());
    $SafeValue = defaulthtmlentities($Value);
    // @codingStandardsIgnoreStart
?>
  <textarea class="cw-field cw-field-value cw-field-textarea cw-field-type-<?PHP print $SafeTypeForClass; ?> <?PHP if ($UsesWysiwygEditor) print "ckeditor"; ?>"
            data-schema_id="<?PHP print $SafeSchemaId; ?>"
            data-resource_id="<?PHP print $SafeResourceId; ?>"
            data-field_id="<?PHP print $SafeFieldId; ?>"
            name="<?PHP print $SafeFormFieldName; ?>"
            rows="<?PHP print $SafeParagraphRows; ?>"
            cols="<?PHP print $SafeParagraphCols; ?>"
            ><?PHP print $SafeValue; ?></textarea>
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a timestamp field value for editing.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param string $Value The resource field value.
*/
function DisplayTimestampResourceFieldValueForEditing(
    Resource $Resource,
    MetadataField $Field,
    $Value)
{
    # display the value in a text input
    DisplayResourceFieldValueWithTextInput($Resource, $Field, $Value);

    # return if an update button doesn't need to be displayed
    if ($Field->UpdateMethod() != MetadataField::UPDATEMETHOD_BUTTON)
    {
        return;
    }

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName());
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-button cw-field-update_method cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         type="button"
         value="Update"
         onclick='jQuery("[name=\"<?PHP print $SafeFormFieldName; ?>\"]").val(jQuery.date("Y-m-d H:i:s"));' />
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a single field value for editing with a radio button.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param string $Value The resource field value.
* @param string $Label The text for the label of the radio button.
* @param bool $Selected Whether or not the radio button is selected.
*/
function DisplayResourceFieldValueWithRadioOption(
    Resource $Resource,
    MetadataField $Field,
    $Value,
    $Label,
    $Selected)
{
    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName());
    $SafeFormFieldId = defaulthtmlentities("F_".$Field->DBFieldName().uniqid());
    $SafeValue = defaulthtmlentities($Value);
    $SafeLabel = defaulthtmlentities($Label);
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-value cw-field-radio cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         type="radio"
         id="<?PHP print $SafeFormFieldId; ?>"
         name="<?PHP print $SafeFormFieldName; ?>"
         value="<?PHP print $SafeValue; ?>"
         <?PHP if ($Selected) print "checked"; ?> />
  <label class="cw-field cw-field-label cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         for="<?PHP print $SafeFormFieldId; ?>"
         ><?PHP print $SafeLabel; ?></label>
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a single field value for editing with a checkbox.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param string $Value The resource field value.
* @param string $Label The text for the label of the checkbox.
* @param bool $Selected Whether or not the checkbox is selected.
*/
function DisplayResourceFieldValueWithCheckboxOption(
    Resource $Resource,
    MetadataField $Field,
    $Value,
    $Label,
    $Selected)
{
    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName()."[]");
    $SafeFormFieldId = defaulthtmlentities("F_".$Field->DBFieldName().uniqid());
    $SafeValue = defaulthtmlentities($Value);
    $SafeLabel = defaulthtmlentities($Label);
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-value cw-field-radio cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         type="checkbox"
         id="<?PHP print $SafeFormFieldId; ?>"
         name="<?PHP print $SafeFormFieldName; ?>"
         value="<?PHP print $SafeValue; ?>"
         <?PHP if ($Selected) print "checked"; ?> />
  <label class="cw-field cw-field-label cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         for="<?PHP print $SafeFormFieldId; ?>"
         ><?PHP print $SafeLabel; ?></label>
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a single field value for editing with a select box.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param string $Value The resource field value.
*/
function DisplayResourceFieldValueWithSelectBox(
    Resource $Resource,
    MetadataField $Field,
    $Value)
{
    # get all possible values and sort them alphabetically
    $PossibleValues = $Field->GetPossibleValues();
    asort($PossibleValues);

    # add an option to select nothing
    $PossibleValues = array(-1 => "--") + $PossibleValues;

    # determine if multiple values are allowed
    $MultipleValuesAllowed = $Field->Type() !== MetadataSchema::MDFTYPE_USER
        && $Field->AllowMultiple();

    $FormFieldName = "F_".$Field->DBFieldName();

    # slightly modify the field name if multiple values are allowed
    if ($MultipleValuesAllowed)
    {
        $FormFieldName .= "[]";
    }

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities($FormFieldName);
    $SafeValue = defaulthtmlentities($Value);
    // @codingStandardsIgnoreStart
?>
  <select class="cw-field cw-field-value cw-field-select cw-field-type-<?PHP print $SafeTypeForClass; ?>"
          data-schema_id="<?PHP print $SafeSchemaId; ?>"
          data-resource_id="<?PHP print $SafeResourceId; ?>"
          data-field_id="<?PHP print $SafeFieldId; ?>"
          name="<?PHP print $SafeFormFieldName; ?>">
    <?PHP foreach ($PossibleValues as $PossibleValue => $Label) {
              $SafePossibleValue = defaulthtmlentities($PossibleValue);
              $SafeLabel = defaulthtmlentities($Label); ?>
      <option value="<?PHP print $SafePossibleValue; ?>"
              <?PHP if ($PossibleValue == $Value) print "selected"; ?>
              ><?PHP print $SafeLabel; ?></option>
    <?PHP } ?>
  </select>
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a single field value for editing with an AJAX-enhanced search box.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param mixed $Value The resource field value, often an ID.
* @param string $Label The label for the resource field value.
*/
function DisplayResourceFieldValueWithSearch(
    Resource $Resource,
    MetadataField $Field,
   $Value,
   $Label)
{
    # determine if multiple values are allowed
    $MultipleValuesAllowed = $Field->Type() !== MetadataSchema::MDFTYPE_USER
        && $Field->AllowMultiple();

    $FormFieldName = "F_".$Field->DBFieldName();

    # slightly modify the field name if multiple values are allowed
    if ($MultipleValuesAllowed)
    {
        $FormFieldName .= "[]";
    }

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities($FormFieldName);
    $SafeMaxNumSearchResults = defaulthtmlentities($Field->NumAjaxResults());
    $SafeValue = defaulthtmlentities($Value);
    $SafeLabel = defaulthtmlentities($Label);
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-value cw-field-hidden cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         type="hidden"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         data-fieldid="<?PHP print $SafeFieldId; ?>"
         name="<?PHP print $SafeFormFieldName; ?>"
         value="<?PHP print $SafeValue; ?>" />
  <textarea class="cw-field cw-field-proxy cw-field-textarea cw-field-type-<?PHP print $SafeTypeForClass; ?> cw-resourceeditor-metadatafield"
            data-schema_id="<?PHP print $SafeSchemaId; ?>"
            data-resource_id="<?PHP print $SafeResourceId; ?>"
            data-field_id="<?PHP print $SafeFieldId; ?>"
            data-fieldid="<?PHP print $SafeFieldId; ?>"
            data-maxnumsearchresults="<?PHP print $SafeMaxNumSearchResults; ?>"
            ><?PHP print $SafeLabel; ?></textarea>
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a field value where multiple values are possible and checkboxes
* should be displayed.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The selected values for the field.
*/
function DisplayResourceFieldValueTermsWithCheckboxOptions(
    Resource $Resource,
    MetadataField $Field,
    array $Values)
{
    DisplayResourceFieldValueWithOptions($Resource, $Field, $Values, "Checkbox");
}

/**
* Display a field value where multiple values are possible and radio buttons
* should be displayed.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The selected values for the field.
*/
function DisplayResourceFieldValueTermsWithRadioOptions(
    Resource $Resource,
    MetadataField $Field,
    array $Values)
{
    DisplayResourceFieldValueWithOptions($Resource, $Field, $Values, "Radio");
}

/**
* Display a field value where multiple values are possible and checkboxes or
* radio buttons should be displayed.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The selected values for the field.
* @param string $Type Either "Radio" or "Checkbox" to determine the field type.
*/
function DisplayResourceFieldValueWithOptions(
    Resource $Resource,
    MetadataField $Field,
    array $Values,
    $Type)
{
    # sort the values alphabetically
    asort($Values);

    # get all possible values and sort them alphabetically
    $PossibleValues = $Field->GetPossibleValues();
    asort($PossibleValues);

    $MaxValueLength = 0;

    # determine the length of the longest value in order to determine how many
    # options will be displayed per row
    foreach ($PossibleValues as $PossibleValue)
    {
        $Length = strlen($PossibleValue);

        if ($Length > $MaxValueLength)
        {
            $MaxValueLength = $Length;
        }
    }

    # determine how many values per row based on length of longest value
    if ($MaxValueLength > 25) {  $OptionsPerRow = 2;  }
    else if ($MaxValueLength > 17) {  $OptionsPerRow = 3;  }
    else if ($MaxValueLength > 12) {  $OptionsPerRow = 4;  }
    else {  $OptionsPerRow = 5;  }

    # determine how many rows there should be
    $NumberOfRows = ceil(
            (count($PossibleValues) + ($OptionsPerRow - 1)) / $OptionsPerRow);

    # reset the array pointer so that the array can be iterated over using the
    # array functions
    reset($PossibleValues);

    $Callback = $Type == "Radio"
        ? "DisplayResourceFieldValueWithRadioOption"
        : "DisplayResourceFieldValueWithCheckboxOption";

    print "<div class=\"cw-table cw-table-fauxtable\">";

    for ($i = 0; $i < $NumberOfRows; $i++)
    {
        print "<div class=\"cw-table-fauxrow\">";

        for ($j = 0; $j < $OptionsPerRow; $j++)
        {
            # reached the end of results before reacing the end of a column
            # also sets $Value
            if (($Value = current($PossibleValues)) === FALSE)
            {
                break 2;
            }

            $ValueId = key($PossibleValues);

            ?><div class="cw-table-fauxcell"><?PHP

                $Callback(
                    $Resource,
                    $Field,
                    $ValueId,
                    $Value,
                    isset($Values[$ValueId]));

            print "</div>";

            next($PossibleValues);
        }

        print "</div>";
    }

    print "</div>";
}

/**
* Display a resource field value terms using select boxes.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The selected values for the field.
*/
function DisplayResourceFieldValueTermsWithSelectBoxes(
    Resource $Resource,
    MetadataField $Field,
    array $Values)
{
    # sort the values alphabetically
    asort($Values);

    # print each set value
    foreach ($Values as $ValueId => $Value)
    {
        DisplayResourceFieldValueWithSelectBox($Resource, $Field, $ValueId);
    }

    # print an extra select box with nothing selected
    DisplayResourceFieldValueWithSelectBox($Resource, $Field, -1);

    $FormFieldName = "F_".$Field->DBFieldName()."[]";
?>
  <script type="text/javascript">
    (function(){
      var selectBoxes = jQuery("select[name='<?PHP print $FormFieldName; ?>']");
          lastSelectBox = selectBoxes.last();

      // add the event handler to add a new select box to the last select box
      lastSelectBox.change(addSelectBox);

      function addSelectBox() {
        var selectBox = jQuery(this),
            clone = selectBox.clone();

        // unselect anything selected
        jQuery("option:selected", clone).removeAttr("selected");

        // add the clone at the end
        selectBox.after(clone);

        // add the change handler to the clone
        clone.bind("change", addSelectBox);

        // remove the change handler from the current select box
        selectBox.unbind("change", addSelectBox);
      }
    }());
  </script>
<?PHP
}

/**
* Display a resource field value terms using AJAX-enhanced search.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The selected values for the field.
*/
function DisplayResourceFieldValueTermsWithSearch(
    Resource $Resource,
    MetadataField $Field,
    array $Values)
{
    # sort the values by key
    ksort($Values);

    # print each set value
    foreach ($Values as $ValueId => $Value)
    {
        DisplayResourceFieldValueWithSearch($Resource, $Field, $ValueId, $Value);
    }

    $MultipleValuesField = $Field->Type() !== MetadataSchema::MDFTYPE_REFERENCE;

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName()."[]");
    $SafeMaxNumSearchResults = defaulthtmlentities($Field->NumAjaxResults());
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-value cw-field-hidden cw-field-type-<?PHP print $SafeTypeForClass; ?> cw-field-empty"
         type="hidden"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         data-fieldid="<?PHP print $SafeFieldId; ?>"
         name="<?PHP print $SafeFormFieldName; ?>"
         value="" />
  <textarea class="cw-field cw-field-proxy cw-field-textarea cw-field-type-<?PHP print $SafeTypeForClass; ?> cw-field-empty cw-resourceeditor-metadatafield cw-resourceeditor-referencefield"
            data-schema_id="<?PHP print $SafeSchemaId; ?>"
            data-resource_id="<?PHP print $SafeResourceId; ?>"
            data-field_id="<?PHP print $SafeFieldId; ?>"
            data-fieldid="<?PHP print $SafeFieldId; ?>"
            data-maxnumsearchresults="<?PHP print $SafeMaxNumSearchResults; ?>"
            ></textarea>
  <?PHP if ($MultipleValuesField) { ?>
  <script type="text/javascript">
    jQuery(document).ready(function(){
      var QuickSearch = cw.require("CW-QuickSearch"),
          multipleValuesFieldQuickSearch = new QuickSearch.MultipleValuesFieldQuickSearch(),
          multipleValuesFields = jQuery("[data-fieldid='<?PHP print addslashes($Field->Id()); ?>']");

        multipleValuesFieldQuickSearch.addTriggerElements(multipleValuesFields);
    });
  </script>
  <?PHP } ?>
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a point metadata field value for editing.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Value The current value for the resource field.
*/
function DisplayPointResourceFieldValueForEditing(
    Resource $Resource,
    MetadataField $Field,
    $Value)
{
    # extract the X and Y values
    $X = isset($Value["X"])? $Value["X"] : "";
    $Y = isset($Value["Y"])? $Value["Y"] : "";

    # determine if the values are empty
    $IsXEmpty = !strlen($X);
    $IsYEmpty = !strlen($Y);

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeXFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName()."X");
    $SafeYFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName()."Y");
    $SafeXValue = defaulthtmlentities($X);
    $SafeYValue = defaulthtmlentities($Y);
    $SafeTextFieldSize = defaulthtmlentities($Field->TextFieldSize());
    // @codingStandardsIgnoreStart
?>
  <input class="cw-field cw-field-value cw-field-text_input cw-field-type-<?PHP print $SafeTypeForClass; ?> <?PHP if ($IsXEmpty) print "cw-field-empty"; ?>"
         type="text"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         name="<?PHP print $SafeXFormFieldName; ?>"
         size="<?PHP print $SafeTextFieldSize; ?>"
         value="<?PHP print $SafeXValue; ?>" />
  <input class="cw-field cw-field-value cw-field-text_input cw-field-type-<?PHP print $SafeTypeForClass; ?> <?PHP if ($IsYEmpty) print "cw-field-empty"; ?>"
         type="text"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         name="<?PHP print $SafeYFormFieldName; ?>"
         size="<?PHP print $SafeTextFieldSize; ?>"
         value="<?PHP print $SafeYValue; ?>" />
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display an image metadata field value for editing.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The current images for the resource field.
*/
function DisplayImageFieldValueForEditing(
    Resource $Resource,
    MetadataField $Field,
    array $Values)
{
    $IsEmpty = count($Values) < 1;

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName());
    $SafeDeletionFormFieldName = defaulthtmlentities(
            "F_".$Field->DBFieldName()."_Delete[]");
    // @codingStandardsIgnoreStart
?>
  <ul class="cw-field cw-field-container cw-field-list cw-field-type-<?PHP print $SafeTypeForClass; ?> <?PHP if ($IsEmpty) print "cw-field-empty"; ?>"
      data-schema_id="<?PHP print $SafeSchemaId; ?>"
      data-resource_id="<?PHP print $SafeResourceId; ?>"
      data-field_id="<?PHP print $SafeFieldId; ?>">
    <?PHP foreach ($Values as $Value) {
              $SafeImageId = defaulthtmlentities($Value->Id());
              $SafeFormId = defaulthtmlentities("F_".$Field->DBFieldName()."_Delete_".uniqid()); ?>
      <li>
        <?PHP DisplayImageResourceFieldValue($Resource, $Field, $Value); ?>
        <input class="cw-field cw-field-delete cw-field-type-<?PHP print $SafeTypeForClass; ?>"
               type="checkbox"
               name="<?PHP print $SafeDeletionFormFieldName; ?>"
               id="<?PHP print $SafeFormId; ?>"
               value="<?PHP print $SafeImageId; ?>" />
        <label for="<?PHP print $SafeFormId; ?>">Delete</label>
      </li>
    <?PHP } ?>
  </ul>
  <input class="cw-field cw-field-value cw-field-file_input cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         type="file"
         name="<?PHP print $SafeFormFieldName; ?>"
         accept="image/*" />
<?PHP
    // @codingStandardsIgnoreEnd
}

/**
* Display a file metadata field value for editing.
* @param Resource $Resource Resource for which to print a field value for
*       editing.
* @param MetadataField $Field Metadata field for which to print the value for
*       editing.
* @param array $Values The current files for the resource field.
*/
function DisplayFileFieldValueForEditing(
    Resource $Resource,
    MetadataField $Field,
    array $Values)
{
    $IsEmpty = count($Values) < 1;

    # escape values that will be printed
    $SafeTypeForClass = defaulthtmlentities(strtolower($Field->TypeAsName()));
    $SafeSchemaId = defaulthtmlentities($Resource->SchemaId());
    $SafeResourceId = defaulthtmlentities($Resource->Id());
    $SafeFieldId = defaulthtmlentities($Field->Id());
    $SafeFormFieldName = defaulthtmlentities("F_".$Field->DBFieldName());
    $SafeDeletionFormFieldName = defaulthtmlentities(
            "F_".$Field->DBFieldName()."_Delete[]");
    // @codingStandardsIgnoreStart
?>
  <ul class="cw-field cw-field-container cw-field-list cw-field-type-<?PHP print $SafeTypeForClass; ?> <?PHP if ($IsEmpty) print "cw-field-empty"; ?>"
      data-schema_id="<?PHP print $SafeSchemaId; ?>"
      data-resource_id="<?PHP print $SafeResourceId; ?>"
      data-field_id="<?PHP print $SafeFieldId; ?>">
    <?PHP foreach ($Values as $Value) {
              $SafeImageId = defaulthtmlentities($Value->Id());
              $SafeFormId = defaulthtmlentities("F_".$Field->DBFieldName()."_Delete_".uniqid()); ?>
      <li>
        <?PHP DisplayFileResourceFieldValue($Resource, $Field, $Value); ?>
        <input class="cw-field cw-field-delete cw-field-type-<?PHP print $SafeTypeForClass; ?>"
               type="checkbox"
               name="<?PHP print $SafeDeletionFormFieldName; ?>"
               id="<?PHP print $SafeFormId; ?>"
               value="<?PHP print $SafeImageId; ?>" />
        <label for="<?PHP print $SafeFormId; ?>">Delete</label>
      </li>
    <?PHP } ?>
  </ul>
  <input class="cw-field cw-field-value cw-field-file_input cw-field-type-<?PHP print $SafeTypeForClass; ?>"
         data-schema_id="<?PHP print $SafeSchemaId; ?>"
         data-resource_id="<?PHP print $SafeResourceId; ?>"
         data-field_id="<?PHP print $SafeFieldId; ?>"
         type="file"
         name="<?PHP print $SafeFormFieldName; ?>" />
<?PHP
    // @codingStandardsIgnoreEnd
}
