/*
 ******************************************************************************
 * Copyright (C) 2003-2007, International Business Machines Corporation and   *
 * others. All Rights Reserved.                                               *
 ******************************************************************************
 */

package com.ibm.icu.dev.tool.localeconverter;

import com.ibm.icu.dev.tool.UOption;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.XMLConstants;

import java.io.*;
import java.util.*;
import java.text.*;

public final class XLIFF2ICUConverter {
    
    /**
     * These must be kept in sync with getOptions().
     */
    private static final int HELP1 = 0;
    private static final int HELP2 = 1;
    private static final int SOURCEDIR = 2;
    private static final int DESTDIR = 3;
    private static final int TARGETONLY = 4;
    private static final int SOURCEONLY = 5;
    private static final int MAKE_SOURCE_ROOT = 6;
    private static final int XLIFF_1_0 = 7;
       
    private static final UOption[] options = new UOption[] {
        UOption.HELP_H(),
        UOption.HELP_QUESTION_MARK(),
        UOption.SOURCEDIR(),
        UOption.DESTDIR(),
        UOption.create("target-only", 't', UOption.OPTIONAL_ARG),
        UOption.create("source-only", 'c', UOption.OPTIONAL_ARG),
        UOption.create("make-source-root", 'r', UOption.NO_ARG),
        UOption.create("xliff-1.0", 'x', UOption.NO_ARG)
    };
    
    private static final int ARRAY_RESOURCE     = 0;
    private static final int ALIAS_RESOURCE     = 1;
    private static final int BINARY_RESOURCE    = 2;
    private static final int INTEGER_RESOURCE   = 3;
    private static final int INTVECTOR_RESOURCE = 4;
    private static final int TABLE_RESOURCE     = 5;
    
    private static final String NEW_RESOURCES[] = {
        "x-icu-array",
        "x-icu-alias",
        "x-icu-binary",
        "x-icu-integer",
        "x-icu-intvector",
        "x-icu-table"
    };
    
    private static final String OLD_RESOURCES[] = {
        "array",
        "alias",
        "bin",
        "int",
        "intvector",
        "table"
    };
    
    private String resources[];
    
    private static final String ROOT            = "root";
    private static final String RESTYPE         = "restype";
    private static final String RESNAME         = "resname";
    //private static final String YES             = "yes";
    //private static final String NO              = "no";
    private static final String TRANSLATE       = "translate";
    //private static final String BODY            = "body";
    private static final String GROUPS          = "group";
    private static final String FILES           = "file";
    private static final String TRANSUNIT       = "trans-unit";
    private static final String BINUNIT         = "bin-unit";
    private static final String BINSOURCE       = "bin-source";
    //private static final String TS              = "ts";
    //private static final String ORIGINAL        = "original";
    private static final String SOURCELANGUAGE  = "source-language";
    private static final String TARGETLANGUAGE  = "target-language";
    private static final String TARGET          = "target";
    private static final String SOURCE          = "source";
    private static final String NOTE            = "note";
    private static final String XMLLANG         = "xml:lang";
    private static final String FILE            = "file";
    private static final String INTVECTOR       = "intvector";
    private static final String ARRAYS          = "array";
    private static final String STRINGS         = "string";
    private static final String BIN             = "bin";
    private static final String INTS            = "int";
    private static final String TABLE           = "table";
    private static final String IMPORT          = "import";
    private static final String HREF            = "href";
    private static final String EXTERNALFILE    = "external-file";
    private static final String INTERNALFILE    = "internal-file";
    private static final String ALTTRANS        = "alt-trans";
    private static final String CRC             = "crc";
    private static final String ALIAS           = "alias";
    private static final String LINESEP         = System.getProperty("line.separator");
    private static final String BOM             = "\uFEFF";
    private static final String CHARSET         = "UTF-8";
    private static final String OPENBRACE       = "{";
    private static final String CLOSEBRACE      = "}";
    private static final String COLON           = ":";
    private static final String COMMA           = ",";
    private static final String QUOTE           = "\"";
    private static final String COMMENTSTART    = "/**";
    private static final String COMMENTEND      = " */";
    private static final String TAG             = " * @";
    private static final String COMMENTMIDDLE   = " * ";
    private static final String SPACE           = " ";
    private static final String INDENT          = "    ";
    private static final String EMPTY           = "";
    private static final String ID              = "id";
    
    public static void main(String[] args) {
        XLIFF2ICUConverter cnv = new XLIFF2ICUConverter();
        cnv.processArgs(args);
    }
    private String    sourceDir      = null;
    //private String    fileName       = null;
    private String    destDir        = null;
    private boolean   targetOnly     = false;
    private String    targetFileName = null; 
    private boolean   makeSourceRoot = false;
    private String    sourceFileName = null;
    private boolean   sourceOnly     = false;
    private boolean   xliff10        = false;
    
    private void processArgs(String[] args) {
        int remainingArgc = 0;
        try{
            remainingArgc = UOption.parseArgs(args, options);
        }catch (Exception e){
            System.err.println("ERROR: "+ e.toString());
            usage();
        }
        if(args.length==0 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
            usage();
        }
        if(remainingArgc==0){
            System.err.println("ERROR: Either the file name to be processed is not "+
                               "specified or the it is specified after the -t/-c \n"+
                               "option which has an optional argument. Try rearranging "+
                               "the options.");
            usage();
        }
        if(options[SOURCEDIR].doesOccur) {
            sourceDir = options[SOURCEDIR].value;
        }
        
        if(options[DESTDIR].doesOccur) {
            destDir = options[DESTDIR].value;
        }
        
        if(options[TARGETONLY].doesOccur){
            targetOnly = true;
            targetFileName = options[TARGETONLY].value;
        }
        
        if(options[SOURCEONLY].doesOccur){
            sourceOnly = true;
            sourceFileName = options[SOURCEONLY].value;
        }
        
        if(options[MAKE_SOURCE_ROOT].doesOccur){
            makeSourceRoot = true;
        }
        
        if(options[XLIFF_1_0].doesOccur) {
            xliff10 = true;
        }
        
        if(destDir==null){
            destDir = ".";
        }
        
        if(sourceOnly == true && targetOnly == true){
            System.err.println("--source-only and --target-only are specified. Please check the arguments and try again.");
            usage();
        }
        
        for (int i = 0; i < remainingArgc; i++) {
            //int lastIndex = args[i].lastIndexOf(File.separator, args[i].length()) + 1; /* add 1 to skip past the separator */
            //fileName = args[i].substring(lastIndex, args[i].length());
            String xmlfileName = getFullPath(false,args[i]);
            System.out.println("Processing file: "+xmlfileName);
            createRB(xmlfileName);
        }
    }
    
    private void usage() {
        System.out.println("\nUsage: XLIFF2ICUConverter [OPTIONS] [FILES]\n\n"+
            "This program is used to convert XLIFF files to ICU ResourceBundle TXT files.\n"+
            "Please refer to the following options. Options are not case sensitive.\n"+
            "Options:\n"+
            "-s or --sourcedir          source directory for files followed by path, default is current directory.\n" +
            "-d or --destdir            destination directory, followed by the path, default is current directory.\n" +
            "-h or -? or --help         this usage text.\n"+
            "-t or --target-only        only generate the target language txt file, followed by optional output file name.\n" +
            "                           Cannot be used in conjunction with --source-only.\n"+
            "-c or --source-only        only generate the source language bundle followed by optional output file name.\n"+
            "                           Cannot be used in conjunction with --target-only.\n"+
            "-r or --make-source-root   produce root bundle from source elements.\n" +
            "-x or --xliff-1.0          source file is XLIFF 1.0" +
            "example: com.ibm.icu.dev.tool.localeconverter.XLIFF2ICUConverter -t <optional argument> -s xxx -d yyy myResources.xlf");
        System.exit(-1);
    }
    
    private String getFullPath(boolean fileType, String fName){
        String str;
        int lastIndex1 = fName.lastIndexOf(File.separator, fName.length()) + 1; /*add 1 to skip past the separator*/
        int lastIndex2 = fName.lastIndexOf('.', fName.length());
        if (fileType == true) {
            if(lastIndex2 == -1){
                fName = fName.trim() + ".txt";
            }else{
                if(!fName.substring(lastIndex2).equalsIgnoreCase(".txt")){
                    fName =  fName.substring(lastIndex1,lastIndex2) + ".txt";
                }
            }
            if (destDir != null && fName != null) {
                str = destDir + File.separator + fName.trim();                   
            } else {
                str = System.getProperty("user.dir") + File.separator + fName.trim();
            }
        } else {
            if(lastIndex2 == -1){
                fName = fName.trim() + ".xlf";
            }else{
                if(!fName.substring(lastIndex2).equalsIgnoreCase(".xml") && fName.substring(lastIndex2).equalsIgnoreCase(".xlf")){
                    fName = fName.substring(lastIndex1,lastIndex2) + ".xlf";
                }
            }
            if(sourceDir != null && fName != null) {
                str = sourceDir + File.separator + fName;
            } else if (lastIndex1 > 0) {
                str = fName;
            } else {
                str = System.getProperty("user.dir") + File.separator + fName;
            }
        }
        return str;
    }   

    /*
     * Utility method to translate a String filename to URL.  
     *
     * Note: This method is not necessarily proven to get the 
     * correct URL for every possible kind of filename; it should 
     * be improved.  It handles the most common cases that we've 
     * encountered when running Conformance tests on Xalan.
     * Also note, this method does not handle other non-file:
     * flavors of URLs at all.
     *
     * If the name is null, return null.
     * If the name starts with a common URI scheme (namely the ones 
     * found in the examples of RFC2396), then simply return the 
     * name as-is (the assumption is that it's already a URL)
     * Otherwise we attempt (cheaply) to convert to a file:/// URL.
     */
    private static String filenameToURL(String filename){
        // null begets null - something like the commutative property
        if (null == filename){
            return null;
        }

        // Don't translate a string that already looks like a URL
        if (filename.startsWith("file:")
            || filename.startsWith("http:")
            || filename.startsWith("ftp:")
            || filename.startsWith("gopher:")
            || filename.startsWith("mailto:")
            || filename.startsWith("news:")
            || filename.startsWith("telnet:")
           ){
               return filename;
           }
        

        File f = new File(filename);
        String tmp = null;
        try{
            // This normally gives a better path
            tmp = f.getCanonicalPath();
        }catch (IOException ioe){
            // But this can be used as a backup, for cases 
            //  where the file does not exist, etc.
            tmp = f.getAbsolutePath();
        }

        // URLs must explicitly use only forward slashes
        if (File.separatorChar == '\\') {
            tmp = tmp.replace('\\', '/');
        }
        // Note the presumption that it's a file reference
        // Ensure we have the correct number of slashes at the 
        //  start: we always want 3 /// if it's absolute
        //  (which we should have forced above)
        if (tmp.startsWith("/")){
            return "file://" + tmp;
        }
        else{
            return "file:///" + tmp;
        }
    }
    private boolean isXmlLang (String lang){

        int suffix;
        char c;
        
        if (lang.length () < 2){
            return false;
        }

        c = lang.charAt(1);
        if (c == '-') {        
            c = lang.charAt(0);
            if (!(c == 'i' || c == 'I' || c == 'x' || c == 'X')){
                return false;
            }
            suffix = 1;
        } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
            c = lang.charAt(0);
            if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))){
                return false;
            }
            suffix = 2;
        } else{
            return false;
        }
        while (suffix < lang.length ()) {
            c = lang.charAt(suffix);
            if (c != '-'){
                break;
            }
            while (++suffix < lang.length ()) {
                c = lang.charAt(suffix);
                if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))){
                    break;
                }
            }
        }
        return  ((lang.length() == suffix) && (c != '-'));
    }
    
    private void createRB(String xmlfileName) {
       
        String urls = filenameToURL(xmlfileName);
        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
        dfactory.setNamespaceAware(true);
        Document doc = null;
        
        if (xliff10) {
            dfactory.setValidating(true);
            resources = OLD_RESOURCES;
        } else {
            try {
                SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                Schema schema = schemaFactory.newSchema();
                
                dfactory.setSchema(schema);
            } catch (SAXException e) {
                System.err.println("Can't create the schema...");
                System.exit(-1);
            }
            
            resources = NEW_RESOURCES;
        }
        
        ErrorHandler nullHandler = new ErrorHandler() {
            public void warning(SAXParseException e) throws SAXException {
                            
            }
            public void error(SAXParseException e) throws SAXException {
                System.err.println("The XLIFF document is invalid, please check it first: ");
                System.err.println("Line "+e.getLineNumber()+", Column "+e.getColumnNumber());
                System.err.println("Error: " + e.getMessage());
                System.exit(-1);
            }
            public void fatalError(SAXParseException e) throws SAXException {
                throw e;
            }
        };
        
        try {
            DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
            docBuilder.setErrorHandler(nullHandler);
            doc = docBuilder.parse(new InputSource(urls));
            
            NodeList nlist = doc.getElementsByTagName(FILES);
            if(nlist.getLength()>1){
                throw new RuntimeException("Multiple <file> elements in the XLIFF file not supported.");
            }
                        
            // get the value of source-language attribute
            String sourceLang = getLanguageName(doc, SOURCELANGUAGE);
            // get the value of target-language attribute
            String targetLang = getLanguageName(doc, TARGETLANGUAGE);
            
            // get the list of <source> elements
            NodeList sourceList = doc.getElementsByTagName(SOURCE);
            // get the list of target elements
            NodeList targetList = doc.getElementsByTagName(TARGET);
            
            // check if the xliff file has source elements in multiple languages
            // the source-language value should be the same as xml:lang values
            // of all the source elements.
            String xmlSrcLang = checkLangAttribute(sourceList, sourceLang);
            
            // check if the xliff file has target elements in multiple languages
            // the target-language value should be the same as xml:lang values
            // of all the target elements.
            String xmlTargetLang = checkLangAttribute(targetList, targetLang);
            
            // Create the Resource linked list which will hold the
            // source and target bundles after parsing
            Resource[] set = new Resource[2];
            set[0] = new ResourceTable();
            set[1] = new ResourceTable();
            
            // lenient extraction of source language
            if(makeSourceRoot == true){ 
                set[0].name = ROOT;
            }else if(sourceLang!=null){
                set[0].name = sourceLang.replace('-','_');
            }else{
                if(xmlSrcLang != null){
                    set[0].name = xmlSrcLang.replace('-','_');
                }else{
                    System.err.println("ERROR: Could not figure out the source language of the file. Please check the XLIFF file.");
                    System.exit(-1);
                }
            }
            
            // lenient extraction of the target language
            if(targetLang!=null){
                set[1].name = targetLang.replace('-','_');
            }else{
                if(xmlTargetLang!=null){
                    set[1].name = xmlTargetLang.replace('-','_');
                }else{
                    System.err.println("WARNING: Could not figure out the target language of the file. Producing source bundle only.");
                }
            }
   
            
            // check if any <alt-trans> elements are present
            NodeList altTrans = doc.getElementsByTagName(ALTTRANS);
            if(altTrans.getLength()>0){
                System.err.println("WARNING: <alt-trans> elements in found. Ignoring all <alt-trans> elements.");
            }
            
            // get all the group elements
            NodeList list = doc.getElementsByTagName(GROUPS);
            
            // process the first group element. The first group element is 
            // the base table that must be parsed recursively
            parseTable(list.item(0), set);
            
            // write out the bundle
            writeResource(set, xmlfileName);
         }
        catch (Throwable se) {
            System.err.println("ERROR: " + se.toString());
            System.exit(1);
        }        
    }
    
    private void writeResource(Resource[] set, String xmlfileName){
        if(targetOnly==false){
            writeResource(set[0], xmlfileName, sourceFileName);
        }
        if(sourceOnly == false){
            if(targetOnly==true && set[1].name == null){
                throw new RuntimeException("The "+ xmlfileName +" does not contain translation\n");
            }
            if(set[1].name != null){
                writeResource(set[1], xmlfileName, targetFileName);
            }
        }
    }
    
    private void writeResource(Resource set, String sourceFilename, String targetFilename){
        try {
            String outputFileName = null;
            if(targetFilename != null){
                outputFileName = destDir+File.separator+targetFilename+".txt";
            }else{
                outputFileName = destDir+File.separator+set.name+".txt";
            }
            FileOutputStream file = new FileOutputStream(outputFileName);
            BufferedOutputStream writer = new BufferedOutputStream(file);

            writeHeader(writer,sourceFilename);
            
            //Now start writing the resource;
            Resource current = set;
            while(current!=null){
                current.write(writer, 0, false);
                current = current.next;
            }
            writer.flush();
            writer.close();
        } catch (Exception ie) {
            System.err.println("ERROR :" + ie.toString());
            return;
        }
    }
    
    private String getLanguageName(Document doc, String lang){
        if(doc!=null){
            NodeList list = doc.getElementsByTagName(FILE);
            Node node = list.item(0);
            NamedNodeMap attr = node.getAttributes();
            Node orig = attr.getNamedItem(lang);
            
            if(orig != null){
                String name = orig.getNodeValue();
                NodeList groupList = doc.getElementsByTagName(GROUPS);
                Node group = groupList.item(0);
                NamedNodeMap groupAtt = group.getAttributes();
                Node id = groupAtt.getNamedItem(ID);
                if(id!=null){
                    String idVal = id.getNodeValue();
                    
                    if(!name.equals(idVal)){
                        System.out.println("WARNING: The id value != language name. " +
                                           "Please compare the output with the orignal " +
                                           "ICU ResourceBundle before proceeding.");
                    }
                }
                if(!isXmlLang(name)){
                    System.err.println("The attribute "+ lang + "=\""+ name +
                                       "\" of <file> element does not satisfy RFC 1766 conditions.");
                    System.exit(-1);
                }
                return name;
            }
        }
        return null;
    }
    
    // check if the xliff file is translated into multiple languages
    // The XLIFF specification allows for single <target> element
    // as the child of <trans-unit> but the attributes of the 
    // <target> element may different across <trans-unit> elements
    // check for it. Similar is the case with <source> elements
    private String checkLangAttribute(NodeList list, String origName){
        String oldLangName=origName;
        for(int i = 0 ;i<list.getLength(); i++){
            Node node = list.item(i);
            NamedNodeMap attr = node.getAttributes();
            Node lang = attr.getNamedItem(XMLLANG);
            String langName = null;
            // the target element should always contain xml:lang attribute
            if(lang==null ){
                if(origName==null){
                    System.err.println("Encountered <target> element without xml:lang attribute. Please fix the below element in the XLIFF file.\n"+ node.toString());
                    System.exit(-1);
                }else{
                    langName = origName;
                }
            }else{
                langName = lang.getNodeValue();
            }

            if(oldLangName!=null && langName!=null && !langName.equals(oldLangName)){
                throw new RuntimeException("The <trans-unit> elements must be bilingual, multilingual tranlations not supported. xml:lang = " + oldLangName + 
                                           " and xml:lang = " + langName);
            }
            oldLangName = langName;
        }
        return oldLangName;
    }
    
    private class Resource{
        String[] note = new String[20];
        int noteLen = 0;
        String translate;
        String comment;
        String name;
        Resource next;
        public String escapeSyntaxChars(String val){
            // escape the embedded quotes
            char[] str = val.toCharArray();
            StringBuffer result = new StringBuffer();
            for(int i=0; i<str.length; i++){
                switch (str[i]){
                    case '\u0022':
                        result.append('\\'); //append backslash
                    default:
                        result.append(str[i]);
                }      
            }
            return result.toString();
        }
        public void write(OutputStream writer, int numIndent, boolean bare){
            while(next!=null){
                next.write(writer, numIndent+1, false);
            }
        }
        public void writeIndent(OutputStream writer, int numIndent){
            for(int i=0; i< numIndent; i++){
                write(writer,INDENT);
            }
        }
        public void write(OutputStream writer, String value){
            try {
                byte[] bytes = value.getBytes(CHARSET);
                writer.write(bytes, 0, bytes.length);
            } catch(Exception e) {
                System.err.println(e);
                System.exit(1);
            }
        }
        public void writeComments(OutputStream writer, int numIndent){
            boolean translateIsDefault = translate == null || translate.equals("yes");
            
            if(comment!=null || ! translateIsDefault || noteLen > 0){
                // print the start of the comment
                writeIndent(writer, numIndent);
                write(writer, COMMENTSTART+LINESEP);
                
                // print comment if any
                if(comment!=null){
                    writeIndent(writer, numIndent);
                    write(writer, COMMENTMIDDLE);
                    write(writer, comment);
                    write(writer, LINESEP);
                }
                
                // print the translate attribute if any
                if(! translateIsDefault){
                    writeIndent(writer, numIndent);
                    write(writer, TAG+TRANSLATE+SPACE);
                    write(writer, translate);
                    write(writer, LINESEP);
                }
                
                // print note elements if any
                for(int i=0; i<noteLen; i++){
                    if(note[i]!=null){
                        writeIndent(writer, numIndent);
                        write(writer, TAG+NOTE+SPACE+note[i]);
                        write(writer, LINESEP);
                    }
                }
                
                // terminate the comment
                writeIndent(writer, numIndent);
                write(writer, COMMENTEND+LINESEP);
            }          
        }
    }

    private class ResourceString extends Resource{
        String val;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            if(bare==true){
                if(name!=null){
                    throw new RuntimeException("Bare option is set to true but the resource has a name!");
                }
                
                write(writer,QUOTE+escapeSyntaxChars(val)+QUOTE); 
            }else{
                write(writer, name+COLON+STRINGS+ OPENBRACE + QUOTE + escapeSyntaxChars(val) + QUOTE+ CLOSEBRACE + LINESEP);
            }
        }
    }
    private class ResourceAlias extends Resource{
        String val;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            String line =  ((name==null)? EMPTY: name)+COLON+ALIAS+ OPENBRACE+QUOTE+escapeSyntaxChars(val)+QUOTE+CLOSEBRACE;
            if(bare==true){
                if(name!=null){
                    throw new RuntimeException("Bare option is set to true but the resource has a name!");
                }
                write(writer,line); 
            }else{
                write(writer, line+LINESEP);
            }
        }
    }
    private class ResourceInt extends Resource{
        String val;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            String line =  ((name==null)? EMPTY: name)+COLON+INTS+ OPENBRACE + val +CLOSEBRACE;
            if(bare==true){
                if(name!=null){
                    throw new RuntimeException("Bare option is set to true but the resource has a name!");
                }
                write(writer,line); 
            }else{
                write(writer, line+LINESEP);
            }
        }
    }
    private class ResourceBinary extends Resource{
        String internal;
        String external;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            if(internal==null){
                String line = ((name==null) ? EMPTY : name)+COLON+IMPORT+ OPENBRACE+QUOTE+external+QUOTE+CLOSEBRACE + ((bare==true) ?  EMPTY : LINESEP);
                write(writer, line);
            }else{
                String line = ((name==null) ? EMPTY : name)+COLON+BIN+ OPENBRACE+internal+CLOSEBRACE+ ((bare==true) ?  EMPTY : LINESEP);
                write(writer,line);
            }
            
        }
    }
    private class ResourceIntVector extends Resource{
        ResourceInt first;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            write(writer, name+COLON+INTVECTOR+OPENBRACE+LINESEP);
            numIndent++;
            ResourceInt current = (ResourceInt) first;
            while(current != null){
                //current.write(writer, numIndent, true);
                writeIndent(writer, numIndent);
                write(writer, current.val);
                write(writer, COMMA+LINESEP);
                current = (ResourceInt) current.next;
            }
            numIndent--;
            writeIndent(writer, numIndent);
            write(writer, CLOSEBRACE+LINESEP);
        }
    }
    private class ResourceTable extends Resource{
        Resource first;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            write(writer, name+COLON+TABLE+OPENBRACE+LINESEP);
            numIndent++;
            Resource current = first;
            while(current != null){
                current.write(writer, numIndent, false);
                current = current.next;
            }
            numIndent--;
            writeIndent(writer, numIndent);
            write(writer, CLOSEBRACE+LINESEP);
        }
    }
    private class ResourceArray extends Resource{
        Resource first;
        public void write(OutputStream writer, int numIndent, boolean bare){
            writeComments(writer, numIndent);
            writeIndent(writer, numIndent);
            write(writer, name+COLON+ARRAYS+OPENBRACE+LINESEP);
            numIndent++;
            Resource current = first;
            while(current != null){
                current.write(writer, numIndent, true);
                write(writer, COMMA+LINESEP);
                current = current.next;
            }
            numIndent--;
            writeIndent(writer, numIndent);
            write(writer, CLOSEBRACE+LINESEP);
        }
    }
    
    private String getAttributeValue(Node sNode, String attribName){
        String value=null;
        Node node = sNode;

        NamedNodeMap attributes = node.getAttributes();
        Node attr = attributes.getNamedItem(attribName);
        if(attr!=null){
            value = attr.getNodeValue();
        }

        return value;
    }
    
    private void parseResourceString(Node node, ResourceString[] set){
        ResourceString currentSource;
        ResourceString currentTarget;
        currentSource =  set[0];
        currentTarget =  set[1];
        String resName   = getAttributeValue(node, RESNAME);
        String translate = getAttributeValue(node, TRANSLATE);
        
        // loop to pickup <source>, <note> and <target> elements
        for(Node transUnit = node.getFirstChild(); transUnit!=null; transUnit = transUnit.getNextSibling()){
            short type = transUnit.getNodeType();
            String name = transUnit.getNodeName();
            if(type == Node.COMMENT_NODE){
                // get the comment
               currentSource.comment =  currentTarget.comment = transUnit.getNodeValue();
            }else if( type == Node.ELEMENT_NODE){
                if(name.equals(SOURCE)){
                    // save the source and target values
                    currentSource.name = currentTarget.name = resName;
                    currentSource.val = currentTarget.val = transUnit.getFirstChild().getNodeValue();
                    currentSource.translate = currentTarget.translate = translate;
                }else if(name.equals(NOTE)){
                    // save the note values
                    currentSource.note[currentSource.noteLen++] = 
                        currentTarget.note[currentTarget.noteLen++] =
                        transUnit.getFirstChild().getNodeValue();
                }else if(name.equals(TARGET)){
                    // if there is a target element replace it
                    currentTarget.val = transUnit.getFirstChild().getNodeValue();
                }
            }
            
        }
    }

    private void parseResourceInt(Node node, ResourceInt[] set){
        ResourceInt currentSource;
        ResourceInt currentTarget;
        currentSource =  set[0];
        currentTarget =  set[1];
        String resName   = getAttributeValue(node, RESNAME);
        String translate = getAttributeValue(node, TRANSLATE);
        // loop to pickup <source>, <note> and <target> elements
        for(Node transUnit = node.getFirstChild(); transUnit!=null; transUnit = transUnit.getNextSibling()){
            short type = transUnit.getNodeType();
            String name = transUnit.getNodeName();
            if(type == Node.COMMENT_NODE){
                // get the comment
               currentSource.comment =  currentTarget.comment = transUnit.getNodeValue();
            }else if( type == Node.ELEMENT_NODE){
                if(name.equals(SOURCE)){
                    // save the source and target values
                    currentSource.name = currentTarget.name = resName;
                    currentSource.translate = currentTarget.translate = translate;
                    currentSource.val = currentTarget.val = transUnit.getFirstChild().getNodeValue();
                }else if(name.equals(NOTE)){
                    // save the note values
                    currentSource.note[currentSource.noteLen++] = 
                        currentTarget.note[currentTarget.noteLen++] =
                        transUnit.getFirstChild().getNodeValue();
                }else if(name.equals(TARGET)){
                    // if there is a target element replace it
                    currentTarget.val = transUnit.getFirstChild().getNodeValue();
                }
            }
            
        }
    }
    
    private void parseResourceAlias(Node node, ResourceAlias[] set){
        ResourceAlias currentSource;
        ResourceAlias currentTarget;
        currentSource =  set[0];
        currentTarget =  set[1];
        String resName   = getAttributeValue(node, RESNAME);
        String translate = getAttributeValue(node, TRANSLATE);
        // loop to pickup <source>, <note> and <target> elements
        for(Node transUnit = node.getFirstChild(); transUnit!=null; transUnit = transUnit.getNextSibling()){
            short type = transUnit.getNodeType();
            String name = transUnit.getNodeName();
            if(type == Node.COMMENT_NODE){
                // get the comment
               currentSource.comment =  currentTarget.comment = transUnit.getNodeValue();
            }else if( type == Node.ELEMENT_NODE){
                if(name.equals(SOURCE)){
                    // save the source and target values
                    currentSource.name = currentTarget.name = resName;
                    currentSource.translate = currentTarget.translate = translate;
                    currentSource.val = currentTarget.val = transUnit.getFirstChild().getNodeValue();
                }else if(name.equals(NOTE)){
                    // save the note values
                    currentSource.note[currentSource.noteLen++] = 
                        currentTarget.note[currentTarget.noteLen++] =
                        transUnit.getFirstChild().getNodeValue();
                }else if(name.equals(TARGET)){
                    // if there is a target element replace it
                    currentTarget.val = transUnit.getFirstChild().getNodeValue();
                }
            }
            
        }
    }
    private void parseResourceBinary(Node node, ResourceBinary[] set){
        ResourceBinary currentSource;
        ResourceBinary currentTarget;
        currentSource =  set[0];
        currentTarget =  set[1];

        // loop to pickup <source>, <note> and <target> elements
        for(Node transUnit = node.getFirstChild(); transUnit!=null; transUnit = transUnit.getNextSibling()){
            short type = transUnit.getNodeType();
            String name = transUnit.getNodeName();
            if(type == Node.COMMENT_NODE){
                // get the comment
               currentSource.comment =  currentTarget.comment = transUnit.getNodeValue();
            }else if( type == Node.ELEMENT_NODE){
                if(name.equals(BINSOURCE)){
                    // loop to pickup internal-file/extenal-file element
                    continue;
                }else if(name.equals(NOTE)){
                    // save the note values
                    currentSource.note[currentSource.noteLen++] = 
                        currentTarget.note[currentTarget.noteLen++] =
                        transUnit.getFirstChild().getNodeValue();
                }else if(name.equals(INTERNALFILE)){
                    // if there is a target element replace it
                    String crc = getAttributeValue(transUnit, CRC);
                    String value = transUnit.getFirstChild().getNodeValue();
                    
                    //verify that the binary value conforms to the CRC
                    if(Integer.parseInt(crc, 10) != CalculateCRC32.computeCRC32(value)) {
                        System.err.println("ERROR: CRC value incorrect! Please check.");
                        System.exit(1);
                    }
                    
                    currentTarget.internal = currentSource.internal= value;
                    
                }else if(name.equals(EXTERNALFILE)){
                    currentSource.external = getAttributeValue(transUnit, HREF);
                    currentTarget.external = currentSource.external;
                }
            }
            
        }
    }
    private void parseTransUnit(Node node, Resource[] set){

        String attrType = getAttributeValue(node, RESTYPE);
        String translate = getAttributeValue(node, TRANSLATE);
        if(attrType==null || attrType.equals(STRINGS)){
            ResourceString[] strings = new ResourceString[2];
            strings[0] = new ResourceString();
            strings[1] = new ResourceString();
            parseResourceString(node, strings);
            strings[0].translate = strings[1].translate = translate;
            set[0] = strings[0];
            set[1] = strings[1];
        }else if(attrType.equals(resources[INTEGER_RESOURCE])){
            ResourceInt[] ints = new ResourceInt[2];
            ints[0] = new ResourceInt();
            ints[1] = new ResourceInt();
            parseResourceInt(node, ints);
            ints[0].translate = ints[1].translate = translate;
            set[0] = ints[0];
            set[1] = ints[1];
        }else if(attrType.equals(resources[ALIAS_RESOURCE])){
            ResourceAlias[] ints = new ResourceAlias[2];
            ints[0] = new ResourceAlias();
            ints[1] = new ResourceAlias();
            parseResourceAlias(node, ints);
            ints[0].translate = ints[1].translate = translate;
            set[0] = ints[0];
            set[1] = ints[1];
        }
    }

    private void parseBinUnit(Node node, Resource[] set){
        if (getAttributeValue(node, RESTYPE).equals(resources[BINARY_RESOURCE])) {
            ResourceBinary[] bins = new ResourceBinary[2];
            
            bins[0] = new ResourceBinary();
            bins[1] = new ResourceBinary();
            
            Resource currentSource = bins[0];
            Resource currentTarget = bins[1];
            String resName   = getAttributeValue(node, RESNAME);
            String translate = getAttributeValue(node, TRANSLATE);
            
            currentTarget.name = currentSource.name = resName;
            currentSource.translate = currentTarget.translate = translate;
            
            for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()){
                short type = child.getNodeType();
                String name = child.getNodeName();
                
                if(type == Node.COMMENT_NODE){
                    currentSource.comment = currentTarget.comment = child.getNodeValue();
                }else if(type == Node.ELEMENT_NODE){
                    if(name.equals(BINSOURCE)){
                        parseResourceBinary(child, bins);
                    }else if(name.equals(NOTE)){
                        String note =  child.getFirstChild().getNodeValue();
                        
                        currentSource.note[currentSource.noteLen++] = currentTarget.note[currentTarget.noteLen++] = note;
                    }
                }
            }
            
            set[0] = bins[0];
            set[1] = bins[1];
        }
    }
    
    private void parseArray(Node node, Resource[] set){
        if(set[0]==null){
            set[0] = new ResourceArray();
            set[1] = new ResourceArray();
        }
        Resource currentSource = set[0];
        Resource currentTarget = set[1];
        String resName = getAttributeValue(node, RESNAME);
        currentSource.name = currentTarget.name = resName;
        boolean isFirst = true;
        
        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()){
            short type = child.getNodeType();
            String name = child.getNodeName();
            if(type == Node.COMMENT_NODE){
                currentSource.comment = currentTarget.comment = child.getNodeValue();
            }else if(type == Node.ELEMENT_NODE){
                if(name.equals(TRANSUNIT)){
                    Resource[] next = new Resource[2];
                    parseTransUnit(child, next);
                    if(isFirst==true){
                       ((ResourceArray) currentSource).first = next[0];
                       ((ResourceArray) currentTarget).first = next[1];
                       currentSource = ((ResourceArray) currentSource).first;
                       currentTarget = ((ResourceArray) currentTarget).first;
                       isFirst = false;
                    }else{
                        currentSource.next = next[0];
                        currentTarget.next = next[1];
                        // set the next pointers
                        currentSource = currentSource.next;
                        currentTarget = currentTarget.next;
                    }
                }else if(name.equals(NOTE)){
                    String note =  child.getFirstChild().getNodeValue();
                    currentSource.note[currentSource.noteLen++] = currentTarget.note[currentTarget.noteLen++] = note;
                }else if(name.equals(BINUNIT)){
                    Resource[] next = new Resource[2];
                    parseBinUnit(child, next);
                    if(isFirst==true){
                       ((ResourceArray) currentSource).first = next[0];
                       ((ResourceArray) currentTarget).first = next[1];
                       currentSource = ((ResourceArray) currentSource).first.next;
                       currentTarget = ((ResourceArray) currentTarget).first.next;
                       isFirst = false;
                    }else{
                        currentSource.next = next[0];
                        currentTarget.next = next[1];
                        // set the next pointers
                        currentSource = currentSource.next;
                        currentTarget = currentTarget.next;
                    }
                }
            }
        }
    }
    private void parseIntVector(Node node, Resource[] set){
        if(set[0]==null){
            set[0] = new ResourceIntVector();
            set[1] = new ResourceIntVector();
        }
        Resource currentSource = set[0];
        Resource currentTarget = set[1];
        String resName = getAttributeValue(node, RESNAME);
        String translate = getAttributeValue(node,TRANSLATE);
        currentSource.name = currentTarget.name = resName;
        currentSource.translate = translate;
        boolean isFirst = true;
        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()){
            short type = child.getNodeType();
            String name = child.getNodeName();
            if(type == Node.COMMENT_NODE){
                currentSource.comment = currentTarget.comment = child.getNodeValue();
            }else if(type == Node.ELEMENT_NODE){
                if(name.equals(TRANSUNIT)){
                    Resource[] next = new Resource[2];
                    parseTransUnit(child, next);
                    if(isFirst==true){
                        // the down cast should be safe .. if not something is terribly wrong!!
                       ((ResourceIntVector) currentSource).first = (ResourceInt)next[0];
                       ((ResourceIntVector) currentTarget).first = (ResourceInt) next[1];
                       currentSource = ((ResourceIntVector) currentSource).first;
                       currentTarget = ((ResourceIntVector) currentTarget).first;
                       isFirst = false;
                    }else{
                        currentSource.next = next[0];
                        currentTarget.next = next[1];
                        // set the next pointers
                        currentSource = currentSource.next;
                        currentTarget = currentTarget.next;
                    }
                }else if(name.equals(NOTE)){
                    String note =  child.getFirstChild().getNodeValue();
                    currentSource.note[currentSource.noteLen++] = currentTarget.note[currentTarget.noteLen++] = note;
                }
            }
        }
    }
    private void parseTable(Node node, Resource[] set){
        if(set[0]==null){
            set[0] = new ResourceTable();
            set[1] = new ResourceTable();
        }
        Resource currentSource = set[0];
        Resource currentTarget = set[1];
        
        String resName = getAttributeValue(node, RESNAME);
        String translate = getAttributeValue(node,TRANSLATE);
        if(resName!=null && currentSource.name==null && currentTarget.name==null){
            currentSource.name = currentTarget.name = resName;
        }
        currentTarget.translate = currentSource.translate = translate;
        
        boolean isFirst = true;
        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()){
            short type = child.getNodeType();
            String name = child.getNodeName();
            if(type == Node.COMMENT_NODE){
                currentSource.comment = currentTarget.comment = child.getNodeValue();
            }else if(type == Node.ELEMENT_NODE){
                if(name.equals(GROUPS)){
                    Resource[] next = new Resource[2];
                    parseGroup(child, next);
                    if(isFirst==true){
                        // the down cast should be safe .. if not something is terribly wrong!!
                       ((ResourceTable) currentSource).first = next[0];
                       ((ResourceTable) currentTarget).first = next[1];
                       currentSource = ((ResourceTable) currentSource).first;
                       currentTarget = ((ResourceTable) currentTarget).first;
                       isFirst = false;
                    }else{
                        currentSource.next = next[0];
                        currentTarget.next = next[1];
                        // set the next pointers
                        currentSource = currentSource.next;
                        currentTarget = currentTarget.next;
                    }
                }else if(name.equals(TRANSUNIT)){
                    Resource[] next = new Resource[2];
                    parseTransUnit(child, next);
                    if(isFirst==true){
                        // the down cast should be safe .. if not something is terribly wrong!!
                       ((ResourceTable) currentSource).first = next[0];
                       ((ResourceTable) currentTarget).first = next[1];
                       currentSource = ((ResourceTable) currentSource).first;
                       currentTarget = ((ResourceTable) currentTarget).first;
                       isFirst = false;
                    }else{
                        currentSource.next = next[0];
                        currentTarget.next = next[1];
                        // set the next pointers
                        currentSource = currentSource.next;
                        currentTarget = currentTarget.next;
                    }
                }else if(name.equals(NOTE)){
                    String note =  child.getFirstChild().getNodeValue();
                    currentSource.note[currentSource.noteLen++] = currentTarget.note[currentTarget.noteLen++] = note;
                }else if(name.equals(BINUNIT)){
                    Resource[] next = new Resource[2];
                    parseBinUnit(child, next);
                    if(isFirst==true){
                        // the down cast should be safe .. if not something is terribly wrong!!
                       ((ResourceTable) currentSource).first = next[0];
                       ((ResourceTable) currentTarget).first = next[1];
                       currentSource = ((ResourceTable) currentSource).first;
                       currentTarget = ((ResourceTable) currentTarget).first;
                       isFirst = false;
                    }else{
                        currentSource.next = next[0];
                        currentTarget.next = next[1];
                        // set the next pointers
                        currentSource = currentSource.next;
                        currentTarget = currentTarget.next;
                    }
                }
            }
        }
    }
    
    private void parseGroup(Node node, Resource[] set){

        // figure out what kind of group this is
        String resType = getAttributeValue(node, RESTYPE);
        if(resType.equals(resources[ARRAY_RESOURCE])){
            parseArray(node, set);
        }else if( resType.equals(resources[TABLE_RESOURCE])){
            parseTable(node, set);
        }else if( resType.equals(resources[INTVECTOR_RESOURCE])){
            parseIntVector(node, set);
        }
    }
    

    private void writeLine(OutputStream writer, String line) {
        try {
            byte[] bytes = line.getBytes(CHARSET);
            writer.write(bytes, 0, bytes.length);
        } catch (Exception e) {
            System.err.println(e);
            System.exit(1);
        }
    }
    
    private void writeHeader(OutputStream writer, String fileName){
        final String header = 
            "// ***************************************************************************" + LINESEP +
            "// *" + LINESEP +
            "// * Tool: com.ibm.icu.dev.tool.localeconverter.XLIFF2ICUConverter.java" + LINESEP +
            "// * Date & Time: {0,date,MM/dd/yyyy hh:mm:ss a z}"+ LINESEP +
            "// * Source File: {1}" + LINESEP +
            "// *" + LINESEP +                    
            "// ***************************************************************************" + LINESEP;
            
        writeBOM(writer);
        MessageFormat format = new MessageFormat(header);
        Object args[] = {new Date(System.currentTimeMillis()), fileName};

        writeLine(writer, format.format(args));
    }
    
    private  void writeBOM(OutputStream buffer) {
        try {
            byte[] bytes = BOM.getBytes(CHARSET);
            buffer.write(bytes, 0, bytes.length);
        } catch(Exception e) {
            System.err.println(e);
            System.exit(1);
        }
    }
}
