#
#	pajekのネットワークファイル（.netファイル）を名前でソート
#		author	shinsuke-m
#		date	
#
#		◇入力
#		       .netファイル
#		◇出力
#		       ソート済み.netファイル
#                      ファイル名は 入力名_sort.net
#
#		◇使用法
#			コマンドラインで、以下のコマンドをたたく(要 Perl 5 以上)
#			perl renumbering.pl data1.net
#
#			

my @resultArcs;
my @resultVert;

&readfile;
&renumbering;
&writefile;

# 2ネットワークのマージング
sub readfile {
    open NET2, $ARGV[0] or die "file open error : $ARGV[0]";
    $line2 = <NET2>;
    while($line2 = <NET2>) {
        if($line2 =~ /^\*Arcs/) {
            last;
        }
        push(@resultVert, $line2);
        $vertMax = $vertMax+1;
    }
    #print @resultVert, "\n--------\n";

    while($line2 = <NET2>) {
        push(@resultArcs, $line2);
    }
    #print @resultArcs, "\n--------\n";
}




# 名前でソートしてrenumbering
sub renumbering {
    my @tmp;

    # 名前順でソート
    orderByArrayStr(\@resultVert, 1, 'ASC');

    # verticies の全探索
    for ($i = 1; $i <= $#resultVert+1; $i++) {
        my($number, $name) = split / /, @resultVert[$i-1];

        @resultVert[$i-1] = "$i $name";

        for ($j = 0; $j <= $#resultArcs; $j++) {
            my($no1, $no2, $val) = split / /, @resultArcs[$j];
            #print "|",$no1, " ", $no2, " ", $number, " ", $i, ":", $val;

            # arcs 側の置換（重複回避のための _ を追記）
            if (($no1 eq $number) and ($no2 eq $number)) {
                @resultArcs[$j] = "_$i _$i $val";
            }
            elsif ($no1 eq $number) {
                @resultArcs[$j] = "_$i $no2 $val";
            }
            elsif ($no2 eq $number) {
                @resultArcs[$j] = "$no1 _$i $val";
            }
        }
    }  
    # _ のトリミング
    for ($i = 0; $i <= $#resultArcs; $i++) {
        @resultArcs[$i] =~ tr/_//d;
    }

    # arcs のソート
    orderByArrayNum(\@resultArcs, 1, 'ASC');
    orderByArrayNum(\@resultArcs, 0, 'ASC');
}

#----------------------
#数値ソート
#----------------------
sub orderByArrayNum{
  my $data = shift;      #配列の参照
  my $key = shift || 0;    #ソートするキー
  my $set = shift || 'DESC';  #昇順or降順
  my @tmp = ();
  
  #-- 一時配列にキーを取り出す --#
  @tmp = map {(split / /)[$key]} @$data;

  #-- ソート開始 --#
  if( $set eq 'ASC' ){
    @$data = @$data[sort {$tmp[$a] <=> $tmp[$b]} 0 .. $#tmp];
  }
  else{
    @$data = @$data[sort {$tmp[$b] <=> $tmp[$a]} 0 .. $#tmp];
  }

}


#----------------------
#文字列ソート
#----------------------
sub orderByArrayStr{
  my $data = shift;      #配列の参照
  my $key = shift || 0;    #ソートするキー
  my $set = shift || 'DESC';  #昇順or降順
  my @tmp = ();
  
  #-- 一時配列にキーを取り出す --#
  @tmp = map {(split / /)[$key]} @$data;

  #-- ソート開始 --#
  if( $set eq 'ASC' ){
    @$data = @$data[sort {$tmp[$a] cmp $tmp[$b]} 0 .. $#tmp];
  }
  else{
    @$data = @$data[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];
  }
}


#----------------------

sub writefile {

    $filename = $ARGV[0];
    $filename =~ s/\./_sort./s;
    open DATA, ">$filename" or die "cannot open savefile.";
    $fh = DATA;
    $max = $#resultVert+1;
    print $fh "*Vertices $max\n", @resultVert;
    print $fh "*Arcs\n", @resultArcs;
}
