#!/usr/bin/perl
package ProcessAlignmentResults;

#########################################################################
# This object holds methods to parse and process results from alignment
# analysis (BLAST, Smith-Waterman etc).
# Date: May 2002
#########################################################################

$| = 1;

#########################################################################
sub new {
#########################################################################

    my ($self, %args) = @_;
    $self = {};
    bless $self;
    $self->{'_inputFile'} = $args{'inputFile'};
    $self->{'_outputFile'} = $args{'outputFile'};
    return $self;
}

sub inputFile { $_[0]->{_inputFile} }
sub outputFile { $_[0]->{_outputFile} }

#########################################################################
sub parseWuBlastReport  {
#########################################################################
    my ($self) = @_;

    my $ELIMIT = 1e-30;

    my $q_beg = 0;
    my $q_end = 0;
    my $s_beg = 0;
    my $s_end = 0;
    my $locus = "";
    my $acc = "";
    my $qlength = 0;
    my $slength = 0;
    my $finish = 0;
    my $insequence = 0;
    my $inscore = 0;
    my $desc = "";
    my $query = "";
    my @records = ();
    my $storeline = "";
    my $count = 0;
    my $evalue = 0;
    my $ident = 0;
    my $iden_percent = 0;

    my $input = $self->inputFile;
    my $output = $self->outputFile;

    open (INPUT, $input) || die

    while (<>) {

        chop;
        my $line = $_;

        #get genbank accession no
        if ( $line =~ /^Query=\s+(\S+)\s+/ ) {
            $query = $1;
        }

        #get the length of the query
        if ( $line =~ /\s+\(([\d,]+) letters/ ) {
	    $qlength = $1;
	    $qlength =~ s/,//;
        }

    #identify the end of a query alignment
    if ( $line =~ /Parameters:/ ) {
	$finish = 1;
    }

    if ( $line =~ /^>ORFN:/ ) {

	if ( $insequence ) {
	    $finish = 1;
	    $insequence = 0;
	    $inscore = 0;
	} 
        else {
	    $finish = 0;
	    $insequence = 1;
	    $inscore = 0;
	}
    }

    if ( $line =~ /^ Score =/ ) {

        #Parse from the ORFN line to the Score line
	if ( $insequence && !$inscore) {

	    $finish = 0;
	    undef @records;
	    @records = split ('\15', $storeline);
	    $count = 0;

	    foreach my $x ( @records ) {
		$count++;
		if ( $count == 1 ) {
		    $x .= " XX";
		    $x =~ s/>//;
		    ( $locus, $acc ) = split(' ', $x, 2);
#		    $locus =~ s/.*://;
                    $acc =~ s/,.*//;
		    ( $desc = $x ) =~ s/[\r\n]//;
		    $desc =~ s/\S* //;
		    $desc =~ s/\S* //;
		} else {
		    if ( $x =~ /.*  Length = .*/ ) {
			$slength = $x;
			$slength =~ s/.* = //;
			$slength =~ s/,//;
			$desc =~ s/  / /g;
			$desc =~ s/  / /g;
			$desc =~ s/  / /g;
			$desc =~ s/[0-9]{1,2}\/[0-9]{1,2}//g;
			last;
		    } else {
			$desc .= $x;
		    }
		}
	    }
	    $storeline = "";
	} #end insequence && !inscore
         else {
	    $finish = 1;
	}

	$inscore = 1;
    } #the end of if score

    if ( $finish ) {
	$finish = 0;
	undef @records;
	@records = split ('\15', $storeline);
	$storeline = "";

	foreach my $x (@records) {

	    if ( $x =~ /.*, Expect = (.*),/ ) {
		$evalue = $1;
		if (( $evalue eq "0.0" ) or ($evalue eq "0.") or ($evalue eq "0"))  {
		    $evalue = "1e-320";
		}
		unless ($evalue) { $evalue = 1; }
	    }
	    if ( $x =~ / Identities = ([0-9]{1,5})\/[0-9]{1,5} \(([0-9]{1,3})\%\)/)
            {
		$ident = $1;
		$iden_percent = $2;
	    }
	    if ( $x =~ /Sbjct: *([0-9]*) .* ([0-9]*).*/ ) {
		if ( !$s_beg ) {
		    $s_beg = $1;
		    $s_end = $2;
		} else {
		    $s_end = $2;
		}
	    }
	    if ( $x =~ /Query: *([0-9]*) .* ([0-9]*).*/ ) {
		if ( !$q_beg ) {
		    $q_beg = $1;
		    $q_end = $2;
		} else {
		    $q_end = $2;
		}
	    }
	}

	unless ( $qlength ) { die "qlength is zero for $query and $locus\n"; }

	if ( ($locus && $acc) && ("$query" ne "$locus") && ($evalue < $ELIMIT) ) {
	    print "$query\t$qlength\t$locus\t$acc\t$slength\t$desc\t$evalue\t$ident\t$iden_percent\t$q_beg\t$q_end\t$s_beg\t$s_end\n";
	}

	$evalue = 1;
	$count = 0;
	$q_beg = $q_end = 0;
	$s_beg = $s_beg = 0;
	@records = ();
	$insequence = 1;

	if ( $line =~ /^Parameters:/ ) {
	    $insequence = 0;
	}
    } #if finish

    #store lines for processing
    if ( $insequence ) {
	$storeline .= $_ . "\15";
    }
    } #end of while
}
