#!/usr/bin/perl -w

use warnings;
use strict;
use File::Find::Rule;
use lib ".";
use FunctionParsing;

=pod
Usage:
perl ptex.pl < source.ptex > destination.tex
=cut

my $ptexStartKeyword = "!PTEX-START";
my $ptexInterfaceKeyword = "!PTEX-START-INTERFACE";
my $ptexEndKeyword = "!PTEX-END";
my $ptexThisClassKeyword="!PTEX_THISCLASS";
my $ptexThisFunctionKeyword="!PTEX_THISFUNCTION";
my $ptexRefKeyword="!PTEX_REF";
my $ptexLabelKeyword="!PTEX_LABEL";

my %GlobalMacros=();
my %GlobalRefs=();
my $GlobalPtexOpen=0;
my $GlobalLabel="";
my $GlobalBuffer="";
my $GlobalIsInterface;

print STDERR "$0: This script is deprecated, please use PsimagDoc found also in this repository\n";

loadMacros(0);
loadMacros(1);

printHeader();
replaceMacros();

sub replaceMacros
{
	while(<STDIN>) {
		
		next if (/\\newcommand\{\\ptex/);

		if (/\\ptexPaste\{([^\}]+)\}/) {
			my $x = $GlobalMacros{$1};
			die "Undefined macro for label $1, line $.\n" if (!defined($x));
			my %xx = %$x;
			my $data = $xx{"data"};
			die "Undefined macro for label $1\n" if (!defined($data));
			s/\\ptexPaste\{([^\}]+)\}/$data/;
		}

		if (/\\ptexLabel\{([^\}]+)\}/) {
			die "Undefined ref for label $1\n" if (!defined($GlobalRefs{$1}));
			s/\\ptexLabel\{([^\}]+)\}/$GlobalRefs{$1}/g;
			print;
		}
		
		
		if (/\\ptexInterface\{([^\}]+)\}/) {
			printInterface($1);
			next;
		}

		if (/\\ptexReadFileVerbatim\{([^\}]+)\}/) {
			readFileVerbatim($1);
			next;
		}

		if (/\\ptexReadFile\{([^\}]+)\}/) {
			readFile($1);
			next;
		}
		next if (/\!PTEX\-/);
		print;
	}
}

sub printHeader
{
my $date=`date`;
chomp($date);
print<<EOF;
%DO NOT edit this file
%Changes will be lost next time you run $0
%Created by $0 by G.A.
%$date
EOF
}


sub loadMacros
{
	my ($passNumber)=@_;
	my @files = File::Find::Rule->file()->name("*.h")
                                ->in("../src");
	foreach my $file (@files) {
		procThisFile($file,$passNumber);
		procThisFile($file,$passNumber+10);
	}
}

sub procThisFile
{
	my ($file,$passNumber)=@_;
	$GlobalPtexOpen=0;
	$GlobalLabel="";
	$GlobalBuffer="";
	$GlobalIsInterface = 0;
	open(FILE, "<", $file) or die "Cannot open file $file: $!\n";
	while(<FILE>) {
		procThisLine($_,$file,$passNumber);
	}
	close(FILE);
}

sub procThisLine
{
	my ($line,$file,$passNumber)=@_;
	my $class = removeTrailingDirs($file);
	
	if ($passNumber==0) {
		if ($line=~/$ptexLabelKeyword\{([^\}]+)\}/) {
			my $tmp = $1;
			$GlobalRefs{$tmp}=removeTrailingDirs("$file:$.");
		}
		return;
	}

	if ($GlobalPtexOpen) {
		if ($line=~/$ptexRefKeyword\{([^\}]+)\}/) {
			$GlobalRefs{"HERE"} = removeTrailingDirs("$file:$.");
			
			die "Undefined reference $1\n" if (!defined($GlobalRefs{$1}));
		}
		$line=~s/$ptexRefKeyword\{([^\}]+)\}/\\verb!$GlobalRefs{$1}!/g;

		$line=~s/$ptexThisClassKeyword/$class/g;
		if ($line=~/$ptexEndKeyword/) {
			$GlobalPtexOpen=0;
			
			my $xy;
			$xy = getFunctionName() if ($passNumber>9);
			$xy = "UNDEFINED" if (!defined($xy));
			if ($xy eq "UNDEFINED") {
				my %x = (
					data => $GlobalBuffer,
					file => $file,
					line => $line,
					isInterface => $GlobalIsInterface,
				);
				$GlobalMacros{"$GlobalLabel"}= \%x;
			} else {
# 				print STDERR "Here\n";
				my $x = $GlobalMacros{"$GlobalLabel"};
				if (defined($x)) {
					my %xx = %$x;
					$xx{"function"}=$xy;
					$xx{"data"} =~ s/$ptexThisFunctionKeyword/$xy/;
					%$x=%xx;
				}
				#$GlobalMacros{"$GlobalLabel"} = \%xx;
			}

# 			print STDERR "Macro found for $GlobalLabel\n";
			$GlobalBuffer="";
			return;
		}
		$GlobalBuffer .= $line;
		return;
	}

	if ($line=~/$ptexStartKeyword +(.*$)/) {
		$GlobalLabel = $1;
# 		print STDERR "GL=$1\n";
		$GlobalLabel=~s/ //g;
		die "Empty level on line $.\n" if ($GlobalLabel eq "");
		$GlobalPtexOpen=1;
		$GlobalBuffer="";
		$GlobalIsInterface=0;
	}
	if ($line=~/$ptexInterfaceKeyword +(.*$)/) {
		$GlobalLabel = $1;
# 		print STDERR "GL=$1\n";
		$GlobalLabel=~s/ //g;
		die "Empty level on line $.\n" if ($GlobalLabel eq "");
		$GlobalPtexOpen=1;
		$GlobalBuffer="";
		$GlobalIsInterface=1;
	}
}

sub removeTrailingDirs
{
	my ($x)=@_;
	if ($x=~/\/([^\/]+$)/) {
		$x = $1;
	}
	$x=~s/\.h$//;
	return $x;
}

sub printInterface
{
	my ($thisClass)=@_;
	foreach (keys %GlobalMacros) {
		my $x = $GlobalMacros{$_};
		my %xx = %$x;
		
		my $if = $xx{"isInterface"};
# print STDERR $xx{"file"}." "."$_ $if\n";
		next if (!$if);
		my $class = removeTrailingDirs($xx{"file"});
		next unless ($class eq $thisClass);
		print $xx{"data"};
		print "\n";
	}
}

sub readFileVerbatim
{
	my ($f)=@_;
	print "\\begin{verbatim}\n";
	readFile($f);
	print "\\end{verbatim}\n";
}

sub readFile
{
	my ($f)=@_;
	open(OTHERFILE, "<", $f) or die "Cannot open file $f: $!\n";
	while(<OTHERFILE>) {
		print;
	}
	close(OTHERFILE);

}

sub getFunctionName
{
	my %func=();
	FunctionParsing::getNextFunction(\%func,*FILE,1);
	return $func{"name"};
}
