#!/usr/bin/env perl
use strict;
use warnings qw"all";
use autodie qw":all";
use Getopt::Long;
use File::Basename;
use Bio::Tools::GFF;
use Bio::SeqIO;
use Term::ReadLine;
use File::Basename;
use Data::Dumper;

my %options = (
    input => undef,
    base => undef,
    );
my $opt = GetOptions(
    "input|i:s" => \$options{input},
    );
if (!defined($options{input})) {
    my $term = new Term::ReadLine('>');
    my $attribs = $term->Attribs;
    $attribs->{completion_suppress_append} = 1;
    my $OUT = $term->OUT || \*STDOUT;
    $options{input} = $term->readline("Please provide an input genbank file: ");
    $options{input} =~ s/\s+$//g;
}
my @suffix = (".gb");
$options{base} = basename($options{input}, @suffix);

my $seqio = new Bio::SeqIO(-format => 'genbank', -file => $options{input});
my $count = 0;
my $fasta = new Bio::SeqIO(-file => qq">${options{base}}.fasta", -format => 'fasta', -flush => 0);
while(my $seq = $seqio->next_seq) {
    $count++;
    $fasta->write_seq($seq);
    my @feature_list = ();
    # defined a default name
    my $gffout = new Bio::Tools::GFF(-file => ">${options{base}}_all.gff", -gff_version => 3);
    my $gene_gff = new Bio::Tools::GFF(-file => ">${options{base}}.gff", -gff_version => 3);
    my $cds_gff = new Bio::Tools::GFF(-file => ">${options{base}}_cds.gff", -gff_version => 3);
    my $inter_gffout = new Bio::Tools::GFF(-file => ">${options{base}}_interCDS.gff", -gff_version => 3);
    my $cds_fasta = new Bio::SeqIO(-file => qq">${options{base}}_cds.fasta", -format => 'Fasta');   
    my $pep_fasta = new Bio::SeqIO(-file => qq">${options{base}}_pep.fasta", -format => 'Fasta');

    foreach my $feature ($seq->top_SeqFeatures()) {
	$gffout->write_feature($feature);
	my $feat_count = 0;
    }
    for my $feat_object ($seq->get_SeqFeatures) {
	my $feat_count = 0;
	if ($feat_object->primary_tag eq "CDS") {
	    $cds_gff->write_feature($feat_object);
	    $feat_count++;
	    my $start = $feat_object->start;
	    my $end = $feat_object->end;
	    my $len = $feat_object->length;
	    my $id = $feat_object->{_gsf_tag_hash}->{locus_tag}->[0];
	    my $seq = $feat_object->spliced_seq->seq;
	    my $pep = $feat_object->spliced_seq->translate->seq;
	    my $size = {
		id => $id,
		start => $start,
		end => $end,
		len => $len,
		feat => $feat_object,
	    };
	    push(@feature_list, $size);
	    my $seq_object = new Bio::PrimarySeq(-id => $id, -seq => $seq);
	    my $pep_object = new Bio::PrimarySeq(-id => $id, -seq => $pep);
	    $cds_fasta->write_seq($seq_object);
	    $pep_fasta->write_seq($pep_object);
	} elsif ($feat_object->primary_tag eq "gene") {
	    $gene_gff->write_feature($feat_object);
	}
    } ## End looking at every feature and putting them into the @feature_list
    ## Now make a hash from it and fill in the inter-cds data

    my %inter_features = ();
    my ($p_st, $p_en, $c_st, $c_en, $inter_start, $inter_end) = 0;
  INTER: for my $c (0 .. $#feature_list) {
      my $p_size = {};
      if ($c == 0) {
	  $p_size = $feature_list[$#feature_list];
      } else {
	  $p_size = $feature_list[$c - 1];
      }
      
      my $c_size = $feature_list[$c];
      next INTER if (!defined($p_size->{start}));
      next INTER if (!defined($p_size->{end}));
      next INTER if (!defined($c_size->{start}));
      next INTER if (!defined($c_size->{end}));

      my $p_start = $p_size->{start};
      my $p_end = $p_size->{end};
      my $c_start = $c_size->{start};
      my $c_end = $c_size->{end};
      my $interstart = 0;
      my $interend = 0;

      if ($p_start > $p_end) {
	  $interstart = $p_start;
      } else {
	  $interstart = $p_end;
      }
      if ($c_start < $c_end) {
	  $interend = $c_start;
      } else {
	  $interend = $c_end;
      }
      my $tmp_start = $interstart;
      my $tmp_end = $interend;
      if ($tmp_start > $tmp_end) {
	  $interstart = $tmp_end;
	  $interend = $tmp_start;
      }
      my $new_feature = $c_size->{feat};
      my $inter_location = new Bio::Location::Atomic(-start => $interstart, -end => $interend, -strand => 1);
      $new_feature->{_location} = $inter_location;
      $inter_gffout->write_feature($new_feature);
  }
}
