<%args>
$name
$label              => undef
$tooltip            => undef
$item_labels        => {}
$render_as          => 'normal'
$default            => undef
$cols               => undef
$rows               => undef
$empty_allowed      => 1
$show_label         => 1
$disables           => {}
$enabled_by         => []
$container_selector => undef
$after_label        => ''
$after_input        => ''
</%args>
<%init>
use RT::Extension::FormTools;
my $queue      = $m->notes('queue');
my $ticket     = $m->notes('ticket');
my $field_type = 'custom';
my $field_label ||= $label;
my $cf;

my @values;

$queue = $ticket->QueueObj
    if !$queue && $ticket;

my $input_name = '';
if ( RT::Extension::FormTools::is_core_field($name) ) {
    $field_type = 'core';
    my $res = $m->notes(
        core_fields_on_page => [ @{$m->notes('core_fields_on_page')||[]}, $name ] );
    $field_label ||= $name;
    $default ||= $ticket->$name if $ticket && $ticket->_Accessible($name, 'read');
    $input_name = $name;
} else {

    $cf = RT::CustomField->new( $session{'CurrentUser'} );
    $cf->SetContextObject($ticket) if $cf->can('SetContextObject');

    # try loading CFs for this Queue, followed by Global, followed by any CF of given $name
    $cf->LoadByName( Name => $name, Queue => $queue->id ) if (defined $queue);
    $cf->LoadByName( Name => $name, Queue => 0 ) unless ( $cf->id );
    unless ( $cf->Id ) {
        # Clear context object because previous call made it global
        # Not needed for RT >= 4.2.5 where this is fixed in LoadByName
        $cf->SetContextObject(undef) if $cf->can('SetContextObject');
        $cf->LoadByName( Name => $name );
    }
    unless ( $cf->id ) {
        my $msg = "Could not find a custom field called $name";
        $msg .= " for the queue ".$queue->Name if (defined $queue);
        RT->Logger->error('Could not load custom field:' . $msg);
        return;
    }

    $m->notes( cfs_on_page => [ @{$m->notes('cfs_on_page')||[]}, $cf->id ] );
    $field_label ||= $cf->Name;
    $tooltip ||= $cf->EntryHint;

    if ($ticket) {
        @values = map { $_->Content } @{ $cf->ValuesForObject($ticket)->ItemsArrayRef };
        $default ||= @values > 1 ? \@values : $values[0];
    }

    if ( $default && !ref $default && $cf->MaxValues != 1 ) {
        $default = [ split /\r?\n/, $default ];
    }

    if ( !( defined $default && length $default ) && $cf->SupportDefaultValues ) {
        if ( defined( my $default_values = $cf->DefaultValues( Object => $queue ) ) ) {
            $default = $default_values;
        }
    }

    # for readonly, @values is used to render multiple value inputs.
    if ( $render_as =~ /readonly/ ) {
        if ( ref $default eq 'ARRAY' ) {
            if ( @$default > 1 ) {
                @values = @$default;
            }
            else {
                $default = $default->[0];
            }
        }
    }

    $input_name = GetCustomFieldInputName(
        Object      => $ticket,
        CustomField => $cf,
    );
}

my $request_args = $DECODED_ARGS;

if ( $render_as !~ /readonly/ ) {
    if ( $field_type eq 'core' && exists $request_args->{$name} ) {
        $default = $request_args->{$name};
    }
    elsif ( $field_type eq 'custom' && $cf->Id && ( exists $request_args->{$input_name} ) ) {
        $default = ( $request_args->{$input_name} || $request_args->{ $input_name . 's' } );
    }
}

$default = '' unless defined $default;

</%init>

% if ( @$enabled_by ) {
%    my $escape = sub { my $res = shift; $res =~ s/'/\\'/; "'$res'" };
    <script>
    jQuery(function () {
        var fields = [<% join ', ', map $escape->($_->{'field'}), @$enabled_by |n %>];
        var values = new Array();
% foreach my $e ( @$enabled_by ) {
        values[<% $escape->($e->{'field'}) |n %>] = [<% join ', ', map $escape->($_), ref($e->{'value'})? (@{ $e->{'value'} }) : ($e->{'value'}) |n %>];
% }
        for ( var i = 0; i<fields.length; i++ ) {
            var field = fields[i];
            jQuery('*[name="'+ field +'"], *[name="'+ field +'s"]').filter('input,select').change( function(e) {
                disable_form_field( should_disable_form_field(fields, values), <% $escape->( $container_selector ) |n %> );
            });
        }
    });
    jQuery(function () {
        var fields = [<% join ', ', map $escape->($_->{'field'}), @$enabled_by |n %>];
        var values = new Array();
% foreach my $e ( @$enabled_by ) {
        values[<% $escape->($e->{'field'}) |n %>] = [<% join ', ', map $escape->($_), ref($e->{'value'})? (@{ $e->{'value'} }) : ($e->{'value'}) |n %>];
% }
        disable_form_field( should_disable_form_field(fields, values), <% $escape->( $container_selector ) |n %> );
    });
    </script>
% }

% if ($field_type eq 'core' && $name eq 'Content' && $render_as ne 'hidden') {

<div
% if ( $ARGS{validation} ) {
    data-validation="<% $ARGS{validation} %>"
% }
>

% if ( $default && RT->Config->Get('MessageBoxRichText',  $session{'CurrentUser'}) && $default !~ /<.{1,5}>/ ) {
%   $default =~ s/&/&amp;/g;
%   $default =~ s/</&lt;/g;
%   $default =~ s/>/&gt;/g;
%   $default =~ s/"/&quot;/g;
%   $default =~ s/'/&#39;/g;
%   $default =~ s{\n}{<br />}g;
% }
<& /Elements/MessageBox,
    Name => $name,
    ($rows ? (Height => $rows) : ()),
    ($cols ? (Width => $cols) : ()),
    IncludeSignature => 0,
    Default => $default,
    FullWidth => 1,
&>
% if ( $ARGS{validation} ) {
  <span class="cfhints my-1 d-inline-block required">
    <% loc('Required') %>
  </span>
% }
</div>

% } else {

% if ($render_as ne 'hidden' && $show_label) { # no label if hidden

<&| /Elements/LabeledValue, RawLabel => $m->interp->apply_escapes($field_label, 'h') . $after_label, LabelSpanClass => $tooltip ? 'prev-icon-helper' : '', LabelTooltip => $tooltip &>
  <div data-name="<% $cf ? $cf->Name : '' %>"
% if ( $ARGS{validation} ) {
    data-validation="<% $ARGS{validation} %>"
% }
% if ( $ARGS{dependent_validation} && $ARGS{dependent_validation}{enabled} && $ARGS{dependent_validation}{name} ) {
%   my $dependent_cf = RT::CustomField->new($session{CurrentUser});
%   $dependent_cf = RT::CustomField->new( $session{'CurrentUser'} );
%   $dependent_cf->SetContextObject($ticket) if $cf->can('SetContextObject');

%   # try loading CFs for this Queue, followed by Global, followed by any CF of given $name
%   $dependent_cf->LoadByName( Name => $ARGS{dependent_validation}{name}, Queue => $queue->id ) if (defined $queue);
%   $dependent_cf->LoadByName( Name => $ARGS{dependent_validation}{name}, Queue => 0 ) unless ( $dependent_cf->id );
%   if ( $dependent_cf ) {
    data-dependent-name="<% GetCustomFieldInputName( Object => $ticket, CustomField => $dependent_cf ) %>"
    data-dependent-values="<% JSON($ARGS{dependent_validation}{values} || []) %>"
%   }
% }
  >
    <& SELF:Value, %ARGS, input_name => $input_name, field_type => $field_type, default => $default, values => \@values, cf => $cf &>
    <% $after_input |n %>
  </div>
</&>

% } else {
  <& SELF:Value, %ARGS, input_name => $input_name, field_type => $field_type, default => $default, values => \@values, cf => $cf &>
% }

% }

<%METHOD Value>
<%ARGS>
$name
$render_as          => 'normal'
$default            => undef
$cols               => undef
$rows               => undef
$empty_allowed      => 1
$disables           => {}
$after_input        => ''
$cf                 => undef
$queue              => undef
$field_type         => undef
$input_name         => undef
@values             => ()
</%ARGS>

% if ($field_type eq 'core') {

% if ($name eq 'Attach') {
<div class="custom-file">
  <input type="file" id="<% $name %>" name="<% $name %>" class="custom-file-input" />
  <label class="custom-file-label" for="<% $name %>"><&|/l&>Choose file</&></label>
</div>
<input type="hidden" class="hidden" name="UpdateAttach" value="1" />

% } elsif ($render_as eq 'hidden') {

<input type="hidden" name=<%$name%> value="<%$default%>">

% } elsif ($render_as eq 'readonly' or $render_as eq 'readonly_plus_values') {

% if (@values > 1) {
    <ul class="list-group list-group-borderless list-group-compact">
% for (@values) {
    <li class="readonly list-group-item"><% $_ %></span>
%   if ($render_as eq 'readonly_plus_values') {
    <input type="hidden" name="<% $input_name %>" value="<% $_ %>"/>
%   }
% }
    </ul>
% } else {
    <span class="readonly form-control current-value"><% $default %></span>
%   if ($render_as eq 'readonly_plus_values') {
    <input type="hidden" name="<% $input_name %>" value="<% $default %>"/>
%   }
% }

% } elsif ($name eq "Owner" ) {
<& /Elements/SelectOwner, Name => $name, QueueObj => $queue, Default => $default, DefaultValue => 0 &>
% } elsif ($name =~ /^(Requestors|Cc|AdminCc)$/ ) {
<& /Elements/EmailInput,
    Name                 => $name,
    Default              => $default,
    AutocompleteMultiple => 1,
    (exists $ARGS{cols} ? (Size => $cols) : ()),
&>
% } elsif ( $name eq "Due" ) {
<& /Elements/SelectDate, Name => $name, Default => $default, current => 0, (defined $cols ? (Size => $cols) : ()) &>
% } elsif ( $name eq "TimeEstimated" ) {
<& /Elements/EditTimeValue, Name => $name, Default => $default &>
% } else {
<input class="form-control" type="text" name="<%$name%>" size="<% $cols || 20 %>" value="<%$default%>">
% }

% } else { # CF

% unless ($render_as =~ /^(?:normal|radio|checkbox|date)/i) {
<input type="hidden" class="hidden" name="<% $input_name %>-Magic" value="1" />
% }


% if ($render_as eq 'hidden') {
    <input type="hidden" class="hidden" name=<% $input_name %> value="<% $default %>">
% } elsif ($render_as =~ /^(?:normal|radio|checkbox|date)/i) {
%   if ($render_as !~ /^(?:normal)/i) {
%       RT->Deprecated( Message => "render_as '$render_as' is ignored: RT already supports it in core" );
%   }
    <& /Elements/EditCustomField, CustomField => $cf,
            ($cf->Type =~ /text/i) ? (Cols => $cols ||60) : (),
            ($cf->Type =~ /freeform/i) ? (Cols => $cols ||30) : (),
            Rows => $rows || 6,
            QueueObj => $queue,
            ($default ? (Default => $default) : ())
            &>
%      if (my $msg = $m->notes('InvalidField-' . $cf->Id)) {
            <span class="cfinvalidfield my-1 d-inline-block"><% $msg %></span>
%      } elsif ($cf->FriendlyPattern) {
            <span class="cfhints my-1 d-inline-block">
              <% $cf->FriendlyPattern %>
            </span>
%      }
% } elsif ($render_as =~  /^boolean/i)  {
%       my $value = 'Yes';
<div class="custom-control custom-checkbox" style="margin-top: 5px">
  <input class="custom-control-input" type="checkbox" name="<% $input_name %>" id="<% $input_name %>" value="<% $value %>"
% my $checked = 0;
%  if ($default) {
%       $checked = ref $default? (grep { $_ eq $value} @$default) : $default eq $value;
% }
        <% $checked? 'checked="checked"' : '' |n %>
% if ( my $disable = $disables->{$value} ) {
        onclick="disable_form_field(this.checked, '<% $disable %>');"
% }
        />
  <label class="custom-control-label" for="<% $input_name %>"><% $value %></label>
</div>

% if ( $checked and my $disable = $disables->{$value} ) {
    <script>
        jQuery(function() { disable_form_field(true, '<% $disable %>') } );
    </script>
% }
% } elsif ($render_as eq 'readonly' or $render_as eq 'readonly_plus_values') {

% if (@values > 1) {
    <ul class="list-group list-group-borderless list-group-compact">
% for (@values) {
    <li name="<% $input_name %>" class="readonly list-group-item"><% $_ %></li>
%   if ($render_as eq 'readonly_plus_values') {
    <input type="hidden" name="<% $input_name %>" value="<% $_ %>"/>
%   }
% }
    </ul>
    <script>
% foreach my $disable ( grep $_, map $disables->{$_}, @values ) {
        jQuery(function() { disable_form_field(true, '<% $disable %>') } );
% }
    </script>

% } else {
    <span name="<% $input_name %>" class="form-control current-value readonly"><% $default %></span>
%   if ($render_as eq 'readonly_plus_values') {
    <input type="hidden" name="<% $input_name %>" value="<% $default %>"/>
%   }
% if ( my $disable = $disables->{ $default } ) {
    <script>
        jQuery(function() { disable_form_field(true, '<% $disable %>') } );
    </script>
% }
% }

% } else {
% RT->Logger->error("'$render_as' isn't a valid rendering option for field '$name'");
% return;
%}

% }


% if (  ( !$cf || !$cf->FriendlyPattern ) && ( $ARGS{validation}
%    || ( $ARGS{dependent_validation} && $ARGS{dependent_validation}{enabled} && $ARGS{dependent_validation}{name} ) )
% ) {
    <span class="cfhints my-1 d-inline-block required">
      <% loc('Required') %>
    </span>
% }
</%METHOD>
