%# BEGIN BPS TAGGED BLOCK {{{
%# 
%# COPYRIGHT:
%#  
%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
%#                                          <jesse@bestpractical.com>
%# 
%# (Except where explicitly superseded by other copyright notices)
%# 
%# 
%# LICENSE:
%# 
%# This work is made available to you under the terms of Version 2 of
%# the GNU General Public License. A copy of that license should have
%# been provided with this software, but in any event can be snarfed
%# from www.gnu.org.
%# 
%# This work is distributed in the hope that it will be useful, but
%# WITHOUT ANY WARRANTY; without even the implied warranty of
%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
%# General Public License for more details.
%# 
%# You should have received a copy of the GNU General Public License
%# along with this program; if not, write to the Free Software
%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
%# 02110-1301 or visit their web page on the internet at
%# http://www.gnu.org/copyleft/gpl.html.
%# 
%# 
%# CONTRIBUTION SUBMISSION POLICY:
%# 
%# (The following paragraph is not intended to limit the rights granted
%# to you to modify and distribute this software under the terms of
%# the GNU General Public License and is only of importance to you if
%# you choose to contribute your changes and enhancements to the
%# community by submitting them to Best Practical Solutions, LLC.)
%# 
%# By intentionally submitting any modifications, corrections or
%# derivatives to this work, or any other work intended for use with
%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
%# you are the copyright holder for those contributions and you grant
%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
%# royalty-free, perpetual, license to use, copy, create derivative
%# works based on those contributions, and sublicense and distribute
%# those contributions and any derivatives thereof.
%# 
%# END BPS TAGGED BLOCK }}}
<& /Elements/ListActions, actions => \@results &>

<form action="<%$RT::WebPath%><% $m->request_comp->path |n %>" method="post" name="EditCustomFields">
<input type="hidden" class="hidden" name="id" value="<% $Object->Id %>" />
<input type="hidden" class="hidden" name="ObjectType" value="<% $ObjectType %>" />
<input type="hidden" class="hidden" name="SubType" value="<% $SubType %>" />
<input type="hidden" class="hidden" name="UpdateCFs" value="1" />

% if ($Object->Id) {
<h2><&|/l&>Global Custom Fields</&></h2>
<& PickCustomFields, CustomFields => \@GlobalCFs, ReadOnly => 1, id => $id, SubType => $SubType &>
% }
<h2><&|/l&>Selected Custom Fields</&></h2>
<& PickCustomFields, CustomFields => [$ObjectCFs->CustomFields], id => $id, Checked => 1, SubType => $SubType &>
<h2><&|/l&>Unselected Custom Fields</&></h2>
<& PickCustomFields, CustomFields => \@UnassignedCFs, id => $id, SubType => $SubType &>

<& /Elements/Submit, CheckAll => 1, ClearAll => 1 &>
</form>


<%INIT>
my $CustomFields = RT::CustomFields->new($session{'CurrentUser'});
my @results;
my (@GlobalCFs, @UnassignedCFs);

my $id = $Object->Id;
if ($id and !$Object->CurrentUserHasRight('AssignCustomFields')) {
    $m->out('<p><i>', loc('(No custom fields)'), '</i></p>');
    return;
}

my $lookup = $ObjectType;
$lookup .= "-$SubType" if $SubType;

$CustomFields->LimitToLookupType($lookup);
$CustomFields->OrderBy( FIELD => 'Name' );


my ($GlobalCFs, $ObjectCFs);
$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
$ObjectCFs->UnLimit;
$ObjectCFs->LimitToObjectId($id);
$ObjectCFs->LimitToLookupType($lookup);

# Check sanity of SortOrders
my %SortOrders;
$SortOrders{$_->SortOrder}++
  while ($_ = $ObjectCFs->Next);

# If there are duplicates, run though and squash them
if (grep {$_ > 1} values %SortOrders) {
    my $i = 1;
    while (my $ObjectCF = $ObjectCFs->Next) {
        $ObjectCF->SetSortOrder($i++);
    }
    $ObjectCFs->GotoFirstItem;
}

# {{{ deal with moving sortorder of custom fields
if ($CustomField and $Move) {
    my $SourceObj = RT::ObjectCustomField->new($session{'CurrentUser'});
    $SourceObj->LoadByCols( ObjectId => $id, CustomField => $CustomField );

    my $TargetObj;
    my $target_order = $SourceObj->SortOrder + $Move;
    while (my $ObjectCF = $ObjectCFs->Next) { 
	my $this_order = $ObjectCF->SortOrder;

	# if we have an exact match, finish the loop now
	($TargetObj = $ObjectCF, last) if $this_order == $target_order;

	# otherwise, we need to apropos toward the general direction
	# ... first, check the sign is correct
	next unless ($this_order - $SourceObj->SortOrder) * $Move > 0;

	# ... next, see if we already have a candidate
	if ($TargetObj) {
	    # ... if yes, compare the delta and choose the smaller one
	    my $orig_delta = abs($TargetObj->SortOrder - $target_order);
	    my $this_delta = abs($this_order - $target_order);
	    next if $orig_delta < $this_delta;
	}

	$TargetObj = $ObjectCF;
    }

    if ($TargetObj) {
	# swap their sort order
	my ($s, $t) = ($SourceObj->SortOrder, $TargetObj->SortOrder);
	$TargetObj->SetSortOrder($s);
	$SourceObj->SetSortOrder($t);
	# because order changed, we must redo search for subsequent uses
    }

    $ObjectCFs->GotoFirstItem;
}
# }}}

if ($id) {
    $GlobalCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
    $GlobalCFs->LimitToObjectId(0);
    $GlobalCFs->LimitToLookupType($lookup);
}

while (my $cf = $CustomFields->Next) { 
    my $cf_id = $cf->Id;

    if ($GlobalCFs and $GlobalCFs->HasEntryForCustomField($cf_id)) {
	push @GlobalCFs, $cf;
	next;
    }

    if ($UpdateCFs) {
	# Go through and delete all the custom field relationships that this object
	# no longer has
	my $key = "Object-$id-CF-$cf_id";
	if ($ARGS{$key}) {
	    if (!$ObjectCFs->HasEntryForCustomField($cf_id)) {
		my ($val, $msg) = $cf->AddToObject($Object);
		push (@results, $msg);
		push @UnassignedCFs, $cf if !$val;
	    }
	}
	else {
	    push @UnassignedCFs, $cf;
	    if ($ObjectCFs->HasEntryForCustomField($cf_id)) {
		my ($val, $msg) = $cf->RemoveFromObject($Object);
		push (@results, $msg);
		pop @UnassignedCFs if !$val;
	    }
	}
    }
    elsif (!$ObjectCFs->HasEntryForCustomField($cf_id)) {
	push @UnassignedCFs, $cf;
    }
        else {
        }
}

# redo search...
$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
$ObjectCFs->UnLimit;
$ObjectCFs->LimitToObjectId($id);
$ObjectCFs->LimitToLookupType($lookup);

</%INIT>
<%ARGS>
$title => undef
$Move => undef
$Source => undef
$CustomField => undef
$FindDisabledCustomFields => undef
$UpdateCFs => 0
$Object
$ObjectType
$SubType => ''
</%ARGS>
