#!/usr/bin/perl 
use 5.010;
use strict ;
use warnings ; 
use List::Util qw/sum/;
use List::MoreUtils qw/pairwise/ ;
use Getopt::Std ; 
my %o ; getopts '=bx' , \%o ; 
use Term::ANSIColor qw/:constants color/ ; 
$Term::ANSIColor::AUTORESET = 1 ; 

$| = 1 ;

die YELLOW "You need to specify 4 file names " if ( $#ARGV < 3 ) ;
for ( @ARGV ) { 
#    die "File ",  BRIGHT_WHITE "$ARGV[0]" , RESET " does not exist," if ( ! -f $ARGV[0] ) ; 
}

# 4個のファイルをオープン
my @fh  ;
for  ( @ARGV[0..3] ) { 
    open my $fh , "<" , $_ or die YELLOW $_ , RESET " ? : ",  $! ; 
    push @fh , $fh 
}

# 主要な集計処理部分
my @kc = map { & kcstore ( $_ ) } @fh  ;  # キーを各ファイルで読み取って配列にしたものの参照の、配列。
my ($B,%kcw)=1 ; for ( @kc ) { for ( @{$_} ) { $kcw{$_}+= $B }  $B *= 2 } # kcw に各キーがどのファイルに現れたかをビットパターンで記録。
my @bcount = (0) x 16 ; for ( values %kcw ) { $bcount[$_] ++ } # 各ビットパターンを表す数が何度出現したかを記録。

# 第一表示
grep {print ON_WHITE BLACK sprintf("%8s",$_) }  (qq//,qw/AB=00 AB=10 AB=11 AB=01/) ;
print "\n" ;
my @rnames  = qw/CD=00 CD=10 CD=11 CD=01/ ;
for my $L (0,1,3,2) { 
    print ON_WHITE BLACK sprintf"%8s",(shift @rnames) ; 
    for my $C (0,1,3,2) { 
    print sprintf("%8d",$bcount[$C+$L*4]) ;
    }
    print "\n" ;
}

exit if ! $o{x} ;

my @abCond = qw/AB=00 AB=10 AB=11 AB=01 A=0 A=1 B=0 B=1 A+B>0 any/ ; 
my @cdCond = qw/CD=00 CD=10 CD=11 CD=01 C=0 C=1 D=0 D=1 C+D>0 any/ ; 
my @dd = ([0],[1],[3],[2],[0,2],[1,3],[0,1],[2,3],[1,2,3],[1,2,3,0]) ;

grep {print ON_WHITE BLUE sprintf("%8s",$_) }  (qq//,@abCond) ; 
print "\n" ;
for my $LL ( @dd ) { 
    print ON_WHITE BLUE sprintf"%8s",(shift @cdCond) ; 
    for my $RR ( @dd ) { 
    print WHITE ON_BLACK sprintf "%8d" , sum map {my $t=$_ ; sum map {$bcount[$t+4*$_]} @$LL } @$RR 
    }
    print "\n" ;
}

sub kcstore { 
    my %kc ; 
    my $fh = $_[0] ;
    while ( <$fh>  ) {
    next if ( $. == 1 && $o{"="} ) ; 
    chomp ; 
    next if ( $_ eq q// && $o{b} ) ;
    s/\r$// ; 
    $kc{$_} ++ ; 
    }
    return \@{[ keys %kc ]} ; 
}

# クローズ
grep { close $_ } grep { $_ } @fh ;



# ヘルプの扱い
sub VERSION_MESSAGE {}
sub HELP_MESSAGE {
    use FindBin qw[ $Script ] ; 
    $ARGV[1] //= '' ;
    open my $FH , '<' , $0 ;
    while(<$FH>){
        s/\$0/$Script/g ;
        print $_ if s/^=head1// .. s/^=cut// and $ARGV[1] =~ /^o(p(t(i(o(ns?)?)?)?)?)?$/i ? m/^\s+\-/ : 1;
    }
    close $FH ;
    exit 0 ;
}
=encoding utf8
=head1

  $0  file1 file2 file3 file4 

    Performs similar things to draw the venn diagram for 4 sets. 
    Each file given is regarded as a set that consists of 
    the elements; an element is a character string separated by
    line ending characters.  The venn diagram can be drawn 
    using 4 rectangles or 4 ovals so this program utilizes this 
    mathematical theorem.

   Options : 
     -= : skip reading the first line of every 4 files.
     -b : skip blank lines.
     -x : Also adds 10 x 10 table to the ouput. You can easily understand it.
     
=cut
