
/* ====================================================================
 * 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.hssf.record;

import java.util.Locale;

/**
 * Title:        Format Record Factory<P>
 * Description:  builds number format according to the locale<P>
 *
 * @author Loïc Lefèvre (llefevre at apache dot org)
 * @version 2.0-pre
 */

public class FormatRecordFactory
{
	/**
	 * Customized english patterns.
	 */
	static final String[] englishFormats = new String[] { "\"$\"#,##0_);\\(\"$\"#,##0\\)",
	                                                      "\"$\"#,##0_);[Red]\\(\"$\"#,##0\\)",
	                                                      "\"$\"#,##0.00_);\\(\"$\"#,##0.00\\)",
	                                                      "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)",
	                                                      "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)",
	                                                      "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)",
	                                                      "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)",
	            					                      "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)" };

	/**
	 * Corresponding customized french patterns.
	 * (DON'T WORK PERFECTLY YET)
	 */
	static final String[] frenchFormats = new String[] { "# ##0 F_);\\(# ##0 F\\)",
	                                                     "# ##0 F_);[Rouge]\\(# ##0 F\\)",
	                                                     "# ##0,00 F_);\\(# ##0,00 F\\)",
	                                                     "# ##0,00 F_);[Rouge]\\(# ##0,00 F\\)",
	                                                     "_(* # ##0 F_);_(* \\(#_##0 F\\);_(* \"-\" F_);_(@_)",
	                                                     "_(* #_##0_);_(* \\(#_##0\\);_(* \"-\"_);_(@_)",
	                                                     "_(* # ##0,00 F_);_(* \\(# ##0,00 F\\);_(* \"-\"?? F_);_(@_)",
	            					                     "_(* # ##0,00_);_(* \\(# ##0,00\\);_(* \"-\"??_);_(@_)" };

    /**
     * Returns a localized FormatRecord object according to the format code and the default Locale.
     *
     * @param	id	the format code
     *
     * @return	a localized FormatRecord object
     */
    public static FormatRecord getInstance( short id )
    {
		return getInstance( id, Locale.getDefault() );
    }

    /**
     * Returns a localized FormatRecord object according to the format code and the given Locale.
     *
     * @param	id	the format code
     * @param	locale	the locale
     *
     * @return	a localized FormatRecord object
     */
    public static FormatRecord getInstance( short id, Locale locale )
    {
		FormatRecord fmtRecord;

		fmtRecord = new FormatRecord();

		if( "FRA".equals( locale.getISO3Country()  ) &&
		    "fra".equals( locale.getISO3Language() ) )
		{
			System.out.println( "French locale" );
			createFrenchFormat( id, fmtRecord, locale.getVariant() );
		}
		else
		{
			System.out.println( "English locale" );
			createEnglishFormat( id, fmtRecord, locale.getVariant() );
		}

		return fmtRecord;
    }

	/**
	 * Fills the FormatRecord object with the english pattern properties according to the code format.
	 *
	 * @param	id	the code format
	 * @param	fmtRecord	the FormatRecord object to be filled
	 * @param	variant	the locale variant (for example: EURO)
	 */
	protected static void createEnglishFormat( short id, FormatRecord fmtRecord, String variant )
	{
		/*
		 * Note about formats:
		 * Four parts may appear in a format, they are parted by a ';' char:
		 * -1- positiv numbers
		 * -2- negativ numbers
		 * -3- zero values
		 * -4- text
		 *
		 * If there are only two part (then one ';'), the first part represents
		 * positiv numbers and zero values, the second, the negativ numbers.
		 * If you don't need a part, eg: only 1st and 3rd, then you have to let
		 * the second part blank, for example: "$"#,##0;;"-";
		 */
		switch( id )
		{
            case 0 :
                fmtRecord.setIndexCode(( short ) 5);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 1 :
                fmtRecord.setIndexCode(( short ) 6);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 2 :
                fmtRecord.setIndexCode(( short ) 7);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 3 :
                fmtRecord.setIndexCode(( short ) 8);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 4 :
                fmtRecord.setIndexCode(( short ) 0x2a);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 5 :
                fmtRecord.setIndexCode(( short ) 0x29);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 6 :
                fmtRecord.setIndexCode(( short ) 0x2c);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;

            case 7 :
                fmtRecord.setIndexCode(( short ) 0x2b);
                fmtRecord.setFormatStringLength(( byte ) englishFormats[id].length() );
                fmtRecord.setFormatString(englishFormats[id]);
                break;
    	}
	}

	/**
	 * Fills the FormatRecord object with the french pattern properties according to the code format.
	 *
	 * @param	id	the code format
	 * @param	fmtRecord	the FormatRecord object to be filled
	 * @param	variant	the locale variant (for example: EURO)
	 */
	protected static void createFrenchFormat( short id, FormatRecord fmtRecord, String variant )
	{

		switch( id )
		{
            case 0 :
                fmtRecord.setIndexCode(( short ) 5);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 1 :
                fmtRecord.setIndexCode(( short ) 6);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 2 :
                fmtRecord.setIndexCode(( short ) 7);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 3 :
                fmtRecord.setIndexCode(( short ) 8);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 4 :
                fmtRecord.setIndexCode(( short ) 0x2a);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 5 :
                fmtRecord.setIndexCode(( short ) 0x29);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 6 :
                fmtRecord.setIndexCode(( short ) 0x2c);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;

            case 7 :
                fmtRecord.setIndexCode(( short ) 0x2b);
                fmtRecord.setFormatStringLength(( byte ) frenchFormats[id].length() );
                fmtRecord.setFormatString(frenchFormats[id]);
                break;
    	}
	}
}