/*
 *  ====================================================================
 *  The Apache Software License, Version 1.1
 *
 *  Copyright (c) 2002 The Apache Software Foundation.  All rights
 *  reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in
 *  the documentation and/or other materials provided with the
 *  distribution.
 *
 *  3. The end-user documentation included with the redistribution,
 *  if any, must include the following acknowledgment:
 *  "This product includes software developed by the
 *  Apache Software Foundation (http://www.apache.org/)."
 *  Alternately, this acknowledgment may appear in the software itself,
 *  if and wherever such third-party acknowledgments normally appear.
 *
 *  4. The names "Apache" and "Apache Software Foundation" and
 *  "Apache POI" must not be used to endorse or promote products
 *  derived from this software without prior written permission. For
 *  written permission, please contact apache@apache.org.
 *
 *  5. Products derived from this software may not be called "Apache",
 *  "Apache POI", nor may "Apache" appear in their name, without
 *  prior written permission of the Apache Software Foundation.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE.
 *  ====================================================================
 *
 *  This software consists of voluntary contributions made by many
 *  individuals on behalf of the Apache Software Foundation.  For more
 *  information on the Apache Software Foundation, please see
 *  <http://www.apache.org/>.
 */
package org.apache.poi.util;

import java.io.UnsupportedEncodingException;

import java.text.NumberFormat;
import java.text.FieldPosition;

/**
 *  Title: String Utility Description: Collection of string handling utilities
 * 
 * Now it is quite confusing: the method pairs, in which
 * one of them write data and other read written data are:
 * putUncompressedUnicodeHigh and getFromUnicode
 * putUncompressedUnicode     and getFromUnicodeHigh
 *
 *@author     Andrew C. Oliver
 *@author     Sergei Kozello (sergeikozello at mail.ru)
 *@created    May 10, 2002
 *@version    1.0
 */

public class StringUtil {
    
    private final static String ENCODING="ISO-8859-1";
    /**
     *  Constructor for the StringUtil object
     */
    private StringUtil() { }

    
    /**
     *  given a byte array of 16-bit unicode characters, compress to 8-bit and
     *  return a string
     *
     * { 0x16, 0x00 } -> 0x16
     * 
     *@param  string                              the byte array to be converted
     *@param  offset                              the initial offset into the
     *      byte array. it is assumed that string[ offset ] and string[ offset +
     *      1 ] contain the first 16-bit unicode character
     *@param  len
     *@return                                     the converted string
     *@exception  ArrayIndexOutOfBoundsException  if offset is out of bounds for
     *      the byte array (i.e., is negative or is greater than or equal to
     *      string.length)
     *@exception  IllegalArgumentException        if len is too large (i.e.,
     *      there is not enough data in string to create a String of that
     *      length)
     *@len                                        the length of the final string
     */

    public static String getFromUnicodeHigh(final byte[] string,
            final int offset, final int len)
             throws ArrayIndexOutOfBoundsException, IllegalArgumentException {

        if ((offset < 0) || (offset >= string.length)) {
            throw new ArrayIndexOutOfBoundsException("Illegal offset");
        }
        if ((len < 0) || (((string.length - offset) / 2) < len)) {
            throw new IllegalArgumentException("Illegal length");
        }
        
        char[] chars = new char[ len ];
        for ( int i = 0; i < chars.length; i++ ) {
            chars[i] = (char)( string[ offset + ( 2*i ) ] & 0xFF | 
                             ( string[ offset + ( 2*i+1 ) ] << 8 ) );
        }

        return new String( chars );
    }
    
    
    /**
     *  given a byte array of 16-bit unicode characters, compress to 8-bit and
     *  return a string
     * 
     * { 0x16, 0x00 } -> 0x16
     *
     *@param  string  the byte array to be converted
     *@return         the converted string
     */

    public static String getFromUnicodeHigh( final byte[] string ) {
        return getFromUnicodeHigh( string, 0, string.length / 2 );
    }


    /**
     *  given a byte array of 16-bit unicode characters, compress to 8-bit and
     *  return a string
     * 
     * { 0x00, 0x16 } -> 0x16
     *
     *@param  string                              the byte array to be converted
     *@param  offset                              the initial offset into the
     *      byte array. it is assumed that string[ offset ] and string[ offset +
     *      1 ] contain the first 16-bit unicode character
     *@param  len
     *@return                                     the converted string
     *@exception  ArrayIndexOutOfBoundsException  if offset is out of bounds for
     *      the byte array (i.e., is negative or is greater than or equal to
     *      string.length)
     *@exception  IllegalArgumentException        if len is too large (i.e.,
     *      there is not enough data in string to create a String of that
     *      length)
     *@len                                        the length of the final string
     */

    public static String getFromUnicode(final byte[] string,
            final int offset, final int len)
             throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
        if ((offset < 0) || (offset >= string.length)) {
            throw new ArrayIndexOutOfBoundsException("Illegal offset");
        }
        if ((len < 0) || (((string.length - offset) / 2) < len)) {
            throw new IllegalArgumentException("Illegal length");
        }

        
        char[] chars = new char[ len ];
        for ( int i = 0; i < chars.length; i++ ) {
            chars[i] = (char)( ( string[ offset + ( 2*i ) ] << 8 ) +
                              string[ offset + ( 2*i+1 ) ] );
        }
        
        return new String( chars );
    }


    /**
     *  given a byte array of 16-bit unicode characters, compress to 8-bit and
     *  return a string
     * 
     * { 0x00, 0x16 } -> 0x16
     *
     *@param  string  the byte array to be converted
     *@return         the converted string
     */

    public static String getFromUnicode(final byte[] string) {
        return getFromUnicode(string, 0, string.length / 2);
    }


      /**
      * read compressed unicode(8bit)
      * 
      * @author Toshiaki Kamoshida(kamoshida.toshiaki at future dot co dot jp)
      * 
      * @param string byte array to read
      * @param offset offset to read byte array
      * @param len    length to read byte array
      * @return String generated String instance by reading byte array
      */
     public static String getFromCompressedUnicode(final byte[] string,
            final int offset, final int len){
         try{
             return new String(string,offset,len,"ISO-8859-1");
         }
         catch(UnsupportedEncodingException e){
             throw new InternalError();/* unreachable */
         }
     }

    /**
     *  write compressed unicode
     *
     *@param  input   the String containing the data to be written
     *@param  output  the byte array to which the data is to be written
     *@param  offset  an offset into the byte arrat at which the data is start
     *      when written
     */

    public static void putCompressedUnicode(final String input,
            final byte[] output,
            final int offset) {
        int strlen = input.length();

        for (int k = 0; k < strlen; k++) {
            output[offset + k] = (byte) input.charAt(k);
        }
    }


    /**
     *  Write uncompressed unicode
     *
     *@param  input   the String containing the unicode data to be written
     *@param  output  the byte array to hold the uncompressed unicode
     *@param  offset  the offset to start writing into the byte array
     */

    public static void putUncompressedUnicode(final String input,
            final byte[] output,
            final int offset) {
        int strlen = input.length();

        for (int k = 0; k < strlen; k++) {
            char c = input.charAt(k);

            output[offset + (2 * k)] = (byte) c;
            output[offset + (2 * k) + 1] = (byte) (c >> 8);
        }
    }

    /**
     *  Write uncompressed unicode
     *
     *@param  input   the String containing the unicode data to be written
     *@param  output  the byte array to hold the uncompressed unicode
     *@param  offset  the offset to start writing into the byte array
     */

    public static void putUncompressedUnicodeHigh(final String input,
            final byte[] output,
            final int offset) {
        int strlen = input.length();

        for (int k = 0; k < strlen; k++) {
            char c = input.charAt(k);

            output[offset + (2 * k)] = (byte) (c >> 8);
            output[offset + (2 * k)] = (byte) c;
        }
    }
    
    
    

    /**
     *  Description of the Method
     *
     *@param  message  Description of the Parameter
     *@param  params   Description of the Parameter
     *@return          Description of the Return Value
     */
    public static String format(String message, Object[] params) {
        int currentParamNumber = 0;
        StringBuffer formattedMessage = new StringBuffer();

        for (int i = 0; i < message.length(); i++) {
            if (message.charAt(i) == '%') {
                if (currentParamNumber >= params.length) {
                    formattedMessage.append("?missing data?");
                } else if ((params[currentParamNumber] instanceof Number)
                        && (i + 1 < message.length())) {
                    i += matchOptionalFormatting(
                            (Number) params[currentParamNumber++],
                            message.substring(i + 1), formattedMessage);
                } else {
                    formattedMessage.append(params[currentParamNumber++].toString());
                }
            } else {
                if ((message.charAt(i) == '\\') && (i + 1 < message.length())
                        && (message.charAt(i + 1) == '%')) {
                    formattedMessage.append('%');
                    i++;
                } else {
                    formattedMessage.append(message.charAt(i));
                }
            }
        }
        return formattedMessage.toString();
    }


    /**
     *  Description of the Method
     *
     *@param  number      Description of the Parameter
     *@param  formatting  Description of the Parameter
     *@param  outputTo    Description of the Parameter
     *@return             Description of the Return Value
     */
    private static int matchOptionalFormatting(Number number,
            String formatting,
            StringBuffer outputTo) {
        NumberFormat numberFormat = NumberFormat.getInstance();

        if ((0 < formatting.length())
                && Character.isDigit(formatting.charAt(0))) {
            numberFormat.setMinimumIntegerDigits(Integer.parseInt(formatting.charAt(0) + ""));
            if ((2 < formatting.length()) && (formatting.charAt(1) == '.')
                    && Character.isDigit(formatting.charAt(2))) {
                numberFormat.setMaximumFractionDigits(Integer.parseInt(formatting.charAt(2) + ""));
                numberFormat.format(number, outputTo, new FieldPosition(0));
                return 3;
            }
            numberFormat.format(number, outputTo, new FieldPosition(0));
            return 1;
        } else if ((0 < formatting.length()) && (formatting.charAt(0) == '.')) {
            if ((1 < formatting.length())
                    && Character.isDigit(formatting.charAt(1))) {
                numberFormat.setMaximumFractionDigits(Integer.parseInt(formatting.charAt(1) + ""));
                numberFormat.format(number, outputTo, new FieldPosition(0));
                return 2;
            }
        }
        numberFormat.format(number, outputTo, new FieldPosition(0));
        return 1;
    }
    
    /**
     * @return the encoding we want to use (ISO-8859-1)
     */
    public static String getPreferredEncoding() {
        return ENCODING;   
    }
}