#!/usr/bin/perl -w

########################################################################
#Modifided from png_pair_float.pl to handle probability maps
#visualize one beta-residue pairing matrix
#Date: 3/18/2005
########################################################################
#use lib 'gd-2.0.28'; 
use GD;

if (@ARGV != 4)
{
	die "need  4 params: residue-pairing matrix(name,seq,ss1,bp1,bp2,matrix), image scale(8), threshold, output file\n"; 	
}

# First argument is always a map
$fmap = shift @ARGV;
$mag = shift @ARGV;
$prob_thresh = shift @ARGV; 
$png_file = shift @ARGV; 

open (MAP,"<$fmap") || die "file $fmap not found";
@tmap=<MAP>;
$name1 = shift @tmap;
$seq1= "";
$seq1 = shift @tmap; 
$ss1 = shift @tmap; 
#shift bp1, bp2
shift @tmap;
shift @tmap; 
close MAP;

$size=($#tmap+1);

#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;
    }
  }
}

#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,$blue);
    }
    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);
    		$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, "Beta-Residue Pairing Map of $name1(Probility Threshold=$prob_thresh)", $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, $black); 
		$image->line($topX1, $topY1, $topX2, $topY2, $black); 
		$image->line($rightX1, $rightY1, $rightX2, $rightY2, $black); 
		$image->line($bottomX1, $bottomY1, $bottomX2, $bottomY2, $black); 
		#$image->line($leftX1, $leftY1, $leftX2, $leftY2, $red); 
		#$image->line($topX1, $topY1, $topX2, $topY2, $red); 
		#$image->line($rightX1, $rightY1, $rightX2, $rightY2, $red); 
		#$image->line($bottomX1, $bottomY1, $bottomX2, $bottomY2, $red); 
	}
	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;

