#!/usr/bin/perl -w
use strict;
use warnings;
use List::Util qw[max];


# Read a HMMER file
sub read_hmm($$) {
    my ($filename_in,$filename_out) = @_;

    my $inhmm_flag = 0;
    my  $cons_flag = 0;
    my   $map_flag = 0;
    my   $ref_flag = 0;


    my $i          = 0;
    my $length     = 0;

    # start reading the HMM file 
    open FILEIN,$filename_in or die $!;
    open FILEOUT,">".$filename_out or die $!;
    
    while (my $line = <FILEIN>) { 

	#<FIXME># print $line;
	if ($inhmm_flag) {
	    # (1) HMM data Parsing
	    if ($line =~/^\s*COMPO[\s\d\.]+$/){
		# ignore COMPO line
		#print "**match COMPO**\n";	
	    } elsif ($line =~/^\s*(\d+)\s+/){
		# state "i"
		$i++;
		print "** State $i : \n";

		# (a) read the match composition letters
		print " - (a) match composition letter\n";
		my @line_match_array = split(' ',$line);
		my $sum_match = 0.0;
		my @match = ();
		foreach (@line_match_array) {
		    if (/^\d+$/) {
			print "<int:".$_.">\n";
		    } elsif (/^\d*\.\d+$/) {
			print "<exp-float: exp(-".$_.") = ".(exp(-$_)).">\n";
			push(@match, exp(-$_));
			$sum_match += exp(-$_);
		    } elsif (/^\*/){
			print "<exp-float exp(*) = exp(-infini) = 0>\n";
			push(@match, 0.0);
		    } else {
			print "<ignored \"".$_."\">\n";
		    }
		}
		print "   sum = ".$sum_match."\n";	
		
		# (b) read the insertion composition letters
		print " - (b) insertion composition letter\n";
		$line = <FILEIN>;
		my @line_insertion_array = split(' ',$line);
		my $sum_insertion = 0.0;
		my @insertion = ();
		foreach (@line_insertion_array) {
		    if (/^\d+$/) {
			print "<int:".$_.">\n";
		    } elsif (/^\d*\.\d+$/) {
			print "<exp-float: exp(-".$_.") = ".(exp(-$_)).">\n";
			$sum_insertion += exp(-$_);
		    } elsif (/^\*/){
			print "<exp-float exp(*) = exp(-infini) = 0>\n";
		    } else {
			print "<ignored \"".$_."\">\n";
		    }
		}
		print "sum = ".$sum_insertion."\n";	
		
		# (c) read the transition probabilities
		print " - (c) transition probabilities \n";
		# <FIXME> voir les cs et autres truc ajoutés
		$line = <FILEIN>;
		my @line_transitions_array = split(' ',$line);
		my $sum_transitions = 0.0;
		my @transitions = ();
		foreach (@line_transitions_array) {
		    if (/^\d+$/) {
			print "<int:".$_.">\n";
		    } elsif (/^\d*\.\d+$/) {
			print "<exp-float: exp(-".$_.") = ".(exp(-$_)).">\n";
			push(@transitions, exp(-$_));
			$sum_transitions += exp(-$_);
		    } elsif (/^\*/){
			print "<exp-float exp(*) = exp(-infini) = 0>\n";
			push(@transitions, 0.0);
		    } else {
			print "<ignored \"".$_."\">\n";
		    }
		}
		print "sum = ".$sum_transitions."\n";	

		# Genere la sortie (selon consensus)
		my $p_match_letter    = max(@match);
		my $p_mismatch_letter = 1.00 - $p_match_letter;

		#print FILEOUT "\t".($transitions[1]+$transitions[2])."\t".($transitions[0]*$p_mismatch_letter)."\t".($transitions[0]*$p_match_letter)."\n";

		print FILEOUT "\t".$i."\t0\n"; # state $i non final
		print FILEOUT "\t\t0\t1\n"; # letter 0 -> 1 transition
		print FILEOUT "\t\t\t".($i>=$length?0:$i+1)."\t".($transitions[1]+$transitions[2])."\n"; # to state $i+1 with pr
		print FILEOUT "\t\t1\t1\n"; # letter 1 -> 1 transition
		print FILEOUT "\t\t\t".($i>=$length?0:$i+1)."\t".($transitions[0]*$p_mismatch_letter)."\n"; # to state $i+1 with pr
		print FILEOUT "\t\t2\t1\n"; # letter 2 -> 1 transition
		print FILEOUT "\t\t\t".($i>=$length?0:$i+1)."\t".($transitions[0]*$p_match_letter)."\n"; # to state $i+1 with pr

	    } elsif ($line =~/^\s*\d+\.\d+\s+/){
		
		print "**match BEGIN WITH DOUBLE\n";	
		my @line_array = split(' ',$line);
		my $sum = 0.0;
		foreach (@line_array) {
		    if (/^\d+$/) {
			print "<int:".$_.">\n";
		    } elsif (/^\d*\.\d+$/) {
			print "<exp-float: exp(-".$_.") = ".(exp(-$_)).">\n";
			$sum += exp(-$_);
		    } elsif (/^\*/){
			print "<exp-float exp(*) = exp(-infini) = 0>\n";
		    } else {
			print "<ignored \"".$_."\">\n";
		    }
		}
		print "sum = ".$sum."\n";	
		
	    }
	    
	} else {
	    # (2) Header Parsing
	    if ($line =~ /^HMM\s+/) {
		# match HMM
		$inhmm_flag = 1;	    
		# -- ignore the next line "m->m m->i m->d i->m i->i d->m d->d"
		$_ = <FILEIN>;
	    } elsif ($line =~/^CS\s+([Yy][Ee][Ss]|[Nn][Oo])/){
		# match CS
		if ($1 =~ /[Yy][Ee][Ss]/) {
		    $cons_flag = 1;
		}
	    } elsif ($line =~/^MAP\s+([Yy][Ee][Ss]|[Nn][Oo])/){
                # match MAP
		if ($1 =~ /[Yy][Ee][Ss]/) {
		    $map_flag = 1;
		}
	    } elsif ($line =~/^RF\s+([Yy][Ee][Ss]|[Nn][Oo])/){
                # match REF
		if ($1 =~ /[Yy][Ee][Ss]/) {
		    $ref_flag = 1;
		}
	    } elsif ($line =~/^LENG\s+(\d+)\s*$/){
		# match LENG
		$length = $1;
		print FILEOUT ($length+1)."\n";
		# state 0
		print FILEOUT "\t0\t1\n"; # state 0 final
		print FILEOUT "\t\t0\t1\n"; # letter 0 -> 1 transition
		print FILEOUT "\t\t\t0\t0.333333\n"; # to state 0 with pr
		print FILEOUT "\t\t1\t1\n"; # letter 1 -> 1 transition
		print FILEOUT "\t\t\t0\t0.333333\n"; # to state 0 with pr
		print FILEOUT "\t\t2\t1\n"; # letter 2 -> 1 transition
		print FILEOUT "\t\t\t0\t0.333333\n"; # to state 0 with pr
	    } else {
		# unknown or ignored line in header
		chomp($line);
		print "Ignored Header Line : \"".$line."\"\n";
	    }
	}
    }
    close FILEIN;
    close FILEOUT;
}
    

&read_hmm("hmmmodel.hmm","autogen_from_hmm.txt");
