#!/usr/bin/env perl

use strict;
use warnings;
use feature qw/state say/;
use 5.010;

use Getopt::Declare;
use Finnigan;


@ARGV == 1 or do {
  say STDERR "Usage: $0 <file>";
  exit -1;
};
my $file = $ARGV[0];
-e $file or do {
  say STDERR "file '$file' does not exist";
  exit -1;
};
-f $file or do {
  say STDERR "'$file' is not a plain file";
  exit -1;
};
-s $file or do {
  say STDERR "'$file' has zero size";
  exit -1;
};

# -----------------------------------------------------------------------------
open INPUT, "<$file" or die "can't open '$file': $!";
binmode INPUT;

my $header = Finnigan::FileHeader->decode(\*INPUT);
my $seq_row = Finnigan::SeqRow->decode(\*INPUT, $header->version);
my $cas_info = Finnigan::CASInfo->decode(\*INPUT);
my $rfi = Finnigan::RawFileInfo->decode(\*INPUT, $header->version);

my $run_header_addr = $rfi->preamble->run_header_addr;

# fast-forward to RunHeader
seek INPUT, $run_header_addr, 0;
my $run_header = Finnigan::RunHeader->decode(\*INPUT, $header->version);

# skip to the error log and read through
seek INPUT, $run_header->error_log_addr, 0;
my $error_log_length = Finnigan::Decoder->read(\*INPUT, ['length' => ['V', 'UInt32']])->{data}->{length}->{value};
foreach my $i ( 0 .. $error_log_length - 1) {
  Finnigan::Error->decode(\*INPUT);
}

# read through the scan event hierarchy
my $nsegs = Finnigan::Decoder->read(\*INPUT, ['nsegs' => ['V', 'UInt32']])->{data}->{nsegs}->{value};
foreach my $i ( 0 .. $nsegs - 1) {
  my $n = Finnigan::Decoder->read(\*INPUT, ['n' => ['V', 'UInt32']])->{data}->{n}->{value};
  foreach my $j ( 0 .. $n - 1) {
    my $e = Finnigan::ScanEventTemplate->decode(\*INPUT, $header->version);
    say "($i, $j)";
    $e->dump();
    say join " ", $e->preamble->list('decode');
    say "--------";
  }
}

__END__
=head1 NAME

uf-segments - dump the scan event hirerarchy of a Finnigan raw file

=head1 SYNOPSIS

uf-segments <file>

=head1 OPTIONS

=over 4

None

=back

=head1 DESCRIPTION

This is a very rough-and-ready means to examine the scan hierarchy in
a Finnigan raw file. All ScanEventTemplate structures are dumped to
STDIN, prepended with their segment and scan event numbers.

=head1 SEE ALSO

Finnigan::ScanEventTemplate

=cut
