package EnsEMBL::Web::Text::FeatureParser::GBrowse;

=head1 NAME

EnsEMBL::Web::Text::FeatureParser::GBrowse;

=head1 SYNOPSIS

This object parses data supplied by the user in BED format and identifies sequence locations for use by other Ensembl objects

=head1 DESCRIPTION

    my $parser = EnsEMBL::Web::Text::FeatureParser->new();
    $parser->init($data);
    $parser->parse($data);

=head1 LICENCE

This code is distributed under an Apache style licence:
Please see http://www.ensembl.org/code_licence.html for details

=head1 CONTACT

=cut

use strict;
use warnings;
use EnsEMBL::Web::Text::FeatureParser;
use EnsEMBL::Web::Text::Feature::GBrowse;
use Data::Dumper;

our @ISA = qw(EnsEMBL::Web::Text::FeatureParser);

#----------------------------------------------------------------------

=head2 parse_row

    Arg [1]   :  
    Function  : Parses an individual row of data, i.e. a single feature
    Returntype: 
    Exceptions: 
    Caller    : 
    Example   : 

=cut

sub parse_row {
    my( $self, $row, $format ) = @_;
    return if ($row =~ /^\#/);
    $row =~ s/[\t\r\s]+$//g;
    return unless $row;
    if( $row =~ /^browser\s+(\w+)\s+(.*)/i ) {
	$self->{'browser_switches'}{$1}=$2;     
    }   elsif ($row =~ s/^track\s+(.*)$/$1/i) {
	my %config;
	while( $row ne '' ) {
	    if( $row =~ s/^(\w+)\s*=\s*\"([^\"]+)\"// ) {  
                my $key   = $1;
                my $value = $2;
                while( $value =~ s/\\$// && $row ne '') {
		    if( $row =~ s/^([^\"]+)\"\s*// ) {
			$value .= "\"$1";
		    } else {
			$value .= "\"$row"; 
			$row = '';
		    }
		}
		$row =~ s/^\s*//;
                $config{$key} = $value;
	    } elsif( $row =~ s/(\w+)\s*=\s*(\S+)\s*// ) {
                $config{$1} = $2;
            } else {
                $row ='';
            }
	}
	$config{'name'} ||= 'default';
        my $current_key = $config{'name'}; # || 'default';
        $self->{'tracks'}{ $current_key } = { 'features' => [], 'config' => \%config };
        $self->{'_current_key'} = $current_key;
    } else {
	my $current_key = $self->{'_current_key'} ; 

	if ($row =~ /\[(\w+)\]/) {
	    my $wigConfig = {
		'data' => 'style',
		'name' => $1,
	    };

	    $self->{'tracks'}{ $current_key }->{'mode'} = $wigConfig;
        } elsif ($row =~ /^reference(\s+)?=(\s+)?(.+)/i) {
	    my $wigConfig = {
		'data' => 'features',
		'name' => $3,
	    };
	    if ($wigConfig->{'name'} =~ /^ENSP/) {
		$self->{'tracks'}{ $current_key }->{'config'}->{'coordinate_system'} = 'ProteinFeature';
	    } else {
		$self->{'tracks'}{ $current_key }->{'config'}->{'coordinate_system'} = 'DnaAlignFeature';
	    }
	    $self->{'tracks'}{ $current_key }->{'mode'} = $wigConfig;
	} else {
	    my $wigConfig = $self->{'tracks'}{ $current_key }->{'mode'};
	    if (my $action = $wigConfig->{data}) {
		if ($action eq 'style') {
		    my $tname = $wigConfig->{name}; 
		    if (my @sdata = split /\=/, $row ) {
			$self->{'tracks'}{ $current_key }->{'styles'}->{$tname}->{$sdata[0]} = $sdata[1];
		    }
		} elsif ($action eq 'features') {
		    my @fields;
		    if (my @fields_with_spaces = ($row =~ m/\"([^\"]*)\"/g)) {
			$row =~ s/\"[^\"]*\"/___/g;
			@fields = split /\s+|\t/, $row;
			for (my $i=0; $i<=$#fields; $i++) {
			    if ($fields[$i] eq '___') {
				$fields[$i] = shift @fields_with_spaces;
			    }
			}
		    } else {
			@fields = split /\s+|\t/, $row;
		    }

		    my ($ftype, $fname, $fpos, $fdesc, $flink) = @fields;
		    my $fscore;

		    if ($fdesc && ($fdesc =~ /score=(\w+)/)) {
			$fscore = $1;
		    }

		    my @fparts = $fpos ? split /\,/, $fpos : ();
		    foreach my $fpart (@fparts) {
			my ($fstart, $fend) = ($fpart=~/\.\./) ? split /\.\./, $fpart : split /\-/, $fpart;
			my $fstrand = ($fstart > $fend) ? -1 : 1;

			$self->store_feature( $current_key , EnsEMBL::Web::Text::Feature::GBrowse->new( [$wigConfig->{'name'}, $fstart, $fend, $fstrand, $fname, $fscore, $ftype, $fdesc, $flink]));
		    }
		}
	    }
	}
    } 
}

1;