#get some information and print out the table (in LaTex)
#for algorithm 2

open(FACTORS,"factors");
my @data = <FACTORS>;
close(FACTORS);

my $n = scalar(@data);

my @factors;
my @types;
my @levels;
my %values;
for(my $i=0;$i<$n-1;$i++){
	chomp $data[$i];
	my @this = split(/\t/,$data[$i]);
	push @factors,$this[0];
	push @types,$this[1];
	$values{$this[0]} = $this[2];
	push @levels,$this[3];
}
my @justlevels = ();
foreach my $i (@levels){
	push @justlevels,substr($i,0,1);
}

my %error;
chomp $data[$n-1];
my @v = split(/\t/,$data[$n-1]);
$error{"value"} = $v[2];
$error{"level"} = $v[3];
$error{"type"}  = $v[1];

sub getFactor {
	my ($factor) = @_;
	
	for(my $i=0;$i<@justlevels;$i++){
		if($justlevels[$i] eq $factor){
			return($factors[$i]);
		}
	}

}

sub df {
	my ($subsc) = @_;
	#my %val = $_[1];
	my $n = length($subsc);
	my $dfn = 1;
	my $dfs = '';

	my $open = index($subsc,"(");
	my $close = index($subsc,")");

	for(my $i = 0;$i<$n;$i++){
		if((substr($subsc,$i,1) ne " ")&&(substr($subsc,$i,1) ne "(")&&(substr($subsc,$i,1) ne ")")){
			my $l = substr($subsc,$i,1);
		
			if($values{ getFactor($l) } !~ m/\D/){
				if(( index($subsc,$l) >= $open )&&( index($subsc,$l) <= $close )){
					$dfn *= $values{ getFactor($l) };
				}else{
					$dfn *= $values{ getFactor($l) } - 1;
				}
			}else{
				$dfs .= "($values{$l}-1)";
			}
		}
	}

	if( $dfn < 0 ){
		$dfn *= -1;
	}

	my $df = $dfn . $dfs;
	if((substr($df,0,1) == 1)&&(length($df) > 1)){
		substr($df,0,1) = '';
	}

	return $df;
}

sub combineParen {
	my ($str) = @_;

	my $fparen = index($str,"(");
	my $sparen = rindex($str,"(");

	if( $fparen == $sparen ){
		return($str);
	}

	my $endfparen = index($str,")");
	my $endsparen = rindex($str,")");

	my $infirstparen = substr($str,$fparen + 1,$endfparen - $fparen - 1);
	my $insecondparen = substr($str,$sparen + 1,length($str) - $sparen - 2);

	#print "$str";

	substr($str,$sparen,$endsparen - $sparen + 1) = '';

	for(my $i=0;$i<length($insecondparen);$i++){
		my $cletter = substr($insecondparen,$i,1);
		if( index($infirstparen,$cletter) < 0 ){
			substr($str,$endfparen - 1,1) = substr($str,$endfparen - 1,1) . $cletter;
			$endfparen = index($str,")");
		}
		#print "$str\t$cletter\t$endfparen\n";
	}

	my $secondendfparen = rindex($str,")");
	if( $endfparen != $secondendfparen ){
		substr($str,$endfparen,1) = '';
	}

	#print "\t$infirstparen\t$insecondparen\t$str";
	#print "\t$str\n";

	return($str);
}

sub parenToEnd {
	my ($str) = @_;

	$str = combineParen($str);

	#print "$str";

	my $start = index($str,"(");
	my $end = index($str,")");

	#exit if already at the end
	if(( $end == length($str) - 1 )||( $start == -1 )){
		return($str);
	}

	my $pre = substr($str,0,$start);
	my $inside = substr($str,$start,$end - $start + 1);
	my $post = substr($str,$end + 1,length($str) - $end + 1);

	#print "$str\t$start\t$end\t$pre\t$inside\t$post";

	if( $start >= 0 ){
		$str = $pre . $post . $inside;
	}
	
	#print "\t$str\n";

	return($str);
}

my @interactions = ();
foreach my $i (@factors){
	push @interactions,$i;
	my @temp = ();
	for(my $j=scalar(@interactions)-1;$j>0;$j--){
		#push @interactions,($i . $interactions[$j-1]);
		push @temp,($i . $interactions[$j-1]);
	}
	push @interactions,reverse @temp;
}

my @subscripts = ();
foreach my $i (@interactions){
	my $temp;
	for(my $j=0;$j<@factors;$j++){
		if( index($i,$factors[$j]) >= 0 ){
			$temp .= $levels[$j];
		}
	}
	$temp = parenToEnd($temp);
	push @subscripts,$temp;
}

my $header = "& df ";
for(my $i=0;$i<@types;$i++){
	$header .= "& $types[$i]/$justlevels[$i]";
}
$header .= "&" . $error{"type"}. "/" . $error{"level"} . "&EMS\\\\ \\hline \n";

my $amp = '&' x ($n);
my $col = 'l' x ($n+4);

open(OUT,">htout.tex");
#print OUT "\\begin{center}\n";
#print OUT "\\begin{tabular}{$col}\n";
print OUT "$header";

sub indexTwice {
	my ($str) = @_;
	my ($idx,$nested) = split(/\(/,$str);
	chop $nested;

	for(my $i=0;$i<length($str);$i++){
		my $letter = substr($str,$i,1);
		if( index($str,$letter,$i + 1) > -1 ){
			return(0);
		}
	}

	return(1);
}

sub sortString {
	my $str = $_[0];
	my @tmp = ();
	for(my $i=0;$i<length($str);$i++){
		push @tmp,substr($str,$i,1);
	}
	@tmp = sort @tmp;
	$str = '';
	foreach my $i (@tmp){
		$str .= $i;
	}
	$str =~ s/\s+//g;
	return($str);
}

sub getThisIdx {
	my $idx = $_[0];

	if( index($idx,"(") > -1 ){
		substr($idx,index($idx,"("),1) = '';
		substr($idx,index($idx,")"),1) = '';
	}

	$idx = sortString($idx);

	return($idx);
}

my $c = 0;
foreach my $i (@interactions){
	if( indexTwice($subscripts[$c]) == 1 ){
		$interactions[$c] = reverse($i);
		print OUT "\$$interactions[$c]_{$subscripts[$c]}\$ &" . df($subscripts[$c]);
		#print "$interactions[$c]\t$subscripts[$c]\n";
		for(my $j=0;$j<@levels;$j++){
			#print "$subscripts[$c]\t$justlevels[$j]\t";

			my $open = index($subscripts[$c],"(");
			my $close = index($subscripts[$c],")");

			my $idx = index($subscripts[$c],$justlevels[$j]);

			#print "$open\t$idx\t$close\n";

			if(( $open >= 0 )&&( $idx >= $open )&&( $idx <= $close )){
				print OUT "& 1";
			}elsif( $idx >= 0 ){
				if( $types[$j] eq 'F' ){
					print OUT "& 0";
				}elsif( $types[$j] eq 'R' ){
					print OUT "& 1";
				}
			}else{
				print OUT "&$values{$factors[$j]}";
			}
		}
		print OUT "&",$error{"value"};
		print OUT "\\\\\n";
	}
	$c++;
}

my $errsubsc = $error{"level"} . "(@justlevels)";
print OUT "\$\\varepsilon_{$errsubsc}\$&",df($errsubsc);
for(my $j=0;$j<@levels;$j++){
	print OUT "& 1";
}
print OUT "&",1,"\n";

#print OUT "\\end{tabular}\n";
#print OUT "\\end{center}\n";
close OUT;

