#!/usr/bin/perl -w
#
# author: axel wintsche
# mail: wint(spider monkey)bioinf(dot)uni-leipzig(dot)de
# uses some parts from tax script

use strict;
use Getopt::Long;


my ($names_file, $nodes_file) = ("/scr/k10/taxonomy/names.dmp", "/scr/k10/taxonomy/nodes.dmp");
my $countfile = "/homes/bierdepot/wint/praktikum/bioinfprak09/data/viechcount";
my $species_list = "/homes/bierdepot/wint/praktikum/bioinfprak09/data/superfam2ncbi.tab";
my $true = 1;
my $all;

GetOptions('a' => \$all);


while ($true) {
   	print STDERR "enter taxon (name or taxid; @ to exit): ";
    $| = 1;  #force a flush after print
    $_ = <STDIN>;
   	chomp $_;   

    my $start = choose_organism($_);
    if ($start > 0) {
		get_from_file($start); $true = 0;
	}
	elsif ($start == -1) { $true = 0; }
}

### SUBS ###

sub choose_organism {
    my $name = shift;
	my @names = ();
    my ($choice, $using, $error) = (0, 0, 1);
    my @grep = ();

    if ($name =~ /^\d+/) {
	@grep = `grep -P '^$name\\s' '$names_file'`;
    } elsif ($name =~ /^[a-zA-Z]+.*/) {
	@grep = `grep -i -P '$name' '$names_file'`;
    } elsif ($name =~ /\@/) {
	return -1;
    } else {
	print STDERR "ERROR: invalid name: \"$name\"\n";
	return 0;
    }

    if (!@grep) {
	print STDERR "ERROR: no such organism: \"$name\"\n";
	return 0;
    }
    
    foreach my $line (@grep) {
	chomp($line);
	my @temp = ();
	@temp = split(/\s*\|\s*/, $line);
	push(@names, \@temp);
    }
    
    if ((@names > 1) && (@names < 100)) {
	print STDERR "Found more than one organism with specified parameters.\n";
	print STDERR "Please choose one:\n"; 
	print STDERR "-------------------------------------------------------\n";
	until ($error == 0) {
	    for ($choice = 0; $choice < @names; $choice++) {
		print STDERR ($choice.": ".join(" - ",@{$names[$choice]})."\n");
	    }
	    print STDERR "$choice: abort. new prompt.\n";
	    print STDERR "Your choice [0-$choice] (or <ENTER> for first hit): ";
	    
	    #force a flush after print
	    $| = 1;
	    $using = <STDIN>;
	    chomp $using;
	    if (!($using =~ /\d/)) {
		$using = 0;
		$error = 0;
	    } elsif ($using > $choice) {
		#print STDERR "\e[2J";
		print STDERR "ERROR: \"$using\" is no valid ID.\n";
		$error = 1;
	    } elsif ($using == $choice) {
		return 0;
	    } else {
		$error = 0;
	    }
	}
    } elsif (@names > 100) {
	print STDERR "Found more than 100 organism with specified parameters.\n";
	print STDERR "Please be more precise.\n";
	return 0;
    }
	
	    my $grep = `grep -m 1 -P '^$names[$using]->[1]\\t' '$countfile'`;
		chomp $grep;

	
	print STDERR "-------------------------------------------------------\n";	
    print STDERR "using:\t", $names[$using]->[1], " (",( split /\t/, $grep )[2], ")\n";
	print STDERR "-------------------------------------------------------\n";

    return $names[$using]->[0];
}

sub get_from_file {
    my $start = shift;
    
    my @grep = `grep -w -P '^\\d+[\\|\\s+]+$start' '$nodes_file'`;
    chomp @grep;
	
    foreach(@grep) {
	my @temp = split /\s+\|\s+/, $_;
	
	#if taxon is the root (id == 1) drop it because the root points to itselfs and
	# would cause an infinity number of recursive calls of print_orgnsims() and also
	# root should not be displayed as child of root
	next if($temp[0] == 1);
	# print taxon if it contains organism of the superfam
	my $count = get_count($temp[0]);
	if( $count > 0 ) {
	    my $name = get_name($temp[0]);
	    print STDERR $name." (".$temp[0].")\t".$count."\n";
	}
	if($all){
	    print_organisms($temp[0]);
	}
    }
    
}

sub print_organisms {
    my $id = shift;
    my $name = get_name($id);
    my $count = get_count($id);
    
    # if taxon has no superfam organisms return
	if($count == 0){ return; }
	
	# if taxon is also organism in superfam print taxon name
	if(is_in_superfam($id) == 1){ print "\t$name\t$id\t$count\n"; }
	
    # get all children
    my @grep = `grep -w -P '^\\d+[\\|\\s+]+$id' '$nodes_file'`;
    
	chomp @grep;

    # if grep found some lines (children)
	foreach(@grep) {

	    my @temp = split /\t/, $_;
	    print_organisms($temp[0]);
	}
}

# grep the ncbi scientific name of a ncbi id
# return: scientific name
# param: ncbi id
sub get_name {
    my $id = shift;

    my $grep = `grep -m 1 -P '^$id\\s.+scientific name' '$names_file'`;
    chomp $grep;

    return ( split(/\s*\|\s*/, $grep) )[1];
}

# grep the number of a superfam organisms in a taxon and return it
# if the organisms is not in the superfam 0 is returned
# param: ncbi id of organism
sub get_count {
    my $id = shift;
    my $grep = `grep -m 1 -P '\\t$id\\t' '$countfile'`;
    if($grep eq ""){ return 0; }
    chomp $grep;

    return ( split /\t/, $grep )[2];
}

# check if the id belongs to a superfam organism
# return: 1 if organism is in superfam and 0 else
# param: organism nscbi id
sub is_in_superfam {
	my $id = shift;
	my $grep = `grep -w -P '\\t$id' '$species_list'`;
	
	return ($grep eq "")? 0:1;
}
