#!/usr/bin/perl -w

use strict;
use Data::Dumper;

sub tst($) {
    my $str = shift;
    if ($str =~ m/^#/) { print "\n"; }
    print "$str\n";
}

my $ver = "";
my @text = (); # ( [ "T ...", text... ], ... )
my @comp = (); # ( [ "C ...", component_lines ], ... )
my @nets = (); # ( [ "N ..." ], ... )

my $state = "i";
my $tcnt = 0;

my $dbg = 0;

########################################

sub collect_line($) {
    my $str = shift;

    if ($str =~ m/^$/) {
	return;
    }

    if ($state eq "i") {
	if ($str =~ m/^v/) {
	    $ver = $str;
	    $state = "top";
	    return;
	} else {
	    warn("not a version line: <$str>");
	    exit;
	}
    }

    if ($state eq "top") {
	if ($str =~ m/^T .* (\d+)$/) {
	    push @text, [ $str ];
	    $tcnt = $1;
	    $state = "T";
	    return;
	}
	if ($str =~ m/^C /) {
	    push @comp, [ $str ];
	    $state = "C";
	    return;
	}
	if ($str =~ m/^N /) {
	    push @nets, $str;
	    return;
	}
    }

    if ($state eq "T") {
	push @{$text[$#text]}, $str;
	if (--$tcnt == 0) {
	    $state = "top";
	}
	return;
    }

    if ($state eq "C") {
	if ($str =~ m/^{$/) {
	    return;
	}
	if ($str =~ m/^}$/) {
	    $state = "top"; return;
	}
	push @{$comp[$#comp]}, $str;
	return;
    }
}

sub readin() {
    while (<>) {
	chomp;
	collect_line($_);
    }
}

########################################

sub pr_ver() {
    print $ver, "\n";
}

########################################

my $mx = 1000000000;
sub textindex($) {
    my $r = shift;
    my $str = $$r[0];
    my @fld = split(/ /, $str);
    if ($fld[9] eq "1" && $$r[1] =~ m/^[-A-Za-z]+=/) {
	# sort attributes first
	return sprintf "0%08d%08d", $fld[1], $mx - $fld[2];
    }
    sprintf "1%08d%08d", $fld[1], $mx - $fld[2];
}

sub pr_text() {
    #tst("### texts");
    for my $r (sort { textindex($a) <=> textindex($b) } @text) {
	#tst("");
	#print textindex($r), " ", $$r[0], "\n";
	for my $l (@$r) {
	    print $l, "\n";
	}
    }
}

########################################

sub compindex($) {
    my $r = shift;
    if ($$r[0] =~ m/ net.*\.sym$/) {
	# sort net symbols per position
	my @fld = split(/ /, $$r[0]);
	return sprintf "a%08d%08d", $fld[1], $mx - $fld[2];
    }
    for my $i (@$r) {
	if ($i =~ m/^refdes=([A-Za-z]+)(\d*)(.*)/) {
	    # sort components per refdes
	    return sprintf "b%5s%10d%s", $1, $2, $3;
	}
    }
}
my @atrorder = (qw| refdes device net value footprint |);
my %atrorder = ();
sub caindex($) {
    my $r = shift;
    my $str = $$r[0];
    my @fld = split(/ /, $str);
    if ($fld[9] eq "1" && $$r[1] =~ m/^([-A-Za-z]+)=/) {
	# sort attributes first
	my $n = $atrorder{$1};
	if (!defined($n)) { $n = @atrorder; }
	return sprintf "0%04d", $n;
    }
    sprintf "1%08d%08d", $fld[1], $mx - $fld[2];
}
sub pr_comp() {
    for (my $ix = 0; $ix < @atrorder; $ix++) {
	$atrorder{$atrorder[$ix]} = $ix;
    }

    #tst("### components");
    for my $r (sort { compindex($a) cmp compindex($b) } @comp) {
	#tst("");
	print shift @$r, "\n";
	print "{\n";
	$state = "top";
	$tcnt = 0;
	@text = ();
	$dbg = 1;
	for my $l (@$r) {
	    collect_line($l);
	}
	#print Dumper(@text);
	for my $r (sort { caindex($a) <=> caindex($b) } @text) {
	    for my $l (@$r) {
		print $l, "\n";
	    }
	}
	print "}\n";
    }
}

########################################

sub netindex($) {
    my $str = shift;
    my @fld = split(/ /, $str);
    sprintf "1%08d%08d", $fld[1], $mx - $fld[2];
}

sub pr_nets() {
    #tst("### Nets");
    for my $str (sort { netindex($a) <=> netindex($b) } @nets) {
	print $str, "\n";
    }
}

########################################

readin();
pr_ver();
pr_text();
pr_comp();
pr_nets();
