<commit_before>package CoGe::Graphics::Feature::HSP;
use strict;
use base qw(CoGe::Graphics::Feature);


BEGIN {
    use vars qw($VERSION $HEIGHT $BLOCK_HEIGHT);
    $VERSION     = '0.1';
    $HEIGHT = 25;
    $BLOCK_HEIGHT = 20;
    __PACKAGE__->mk_accessors(
"alignment",
"color_matches", #flag for whether to just fill the hsp with a color, or color each match individually
);
}

sub _initialize
  {
    my $self = shift;
    my %opts = @_;
    my $h = $HEIGHT; #total image height 
    my $s = $self->start;
    my $e = $self->stop;;
    my $w = $e-$s;
    $self->image_width($w);
    $self->image_height($h);
    $self->merge_percent(100);
    $self->bgcolor([255,255,255]) unless $self->bgcolor;
    $self->skip_duplicate_search(1);
    $self->force_label(1);
    $self->type('HSP');
    $self->mag(1);
    $self->font_size(10);
    $self->color_matches(1) unless defined $self->color_matches();
  }

sub _post_initialize
  {
    my $self = shift;
    my %opts = @_;
    my $gd = $self->gd;
    my $w = $self->image_width;
    my $h = $self->image_height;
#    unless ($self->
    unless ($self->color_matches)
      {
	$gd->fill(0,0, $self->get_color($self->color));
        unless ($w < 10)
          {
            $self->_rounded_edges(x1=>0, y1=>0);
            $self->_rounded_edges(x1=>$w, y1=>0, negx=>-1);
            $self->_rounded_edges(x1=>$w, y1=>$h, negx=>-1, negy=>-1);
            $self->_rounded_edges(x1=>0, y1=>$h, negy=>-1);
          }
	return;
      }
    my $alignment = $self->alignment;
    my $count = 0;
    #make a colored box around the hsp
    $gd->fill(0,0, $self->get_color([255,255,255]));

    foreach my $chr (split //, $alignment)
      {
	if ($chr eq "|")
	  {
	    $gd->line($count, 0,  $count, $self->ih, $self->get_color($self->color));
	  }
	elsif ($chr ne " ") #probably an amino acid match
	  {
	    $gd->filledRectangle($count*3, 0,  $count*3+2, $self->ih, $self->get_color($self->color));
	  }  
	$count++;
      }
    $gd->rectangle(0,0,$self->iw-1, $self->ih-1, $self->get_color($self->color));
  }

sub _rounded_edges
{
	my $self = shift;
	my %opts = @_;
	my $x1 = $opts{x1};
	my $y1 = $opts{y1};
	my $neg_x = $opts{negx} || 1;
	my $neg_y = $opts{negy} || 1;
	my $gd = $self->gd;
	my $poly1 = GD::Polygon->new;
        my $poly2 = GD::Polygon->new;
        my $poly3 = GD::Polygon->new;
        $poly1->addPt($x1,$y1);
        $poly1->addPt($x1+($neg_x*3),$y1);
        $poly1->addPt($x1,$y1+($neg_y*1)); 
        $poly2->addPt($x1,$y1);
        $poly2->addPt($x1+($neg_x*2),$y1);
        $poly2->addPt($x1,$y1+($neg_y*2)); 
        $poly3->addPt($x1,$y1);
        $poly3->addPt($x1+($neg_x*1),$y1);
        $poly3->addPt($x1,$y1+($neg_y*3));
        $gd->filledPolygon($poly1, $self->get_color(255,255,255));
        $gd->filledPolygon($poly2, $self->get_color(255,255,255));
        $gd->filledPolygon($poly3, $self->get_color(255,255,255));
}

#################### subroutine header begin ####################

=head2 sample_function

 Usage     : How to use this function/method
 Purpose   : What it does
 Returns   : What it returns
 Argument  : What it wants to know<commit_msg>added flexible corner rounding function<commit_after>package CoGe::Graphics::Feature::HSP;
use strict;
use base qw(CoGe::Graphics::Feature);

BEGIN {
    use vars qw($VERSION $HEIGHT $BLOCK_HEIGHT);
    $VERSION     = '0.1';
    $HEIGHT = 25;
    $BLOCK_HEIGHT = 20;
    __PACKAGE__->mk_accessors(
"alignment",
"color_matches", #flag for whether to just fill the hsp with a color, or color each match individually
);
}

sub _initialize
  {
    my $self = shift;
    my %opts = @_;
    my $h = $HEIGHT; #total image height 
    my $s = $self->start;
    my $e = $self->stop;;
    my $w = $e-$s;
    $self->image_width($w);
    $self->image_height($h);
    $self->merge_percent(100);
    $self->bgcolor([255,255,255]) unless $self->bgcolor;
    $self->skip_duplicate_search(1);
    $self->force_label(1);
    $self->type('HSP');
    $self->mag(1);
    $self->font_size(10);
    $self->color_matches(1) unless defined $self->color_matches();
  }

sub _post_initialize
  {
    my $self = shift;
    my %opts = @_;
    my $gd = $self->gd;
    my $w = $self->image_width;
    my $h = $self->image_height;
    unless ($self->color_matches)
      {
	$gd->fill(0,0, $self->get_color($self->color));
        unless ($w < 10)
          {
            $self->_rounded_edges(x1=>0, y1=>0);
            $self->_rounded_edges(x1=>$w-1, y1=>0, negx=>-1);
            $self->_rounded_edges(x1=>$w-1, y1=>$h-1, negx=>-1, negy=>-1);
            $self->_rounded_edges(x1=>0, y1=>$h-1, negy=>-1);
          }
	return;
      }
    my $alignment = $self->alignment;
    my $count = 0;
    #make a colored box around the hsp
    $gd->fill(0,0, $self->get_color([255,255,255]));

    foreach my $chr (split //, $alignment)
      {
	if ($chr eq "|")
	  {
	    $gd->line($count, 0,  $count, $self->ih, $self->get_color($self->color));
	  }
	elsif ($chr ne " ") #probably an amino acid match
	  {
	    $gd->filledRectangle($count*3, 0,  $count*3+2, $self->ih, $self->get_color($self->color));
	  }  
	$count++;
      }
    $gd->rectangle(0,0,$self->iw-1, $self->ih-1, $self->get_color($self->color));
  }

sub _rounded_edges
{
	my $self = shift;
	my %opts = @_;
	my $x1 = $opts{x1};
	my $y1 = $opts{y1};
	my $dist = $opts{dist} || 6;
	my $negx = $opts{negx} || 1;
	my $negy = $opts{negy} || 1;
	my $gd = $self->gd;
	foreach my $i (0..$dist-1)
	  {
	    my $poly = GD::Polygon->new;
	    $poly->addPt($x1,$y1);
	    $poly->addPt($x1+($negx*($dist-$i)),$y1);
	    $poly->addPt($x1,$y1+($negy*($i+1))); 
	    $gd->filledPolygon($poly, $self->get_color(255,255,255));
	  }
}

#################### subroutine header begin ####################

=head2 sample_function

 Usage     : How to use this function/method
 Purpose   : What it does
 Returns   : What it returns
 Argument  : What it wants to know
{'fraction_non_alphanumeric': 0.21554351506942093, 'fraction_numerical': 0.03945140535049103, 'mean_word_length': 2.98582995951417, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 138, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3948220', 'n_tokens_mistral': 2448, 'n_tokens_neox': 2309, 'n_words': 455}