/*
 *****************************************************************************
 * Copyright (C) 2000-2004, International Business Machines Corporation and  *
 * others. All Rights Reserved.                                              *
 *****************************************************************************
 */
package com.ibm.rbm;

import java.io.*;
import javax.swing.*;
import java.util.*;

/**
 * This class provides a plug-in exporter utility for RBManager that outputs ICU
 * resource bundle files in the according to the file structure of Resource
 * Bundles. Most of the meta-data is lost in this export.
 * 
 * @author George Rhoten
 * @see com.ibm.rbm.RBManager
 */
public class RBICUExporter extends RBExporter {
    /** Do characters beyond \\u007f need \\u escape notation? */
    private boolean escapeNonAscii = false;

    /** Write the meta data for each resource? */
    private boolean writeMetaData = true;
	
    /** Write the groups as keys? */
    private boolean writeGroupsAsKeys = false;

    public RBICUExporter() {
        super();
		
        // Initialize the file chooser if necessary
        if (chooser == null) {
            chooser = new JFileChooser();
            chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){
                public String getDescription() {
                    return "root ICU File";
                }
                public boolean accept(File f) {
                    if (f.isDirectory()) return true;
                    return (f.getName().startsWith("root."));
                }
            });
        } // end if
    }
	
    public void export(RBManager rbm) throws IOException {
        if (rbm == null) return;
        // Open the Save Dialog
        int ret_val = chooser.showSaveDialog(null);
        if (ret_val != JFileChooser.APPROVE_OPTION) {
            return;
        }
        // Retrieve basic file information
        File file = chooser.getSelectedFile();                  // The file(s) we will be working with
        File directory = new File(file.getParent());            // The directory we will be writing to
        String base_name = file.getName();                      // The base name of the files we will write
        if (base_name == null || base_name.equals("")) {
            base_name = rbm.getBaseClass();
        }
        if (base_name.toLowerCase().endsWith(".properties")) {
            base_name = base_name.substring(0,base_name.length()-11);
        }
		
        Vector bundle_v = rbm.getBundles();
        for (int i=0; i < bundle_v.size(); i++) {
            Bundle bundle = (Bundle)bundle_v.elementAt(i);
            String base_enc = base_name;
            if (bundle.encoding != null && !bundle.encoding.equals("")) {
                base_enc = base_enc + "_" + bundle.encoding;
            }
            String file_name = base_enc + ".txt";
            String header = "\ufeff// Resource Bundle: " + file_name + " - File automatically generated by RBManager at " + (new Date());

            OutputStream fos = new FileOutputStream(new File(directory, file_name));
            PrintWriter resOut = new PrintWriter(new OutputStreamWriter(fos, "UTF-8"));

            Vector group_v = bundle.getGroupsAsVector();
            resOut.println(header);
            resOut.println(base_enc + " { ");
            for (int j=0; j < group_v.size(); j++) {
                BundleGroup group = (BundleGroup)group_v.elementAt(j);

                Vector itemVect = group.getItemsAsVector();
                int itemVectSize = itemVect.size();
                if (itemVectSize > 0) {
                    if (writeMetaData) {
                        String groupComment = group.getComment();
                        if (groupComment != null && !groupComment.equals("")) {
                            resOut.println("    // @groupComment " + groupComment);
                        }
                    }

                    boolean writeGroupName = !bundle.getUngroupedGroup().getName().equals(group.getName());
                    if (writeGroupName) {
	                    if (writeGroupsAsKeys) {
		                    resOut.println("    " + escapeString(group.getName(), true) + " { ");
	                    }
	                    else if (writeMetaData) {
		                    resOut.println("    // @group " + escapeString(group.getName(), true));
	                    }
                    }
                    for (int k=0; k < itemVectSize; k++) {
                        BundleItem item = (BundleItem)itemVect.elementAt(k);

                        if (writeMetaData) {
                            resOut.print("        //");
                            resOut.print(" @translated " + item.isTranslated());
                            resOut.print(" @created " + item.getCreatedDate());
                            resOut.print(" @modified " + item.getModifiedDate());
                            resOut.print(" @creator " + item.getCreator());
                            resOut.println(" @modifier " + item.getModifier());
                            String itemComment = item.getComment();
                            if (itemComment != null && !itemComment.equals("")) {
                                resOut.println("        // @comment " + itemComment);
                            }
                        }

                        resOut.println("        " + escapeString(item.getKey(), true)
                                       + " { " + escapeString(item.getTranslation(), false) + " }");
                    } // end for - k
                    if (writeGroupName && writeGroupsAsKeys) {
	                    resOut.println("    }");
                    }
                }
            } // end for - j
            resOut.println("}");
			
            // Write out the file
            resOut.close();
            fos.close();
        } // end for - i
    }

    /**
     * Escape a string according to how the ICU tool "genrb" handles strings.
     * @param str The string to escape
     * @param isKey If this is a key, then quotes are optional.
     * @return A string that can be used in an ICU resource bundle.
     */
    protected String escapeString(String str, boolean isKey) throws IOException {
        StringBuffer strBuf = new StringBuffer();
        int len = str.length();
        boolean quoteRequired = !isKey;
        for (int idx = 0; idx < len; idx++) {
            int ch = str.charAt(idx);
            if (ch <= ' ' || '~' < ch) {
                if (isKey && ch != ' ') {
                    IOException e = new IOException(str + " needs to use invariant characters for the key.");
                    e.fillInStackTrace();
                    throw e;
                } else if (escapeNonAscii && ch != ' ') {
                    String zeros;
                    String hexNum;
                    if ((ch & 0xf800) == 0xd800) {
                        // We assume that we found a valid UTF-16 string with a surrogate
                        int ch2 = str.charAt(idx++);
                        int chSurrogate = (((ch)<<10)+(ch2)-((0xd800<<10)+0xdc00-0x10000));

                        zeros = "00000000";
                        hexNum = Integer.toHexString(chSurrogate);
                        strBuf.append("\\U");
                    } else {
                        zeros = "0000";
                        hexNum = Integer.toHexString(ch);
                        strBuf.append("\\u");
                    }
                    strBuf.append(zeros.substring(hexNum.length()) + hexNum.toUpperCase());
                } else {
                    quoteRequired = true;
                    strBuf.append(ch);
                }
            } else if (ch == '\"') {
                quoteRequired = true;
                strBuf.append("\\\"");
            } else  {
                if (ch == '{' || ch == '}') {
                    quoteRequired = true;
                }
                strBuf.append(ch);
            }
        }
        if (quoteRequired) {
            strBuf.insert(0, '\"');
            strBuf.append('\"');
        }
        return strBuf.toString();
    }
}