%# BEGIN BPS TAGGED BLOCK {{{
%#
%# COPYRIGHT:
%#
%# This software is Copyright (c) 1996-2026 Best Practical Solutions, LLC
%#                                          <sales@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/licenses/old-licenses/gpl-2.0.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 }}}
<& NewListActions, actions => $actions &>
<&|/Widgets/TitleBox, title => join(': ', grep defined, loc("Current search"), $Name) &>

<div class="row mt-2">
  <div class="col">
    <select size="10" name="clauses" class="tall form-control" style="width: 100%" multiple="multiple">
%   $m->out($optionlist);
    </select>
  </div>
</div>

<div class="row mt-2">
  <div class="col">
    <div align="center" class="text-center">
      <input type="submit" class="btn btn-primary" name="Up" value=" &uarr; " />
      <input type="submit" class="btn btn-primary" name="Down" value=" &darr; " />
      <input type="submit" class="btn btn-primary" name="Left" value=" &larr; " />
      <input type="submit" class="btn btn-primary" name="Right" value=" &rarr; " />
      <input type="submit" class="btn btn-primary" name="Toggle" value="<&|/l&>And/Or</&>" />
      <input type="submit" class="btn btn-primary" name="DeleteClause" value="<&|/l&>Delete</&>" />
%#    <input type="submit" class="btn btn-primary" name="EditQuery" value="Advanced" />
    </div>
  </div>
</div>

</&>
<%ARGS>
$Name => undef
$optionlist => ''
$actions => []
</%ARGS>

<%METHOD Process>
<%ARGS>
$Tree
$Selected
@New       => ()
</%ARGS>
<%INIT>

my @NewSelection = ();

my @results;
if ( $ARGS{'Up'} || $ARGS{'Down'} ) {
    if (@$Selected) {
        foreach my $value (@$Selected) {
            my $parent = $value->getParent;
            my $index = $value->getIndex;
            my $newindex = $index;
            $newindex++ if $ARGS{'Down'};
            $newindex-- if $ARGS{'Up'};
            if ( $newindex < 0 || $newindex >= $parent->getChildCount ) {
                push( @results, [ loc("error: can't move up"), -1 ] ) if $ARGS{'Up'};
                push( @results, [ loc("error: can't move down"), -1 ] ) if $ARGS{'Down'};
                next;
            }

            $parent->removeChild( $index );
            $parent->insertChild( $newindex, $value );
        }
    }
    else {
        push( @results, [ loc("error: nothing to move"), -1 ] );
    }
}
elsif ( $ARGS{"Left"} ) {
    if (@$Selected) {
        foreach my $value (@$Selected) {
            my $parent = $value->getParent;
            if( $value->isRoot || $parent->isRoot ) {
                push( @results, [ loc("error: can't move left"), -1 ] );
                next;
            }

            my $grandparent = $parent->getParent;
            if( $grandparent->isRoot ) {
                push( @results, [ loc("error: can't move left"), -1 ] );
                next;
            }
            
            my $index = $parent->getIndex;
            $parent->removeChild($value);
            $grandparent->insertChild( $index, $value );
            if ( $parent->isLeaf ) {
                $grandparent->removeChild($parent);
            }
        }
    }
    else {
        push( @results, [ loc("error: nothing to move"), -1 ] );
    }
}
elsif ( $ARGS{"Right"} ) {
    if (@$Selected) {
        foreach my $value (@$Selected) {
            my $parent = $value->getParent;
            my $index  = $value->getIndex;

            my $newparent;
            if ( $index > 0 ) {
                my $sibling = $parent->getChild( $index - 1 );
                $newparent = $sibling unless $sibling->isLeaf;
            }
            $newparent ||= RT::Interface::Web::QueryBuilder::Tree->new( $ARGS{'AndOr'} || 'AND', $parent );

            $parent->removeChild($value);
            $newparent->addChild($value);
        }
    }
    else {
        push( @results, [ loc("error: nothing to move"), -1 ] );
    }
}
elsif ( $ARGS{"DeleteClause"} ) {
    if (@$Selected) {
        my (@top);
        my %Selected = map { $_ => 1 } @$Selected;
        foreach my $node ( @$Selected ) {
            my $tmp = $node->getParent;
            while ( !$Selected{ $tmp } && !$tmp->isRoot ) {
                $tmp = $tmp->getParent;
            }
            next if $Selected{ $tmp };
            push @top, $node;
        }

        my %seen;
        my @non_siblings_top = grep !$seen{ $_->getParent }++, @top;

        foreach ( @New ) {
            my $add = $_->clone;
            foreach my $selected( @non_siblings_top ) {
                my $newindex = $selected->getIndex + 1;
                $selected->insertSibling( $newindex, $add );
            }
            $add->getParent->setNodeValue( $ARGS{'AndOr'} );
            push @NewSelection, $add;
        }
        @New = ();
    
        while( my $node = shift @top ) {
            my $parent = $node->getParent;
            $parent->removeChild($node);
            $node->DESTROY;
        }
        @$Selected = ();
    }
    else {
        push( @results, [ loc("error: nothing to delete"), -1 ] );
    }
}
elsif ( $ARGS{"Toggle"} ) {
    if (@$Selected) {
        my %seen;
        my @unique_nodes = grep !$seen{ $_ + 0 }++,
            map ref $_->getNodeValue? $_->getParent: $_,
            @$Selected;

        foreach my $node ( @unique_nodes ) {
            if ( $node->getNodeValue eq 'AND' ) {
                $node->setNodeValue('OR');
            }
            else {
                $node->setNodeValue('AND');
            }
        }
    }
    else {
        push( @results, [ loc("error: nothing to toggle"), -1 ] );
    }
}

if ( @New && @$Selected ) {
    my %seen;
    my @non_siblings_selected = grep !$seen{ $_->getParent }++, @$Selected;

    foreach ( @New ) {
        my $add = $_->clone;
        foreach my $selected( @non_siblings_selected ) {
            my $newindex = $selected->getIndex + 1;
            $selected->insertSibling( $newindex, $add );
        }
        $add->getParent->setNodeValue( $ARGS{'AndOr'} );
        push @NewSelection, $add;
    }
    @$Selected = ();
}
elsif ( @New ) {
    foreach ( @New ) {
        my $add = $_->clone;
        $Tree->addChild( $add );
        push @NewSelection, $add;
    }
    $Tree->setNodeValue( $ARGS{'AndOr'} );
}
$_->DESTROY foreach @New;

push @$Selected, @NewSelection;

$Tree->PruneChildlessAggregators;

return @results;
</%INIT>
</%METHOD>
