package SGN::View::Mason::Commands;
use strict;
use vars qw($m $c);
#line 124 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"

use List::Util qw/ min max sum /;
use List::MoreUtils qw/ minmax /;
use POSIX;
use Storable 'dclone';

use Bio::Range ();

use CXGN::Page::FormattingHelpers qw(
   info_table_html
  );

use CXGN::Tools::Identifiers qw/ link_identifier /;
use CXGN::Tools::Text qw/ commify_number /;

use constant LINE_WINDOW_EXPAND => 5;

sub coords_to_ranges {
    my ( $seq, $coords ) = @_;
    return
        map {
            Bio::Range->new( -start => max( 1, $_->[0]),
                             -end   => min( $seq->length, $_->[1] ),
                            )
        }
        sort { $a->[0] <=> $b->[0] }
        @$coords;
}

sub seq_windows_and_ranges {
    my ( $seq, $coords, $width ) = @_;

    unless ( $coords && @$coords ) {
        return {
            window     => Bio::Range->new( -start => 1, -end => $seq->length ),
            abs_ranges => [],
            rel_ranges => [],
        };
    }

    # change the coords into ranges and sort by start coord, also
    # clamping them to the sequence length if needed, and merge any
    # overlapping ranges
    my @ranges = Bio::Range->unions( coords_to_ranges( $seq, $coords ) );

    # calculate the windows of context for highlighted regions
    my @windows =
       # calculate 1-based non-overlapping ranges of *sequence* we will display
       sort { $a->start <=> $b->start }
       Bio::Range->unions(
           map {
               my $r = $_;
               my $match = Bio::Range->new(
                   -start => max( 0,
                                  ( POSIX::floor(($r->start-1)/$width) - LINE_WINDOW_EXPAND ),
                                ) * $width + 1,
                   -end   => min( $seq->length/$width,
                                  ( POSIX::floor(($r->end)/$width ) + 1 + LINE_WINDOW_EXPAND ),
                                ) * $width,
                  );
           } @ranges
       );

    # decorate the windows with the other things that are needed to render them
    return map {
        my $window = $_;

        # find ranges appicable to this window
        my @window_ranges =
            grep { $_->start >= $window->start && $_->end <= $window->end }
            @ranges;

        # make another set of ranges that are relative to the window
        my @rel_window_ranges = map {
            my $r = dclone $_;
            $r->start( $r->start - $window->start + 1 );
            $r->end(   $r->end   - $window->start + 1 );
            $r
        } @window_ranges;

        { window => $window, abs_ranges => \@window_ranges, rel_ranges => \@rel_window_ranges }
    } @windows;
}


sub highlighted_regions {
    my ( $coords, $highlight_description ) = @_;
    return unless $coords && @$coords;

    return
        "Highlighted Regions ($highlight_description)" =>
        join ', ',
        map "$_->[0]-$_->[1]",
        @$coords;
}

HTML::Mason::Component::FileBased->new(
'code' => sub {
use utf8; local $SGN::View::Mason::Commands::m = $HTML::Mason::Commands::m;
HTML::Mason::Exception::Params->throw
    ( error =>
      "Odd number of parameters passed to component expecting name/value pairs"
    ) if @_ % 2;
my ( $title, $seq, $highlight_description, $highlight_coords, $width, $source, $whole_seq, $blast_url, $collapsable, $collapsed );
{
    my %pos;
    for ( my $x = 0; $x < @_; $x += 2 )
    {
        $pos{ $_[$x] } = $x + 1;
    }

    foreach my $arg ( qw( seq ) )
    {
        HTML::Mason::Exception::Params->throw
            ( error => "no value sent for required parameter '$arg'" )
                unless exists $pos{$arg};
    }
#line 58 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $title = exists $pos{'title'} ? $_[ $pos{'title'} ] :  undef;
#line 59 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
    $seq = $_[ $pos{'seq'} ];
#line 60 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $highlight_description = exists $pos{'highlight_description'} ? $_[ $pos{'highlight_description'} ] :  'matches';
#line 61 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $highlight_coords = exists $pos{'highlight_coords'} ? $_[ $pos{'highlight_coords'} ] :  [ ];
#line 62 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $width = exists $pos{'width'} ? $_[ $pos{'width'} ] :  100;
#line 63 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $source = exists $pos{'source'} ? $_[ $pos{'source'} ] :  '<span class="ghosted">not recorded</span>';
#line 64 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $whole_seq = exists $pos{'whole_seq'} ? $_[ $pos{'whole_seq'} ] :  0;
#line 65 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $blast_url = exists $pos{'blast_url'} ? $_[ $pos{'blast_url'} ] :  undef;
#line 66 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $collapsable = exists $pos{'collapsable'} ? $_[ $pos{'collapsable'} ] :  0;
#line 67 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
     $collapsed = exists $pos{'collapsed'} ? $_[ $pos{'collapsed'} ] :  0;
}
$m->debug_hook( $m->current_comp->path ) if ( HTML::Mason::Compiler::IN_PERL_DB() );

#line 115 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"

  # sanitize the coords array (add 0 to all the numbers in it, forcing them to be purely numeric)
  my @highlight_coords = map [map $_+0, @$_], @$highlight_coords;

  # calculate the pieces of the sequence that we will display, and that we will highlight
  my @regions = seq_windows_and_ranges( $seq, \@highlight_coords, $width );

#line 56 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
' );
#line 69 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
' );
#line 70 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->comp( { content => sub {
#line 70 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '

    ' );
#line 79 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print(  info_table_html( 'Sequence ID' => link_identifier($seq->id) || $seq->id,
                        'Length'      => commify_number( $seq->length ),
                        'Source'      => $source,
                        __multicol    => 3,
                        __border      => 0,
			
                        )
     );
#line 79 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
    ' );
#line 84 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print(  info_table_html( 'Description' => $seq->desc || '<span class="ghosted">none</span>',
                        highlighted_regions( $highlight_coords, $highlight_description ),
                        __border => 0,
                        )
     );
#line 84 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '

    <div style="margin: 0.4em 0">&nbsp;</div>

' );
#line 88 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
   for my $r ( @regions ) {
       my $w = $r->{window};
       my $highlight_count = sum map $_->end - $_->start +1, @{$r->{abs_ranges}};
$m->print( '
        ' );
#line 92 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->comp( { content => sub {
#line 96 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
' );
#line 97 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
            my $wseq = $w->start == 1 && $w->end == $seq->length ? $seq : $seq->trunc( $w->start, $w->end );
            if( $wseq->length > 200_000 ) {
$m->print( '                 <span class="ghosted">Region too large to display.</span>
' );
#line 100 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
            } else {
$m->print( '                 ' );
#line 101 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->comp(   '/sequence/with_markup.mas',
                     width   => $width,
                     subdiv  => 10,
                     seq     => $wseq,
                     styles  => { highlight => [ '<span class="highlighted">', '</span>'] },
                     regions => [ map ['highlight', $_->start-1, $_->end], @{ $r->{rel_ranges} } ],
                     blast_url => $blast_url,
                   
); #line 108 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
' );
#line 109 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
            }
$m->print( '       ' );
#line 110 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
} }, '/page/info_section.mas',
              title => "Residues ".commify_number( $w->start ).' - '.commify_number( $w->end ),
              is_subsection => 1,
              subtitle => commify_number( $w->end - $w->start + 1 ).' residues shown, '.commify_number( $highlight_count || 0 ).' highlighted',
 );
#line 110 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
' );
#line 111 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
    }
$m->print( '
' );
#line 113 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
} }, '/page/info_section.mas', title => $title || $seq->id(), collapsible=> $collapsable, collapsed=> $collapsed
 );
#line 113 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '

' );
#line 123 "/home/production/cxgn/sgn/mason/sequence/highlighted.mas"
$m->print( '
' );
;return;
},
'declared_args' => {
  '$blast_url' => { default => ' undef' },
  '$collapsable' => { default => ' 0' },
  '$collapsed' => { default => ' 0' },
  '$highlight_coords' => { default => ' [ ]' },
  '$highlight_description' => { default => ' \'matches\'' },
  '$seq' => { default => undef },
  '$source' => { default => ' \'<span class="ghosted">not recorded</span>\'' },
  '$title' => { default => ' undef' },
  '$whole_seq' => { default => ' 0' },
  '$width' => { default => ' 100' }
},
'load_time' => 1778161189,

)
;