#! /usr/bin/perl
#
# Construct new FILE with POS WORD tiers from CGN target&lemma files
#
# Use:
# WritePOSsourceSentences.pl <SpeakerGlob> <FileNamePattern> ...
#
# (NO path information)
#
###############################################################################
#
# Copyright R.J.J.H. van Son © 2000, 2001
#
# Author Rob van Son
# Institute of Phonetic Sciences & ACLC
# University of Amsterdam
# Herengracht 338
# NL-1016CG Amsterdam, The Netherlands
# Email: Rob.van.Son@hum.uva.nl
#        rob.van.son@workmail.com
# WWW  : http://www.fon.hum.uva.nl/rob/
# mail:  Institute of Phonetic Sciences
#        University of Amsterdam
#        Herengracht 338
#        NL-1016CG Amsterdam
#        The Netherlands
#        tel +31 205252183
#        fax +31 205252197
#
# License for use and disclaimers
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
#######################################################
#
$HomeDir = "..";
require "$HomeDir/Links.pl";
require "$Scripts/SentenceLabel.pl";

# Get arguments
my $SpeakerGlob = shift(@ARGV);
$SpeakerGlob = '*' unless $SpeakerGlob;
my @FilePatterns = @ARGV;
@FilePatterns = ('*') unless @FilePatterns;

my $SourcePath = "$HomeDir/home/POS/tags";
my $TargetPath = "$HomeDir/Labels/sentences";
my $WordsPath = "$HomeDir/Labels/sentences";

# Get the real speakers matchin the Speaker Glob
my @SpeakerList = map {m@/?([^\/]+)$@;$1;} glob("$SentenceLabels/$SpeakerGlob");
print "@SpeakerList\n";

# Iterate over all speakers
my $CurrentSpeaker;
foreach $CurrentSpeaker (@SpeakerList)
{
	# Skip CVS directories
	next if $CurrentSpeaker =~ /CVS/;
	
	# Make sure the target directory exists
	unless(-e "$TargetPath/$CurrentSpeaker/POS" && -d "$TargetPath/$CurrentSpeaker/POS")
	{
	    # Prevent weird directory problems
	    die "$TargetPath/$CurrentSpeaker/POS exists and is NOT a directory\n"
	    	if -e "$TargetPath/$CurrentSpeaker/POS"; 
	    # Create the target directory
            mkdir("$TargetPath/$CurrentSpeaker/POS", 0744) 
	    	|| die "$TargetPath/$CurrentSpeaker/POS directory: $!\n";
	};
	
	# Iterate over all file patterns
	my $CurrentFilePattern;
	foreach $CurrentFilePattern (@FilePatterns)
	{
		# Get all files matching the pattern
		my @FileList = glob("$SourcePath/$CurrentSpeaker/$CurrentFilePattern");
		# Process all files
		my $CurrentFile;
		NEXTFILE:
		foreach $CurrentFile (@FileList)
		{
			next unless $CurrentFile =~ /\S/;
			# Skip CVS directories
			next if $CurrentFile =~ /CVS/;
			
			# Put tags and lemmas in a list
			# Read the tag file
			open(TAGFILE, "<$CurrentFile") || die "<'$CurrentFile':$!\n";
			my @TagList = <TAGFILE>;	
			@TagList = grep(/\S/, @TagList);	# No empty lines
			close(TAGFILE);
			# Clean up taglist
			while(@TagList && $TagList[0] !~ /\<([^\>]*)\>/)
			{
				shift(@TagList);
			};
			if($TagList[0] =~ /s\=[\"\']([^\"\']+)[\"\']/)
			{
				$FileID = $1;
				shift(@TagList);
			}
			else
			{
				print STDERR "$CurrentFile is not a tag and lemma file\n";
				next;
			};

			# Get the Label file
			my @WordTiers = glob("$WordsPath/$CurrentSpeaker/phoneme/${FileID}_*.phoneme");
			my $CurrentLabelFile = "";
			while(@WordTiers && $CurrentLabelFile !~ /\S/)
			{
				$CurrentLabelFile = shift(@WordTiers);
			};
			my $TargetFile;
			if($CurrentLabelFile =~ /\_([^\.]+)\.phoneme$/)
			{
				# Create the name of the future target file
				$TargetFile = "$TargetPath/$CurrentSpeaker/POS/${FileID}_$1.POS";
			}
			else
			{
				die "Error in filename: $WordsPath/$CurrentSpeaker/phoneme/${FileID}_*.phoneme -> '$CurrentLabelFile'\n";
			};
			# Read the label file 
			my $Label = new SentenceLabel;
			$Label->ReadLabelFile($CurrentLabelFile);
			# Construct new POS related tiers
			$Label->copyTier('POS', 'WORDS');	# Head tag
			$Label->copyTier('POSspec', 'WORDS');	# Specification list
			$Label->copyTier('LEMMA', 'WORDS');	# Lemma
			$Label->copyTier('POSfit', 'WORDS');	# Nummerical fit (0-100)
			#
			# Iterate over words and add POS tags, entering # for silences
			$Label->presetItem('WORDS');
			my $CurrentItem;
			while(($CurrentItem = $Label->nextItem('WORDS')) > -1)
			{
				# Synchronize other Tiers
				$Label->currentItem('POS', $CurrentItem);
				$Label->currentItem('POSspec', $CurrentItem);
				$Label->currentItem('LEMMA', $CurrentItem);
				$Label->currentItem('POSfit', $CurrentItem);
				
				# Silence: zero out and continue
				my $CurrentWord = $Label->currentValue('WORDS');
				my $StartNotValid = $CurrentWord =~ /^\=/ ? '=' : '';
				my $EndNotValid = $CurrentWord =~ /\=$/ ? '=' : '';
				$CurrentWord =~ s/\=//g;
				if($CurrentWord =~ /(^|\s+)[\#\*](\s+|$)/)
				{
					my $CurrentValue = "$StartNotValid#$EndNotValid";
					$Label->currentValue('POS', $CurrentValue);
					$Label->currentValue('POSspec', $CurrentValue);
					$Label->currentValue('LEMMA', $CurrentValue);
					$Label->currentValue('POSfit', $CurrentValue);
					
					# NEXT round
					next;
				};
				
				# Get and split current tag line. Enter values in tiers
				my $CurrentTagLine = shift(@TagList);
				if($CurrentTagLine =~ /^\s*(\S+)\t+([A-Z]+)[\(]([^\)]*)[\)]\s+(\S+)\s+([\d\.]+)\s+/)
				{
					my ($WORDS, $POS, $POSspec, $LEMMA, $POSfit) = ($1, $2, $3, $4, $5);
					# Check alignment of words
					unless(lc($CurrentWord) eq lc($WORDS) || $WORDS =~ /\&\w+\;/)
					{
						print STDERR "$CurrentWord is not equal to $WORDS in $CurrentLabelFile vs. $CurrentFile\n";
						print STDERR join(' ', @{$Label->{TIER}{'WORDS'}}), "\n";
						next NEXTFILE;
					};

					# Write POS values to tiers
					$Label->currentValue('POS', "${StartNotValid}$POS${EndNotValid}");
					$Label->currentValue('POSspec', "${StartNotValid}$POSspec${EndNotValid}");
					$Label->currentValue('LEMMA', "${StartNotValid}$LEMMA${EndNotValid}");
					$Label->currentValue('POSfit', "${StartNotValid}$POSfit${EndNotValid}");
				};
			};
			# Write to output
			$Label->FoldedIDcodes;
			$Label->print("$TargetFile", 'POSfit', 'LEMMA', 'POSspec', 'POS', 'WORDS', 'TRANSLIT');
		};
	};
};
