
package xdesc ;

my $dbgen ;
my $dbkeygen ;
my $dbinvkeygen ;
my %db ;
my %dbkeys ;
my %dbinvkeys ;
my $sortgroup ;
my @sortkeys ;
my @sortarray ;
my @sortinvkeys ;
my $nameinvkey ;
my @sortedarray ;
my @texforms ;
my %grouptimes ;

#D Note the trick: we read them in order, but we want
#D to be able to access them by key value.
#D I would use pseudo-hashes if they weren't experimental.
#D I'm going the key/invkey way because I know of no way
#D to let Perl find "which key has value <val>?"

sub xdesc::initialize {
	$dbgen = { 'null' => [{}] } ;
	$dbkeygen = { 'null' => {} } ;
	$dbinvkeygen = { 'null' => {} } ;
	%db = %{$dbgen};
	%dbkeys = %{$dbkeygen};
	%dbinvkeys = %{$dbinvkeygen};
	$sortgroup ;
	@sortkeys ;
	@sortarray ;
	@sortinvkeys ;
	$nameinvkey ;
	@sortedarray ;
	@texforms ;   # TeX forms are needed so that xdesc
	              # can be made available on the next run
	%grouptimes ; # times a group has been sorted.
		      # Needed for the twopass list data
}

sub xdesc::identify {
	return "Extended Descriptions plug-in"
}

sub xdesc::handle {
	my ($self, $command, @rest) =  @_ ;
	if ($command eq "define") {
		($XDescName, @Attribs) = @rest ;
		## print "Defining object $XDescName.\n" ;
		# TeX form: note that it is not important to redefine it properly;
		# we just need to have it there so that it can be used.
		my $texform = "\\defineextendeddescription[${XDescName}][${XDescName}][]\n" ;
		for ($i=0; $i < @Attribs; $i++) {
			$dbkeys{$XDescName}{$i} = $Attribs[$i] ;
			$dbinvkeys{$XDescName}{$Attribs[$i]} = $i ;
			# $keyname = $Attribs[$i] ;
			# if ($keyname eq 'handle') {
			# } elsif ($keyname eq 'content') {
			# } else {
			# 	$texform= $texform . "$keyname,"
			# } ;
		}
		$grouptimes{$XDescName} = 0 ;
		push @texforms, $texform ;
		#print "\tAttributes:\n" ;
		#while ( ($key, $val) = each %{$dbkeys{$XDescName}}) {
		#	print "\t\tKey $key: ", $val, ".\n" ;
		#}
	} ;
	if ($command eq "element") {
		($XDescName, @Attribs) = @rest ;
		my $rec = {} ;
		my $texform = "\\start${XDescName}[" ;
		for ($i=0; $i < @Attribs; $i++) {
			#print "\tAssigning $dbkeys{$obj}{$i}\n" ;
			$rec->{$i} = $Attribs[$i] ;
			$keyname =  $dbkeys{$XDescName}{$i} ;
			$keyval = $Attribs[$i] ;
			if ($keyname eq 'handle') {
				## print "Defining $XDescName $keyval.\n" ;
				$texform = $texform . "$keyval]["
			} elsif ($keyname eq 'content') {
				$texform = $texform . "]\n$keyval\n\\stop$XDescName\n"
			} else {
				$texform= $texform . "$keyname={$keyval},"
			} ;
		} ;
		push @{$db{$XDescName}}, $rec ;
		push @texforms, $texform ;
		#print "\tValues:\n" ;
		#$current = @{$db{$obj}} ;
		#$recx = $db{$obj}[$current-1] ;
		#while ( ($key, $val) = each %{$recx} ) {
		#	print "\t\tKey $key ($dbkeys{$obj}{$key}): ", $val, "\n" ;
		#}
		
	} ;
	if ($command eq "sort") {
		($sortgroup, $sortkeylist) = @rest ;
		$grouptimes{$sortgroup} = $grouptimes{$sortgroup}+1 ;
		#print "Sorting $1 for the $grouptimes{$sortgroup}" ;
		#if ( $grouptimes{$sortgroup} == 1 ) {
		#	print "st"
		#} elsif ($grouptimes{$sortgroup} == 2) {
		#	print "nd"
		#} elsif ($grouptimes{$sortgroup} == 3) {
		#	print "rd"
		#} else { print "th" } ;
		#print " time.\n" ;
                @sortkeys = split /,/, $sortkeylist ;
		@sortarray = @{$db{$sortgroup}} ;
		@sortinvkeys = @{$dbinvkeys{$sortgroup}}{@sortkeys} ;
		$nameinvkey = ${$dbinvkeys{$sortgroup}}{'handle'} ;
		@sortedarray = sort XDescMultiSort @sortarray ;
		XDescWriteArray(@sortedarray) ;
	}
} ;

sub xdesc::report {
	if (@texforms) {
		return "Extended Descriptions parsed"
	} else {
		return "Nothing done for Extended Descriptions"
	}
}

sub xdesc::results {
	if (@texforms) {
		return (join("\n","\\syncxdescs{\\xdesctoauxfalse", @texforms, "\\xdesctoauxtrue}")) ;
	}
}

sub xdesc::process {}

sub XDescWriteArray {
	my @myarray = @_ ;
	my $i ;
	print main::TUO "\\twopassentry{desc:$sortgroup}{" ;
	print main::TUO $grouptimes{$sortgroup} ;
        print main::TUO "}{{" ;
	for ($i=0; $i < @myarray; $i++) {
		if ($i > 0) {
			print main::TUO "," ;
		} ;
		print main::TUO ${$myarray[$i]}{$nameinvkey} ;
	} ;
	print main::TUO "}}\n" ;
}

sub XDescMultiSort {
	my $i = 0 ;
	my $result ;
	while ($i <= @sortkeys) {
		$sortkey = $sortinvkeys[$i] ;
		$result = ${$a}{$sortkey} cmp ${$b}{$sortkey} ;
		#print "Comparing ${$a}{$sortkey} and ${$b}{$sortkey} ($result)\n" ;
		if ($result) { last } else {$i++} ;
	}
	return $result ;
}

1 ;
