////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

/** integrateLocDiffs.as
/*   This script integrates translated versions of diff files (generated by generateLocalDiffs.abc) back
*      into the full, translated version of that file.  Arguments include

*      existingFile:   the filename of the full, current localized version
*      localizedDiffs: The filename of the translated version of the xml diff file. 
*                      The english diff file is generated by running generateLocalDiffs.abc on two 
*					   revisions of the English master file.  The translated diff file is what is used as an argument here  
*      integratedFile: This is the filename of the output, integrated file.
*      keyword: This is the tag name in the original file of the items which are being translated 
*               (error or warning for us)
*      baseTag: This is the  name of the parent xml element of the keyword tags.  Omitted or "" for error files, 
*               "warnings" for warning files.
*
*      chris nuuja  6/25/06
*/

import avmplus.*
		
if (System.argv.length != 4 && System.argv.length != 5)
{
	trace("Usage avmplus integrateLocDiffs.abc -- originalFile diffFile newFile tagNameToReplace optionalBaseTagName " );
}
else
{
	var origFile:String = System.argv[0];
	var localizedDiffFile:String = System.argv[1];
	var outputFile:String = System.argv[2];
	var keyword:String = String(System.argv[3]); 
	var baseTag:String = System.argv[4] == undefined ? null : String(System.argv[4]);
	if (baseTag == "")
		baseTag = null;
	trace("BaseTag: " + baseTag);
	
	var existingFile:XML = XML(File.read(origFile));
	var localizedDiffs:XML = XML(File.read(localizedDiffFile));
	trace(existingFile[baseTag]);

	// Append the new entries from the diff file into the existingFile
	for each (var w:XML in localizedDiffs..New)
	{
		var newElement:XML = <{keyword} id={w.@id} label={w.@label}>{String(w)}</{keyword}>;	
		if (baseTag)
			existingFile[baseTag].appendChild(newElement);
		else
			existingFile.appendChild(newElement);
	}
	
	// replace text of old keyword tags with updated version from diff file.
	for each (var changedElement:XML in localizedDiffs..changed)
	{
		var oldElement:XMLList = null; // always a single element XMLList for our data.  @ids are unique
		
		if (baseTag)
			oldElement = existingFile[baseTag].descendants(keyword).(@id == changedElement.@id);
		else
			oldElement = existingFile.descendants(keyword).(@id == changedElement.@id);

		delete changedElement.originalText; // this was only added to the diff file to aid localizers
		
		// hack to keep our current description tag while replacing the simple text string child of oldElement
		var temp:XMLList = oldElement.description;	// keep the description,
		oldElement.setChildren(String(changedElement)); //  but replace the text.  Is this really the only way to replace the text?
		if (temp != null)
			oldElement.appendChild(temp);
	}
	
	// output the result.
	var s:String = "<?xml version='1.0' encoding='utf-8' standalone='no' ?>\n";
	s += existingFile.toXMLString()
	File.write(outputFile, s);
}