package MetaGene::ORF;
BEGIN{ push(@INC, $ENV{LOCAL_PERL_MODULES}); }
use Carp;
use warnings;
use strict;
use Sequence::Util;

###################################################
sub new {
    my $pkg = shift;
    bless {
	seqName => undef, 
	start   => undef, 
	end     => undef, 
	strand  => undef, 
	frame   => undef, 
	score   => undef, 
	status  => undef
    }, $pkg;
}

###################################################
sub set {
    my $self = shift;
    my $seqName = shift;
    my $cols = shift;
    $self->{seqName} = $seqName;
    $self->{start}   = shift @$cols;
    $self->{end}     = shift @$cols;
    $self->{strand}  = shift @$cols;
    $self->{frame}   = shift @$cols;
    $self->{score}   = shift @$cols;
    $self->setStatus( shift @$cols );
}

###################################################
sub setStatus {
    my $self = shift;
    my $status = shift;
    if( $status eq "partial (lack 3'-end)" ){
	$self->{status} = "partial3";
    } elsif( $status eq "partial (lack 5'-end)" ){
	$self->{status} = "partial5";
    } elsif( $status eq "partial (lack both ends)" ){
	$self->{status} = "partial53";
    } elsif( $status eq "complete" ){
	$self->{status} = "complete";
    } else {
	die "Invalid ORF status: " . $status;
    }
}

###################################################
sub getSequenceName {
    my $self = shift;
    return $self->{seqName};
}

###################################################
sub getStart {
    my $self = shift;
    return $self->{start};
}

###################################################
sub getEnd {
    my $self = shift;
    return $self->{end};
}

###################################################
sub getStrand {
    my $self = shift;
    return $self->{strand};
}

###################################################
sub getFrame {
    my $self = shift;
    return $self->{frame};
}

###################################################
sub getScore {
    my $self = shift;
    return $self->{score};
}

###################################################
sub getStatus {
    my $self = shift;
    return $self->{status};
}

###################################################
sub getORFName {
    my $self = shift;
    my $name = $self->getSequenceName() . ":"
	. $self->getStart()  . ":"
	. $self->getEnd()    . ":"
	. $self->getStrand() . ":"
	. $self->getFrame()  . ":"
	. $self->getScore()  . ":"
	. $self->getStatus();
    return $name;
}

###################################################
sub getCDS {
    my $self = shift;
    my $seq = shift;
    my $cds = substr($seq, $self->getStart()-1, $self->getLength());
    if( $self->getStrand() eq '-' ){
	$cds = Sequence::Util::complement($cds);
    }
    if( $self->getFrame() ){
	$cds = substr($cds, $self->getFrame());
    }
    return $cds;
}

###################################################
sub getLength {
    my $self = shift;
    return $self->getEnd() - $self->getStart() + 1;
}

###################################################
sub isPartial5 {
    my $self = shift;
    if( $self->getStatus() eq "partial5" ){
	return 1;
    } elsif( $self->getStatus() eq "partial53" ){
	return 1;
    } else {
	return 0;
    }
}

###################################################
sub isPartial3 {
    my $self = shift;
    if( $self->getStatus() eq "partial3" ){
	return 1;
    } elsif( $self->getStatus() eq "partial53" ){
	return 1;
    } else {
	return 0;
    }
}

###################################################
sub getLine {
    my $self = shift;
    my $lines = $self->getSequenceName() . ":"
	. $self->getStart()  . ":" 
	. $self->getEnd()    . ":"
	. $self->getStrand() . "\t"
	. $self->getFrame()  . "\t"
	. $self->getScore()  . "\t"
	. $self->getStatus();
    return $lines;
}

1;
