# $Id: Mrp.pm 843 2009-03-04 23:50:27Z rvos $
package Bio::Phylo::Unparsers::Mrp;
use strict;
use Bio::Phylo::IO;
use vars qw(@ISA);
@ISA=qw(Bio::Phylo::IO);

=head1 NAME

Bio::Phylo::Unparsers::Mrp - Serializer used by Bio::Phylo::IO, no serviceable parts inside

=head1 DESCRIPTION

This module turns a L<Bio::Phylo::Forest> object into an MRP nexus
formatted matrix. It is called by the L<Bio::Phylo::IO> facade, don't call it
directly.

=begin comment

 Type    : Constructor
 Title   : _new
 Usage   : my $mrp = Bio::Phylo::Unparsers::Mrp->_new;
 Function: Initializes a Bio::Phylo::Unparsers::Mrp object.
 Returns : A Bio::Phylo::Unparsers::Mrp object.
 Args    : none.

=end comment

=cut

sub _new {
    my $class = shift;
    my $self  = {};
    if (@_) {
        my %opts = @_;
        foreach my $key ( keys %opts ) {
            my $localkey = uc $key;
            $localkey =~ s/-//;
            unless ( ref $opts{$key} ) {
                $self->{$localkey} = uc $opts{$key};
            }
            else {
                $self->{$localkey} = $opts{$key};
            }
        }
    }
    bless $self, $class;
    return $self;
}

=begin comment

 Type    : Wrapper
 Title   : _to_string
 Usage   : my $mrp_string = $mrp->_to_string;
 Function: Stringifies a matrix object into
           an MRP nexus formatted table.
 Alias   :
 Returns : SCALAR
 Args    : Bio::Phylo::Matrices::Matrix;

=end comment

=cut

sub _to_string {
    my $self   = shift;
    my $forest = $self->{'PHYLO'};
    my $string = "BEGIN DATA;\n[! Data block written by " . ref $self;
    $string .= " " . $self->VERSION . " on " . localtime() . " ]\n";
    my $taxa = $forest->make_taxa;
    my $ntax = scalar @{ $taxa->get_entities } + 1;    # + 1 for mrp_outgroup
    $string .= "    DIMENSIONS NTAX=$ntax ";
    my $nchar = 0;

    foreach my $tree ( @{ $forest->get_entities } ) {
        foreach my $node ( @{ $tree->get_internals } ) {
            $nchar++;
        }
    }
    $string .= "NCHAR=$nchar;\n";
    $string .= "    FORMAT DATATYPE=STANDARD MISSING=?;\n    MATRIX\n";
    my $length = length('mrp_outgroup');
    foreach my $taxon ( @{ $taxa->get_entities } ) {
        $length = length( $taxon->get_name )
          if length( $taxon->get_name ) > $length;
    }
    $length += 4;
    my $sp = ' ';
    my %mrp;
    foreach my $tree ( @{ $forest->get_entities } ) {
        my %in_tree = map { $_->get_taxon => 1 } @{ $tree->get_terminals };
        my $n = scalar @{ $tree->get_internals };
        foreach my $t ( @{ $taxa->get_entities } ) {
            $mrp{$t} = ( $sp x ( $length - length( $t->get_name ) ) )
              if !defined $mrp{$t};
            if ( exists $in_tree{$t} ) {
                foreach my $node ( @{ $tree->get_internals } ) {
                    my %in_clade =
                      map { $_->get_taxon => 1 } @{ $node->get_terminals };
                    if ( exists $in_clade{$t} ) {
                        $mrp{$t} .= '1';
                    }
                    else {
                        $mrp{$t} .= '0';
                    }
                }
            }
            else {
                $mrp{$t} .= '?' x $n;
            }
        }
    }
    $string .=
      '        mrp_outgroup' . ( $sp x ( $length - length('mrp_outgroup') ) );
    $string .= ( '0' x $nchar ) . "\n";
    foreach my $taxon ( @{ $taxa->get_entities } ) {
        $string .= '        ' . $taxon->get_name;
        $string .= $mrp{$taxon} . "\n";
    }
    $string .= "    ;\nEND;\n";
    return $string;
}

# podinherit_insert_token
# podinherit_start_token_do_not_remove
# AUTOGENERATED pod created by /Users/rvosa/Applications/podinherit on Wed Mar  4 17:13:58 2009
# DO NOT EDIT the code below, rerun /Users/rvosa/Applications/podinherit instead.

=pod

=head1 INHERITED METHODS

Bio::Phylo::Unparsers::Mrp inherits from one or more superclasses. This means that objects of 
class Bio::Phylo::Unparsers::Mrp also "do" the methods from the superclasses in addition to the 
ones implemented in this class. Below is the documentation for those additional 
methods, organized by superclass.

=head2 SUPERCLASS Bio::Phylo::IO

Bio::Phylo::Unparsers::Mrp inherits from superclass L<Bio::Phylo::IO>. 
Below are the public methods (if any) from this superclass.

=over

=item parse()

Parses a file or string.

 Type    : Class method
 Title   : parse
 Usage   : my $obj = Bio::Phylo::IO->parse(%options);
 Function: Creates (file) handle, 
           instantiates appropriate parser.
 Returns : A Bio::Phylo::* object
 Args    : -file    => (path),
            or
           -string  => (scalar),
           -format  => (description format),
           -(other) => (parser specific options)
 Comments: The parse method makes assumptions about 
           the capabilities of Bio::Phylo::Parsers::* 
           modules: i) their names match those of the
           -format => (blah) arguments, insofar that 
           ucfirst(blah) . '.pm' is an existing module; 
           ii) the modules implement a _from_handle, 
           or a _from_string method. Exceptions are 
           thrown if either assumption is violated. 
           
           If @ARGV contains even key/value pairs such
           as "format newick file <filename>" (note: no
           dashes) these will be prepended to @_, for
           one-liners.          

=item unparse()

Unparses object(s) to a string.

 Type    : Class method
 Title   : unparse
 Usage   : my $string = Bio::Phylo::IO->unparse(
               %options
           );
 Function: Turns Bio::Phylo object into a 
           string according to specified format.
 Returns : SCALAR
 Args    : -phylo   => (Bio::Phylo object),
           -format  => (description format),
           -(other) => (parser specific options)

=back

=cut

# podinherit_stop_token_do_not_remove

=head1 SEE ALSO

=over

=item L<Bio::Phylo::IO>

The newick unparser is called by the L<Bio::Phylo::IO> object.
Look there to learn how to create mrp matrices.

=item L<Bio::Phylo::Manual>

Also see the manual: L<Bio::Phylo::Manual> and L<http://rutgervos.blogspot.com>.

=back

=head1 REVISION

 $Id: Mrp.pm 843 2009-03-04 23:50:27Z rvos $

=cut

1;
