#!/usr/bin/perl -w

use strict;
use Getopt::Long;

my ($width, $upcase);
if (!GetOptions('n=i' => \$width,
                'upcase' => \$upcase) ||
    !defined($width)  ||  @ARGV == 0) {
    print "usage: fa_wrap -n <max width of line> [-upcase] <fa-file> \n\n";
    exit 1;
}

open INFILE, $ARGV[0];
my $buff = '';
my $inHeader = 0;
do {
    read(INFILE, $buff, 1000000, length($buff));
    if (defined $upcase) {
        $buff = uc $buff;
    }
    my @splits = split /(>)/, $buff;
    $buff = '';
    my $i = 0;
    foreach my $seq (@splits) {
        ++$i;
        if ($seq eq '>') {
            print ">";
            $inHeader = 1;
            next;
        }
        if ($inHeader) {
            my ($header, $nl);
            ($header, $seq) = split /\n/, $seq, 2;
            print $header;
            if (!defined $seq) {
                next;
            }
            print "\n";
            $inHeader = 0;
        }
        if (!defined($seq)) {
            print $i, "\n";
            die;
        }
        $seq =~ s/\n//g;
        my $start;
        my $end = ($i == @splits) ? length($seq) - $width : length($seq);
        for ($start = 0;  $start < $end;  $start += $width) {
            print substr($seq, $start, $width), "\n";
        }
        #handle any trailing seq
        if ($i == @splits) {
            $buff = substr($seq, $start, $width);
        }
    }
} while (!eof(INFILE));
print $buff, "\n";
close INFILE;
exit 0;

#below definitely works; above is newer & faster but relatively untested

my $remainder = '';
while (<>) {
    if (/^>/) {
        print $remainder, "\n" if $remainder ne '';
        $remainder = '';
        print $_;
    } else {
        chomp;
        $_ = $remainder.$_;
        if (length($_) > $width) {
            do {
                print substr($_, 0, $width), "\n";
                $_ = substr($_, $width);
            } while (length($_) > $width);
            $remainder = $_;
        } else {
            print $_, "\n";
            $remainder = '';
        }
    }
}
print $remainder, "\n" if $remainder ne '';
