=head1 NAME

iPE::Options - holder of all options for parameter estimation.

=head1 DESCRIPTION

Reads in the options for parameter estimation.  These are set in the options element of the instance file.  For all boolean options, the element should look like this:

    <verbose>true</verbose>

All other options with variable types are just the character data from between the tags.  Defaults are contained in this module as well, so if you wish to change the defaults, look here.

You may also get a default options object by calling

    $options = new iPE::Options;

=head1 FUNCTIONS

=over 8

=cut

package iPE::Options;
use iPE::Globals;
use base ("iPE::XML::Object");
use strict;

#XXX: Potential bug here, if we somehow decide to use the xml functionality, this will crash.  Should make a default xml constructor (without a prior element).
sub new {
    my $class = shift;
    my $this;
    if (scalar(@_)) {
        my ($tag, $att, $data, $element) = @_;
        $this = $class->SUPER::new(@_);
        $this->handle_children($element);
    }
    else {
        $this = bless {}, $class;
    }
    return $this;
}

=item default (optionName)

Returns the default value of the option.  Upon instantiation, the options are all unset.  The XML file is read and all the options are parsed.  When an option is requested, it searches all options for an option that was set from the XML file.  If that fails, it searches this default function for a default value.  If that fails, the script dies.

=cut

sub default {
    my ($this, $option) = @_;

    for($option) {
        if(/^allowPartialTranscripts$/)     { return 0; }
        elsif(/^allowGappedTranscripts$/)   { return 1; }
        elsif(/^allowBadTransitions$/)      { return 0; }
        elsif(/^loadSequences$/)            { return 1; }
        elsif(/^annotationSanityCheck$/)    { return 0; }
        elsif(/^expandAmbigSequences$/)     { return 0; }
        elsif(/^performCount$/)             { return 1; }
        elsif(/^performNormalize$/)         { return 1; }
        elsif(/^performScore$/)             { return 1; }
        elsif(/^weightCounts$/)             { return 1; }
        elsif(/^isochoreWindow$/)           { return 100000; }
        elsif(/^verbose$/)                  { return 0; }
        elsif(/^veryVerbose$/)              { return 0; }
        elsif(/^supressWarnings$/)          { return 0; }
        elsif(/^debugOutput$/)              { return 0; }
        elsif(/^outputBaseDir$/)            { return "."; }
        elsif(/^featureOutputDir$/)         { return ""; }
        elsif(/^modelOutputDir$/)           { return ""; }
        elsif(/^countOutputFile$/)          { return ""; }
        elsif(/^smoothedCountOutputFile$/)  { return ""; }
        elsif(/^probOutputFile$/)           { return ""; }
        elsif(/^zoeOutputFile$/)            { return ""; }
        elsif(/^xmlOutputFile$/)            { return ""; }
        elsif(/^blacklistOutputFile$/)      { return ""; }
        elsif(/^messageOutputFile$/)        { return ""; }
        elsif(/^warningOutputFile$/)        { return ""; }
        elsif(/^debugOutputFile$/)          { return ""; }
        elsif(/^sequenceNegInf$/)           { return -100; }
        elsif(/^durationNegInf$/)           { return -300; }
        elsif(/^scaleFactor$/)              { return 10;    }
        elsif(/^zoeCommentsAtEnd$/)         { return 0; }
        elsif(/^randomSeed$/)               { return time(); }
        elsif(/^nscanModel$/)               { return "R1"; }
        elsif(/^nscanTopology$/)            { return ""; }
        elsif(/^keepSSFiles$/)              { return 0;   }
        else                        { die "Unknown option: $option \n"; }
    }
}

sub AUTOLOAD {
    my $this = shift;
    my $member = our $AUTOLOAD;
    return if $member =~ /::DESTROY$/;
    $member =~ s/.*:://;

    if(scalar(@_)) {
        my $value = shift;
        if(defined($value) && $value =~ m/(true|false)/) {
            $value = ($value =~ m/true/) ? 1 : 0;
        }
        $this->{$member."_"} = $value;
    }
    else {
        return $this->{$member."_"} if defined $this->{$member."_"};
        return $this->default($member);
    }
}

sub handle_subelement {
    my ($this, $tag, $att, $data, $element) = @_;

    chomp($data);
    if($data =~ m/(true|false)/) { $data = ($data =~ m/true/) ? 1 : 0 }
    $this->{$tag."_"} = $data;
}
=back

=head1 SEE ALSO

L<iPE::XML::Object>

=head1 AUTHOR 

Bob Zimmermann (rpz@cse.wustl.edu).

=cut

1;
