#!/usr/bin/perl -w

########################################################################
# Generates png files from raw square maps of [0, 1]
# copy from map2png_pair.pl
#Handle map format 2, and generate grid and band color, and text info. 
#Date: 9/15/2004
#
#Modifided from png_pair_grid.pl to handle probability maps
#Probability threshold is hard coded now. 
#Date: 10/16/2004
########################################################################
BEGIN{ unshift(@INC,"/home/jianlinc/betapro/gd-2.0.28"); }
use lib '/home/jianlinc/perlgraph/libgd'; 
use lib '/home/jianlinc/perlgraph/libpng'; 
require '/home/jianlinc/betapro/gd-2.0.28/GD.pm'; 
#use lib '/home/jianlinc/betapro/GD-2.15'; 
#use GD;

if (@ARGV != 5)
{
	die "need params: map file 1(upper triangle), map file 2(lower triangle), image scale(1), output file, threshold\n"; 	
}

# First argument is always a map
$fmap = shift @ARGV;
$fmap2 = shift @ARGV;
$mag = shift @ARGV;
$png_file = shift @ARGV; 

$prob_thresh = shift @ARGV; 

open (MAP,"<$fmap") || die "file $fmap not found";
@tmap=<MAP>;
$name1 = shift @tmap;
$seq1 = shift @tmap; 
$ss1 = shift @tmap; 
$bp11 = shift @tmap;
$bp12 = shift @tmap; 
close MAP;

$size=($#tmap+1);
open (MAP,"<$fmap2") || die "file $fmap2 not found";
@tmap2=<MAP>;
$name2 = shift @tmap2;
$seq2 = shift @tmap2; 
$ss2 = shift @tmap2; 
$bp21 = shift @tmap2;
$bp22 = shift @tmap2; 
close MAP;
$size2=($#tmap2+1);
if ($size2 != $size) { die "Map 1 and 2 should have the same size"; }
if ($seq1 ne $seq2)
{
	die "sequence in map1 doesn't match with sequnce in map2.\n"; 
}

#generate beta-strand information
@bandStart = ();
@bandEnd = ();
@posStart = ();
@posEnd = (); 
chomp $ss1; 

$preStrand = 0; 
$index = 0; 
for ($i = 0; $i < length($ss1); $i++)
{
	$sec = substr($ss1, $i, 1); 
	if ($sec eq "E" || $sec eq "B")
	{
		$index++; 
		if ($preStrand == 0)
		{
			push @bandStart, $index;
			push @posStart, $i+1; 
			$preStrand = 1; 
		}
		if ($i == length($ss1) - 1) #last char
		{
			push @bandEnd, $index;
			push @posEnd, $i+1; 
		}
	}
	else
	{
		if ($preStrand == 1)
		{
			push @bandEnd, $index;
			#bug?, should not be $i + 1, should be $i
			push @posEnd, $i; 
			$preStrand = 0; 
		}
	}
}
if ($size != $index)
{
	die "matrix size doesn't match with number of aa in strands.\n"; 
}
#print "@bandStart\n@bandEnd\n@posStart\n@posEnd\n"; 

# create a new image
#set the size of edge
$edge = 50; 
$image = new GD::Image($mag*$size + 2 * $edge, $mag*$size + 2 * $edge);

# Define colour scale
$white = $image->colorAllocate(255,255,255);
$black = $image->colorAllocate(0,0,0);       
$gray = $image->colorAllocate(190, 190, 190); 
$red = $image->colorAllocate(255,0,0);      
$blue = $image->colorAllocate(0,0,255);
$purple = $image->colorAllocate(255,0, 255);  
$green = $image->colorAllocate(0,255,0); 

# Translate the first map into an array
@map=();
for ($i=0;$i<$size;$i++) {
  @line = split(/\s+/,$tmap[$i]);
  for ($j=0;$j<=$#line;$j++) {
    if ($line[$j] > $prob_thresh)
    {
    	$map[$i][$j] = 1;
    }
    else
    {
    	
    	$map[$i][$j] = 0;
    }
  }
}
if ($fmap2) {
  for ($i=1;$i<$size;$i++) {
    @line = split(/\s+/,$tmap2[$i]);
    for ($j=0;$j<$i;$j++) {
      if ($line[$j] > $prob_thresh)
      {
      	$map[$j][$i] = 1;
      }
      else
      {
      	$map[$j][$i] = 0;
      }
    }
  }
}

#clear the image
for ($i=0;$i<$mag*$size + 2 * $edge;$i++) {
  for ($j=0;$j<$mag*$size + 2 * $edge;$j++) {
  	
    	$image->setPixel($i,$j,$white); 
  }
 }



# Set pixels in the image according to the map
for ($i=0;$i<$mag*$size;$i++) {
  for ($j=0;$j<$mag*$size;$j++) {
    if ($map[$i/$mag][$j/$mag] == 1)
    {
    	$image->setPixel($edge+$i,$edge+$j,$red);
    }
    else
    {
    	$image->setPixel($edge+$i,$edge+$j,$white); 
    }
    #for lower diag (second map)
    if ($i > $j)
    {
       if ( $map[$i/$mag][$j/$mag] == 1)
       {
    		$image->setPixel($edge+$i,$edge+$j,$blue);
       }
    }
  }
}

#draw diagonal, grid line, color band
#$image->line($edge,$edge,$edge+$mag*$size-1,$edge+$mag*$size-1,$gray);
$image->dashedLine($edge,$edge,$edge+$mag*$size-1,$edge+$mag*$size-1,$gray);
#draw the outer frame in alternate color
#$image->rectangle($edge, $edge,$edge+$mag*$size-1,$edge+$mag*$size-1, $black); 

#draw title
chomp $name1; 
$image->string(gdTinyFont, $edge, 20, "H-Bond Plot of Beta Strand for $name1", $black); 
for ($i = 0; $i < @bandStart; $i++)
{
	$start = $bandStart[$i]; 
	$end = $bandEnd[$i]; 
	$leftX1 = $edge;  $leftY1 = $edge + ($start-1)*$mag;  
	$leftX2 = $edge;  $leftY2 = $edge + $end*$mag - 1;  
	$topX1 = $edge + ($start-1)*$mag; $topY1 = $edge;  
	$topX2 = $edge + $end*$mag - 1; $topY2 = $edge;  
	$rightX1 = $edge+$mag*$size-1; $rightY1 = $edge + ($start-1)*$mag; 
	$rightX2 = $edge+$mag*$size-1; $rightY2 = $edge + $end*$mag - 1;
	$bottomX1 = $edge + ($start-1)*$mag; $bottomY1 = $edge+$mag*$size-1;
	$bottomX2 = $edge + $end*$mag - 1; $bottomY2 = $edge+$mag*$size-1;

	if ($i % 2 == 0)
	{
		$image->line($leftX1, $leftY1, $leftX2, $leftY2, $purple); 
		$image->line($topX1, $topY1, $topX2, $topY2, $purple); 
		$image->line($rightX1, $rightY1, $rightX2, $rightY2, $purple); 
		$image->line($bottomX1, $bottomY1, $bottomX2, $bottomY2, $purple); 
	}
	else
	{
		$image->line($leftX1, $leftY1, $leftX2, $leftY2, $green); 
		$image->line($topX1, $topY1, $topX2, $topY2, $green); 
		$image->line($rightX1, $rightY1, $rightX2, $rightY2, $green); 
		$image->line($bottomX1, $bottomY1, $bottomX2, $bottomY2, $green); 
	}
	#draw band name
	$band = $i+1; 
	$pos1 = $posStart[$i]; 
	$pos2 = $posEnd[$i]; 
	$image->string(gdTinyFont, 1, ($leftY1+$leftY2)/2 - 1,"$band [$pos1:$pos2]",  $black);  

	#draw grid line
	if ($i + 1 < @bandStart)
	{
		$image->dashedLine($leftX2, $leftY2, $rightX2, $rightY2, $gray); 
		$image->dashedLine($topX2, $topY2, $bottomX2, $bottomY2, $gray); 
	}

}

# Write in output
$png_data = $image->png;
open (DISPLAY,">$png_file") || die "can't create $png_file\n";
binmode DISPLAY;
print DISPLAY $png_data;
close DISPLAY;

