#########
# Author: js5@sanger.ac.uk
# Maintainer: webmaster@sanger.ac.uk
# Created: 2003
#
package Sanger::Graphics::Renderer::pdf;
use strict;
use PDF::API2;

use base qw(Sanger::Graphics::Renderer);

1;

sub init_canvas {
  my ($self, $config, $im_width, $im_height) = @_;

  $im_height = int($im_height* $self->{sf})+0;
  $im_width  = int($im_width* $self->{sf})+0;

  my $pdf = PDF::API2->new;
  my $page = $pdf->page();
     $page->mediabox( $im_width , $im_height );

  $self->canvas(
    { 'im_height' => $im_height, 'page' => $page, 'pdf' => $pdf, 'g' => $page->gfx, 't'=>$page->text, 'font' => $pdf->corefont('Helvetica-Bold',1) }
  );
  $self->{'canvas'}{'g'}->linewidth(0.25);
}

sub add_canvas_frame {
}

sub canvas {
  my ($self, $canvas) = @_;

  if(defined $canvas) {
  $self->{'canvas'} = $canvas;
  } else {
  my $result = $self->{'canvas'}{'pdf'}->stringify;
    $self->{'canvas'}{'pdf'}->end;
    return $result;
  }
}

sub Y { my( $self, $glyph ) = @_; return $self->{'canvas'}{'im_height'} - ($glyph->pixely() - $glyph->pixelheight())* $self->{sf}; }
sub X { my( $self, $glyph ) = @_; return $glyph->pixelx()* $self->{sf} ; }
sub XY { my( $self, $x, $y ) = @_; return ( $x* $self->{sf}, $self->{'canvas'}{'im_height'} - $y* $self->{sf} ); }
sub H { my( $self, $glyph ) = @_; return 1 + $glyph->pixelheight()* $self->{sf}; }
sub W { my( $self, $glyph ) = @_; return 1 + $glyph->pixelwidth()* $self->{sf}; }

sub strokecolor { my $self = shift; $self->{'canvas'}{'g'}->strokecolor( "#".$self->{'colourmap'}->hex_by_name( shift ) ); }
sub fillcolor   { my $self = shift; $self->{'canvas'}{'g'}->fillcolor(   "#".$self->{'colourmap'}->hex_by_name( shift ) ); }
sub stroke    { my $self = shift; $self->{'canvas'}{'g'}->stroke; }
sub fill    { my $self = shift; $self->{'canvas'}{'g'}->fill; }
sub rect    { my $self = shift; $self->{'canvas'}{'g'}->rect(@_); }
sub move    { my $self = shift; $self->{'canvas'}{'g'}->move(@_); }
sub line    { my $self = shift; $self->{'canvas'}{'g'}->line(@_); }
sub hybrid    { my $self = shift; $self->{'canvas'}{'page'}->hybrid; }

sub render_Rect {
  my ($self, $glyph) = @_;
  my $gcolour     = $glyph->colour();
  my $gbordercolour = $glyph->bordercolour();

	my($x,$y) = $self->XY($glyph->pixelx,$glyph->pixely);
	my($a,$b) = $self->XY($glyph->pixelx+$glyph->pixelwidth,$glyph->pixely+$glyph->pixelheight);

  if(defined $gcolour) {
    unless( $gcolour eq 'transparent' ) {
    $self->fillcolor( $gcolour );
    $self->strokecolor( $gcolour );
    $self->rect($x,$y,$a-$x,$b-$y);
    # $self->stroke();
    $self->fill();
    }
  } elsif(defined $gbordercolour) {
    unless( $gbordercolour eq 'transparent' ) {
    $self->strokecolor( $gbordercolour );
    $self->rect($x,$y,$a-$x,$b-$y);
    $self->stroke();
    }
  }
}

sub render_Text {
  my ($self, $glyph) = @_;
  my $font = $glyph->font();
#  return;

  my $gcolour = $glyph->colour() || "black";
  my $text  = $glyph->text();

	my($x,$y) = $self->XY($glyph->pixelx,$glyph->pixely);
	my($a,$b) = $self->XY($glyph->pixelx+$glyph->pixelwidth,$glyph->pixely+$glyph->pixelheight);

	my $h = $y - $b;

	warn "      $x $y [$h] $a $b [$text]";
  my $S = ($glyph->{'ptsize'}||8)* $self->{sf};
  my $T = $self->{'canvas'}{'t'};
     $T->font( $self->{'canvas'}{'font'}, $S );
     $T->fillcolor( $gcolour ); 
  if( $glyph->{'valign'} eq 'top' ) {
    $y -= $S;
  } elsif( $glyph->{'valign'} ne 'bottom' ) {
	  $y = ( $y + $b - $S ) /2;
  } else {
    $y = $b;
	}
  warn "$glyph->{valign} $y";
  if( $glyph->{'halign'} eq 'right' ) {
    $T->translate( $a, $y );
    $T->text_right( $text );
  } elsif( $glyph->{'halign'} eq 'center' ) {
    $T->translate( ($x+$a)/2, $y );
    $T->text_center( $text );
  } else {
    $T->translate( $x, $y );
    $T->text( $text );
  }
}

sub render_Circle {
#  die "Not implemented in pdf yet!";
}

sub render_Ellipse {
#  die "Not implemented in pdf yet!";
}

sub render_Intron {
  my ($self, $glyph) = @_;
  my $gcolour = $glyph->colour();

	my($x,$y) = $self->XY($glyph->pixelx,$glyph->pixely);
	my($a,$b) = $self->XY($glyph->pixelx+$glyph->pixelwidth,$glyph->pixely+$glyph->pixelheight);

  my $mid = $glyph->strand() == -1 ? 7*$b+$y : 7*$y+$b;

  $self->strokecolor( $gcolour );
  $self->move( $x ,       ($y+$b)/2 );
  $self->line( ($x+$a)/2,  $mid/8 );
  $self->line( $a ,       ($y+$b)/2 );
  $self->stroke();
}

sub render_Line {
  my ($self, $glyph) = @_;

  my $gcolour = $glyph->colour();
  return if $gcolour eq 'transparent';

  $glyph->transform($self->{'transform'});

	my($x,$y) = $self->XY($glyph->pixelx,$glyph->pixely);
	my($a,$b) = $self->XY($glyph->pixelx+$glyph->pixelwidth,$glyph->pixely+$glyph->pixelheight);

  $self->strokecolor( $gcolour );
  $self->{'canvas'}{'g'}->linedash(5,5) if defined $glyph->dotted();
  $self->move( $x, $y );
  $self->line( $a, $b );
  $self->stroke();
  $self->{'canvas'}{'g'}->linedash() if defined $glyph->dotted();
}

sub render_Poly {
  my ($self, $glyph) = @_;
  my $gbordercolour = $glyph->bordercolour();
  my $gcolour     = $glyph->colour();

  my @points = @{$glyph->pixelpoints()};
  my $pairs_of_points = (scalar @points)/ 2;
  my ($lastx,$lasty) = $self->XY($points[-2],$points[-1]);

  if(defined $gcolour) {
    return if $gcolour eq 'transparent';
    $self->strokecolor( $gcolour );
    $self->fillcolor( $gcolour );
  } elsif(defined $gbordercolour) {
    return if $gbordercolour eq 'transparent';
    $self->strokecolor( $gbordercolour );
  }

  $self->move( $lastx , $lasty );
  while( my ($x,$y) = splice(@points,0,2) ) {
     ($x,$y) = $self->XY($x,$y);
     $self->line( $x , $y );
  }
  if(defined $gcolour) {
     # $self->stroke();
     $self->fill();
  } elsif(defined $gbordercolour) {
     $self->stroke();
  }
}

sub render_Composite {
  my ($self, $glyph,$Ta) = @_;

  #########
  # draw & colour the bounding area if specified
  # 
  $self->render_Rect($glyph) if(defined $glyph->colour() || defined $glyph->bordercolour());

  #########
  # now loop through $glyph's children
  #
  $self->SUPER::render_Composite($glyph,$Ta);
}

sub render_Sprite {
  my ($self, $glyph) = @_;
  my $spritename   = $glyph->{'sprite'} || "unknown";
  my $config     = $self->config();

  unless(exists $config->{'_spritecache'}->{$spritename}) {
  my $libref = $config->get_parameter(  "spritelib");
  my $lib  = $libref->{$glyph->{'spritelib'} || "default"};
  my $fn   = "$lib/$spritename.png";
  unless( -r $fn ){
    warn( "$fn is unreadable by uid/gid" );
    return;
  }
  eval {
    $config->{'_spritecache'}->{$spritename} = $self->{'canvas'}{'page'}->image_png($fn);
  };
  if( $@ || !$config->{'_spritecache'}->{$spritename} ) {
    eval {
    $config->{'_spritecache'}->{$spritename} = $self->{'canvas'}{'page'}->image_png("$lib/missing.png");
    };
  }
  }

  return $self->SUPER::render_Sprite($glyph);
}

1;