#######################################################################
# This software has been created by Genome Research Limited (GRL).    # 
# GRL hereby grants permission to use, copy, modify and distribute    # 
# this software and its documentation for non-commercial purposes     # 
# without fee at the user's own risk on the basis set out below.      #
# GRL neither undertakes nor accepts any duty whether contractual or  # 
# otherwise in connection with the software, its use or the use of    # 
# any derivative, and makes no representations or warranties, express #
# or implied, concerning the software, its suitability, fitness for   #
# a particular purpose or non-infringement.                           #
# In no event shall the authors of the software or GRL be responsible # 
# or liable for any loss or damage whatsoever arising in any way      # 
# directly or indirectly out of the use of this software or its       # 
# derivatives, even if advised of the possibility of such damage.     #
# Our software can be freely distributed under the conditions set out # 
# above, and must contain this copyright notice.                      #
#######################################################################

package Qplot;

#################################################################################################
##
## Quality Graph
##


use Tk;
use Tk::Dialog;
use Tk::ErrorDialog;

my $FONT = '8x13';            # normal font
my $FONTs = '6x10';		# small font
				# good   
my %D ;				# bad
my %C ;
my %E ;
#my %PlotObjs;			# ids of visible objects
#my %HiddenObjs;			# non vis
my %BadConts;
my $scale;
my $c;				# temp canvas variable
my $xxt;			# x-extent
my $yxt;			# y-extent
my $gxmax ;			# good x val max
my $gymax ;                     # good y val max
my $bxmax ;			# bad x max
my $bymax ;                     # bad y max
my $nxmax;
my $nymax; 
my $cymax ;			# combo y max 
my $xmax ;
my $ymax ; 
my $gymin ;			# minima as above
my $cymin ;
my $bymin ;
my $nymin;
my $ymin ;

##################################################################################################
# set bounds for scaling

sub Set_xxt_yxt{
	my ($x,$y) = @_;

	$xxt = $x;
	$yxt = $y;

}
#################################################################################################
# Set Good data points

sub Set_sa{

    my (%S1) =@_;
    %D = %S1;
}
################################################################################################
# Set Bad

sub Set_sb{

    my (%S2) =@_;
    %C = %S2;
}
sub Set_sc{
    my (%S3) = @_;
    %E = %S3;
}
sub GetScale{
    $scale;
}
#################################################################################################
# Un- hides marked objects

#################################################################################################
# Hide drawn objects



##################################################################################################
# draw the graph lines 

sub Plot_series{
   my ($canv,$xext,$yext, $redraw)= @_;

   # canvas    max x  max y 

   my %Combo;
   my @combo;
   my $i=0;
   
   $c = $canv;			# global canvas become given canvas
   $xxt = $xext;                # set global x-ext
   $yxt = $yext;		# ditto y

 
   foreach (keys(%C))		# data .. keys == x co-ord  value == y co-ord
       {
	   $Combo{$_} =  ($D{$_} - $C{$_});       # combo is the overall line 
           
       }
 
   if($redraw)
   {				
      
       &Draw_scale($xmax,$ymax,$ymin);               # draw graph scale (axis)
       &Plot($xmax,$ymax,'green',$ymin,%D);          # plot good as green
       &Plot($xmax,$ymax,'red',$ymin,%C);            # plot bad - red
       &Plot($xmax,$ymax,'black',$ymin,%Combo);      # plot combination as black
       return;
   }

   $gxmax = &max(keys(%D));	                  # good x val max
   $gymax = &max(values(%D));                  # good y val max
   $bxmax = &max(keys(%C));	                  # bad x max
   $bymax = &max(values(%C));                  # bad y max 
   $nxmax = &max(keys(%E));
   $nymax = &max(values(%E));

   $cymax = &max(values(%Combo));              # combo y max 

   $xmax = $bxmax;		                  # 
   $ymax = &max($bymax,$gymax,$cymax,$nymax); 

   $gymin = &min(values(%D));                  # minima as above
   $cymin = &min(values(%Combo));
   $bymin = &min(values(%C));
   $nymin = &min(values(%E));
 #  $ymin = &min($gymin,$cymin,$bymin,$nymin);
   
 #  &Erase("*") if(!defined(%PlotObjs));          # undraw stuff we don't want
   $xmax = &scale_max($gxmax,$bxmax,$cxmax,$nxmax);     # rescale maxima to screen co-ords 
   $ymax = &scale_max($gymax,$bymax,$cymax,$nymax);    
   $ymin = &scale_min($gymin,$bymin,$cymin,$nymin);     # ditto min
       
   &Draw_scale($xmax,$ymax,$ymin);               # draw graph scale (axis)
   &Plot($xmax,$ymax,'green',$ymin,%D);          # plot good as green
   &Plot($xmax,$ymax,'red',$ymin,%C);            # plot bad - red
   &Plot($xmax,$ymax,'blue',$ymin,%E);

   &Plot($xmax,$ymax,'black',$ymin,%Combo);      # plot combination as black
   
}
##################################################################################################
##################################################################################################
# find min val

sub scale_min{
  #  my ($first,$sec,$third) =@_;        # yes I know this can probably be replaced !!
    my @vals = @_;
 #   my $min = &min(@vals);
    @vals = sort by_val @vals;
    my $min = $vals[0];
}
sub by_val{
    $a<=>$b;
}
##################################################################################################
sub scale_max{
    #my ($first,$sec,$third) =@_;     # and this
    my @vals = @_;
#    my @vals = ($first,$sec,$third);
#    my $max = &max(@vals);	# 
    @vals =  sort by_val @vals;
  
    @vals = reverse @vals;
  
    my $max = $vals[0];
}
##################################################################################################
# actually draw the data

sub Plot{

    my ($xmax,$ymax,$col,$ymin,%Data) = @_;

    my @X = keys(%Data);        # x co-ords
    my @Y = values(%Data);	# y co-ords
    my $xmin = &min(@X);        # least x
    my $x; 
    my $xold =50;		# actually zero point on axis
    my $yold = $yxt;		# top left y
    my $px;
    my $y;
    my $width =1;
    my $point;

   
    @X = sort by_val @X;	# get them in order
    if($col eq 'black'){$width = 2;}
    foreach $px (@X)
    {
	my $x = &dmapx($px,$xmax,0); # transfrom x to fit on screen
        my $y = &dmapy($Data{$px},$ymax,$ymin); # transform y
      
   #     $PlotObjs{$c->create('line', $xold, $yold, $x, $y, -width => $width,-fill => $col)} = 'Line';
	$c->create('line', $xold, $yold, $x, $y, -width => $width,-fill => $col);
	$xold = $x; 
	$yold = $y;
    }
    $c->update;
}
##################################################################################################
# transformation in x

sub dmapx{
    my ($xin,$xmax,$xmin) = @_;

    my $nx;
    my $s = $xmax - $xmin;
    my $val;
    # offset from left = 50 pix
   

    if($s == 0) {$s =1;}  
    if($s > $xxt-50)
    {
	$nx = $s / ($xxt-50);
	$val = int($xin / $nx);
    }else{
	$nx = (($xxt-50) / $s);
	$val = int($xin * $nx);
    }
    $val += 50;
    $val;
}
########################################################################################################
# transformation to y co-ordinate

sub dmapy{
    my ($yin,$ymax,$ymin) = @_;

    my $nx;
    my $s = $ymax - $ymin;
    my $val;
    my $diff = abs($ymin);

    if ($s == 0){$s =1;}
    $yin += $diff;    
    if($s > ($yxt -20))
    {
	$nx = $s / ($yxt-20);
	$val = int($yin / $nx);
    }else{
	$nx = (($yxt-20) / $s);
	$val = int($yin * $nx);
    }
   
    $val = (($yxt-20) - $val)+20;
    $val;			
}
########################################################################################################
sub max{

    my(@in) = @_;
    my $max =0;
    @in = reverse sort by_val @in;
    $max = $in[0];
   
    $max;
}
#######################################################################################################
sub min{
    my(@in) =@_;
    my $min;

    @in = sort by_val @in;
    $min = $in[0];
    $min;
}
######################################################################################################
# axis scales

sub Draw_scale{

    my ($xmax,$ymax,$ymin) =@_;

    my $xscal=0.0;
    my $yscal=$ymin;
    my $i;
    my $interval;
    my $zero = &dmapy(0,$ymax,$ymin);
    my $inc = int ($xxt / 50);
     
    $interval = int($xmax / 50);     # x interval
   

    $c->create('line', 50, 20, 50, $yxt, -width => 2);
    $scale = $c->create('line', 50, $zero, $xxt, $zero, -width => 2);
    $c->create('text', int($xxt/2), 10, -text => 'Quality Plot', -font => $FONT,
			 -fill => 'red');
    ###### x axis bobbles and numbers

    for($i= 50;$i <= ($xxt + $inc); $i+=$inc)
    {
      
	$c->create('line',$i,$zero,$i,$zero+5,-width =>1);
        $c->create('text',$i,$zero+10,-text => $xscal, -font => $FONTs,-fill => 'black');
	$xscal += $interval;
  }

     $c->create('text',30,$zero,-text => '0',-font => $FONT,-fill => 'black');
     $c->create('text', int($xxt/2),$yxt + 40,-text => 'Base ',-font => $FONT, -fill => 'blue');

    ###### y axis bobbles and numbers 

    my %o = (60,'Q',80,'u',100,'a',120,'l',140,'i',160,'t',180,'y');
    foreach (keys(%o))
    {
#	$PlotObjs{$c->create('text',10,$_,-text => $o{$_}, -font => $FONT, -fill => 'blue')} = 'Ylabel';
	$c->create('text',10,$_,-text => $o{$_}, -font => $FONT, -fill => 'blue');
    }

    if($ymin > 0){$ymin = 0;};	                    # origin always <= 0 
    $interval = (($ymax - $ymin) / 5);
   
    $yscal = $ymin;
    for($i=($yxt - 40) ;$i >= 20; $i-= 40)
    {
        $yscal += $interval;

	$c->create('line',50,$i,45,$i,-width =>1);
	$c->create('text',30,$i,-text => $yscal, -font => $FONTs, -fill => 'black');
    }
    $c->update;
}
###################################################################################################
sub ReScale{

    my ($c,$scfactx,$scfacty) = @_;
 
 foreach(keys(%PlotObjs))
 {
     $c->scale($_,0,0,$scfactx,$scfacty);

 }

}
###################################################################################################
sub by_val{
    $a<=>$b;
}
##################################################################################################
sub CleanUp{

    undef(%PlotObjs);
}
1;
