Index: /gsdl/trunk/bin/script/gti.pl
===================================================================
--- /gsdl/trunk/bin/script/gti.pl	(revision 18459)
+++ /gsdl/trunk/bin/script/gti.pl	(revision 18460)
@@ -89,5 +89,13 @@
 	# 'target_file' => "greenorg/macros/{iso_639_1_target_language_name}.dm" 
       }
+
+      # { 'key' => "gs3interface",
+	#'file_type' => "resource_bundle",
+	#'source_file' => "greenstone3",
+	#'target_file' => "greenstone3"
+      #}
     ];
+
+my @gs3_interface_files = ("AbstractBrowse", "AbstractGS2FieldSearch", "Authentication", "CrossCollectionSearch", "GATEServices", "GS2Construct", "GS2LuceneSearch", "interface_default", "interface_nzdl", "IViaSearch", "LuceneSearch", "MapRetrieve", "MapSearch", "metadata_names", "PhindPhraseBrowse", "QBRWebServicesHelp", "Visualizer");
 
 
@@ -97,4 +105,5 @@
     my $gti_command = shift(@_);
     my @gti_command_arguments = @_;
+    my $module = $_[1];
 
     # Open the GTI log file for appending, or write to STDERR if that fails
@@ -109,12 +118,21 @@
     if (!$gti_command) {
 	&throw_fatal_error("Missing command.");
-    }
+    }      
 
     # Process the command
     if ($gti_command =~ /^get-all-chunks$/i) {
-	print &get_all_chunks(@gti_command_arguments);
+	# Check that GS3 interface is the target
+	if ($module eq "gs3interface") {	   
+	    print &get_all_chunks_for_gs3(@gti_command_arguments);
+	} else {
+	    print &get_all_chunks(@gti_command_arguments);
+	}
     }
     if ($gti_command =~ /^get-first-n-chunks-requiring-work$/i) {
-	print &get_first_n_chunks_requiring_work(@gti_command_arguments);        
+	if ($module eq "gs3interface") {	   
+	    print &get_first_n_chunks_requiring_work_for_gs3(@gti_command_arguments);
+	} else {
+	    print &get_first_n_chunks_requiring_work(@gti_command_arguments);
+	}
     }
     if ($gti_command =~ /^get-language-status$/i) {
@@ -128,7 +146,12 @@
 	&submit_translations(@gti_command_arguments);
     }
-
-    # The command was not recognized
-    # &throw_fatal_error("Unknown command \"$gti_command\".");
+    if ($gti_command =~ /^create-glihelp-zip-file$/i) {
+	# This command cannot produce any output since it reads input
+	&create_glihelp_zip_file(@gti_command_arguments);
+    }
+#    else {
+	# The command was not recognized
+	#&throw_fatal_error("Unknown command \"$gti_command\".");
+    #}
 }
 
@@ -197,34 +220,7 @@
     my %source_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($source_file, \@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
     my %target_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($target_file, \@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
-    
-    # Form an XML response to the command
-    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
-    $xml_response .= "<GTIResponse>\n";
-    $xml_response .= "  <TranslationFile"
-	. " key=\"" . $translation_file_key . "\""
-	    . " target_file_path=\"" . $target_file . "\"\/>\n";
-    
-    # Do all the chunks
-    $xml_response .= "  <Chunks size=\"" . scalar(keys(%source_file_key_to_text_mapping)) . "\">\n";
-    foreach my $chunk_key (keys(%source_file_key_to_text_mapping)) {
-	my $source_file_chunk_date = $source_file_key_to_last_update_date_mapping{$chunk_key};
-	my $source_file_chunk_text = &make_text_xml_safe($source_file_key_to_text_mapping{$chunk_key});
-
-	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";
-	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";
-	if (defined($target_file_key_to_text_mapping{$chunk_key})) {
-	    my $target_file_chunk_date = $target_file_key_to_last_update_date_mapping{$chunk_key};
-	    my $target_file_chunk_text = &make_text_xml_safe($target_file_key_to_text_mapping{$chunk_key});
-	    $xml_response .= "      <TargetFileText date=\"$target_file_chunk_date\">$target_file_chunk_text</TargetFileText>\n";
-	}
-	else {
-	    $xml_response .= "      <TargetFileText></TargetFileText>\n";
-	}
-
-	$xml_response .= "    </Chunk>\n";
-    }
-    $xml_response .= "  </Chunks>\n";
-    
-    $xml_response .= "</GTIResponse>\n";
+
+    my $xml_response = &create_xml_response_for_all_chunks($translation_file_key, $target_file, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, \%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);   
+    
     return $xml_response;
 }
@@ -281,73 +277,6 @@
     &log_message("Number of target chunks requiring updating: " . scalar(@target_file_keys_requiring_updating));
 
-    # Form an XML response to the command
-    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
-    $xml_response .= "<GTIResponse>\n";
-    $xml_response .= "  <TranslationFile"
-	. " key=\"" . $translation_file_key . "\""
-	. " target_file_path=\"" . $target_file . "\""
-	. " num_chunks_translated=\"" . (scalar(keys(%source_file_key_to_text_mapping)) - scalar(@target_file_keys_requiring_translation)) . "\""
-	. " num_chunks_requiring_translation=\"" . scalar(@target_file_keys_requiring_translation) . "\""
-	. " num_chunks_requiring_updating=\"" . scalar(@target_file_keys_requiring_updating) . "\"\/>\n";
-
-    # Do chunks requiring translation first
-    if ($num_chunks_to_return > scalar(@target_file_keys_requiring_translation)) {
-	$xml_response .= "  <ChunksRequiringTranslation size=\"" . scalar(@target_file_keys_requiring_translation) . "\">\n";
-    }
-    else {
-	$xml_response .= "  <ChunksRequiringTranslation size=\"" . $num_chunks_to_return . "\">\n";
-    }
-
-    foreach my $chunk_key (@target_file_keys_requiring_translation) {
-	last if ($num_chunks_to_return == 0);
-
-	my $source_file_chunk_date = $source_file_key_to_last_update_date_mapping{$chunk_key};
-	my $source_file_chunk_text = &make_text_xml_safe($source_file_key_to_text_mapping{$chunk_key});
-	
-	if(!defined $source_file_chunk_date){
-		$source_file_chunk_date = "";
-	}
-	
-	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";
-	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";	
-	$xml_response .= "      <TargetFileText></TargetFileText>\n";
-	$xml_response .= "    </Chunk>\n";
-
-	$num_chunks_to_return--;
-    }
-
-    $xml_response .= "  </ChunksRequiringTranslation>\n";
-
-    # Then do chunks requiring updating
-    if ($num_chunks_to_return > scalar(@target_file_keys_requiring_updating)) {
-	$xml_response .= "  <ChunksRequiringUpdating size=\"" . scalar(@target_file_keys_requiring_updating) . "\">\n";
-    }
-    else {
-	$xml_response .= "  <ChunksRequiringUpdating size=\"" . $num_chunks_to_return . "\">\n";
-    }
-
-    foreach my $chunk_key (@target_file_keys_requiring_updating) {
-	last if ($num_chunks_to_return == 0);
-
-	my $source_file_chunk_date = $source_file_key_to_last_update_date_mapping{$chunk_key};
-	my $source_file_chunk_text = &make_text_xml_safe($source_file_key_to_text_mapping{$chunk_key});
-	my $target_file_chunk_date = $target_file_key_to_last_update_date_mapping{$chunk_key};
-	my $target_file_chunk_text = &make_text_xml_safe($target_file_key_to_text_mapping{$chunk_key});
-	
-	if(!defined $source_file_chunk_date){
-		$source_file_chunk_date = "";
-	}
-
-	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";	
-	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";
-	$xml_response .= "      <TargetFileText date=\"$target_file_chunk_date\">$target_file_chunk_text</TargetFileText>\n";
-	$xml_response .= "    </Chunk>\n";
-
-	$num_chunks_to_return--;
-    }
-
-    $xml_response .= "  </ChunksRequiringUpdating>\n";
-
-    $xml_response .= "</GTIResponse>\n";
+    my $xml_response = &create_xml_response_for_chunks_requiring_work($translation_file_key, $target_file, scalar(keys(%source_file_key_to_text_mapping)), \@target_file_keys_requiring_translation, \@target_file_keys_requiring_updating, $num_chunks_to_return, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, \%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);   
+    
     return $xml_response;
 }
@@ -369,8 +298,105 @@
     $xml_response .= "  <LanguageStatus code=\"$target_language_code\">\n";
 
-    foreach my $translation_file (@$gti_translation_files) {
+    foreach my $translation_file (@$gti_translation_files) {	
+	my ($num_source_chunks, $num_target_chunks, $num_chunks_requiring_translation, $num_chunks_requiring_updating) = 0;
+	my $target_file_name = "";
+	
+	if ($translation_file->{'key'} eq "gs3interface") {
+	    my (%source_file_key_to_text_mapping, %target_file_key_to_text_mapping, %source_file_key_to_last_update_date_mapping, %target_file_key_to_last_update_date_mapping ) = ();
+	    &build_gs3_configuration($target_language_code, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, \%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping );    
+	    
+	    my @target_file_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping);	    
+	    my @target_file_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);
+
+	    $num_source_chunks = scalar(keys(%source_file_key_to_text_mapping));
+	    $num_target_chunks = scalar(keys(%target_file_key_to_text_mapping));
+	    $num_chunks_requiring_translation = scalar(@target_file_keys_requiring_translation);
+	    $num_chunks_requiring_updating = scalar(@target_file_keys_requiring_updating);
+	}
+	else {
+	    # Get (and check) the translation configuration
+	    my ($source_file, $target_file, $translation_file_type) = &get_translation_configuration($target_language_code, $translation_file->{'key'});
+	    $target_file_name = $target_file;
+
+	    # Parse the source language and target language files
+	    my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
+	    my @source_file_lines = &read_file_lines($source_file_path);
+	    my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+
+	    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+	    my @target_file_lines = &read_file_lines($target_file_path);
+	    my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+
+	    # Filter out any automatically translated chunks
+	    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+		if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+		    delete $source_file_key_to_line_mapping{$chunk_key};
+		    delete $target_file_key_to_line_mapping{$chunk_key};
+		}
+	    }
+
+	    my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	    my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+
+	    # Determine the target file chunks requiring translation
+	    my @target_file_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping);	    
+
+	    # Determine the target file chunks requiring updating
+	    my @target_file_keys_requiring_updating = ();
+	    if (-e $target_file_path) {
+		my %source_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($source_file, \@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+		my %target_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($target_file, \@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+		@target_file_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);		
+	    }
+
+	    $num_source_chunks = scalar(keys(%source_file_key_to_text_mapping));
+	    $num_target_chunks = scalar(keys(%target_file_key_to_text_mapping));
+	    $num_chunks_requiring_translation = scalar(@target_file_keys_requiring_translation);
+	    $num_chunks_requiring_updating = scalar(@target_file_keys_requiring_updating);
+	}
+	
+	&log_message("Status of " . $translation_file->{'key'});
+	&log_message("Number of source chunks: " . $num_source_chunks);
+	&log_message("Number of target chunks: " . $num_target_chunks);
+	&log_message("Number of target chunks requiring translation: " . $num_chunks_requiring_translation);
+	&log_message("Number of target chunks requiring updating: " . $num_chunks_requiring_updating);
+
+	$xml_response .= "    <TranslationFile"
+	    . " key=\"" . $translation_file->{'key'} . "\""
+	    . " target_file_path=\"" . $target_file_name . "\""
+	    . " num_chunks_translated=\"" . ($num_source_chunks - $num_chunks_requiring_translation) . "\""
+	    . " num_chunks_requiring_translation=\"" . $num_chunks_requiring_translation . "\""
+	    . " num_chunks_requiring_updating=\"" . $num_chunks_requiring_updating . "\"\/>\n";
+    }
+
+    $xml_response .= "  </LanguageStatus>\n";
+
+    $xml_response .= "</GTIResponse>\n";
+    return $xml_response;
+}
+
+
+sub search_chunks
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+    # The query string
+    my $query_string = join(' ', @_);
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key || !$query_string) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    my ($source_file, $target_file, $translation_file_type) = ();
+    my %source_file_key_to_text_mapping = ();
+    my %target_file_key_to_text_mapping = ();
+    
+    
+    if ($translation_file_key ne "gs3interface") {
 	# Get (and check) the translation configuration
-	my ($source_file, $target_file, $translation_file_type)
-	    = &get_translation_configuration($target_language_code, $translation_file->{'key'});
+	($source_file, $target_file, $translation_file_type) = &get_translation_configuration($target_language_code, $translation_file_key);
 
 	# Parse the source language and target language files
@@ -391,74 +417,14 @@
 	}
 
-	my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
-	my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
-	&log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
-	&log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
-
-	# Determine the target file chunks requiring translation
-	my @target_file_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping);
-	&log_message("Number of target chunks requiring translation: " . scalar(@target_file_keys_requiring_translation));
-
-	# Determine the target file chunks requiring updating
-	my @target_file_keys_requiring_updating = ();
-	if (-e $target_file_path) {
-	    my %source_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($source_file, \@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
-	    my %target_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($target_file, \@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
-	    @target_file_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);
-	    &log_message("Number of target chunks requiring updating: " . scalar(@target_file_keys_requiring_updating));
-	}
-
-	$xml_response .= "    <TranslationFile"
-	    . " key=\"" . $translation_file->{'key'} . "\""
-	    . " target_file_path=\"" . $target_file . "\""
-	    . " num_chunks_translated=\"" . (scalar(keys(%source_file_key_to_text_mapping)) - scalar(@target_file_keys_requiring_translation)) . "\""
-	    . " num_chunks_requiring_translation=\"" . scalar(@target_file_keys_requiring_translation) . "\""
-	    . " num_chunks_requiring_updating=\"" . scalar(@target_file_keys_requiring_updating) . "\"\/>\n";
-    }
-
-    $xml_response .= "  </LanguageStatus>\n";
-
-    $xml_response .= "</GTIResponse>\n";
-    return $xml_response;
-}
-
-
-sub search_chunks
-{
-    # The code of the target language (ensure it is lowercase)
-    my $target_language_code = lc(shift(@_));
-    # The key of the file to translate (ensure it is lowercase)
-    my $translation_file_key = lc(shift(@_));
-    # The query string
-    my $query_string = join(' ', @_);
-
-    # Check that the necessary arguments were supplied
-    if (!$target_language_code || !$translation_file_key || !$query_string) {
-	&throw_fatal_error("Missing command argument.");
-    }
-
-    # Get (and check) the translation configuration
-    my ($source_file, $target_file, $translation_file_type)
-	= &get_translation_configuration($target_language_code, $translation_file_key);
-
-    # Parse the source language and target language files
-    my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
-    my @source_file_lines = &read_file_lines($source_file_path);
-    my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
-
-    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
-    my @target_file_lines = &read_file_lines($target_file_path);
-    my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
-
-    # Filter out any automatically translated chunks
-    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
-	if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
-	    delete $source_file_key_to_line_mapping{$chunk_key};
-	    delete $target_file_key_to_line_mapping{$chunk_key};
-	}
-    }
-
-    my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
-    my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+	%source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	%target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+    }
+    else {
+	# Not needed in this case
+	my (%source_file_key_to_gti_command_mapping, %target_file_key_to_gti_command_mapping) = ();
+	&build_gs3_configuration($target_language_code, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping,
+				 \%source_file_key_to_gti_command_mapping, \%target_file_key_to_gti_command_mapping);
+    }
+
     &log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
     &log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
@@ -509,20 +475,35 @@
 	die "\n";
     }
-
-    # Get (and check) the translation configuration
-    my ($source_file, $target_file, $translation_file_type)
-	= &get_translation_configuration($target_language_code, $translation_file_key);
-
-    # Parse the source language and target language files
-    my @source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
-    my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
-    my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
-    my %source_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+    
+    my %source_file_key_to_text_mapping = ();
+    my %source_file_key_to_gti_comment_mapping = ();
+    my %target_file_key_to_text_mapping = ();
+    my %target_file_key_to_gti_comment_mapping = ();
+
+    my (@source_file_lines, @target_file_lines) = ();
+    my ($source_file, $target_file, $translation_file_type);
+
+    
+    if ($translation_file_key ne "gs3interface") {
+	# Get (and check) the translation configuration
+	($source_file, $target_file, $translation_file_type)
+	    = &get_translation_configuration($target_language_code, $translation_file_key);
+
+	# Parse the source language and target language files
+	@source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+	%source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	%source_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);	
+
+	@target_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $target_file));
+	my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+	%target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+	%target_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);	
+    } 
+    else {
+	&build_gs3_configuration($target_language_code, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, 
+				 \%source_file_key_to_gti_comment_mapping, \%target_file_key_to_gti_comment_mapping);
+    }
     &log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
-
-    my @target_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $target_file));
-    my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
-    my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
-    my %target_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
     &log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
 
@@ -538,8 +519,8 @@
 
     # Remove any nasty carriage returns
-    &log_message("Submission:");
+    # &log_message("Submission:");
     foreach my $submission_line (@submission_lines) {
 	$submission_line =~ s/\r$//;
-	&log_message("  $submission_line");
+	#&log_message("  $submission_line");
     }
 
@@ -561,6 +542,6 @@
 	    $source_file_chunk_text = &unmake_text_xml_safe($source_file_chunk_text);
 
-	    &log_message("Source file key: $chunk_key");
-	    &log_message("Source file text: $source_file_chunk_text");
+	    #&log_message("Source file key: $chunk_key");
+	    #&log_message("Source file text: $source_file_chunk_text");
 	    $source_file_key_to_submission_mapping{$chunk_key} = $source_file_chunk_text;
 	}
@@ -580,6 +561,6 @@
 	    $target_file_chunk_text = &unmake_text_xml_safe($target_file_chunk_text);
 
-	    &log_message("Target file key: $chunk_key");
-	    &log_message("Target file text: $target_file_chunk_text");
+	    #&log_message("Target file key: $chunk_key");
+	    #&log_message("Target file text: $target_file_chunk_text");
 	    $target_file_key_to_submission_mapping{$chunk_key} = $target_file_chunk_text;
 	}
@@ -619,6 +600,60 @@
 	}
     }
-
-    eval "&write_translated_${translation_file_type}(\$source_file, \\\@source_file_lines, \\\%source_file_key_to_text_mapping, \$target_file, \\\@target_file_lines, \\\%target_file_key_to_text_mapping, \\\%target_file_key_to_gti_comment_mapping, \$target_language_code)";
+    
+    if ($translation_file_key ne "gs3interface") {
+	eval "&write_translated_${translation_file_type}(\$source_file, \\\@source_file_lines, \\\%source_file_key_to_text_mapping, \$target_file, \\\@target_file_lines, \\\%target_file_key_to_text_mapping, \\\%target_file_key_to_gti_comment_mapping, \$target_language_code)";
+    } else {
+	eval "&write_translated_gs3interface(\\\%source_file_key_to_text_mapping, \\\%target_file_key_to_text_mapping, \\\%target_file_key_to_gti_comment_mapping, \$target_language_code)";
+    }
+}
+
+
+sub create_glihelp_zip_file
+{
+    my $target_language_code = shift(@_);
+    my $translation_file_key = "glihelp";
+    
+    &log_message("Creating GLI Help zip file for $target_language_code");
+
+    my ($source_file, $target_file, $translation_file_type) = &get_translation_data_for($target_language_code, $translation_file_key);    
+    
+    my $classpath = &util::filename_cat($gsdl_root_directory, "gti-lib");
+    if ( ! -e $classpath) {
+	&throw_fatal_error("$classpath doesn't exist! Need the files in this directory (ApplyXLST and its related files) to create the zip file for GLI Help");
+    }    
+    
+    my $gli_help_directory = &util::filename_cat($gsdl_root_directory, "gli");
+    $gli_help_directory = &util::filename_cat($gli_help_directory, "help");
+    
+    my $gen_many_html_xsl_filepath = &util::filename_cat($gli_help_directory, "gen-many-html.xsl");
+    if ( ! -e $gen_many_html_xsl_filepath) {
+	&throw_fatal_error("$gen_many_html_xsl_filepath doesn't exist! Need this file to create the zip file for GLI Help");
+    }
+
+    my $gen_index_xml_xsl_filepath = &util::filename_cat($gli_help_directory, "gen-index-xml.xsl");   
+    my $split_script_filepath = &util::filename_cat($gli_help_directory, "splithelpdocument.pl");   
+    
+    my $target_file_directory = &util::filename_cat($gli_help_directory, $target_language_code);
+    $target_file_directory = $target_file_directory."/";
+
+    my $target_filepath = &util::filename_cat($gsdl_root_directory, $target_file);
+    my $cmd = "/opt/jdk1.6.0/bin/java -cp $classpath:$classpath/xalan.jar ApplyXSLT $target_language_code $gen_many_html_xsl_filepath $target_filepath | perl -S $split_script_filepath $target_file_directory";
+    my $response = `$cmd`;
+    &log_message($cmd);
+    &log_message($response);    
+    &log_message("Created HTML operational files");
+    
+    $cmd = "/opt/jdk1.6.0/bin/java -cp $classpath:$classpath/xalan.jar ApplyXSLT $target_language_code $gen_index_xml_xsl_filepath $target_filepath > " . $target_file_directory . "help_index.xml"; # 2>/dev/null";
+    $response = `$cmd`;
+    &log_message($cmd);
+    &log_message($response);    
+    &log_message("Created xml index file");
+
+    my $zip_file_path = "/greenstone/custom/gti/" . $target_language_code . "_GLIHelp.zip";
+    $cmd = "zip -rj $zip_file_path $target_file_directory -i \*.htm \*.xml";
+    $response = `$cmd`;
+    &log_message($cmd);
+    &log_message($response);    
+    &log_message("Created the zip file");
 }
 
@@ -767,5 +802,5 @@
 	my $chunk_cvs_date = $key_to_cvs_date_mapping{$chunk_key};
 	$key_to_last_update_date_mapping{$chunk_key} = $chunk_cvs_date;
-                
+
 	# If a comment date exists and it is after the CVS date, use that instead
         # need to convert the comment date format to SVN format
@@ -773,6 +808,13 @@
 	if (defined($chunk_gti_comment) && $chunk_gti_comment =~ /(\d?\d-\D\D\D-\d\d\d\d)/) {
 	    my $chunk_comment_date = $1;            
-	    if ((!defined($chunk_cvs_date) || &is_date_after($chunk_comment_date, $chunk_cvs_date))) {
+	    # if the changes were made on 2009 Jan 27, ie. tidying up the GTI commands following each fragment, 
+	    # then should use the GTI comment date instead
+	    # if ((!defined($chunk_cvs_date) || &is_date_after($chunk_comment_date, $chunk_cvs_date))) {
+	    if ((!defined($chunk_cvs_date) || &is_date_after($chunk_comment_date, $chunk_cvs_date) 
+		 || (&is_date_after($chunk_cvs_date,$chunk_comment_date) && ($chunk_cvs_date eq "2009-01-27" || $chunk_cvs_date eq "2009-01-28")))) {
 		$key_to_last_update_date_mapping{$chunk_key} = $chunk_comment_date;
+		
+		# &log_message("cvs date: $chunk_cvs_date, comment date: $chunk_comment_date");
+		# die;
 	    }
 	}
@@ -1027,4 +1069,117 @@
 
 
+sub create_xml_response_for_chunks_requiring_work
+{
+    my ($translation_file_key, $target_file, $total_num_chunks, $target_files_keys_requiring_translation, $target_files_keys_requiring_updating, $num_chunks_to_return, $source_files_key_to_text_mapping, $target_files_key_to_text_mapping, $source_files_key_to_last_update_date_mapping, $target_files_key_to_last_update_date_mapping) = @_;
+
+    # Form an XML response to the command
+    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    $xml_response .= "<GTIResponse>\n";
+    $xml_response .= "  <TranslationFile"
+	. " key=\"" . $translation_file_key . "\""
+	. " target_file_path=\"" . $target_file . "\""
+	. " num_chunks_translated=\"" . ($total_num_chunks - scalar(@$target_files_keys_requiring_translation)) . "\""
+	. " num_chunks_requiring_translation=\"" . scalar(@$target_files_keys_requiring_translation) . "\""
+	. " num_chunks_requiring_updating=\"" . scalar(@$target_files_keys_requiring_updating) . "\"\/>\n";
+
+    # Do chunks requiring translation first
+    if ($num_chunks_to_return > scalar(@$target_files_keys_requiring_translation)) {
+	$xml_response .= "  <ChunksRequiringTranslation size=\"" . scalar(@$target_files_keys_requiring_translation) . "\">\n";
+    }
+    else {
+	$xml_response .= "  <ChunksRequiringTranslation size=\"" . $num_chunks_to_return . "\">\n";
+    }
+
+    my @sorted_chunk_keys = sort (@$target_files_keys_requiring_translation);
+    foreach my $chunk_key (@sorted_chunk_keys) {
+	last if ($num_chunks_to_return == 0);
+
+	my $source_file_chunk_date = $source_files_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $source_file_chunk_text = &make_text_xml_safe($source_files_key_to_text_mapping->{$chunk_key});	
+	
+	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";
+	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";	
+	$xml_response .= "      <TargetFileText></TargetFileText>\n";
+	$xml_response .= "    </Chunk>\n";
+
+	$num_chunks_to_return--;
+    }
+
+    $xml_response .= "  </ChunksRequiringTranslation>\n";
+
+    # Then do chunks requiring updating
+    if ($num_chunks_to_return > scalar(@$target_files_keys_requiring_updating)) {
+	$xml_response .= "  <ChunksRequiringUpdating size=\"" . scalar(@$target_files_keys_requiring_updating) . "\">\n";
+    }
+    else {
+	$xml_response .= "  <ChunksRequiringUpdating size=\"" . $num_chunks_to_return . "\">\n";
+    }
+        
+    # foreach my $chunk_key (@target_file_keys_requiring_updating) {
+    @sorted_chunk_keys = sort (@$target_files_keys_requiring_updating);
+    foreach my $chunk_key (@sorted_chunk_keys) {
+	last if ($num_chunks_to_return == 0);
+
+	my $source_file_chunk_date = $source_files_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $source_file_chunk_text = &make_text_xml_safe($source_files_key_to_text_mapping->{$chunk_key});
+	my $target_file_chunk_date = $target_files_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $target_file_chunk_text = &make_text_xml_safe($target_files_key_to_text_mapping->{$chunk_key});
+
+	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";	
+	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";
+	$xml_response .= "      <TargetFileText date=\"$target_file_chunk_date\">$target_file_chunk_text</TargetFileText>\n";
+	$xml_response .= "    </Chunk>\n";
+
+	$num_chunks_to_return--;
+    }
+
+    $xml_response .= "  </ChunksRequiringUpdating>\n";
+
+    $xml_response .= "</GTIResponse>\n";
+
+    return $xml_response;
+}
+
+
+sub create_xml_response_for_all_chunks
+{
+    my ($translation_file_key, $target_file, $source_file_key_to_text_mapping, $target_file_key_to_text_mapping, $source_file_key_to_last_update_date_mapping, $target_file_key_to_last_update_date_mapping) = @_;
+
+    # Form an XML response to the command
+    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    $xml_response .= "<GTIResponse>\n";
+    $xml_response .= "  <TranslationFile"
+	. " key=\"" . $translation_file_key . "\""
+	. " target_file_path=\"" . $target_file . "\"\/>\n";
+    
+    # Do all the chunks
+    $xml_response .= "  <Chunks size=\"" . scalar(keys(%$source_file_key_to_text_mapping)) . "\">\n";
+
+    my @sorted_chunk_keys = sort (keys(%$source_file_key_to_text_mapping));
+    foreach my $chunk_key (@sorted_chunk_keys) {
+	my $source_file_chunk_date = $source_file_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $source_file_chunk_text = &make_text_xml_safe($source_file_key_to_text_mapping->{$chunk_key});
+
+	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";
+	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";
+	if (defined($target_file_key_to_text_mapping->{$chunk_key})) {
+	    my $target_file_chunk_date = $target_file_key_to_last_update_date_mapping->{$chunk_key} || "";
+	    my $target_file_chunk_text = &make_text_xml_safe($target_file_key_to_text_mapping->{$chunk_key});
+	    $xml_response .= "      <TargetFileText date=\"$target_file_chunk_date\">$target_file_chunk_text</TargetFileText>\n";
+	}
+	else {
+	    $xml_response .= "      <TargetFileText></TargetFileText>\n";
+	}
+
+	$xml_response .= "    </Chunk>\n";
+    }
+    $xml_response .= "  </Chunks>\n";
+    
+    $xml_response .= "</GTIResponse>\n";
+    return $xml_response;
+}
+
+
+
 # ==========================================================================================
 #   MACROFILE FUNCTIONS
@@ -1265,5 +1420,5 @@
 
 	# Line contains a dictionary string
-	if ($line =~ /^(\S+?):(.*)$/) {
+	if ($line =~ /^(\S+?)[:|=](.*)$/) {
 	    my $chunk_key = $1;
 
@@ -1282,5 +1437,5 @@
 
     # Simple: just remove string key
-    $chunk_text =~ s/^(\S+?):(\s*)//;
+    $chunk_text =~ s/^(\S+?)[:|=](\s*)//;
     $chunk_text =~ s/(\s*)$//;  # Remove any nasty whitespace, carriage returns etc.
     $chunk_text =~ s/(\s*)\#\s+Updated\s+(\d?\d-\D\D\D-\d\d\d\d.*)\s*$//i;
@@ -1510,3 +1665,198 @@
 
 
+# ==========================================================================================
+#   GREENSTONE3 FUNCTIONS
+
+sub get_all_chunks_for_gs3
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    my $translation_file_key = lc(shift(@_));
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    # Get (and check) the translation configuration
+    # my ($source_file_dir, $target_file, $translation_file_type) = &get_translation_configuration($target_language_code, $translation_file_key);
+    
+    my %source_files_key_to_text_mapping = ();
+    my %target_files_key_to_text_mapping = ();
+    my %source_files_key_to_last_update_date_mapping = ();
+    my %target_files_key_to_last_update_date_mapping = ();
+
+    &build_gs3_configuration($target_language_code, \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping, \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+
+    &log_message("Total number of source chunks: " . scalar(keys(%source_files_key_to_text_mapping)));
+    &log_message("Total number of target chunks: " . scalar(keys(%target_files_key_to_text_mapping)));
+
+    my $xml_response = &create_xml_response_for_all_chunks($translation_file_key, "", \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping, \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);   
+    return $xml_response;
+}
+
+
+sub get_first_n_chunks_requiring_work_for_gs3
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+    # The number of chunks to return (defaults to one if not specified)
+    my $num_chunks_to_return = shift(@_) || "1";
+    
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key) {
+	&throw_fatal_error("Missing command argument.");
+    }
+    
+    my %source_files_key_to_text_mapping = ();
+    my %target_files_key_to_text_mapping = ();
+    my %source_files_key_to_last_update_date_mapping = ();
+    my %target_files_key_to_last_update_date_mapping = ();
+
+    &build_gs3_configuration($target_language_code, \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping, 
+			     \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+    
+    # Determine the target file chunks requiring translation
+    my @target_files_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping);    
+    # Determine the target file chunks requiring updating
+    my @target_files_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+    &log_message("Total number of target chunks requiring translation: " . scalar(@target_files_keys_requiring_translation));
+    &log_message("Total number of target chunks requiring updating: " . scalar(@target_files_keys_requiring_updating));
+
+    my $xml_response = &create_xml_response_for_chunks_requiring_work($translation_file_key, "", scalar(keys(%source_files_key_to_text_mapping)),
+								      \@target_files_keys_requiring_translation, \@target_files_keys_requiring_updating,
+								      $num_chunks_to_return, \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping,
+								      \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+   
+    return $xml_response;
+}
+
+
+
+sub build_gs3_configuration
+{
+    my ($target_language_code, $source_files_key_to_text_mapping, $target_files_key_to_text_mapping,
+	$source_files_key_to_gti_comment_mapping, $target_files_key_to_gti_comment_mapping) = @_;
+    
+    my $source_file_directory = "greenstone3";
+    my $translation_file_type = "resource_bundle";
+
+    foreach my $interface_file_key (@gs3_interface_files) {
+
+	&log_message("Greenstone 3 interface file: " . $interface_file_key);
+
+	# Parse the source language and target language files
+	my $source_file = &util::filename_cat($source_file_directory, $interface_file_key.".properties");
+	my @source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+	my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	my %source_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);	
+	
+	my $target_file = &util::filename_cat($source_file_directory, $interface_file_key."_".$target_language_code.".properties");
+	my @target_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $target_file));
+	my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+	my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+	my %target_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+
+
+	# Filter out any automatically translated chunks
+	foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	    if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+		delete $source_file_key_to_line_mapping{$chunk_key};
+		delete $target_file_key_to_line_mapping{$chunk_key};
+	    }
+	}
+
+	&log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
+	&log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
+
+	foreach my $chunk_key (keys(%source_file_key_to_text_mapping)) {
+	    my $global_chunk_key = "$interface_file_key.$chunk_key";
+	    $source_files_key_to_text_mapping->{$global_chunk_key} = $source_file_key_to_text_mapping{$chunk_key};
+	    $source_files_key_to_gti_comment_mapping->{$global_chunk_key} = $source_file_key_to_gti_comment_mapping{$chunk_key};
+
+	    if (defined $target_file_key_to_text_mapping{$chunk_key}) {
+		$target_files_key_to_text_mapping->{$global_chunk_key} = $target_file_key_to_text_mapping{$chunk_key};
+		$target_files_key_to_gti_comment_mapping->{$global_chunk_key} = $target_file_key_to_gti_comment_mapping{$chunk_key};
+	    }
+	}	
+    }
+}
+
+
+sub write_translated_gs3interface
+{
+    my $source_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_gti_comment_mapping = shift(@_);
+    my $target_language_code = shift(@_);
+    
+    my @sorted_chunk_keys = sort (keys(%$source_file_key_to_text_mapping));
+
+    my %translated_interface_file_keys = ();
+    foreach my $chunk_key (keys(%$target_file_key_to_text_mapping)) {
+	$chunk_key =~ /^([^\.]+)?\.(.*)$/;
+	if (!defined $translated_interface_file_keys{$1}) {
+	    &log_message("Updated interface file: " . $1);	
+	    $translated_interface_file_keys{$1}="";
+	}
+    }
+    &log_message("Updated interface files: " . scalar(keys(%translated_interface_file_keys)));
+    
+    my $source_file_directory = "greenstone3";    
+    
+    foreach my $interface_file_key (keys(%translated_interface_file_keys)) {
+	
+	# Build a mapping from chunk key to source file line, and from source file line to chunk key
+	my $source_file = &util::filename_cat($source_file_directory, "$interface_file_key.properties");
+	my @source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping_for_resource_bundle(@source_file_lines);
+	my %source_file_line_to_key_mapping = ();
+	foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	    $source_file_line_to_key_mapping{$source_file_key_to_line_mapping{$chunk_key}} = $chunk_key;
+	}
+	
+	# Write the new target file
+	my $target_file = &util::filename_cat($source_file_directory, $interface_file_key . "_" . $target_language_code . ".properties");
+	my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+	if (!open(TARGET_FILE, ">$target_file_path")) {
+	    &throw_fatal_error("Could not write target file $target_file_path.");
+	}
+
+	# Model the new target file on the source file, with the target file translations
+	my $source_file_line_number = 0;
+	foreach my $line_key (sort sort_by_line (keys(%source_file_line_to_key_mapping))) {
+	    # Fill in the gaps before this chunk starts
+	    my $source_file_chunk_starting_line_number = (split(/-/, $line_key))[0];
+	    my $source_file_chunk_finishing_line_number = (split(/-/, $line_key))[1];
+	    while ($source_file_line_number < $source_file_chunk_starting_line_number) {
+		print TARGET_FILE $source_file_lines[$source_file_line_number];
+		$source_file_line_number++;
+	    }
+	    $source_file_line_number = $source_file_chunk_finishing_line_number + 1;
+
+	    my $chunk_key = $source_file_line_to_key_mapping{$line_key};
+	    my $global_chunk_key = "$interface_file_key.$chunk_key";
+	    my $source_file_chunk_text = $source_file_key_to_text_mapping->{$global_chunk_key};
+	    my $target_file_chunk_text = $target_file_key_to_text_mapping->{$global_chunk_key} || "";
+
+	    # If no translation exists for this chunk, show this, and move on
+	    if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
+		print TARGET_FILE "# -- Missing translation: $chunk_key\n";
+		next;
+	    }
+
+	    print TARGET_FILE "$chunk_key:$target_file_chunk_text";
+	    if ($target_file_key_to_gti_comment_mapping->{$global_chunk_key}) {
+		print TARGET_FILE "  # " . $target_file_key_to_gti_comment_mapping->{$global_chunk_key};
+		}
+	    print TARGET_FILE "\n";
+	}
+
+	close(TARGET_FILE);	
+    }           
+}
+
 &main(@ARGV);
Index: /gsdl/trunk/macros/english2.dm
===================================================================
--- /gsdl/trunk/macros/english2.dm	(revision 18459)
+++ /gsdl/trunk/macros/english2.dm	(revision 18460)
@@ -1096,5 +1096,5 @@
 _textgtitutorials_ {Tutorial Exercises}
 _textgtigreenorg_ {Greenstone.org}
-_textgtigs3core_ {Greenstone3 Interface (Default)}
+_textgtigs3interface_ {Greenstone3 Interface}
 
 #for greenstone manuals
@@ -1137,5 +1137,5 @@
 
 <ol>
-<li>Download <a href="_gwcgi_?a=gti&amp;p=excel&amp;e=_compressedoptions_">this file</a>.
+<li>Download either <a href="_gwcgi_?a=gti&amp;p=excel&amp;tct=work&amp;e=_compressedoptions_">this file</a> for all the remaining work, or <a href="_gwcgi_?a=gti&amp;p=excel&amp;tct=all&amp;e=_compressedoptions_">this file</a> for all the strings in this module.
 <li>Open the downloaded file in Microsoft Excel (Office 2003/XP or more recent versions is required) and save as Microsoft Excel workbook (.xls) format.
 <li>Enter the translations in the boxes provided.
Index: /gsdl/trunk/macros/gti.dm
===================================================================
--- /gsdl/trunk/macros/gti.dm	(revision 18459)
+++ /gsdl/trunk/macros/gti.dm	(revision 18460)
@@ -179,5 +179,7 @@
      <a href="_gwcgi_?a=gti&amp;p=find&amp;e=_compressedoptions_">_textgticorrectexistingtranslations_</a><br>
      _If_(_4_ eq _gtidownloadglihelp, <a href="_4_">, <a href="_httpprefix_/_4_">)_textgtidownloadtargetfile_</a>
-     _If_(_gtiglihelpzipfilepath_ eq "disabled", <a href="_gwcgi_?a=gti&amp;p=glihelp&amp;e=_compressedoptions_">_textgtiglihelpzipfile_</a>, <a href="_httpprefix_/_gtiglihelpzipfilepath_">_gtiglihelpzipfilepath_ Reday to download</a>)<br>
+
+     _If_(_gtiglihelpzipfilepath_, <a href="_httpprefix_/_gtiglihelpzipfilepath_">_textgtiglihelpzipfile_</a>,)<br>
+
      <a href="_gwcgi_?a=gti&amp;p=offline&amp;e=_compressedoptions_">_textgtitranslatefileoffline_</a><br>
      _gtiviewtranslationfileinaction_
@@ -186,7 +188,7 @@
 }
 
-_gtiglihelpzipfilepath_ {disabled}
-
-_textgtiglihelpzipfile_ {Download the zipped GLI Help operational files}
+_gtiglihelpzipfilepath_ {}
+
+_textgtiglihelpzipfile_ {Clicke here to download the operational files for GLI Help}
 
 # --------------------------------------------------------------------------------
Index: /gsdl/trunk/runtime-src/src/recpt/gtiaction.cpp
===================================================================
--- /gsdl/trunk/runtime-src/src/recpt/gtiaction.cpp	(revision 18459)
+++ /gsdl/trunk/runtime-src/src/recpt/gtiaction.cpp	(revision 18460)
@@ -192,12 +192,16 @@
   
   // Define the page content for the GTI view status page
-	if (args["p"] == "status") {
-		define_gti_status_page(disp, args, logout);
-		return;
-	}
+  if (args["p"] == "status") {
+    define_gti_status_page(disp, args, logout);
+    return;
+  }
 
   // Process user translations
   if (args["p"] == "submit") {
     process_gti_submissions(disp, args, logout, true);
+  }
+
+  if (args["p"] == "glihelp") {
+    produce_glihelp_zipfile(disp, args, logout);    
   }
   	
@@ -335,8 +339,8 @@
     	
     	
-   		//lang_status_temp += "<td valign=\"top\" nowrap>_gtitranslationfilestatus2_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td>";   		
+	//lang_status_temp += "<td valign=\"top\" nowrap>_gtitranslationfilestatus2_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td>";   		
    		
-   		// List the file names as the first row of the status table 
-   		// Add up number of strings need to be translate in each file, as the second line of the status table
+	// List the file names as the first row of the status table 
+	// Add up number of strings need to be translate in each file, as the second line of the status table
       if (first_lang) {
         files_temp += "<th class=\"status\">_textgti" + translation_file_key + "_</th>\n";
@@ -484,5 +488,9 @@
   languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
   disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
-  disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]);
+  if (translation_file_key == "glihelp") {
+    disp.setmacro("gtitargetfilepath", "gti", "_gtidownloadglihelp_");
+  } else {
+    disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]);
+  }
   disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
   disp.setmacro("gtiviewtranslationfileinaction", "gti", "_gti:gtiview" + translation_file_key + "inaction_");
@@ -618,8 +626,15 @@
   text_t target_language_code = args["tlc"];
   text_t translation_file_key = args["tfk"];
+  text_t target_chunk_type = args["tct"];
 
   // Send a request to gti.pl to get the Excel spreadsheet data
-  text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + "10000" + " | java -cp /home/nzdl/gti ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
-  text_t gti_response_xml_text = do_gti_request(gti_arguments, logout);
+  text_t gti_arguments = "";
+  if (target_chunk_type == "work") {
+    gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + "10000" + " | /opt/jdk1.6.0/bin/java -cp /home/nzdl/gti:/home/nzdl/gti/xalan.jar ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
+  } else {
+    gti_arguments = "get-all-chunks " + target_language_code + " " + translation_file_key + " | /opt/jdk1.6.0/bin/java -cp /home/nzdl/gti:/home/nzdl/gti/xalan.jar ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
+  }
+  
+  text_t gti_response_xml_text = do_gti_request(gti_arguments, logout);  
   if (gti_response_xml_text == "") {
     // An error has occurred
@@ -635,4 +650,15 @@
 }
 
+bool gtiaction::produce_glihelp_zipfile(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+ text_t target_language_code = args["tlc"];
+ text_t gti_arguments = "create-glihelp-zip-file " + target_language_code;
+
+ do_gti_request(gti_arguments, logout); 
+
+ disp.setmacro("gtiglihelpzipfilepath", "gti", target_language_code + "_GLIHelp.zip");
+
+ return true;
+}
 
 
Index: /gsdl/trunk/runtime-src/src/recpt/gtiaction.h
===================================================================
--- /gsdl/trunk/runtime-src/src/recpt/gtiaction.h	(revision 18459)
+++ /gsdl/trunk/runtime-src/src/recpt/gtiaction.h	(revision 18460)
@@ -118,4 +118,6 @@
 
   bool produce_excel_spreadsheet(cgiargsclass& args, ostream& logout);
+
+  bool produce_glihelp_zipfile(displayclass& disp, cgiargsclass& args, ostream& logout);
 };
 
