<%INIT>
my $Move = ($Direction eq 'Down') ? 1 : -1;

my $TargetObj;
my $target_order = $SubItem->SortOrder + $Move;
while (my $v = $Values->Next) {
    my $this_order = $v->SortOrder;

    # if we have an exact match, finish the loop now
    ($TargetObj = $v, 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 - $SubItem->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 = $v;
}

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

$Values->GotoFirstItem;

return($TargetObj ? 1 : 0);
</%INIT>
<%ARGS>
$SubItem
$Direction
$Values
</%ARGS>
