
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 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 org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
import org.apache.poi.util.BitField;

/**
 * Title:        Style Record<P>
 * Description:  Describes a builtin to the gui or user defined style<P>
 * REFERENCE:  PG 390 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
 * @author Andrew C. Oliver (acoliver at apache dot org)
 * @author aviks : string fixes for UserDefined Style
 * @version 2.0-pre
 */

public class StyleRecord
    extends Record
{
    public final static short sid                = 0x293;
    public final static short STYLE_USER_DEFINED = 0;
    public final static short STYLE_BUILT_IN     = 1;

    // shared by both user defined and builtin styles
    private short             field_1_xf_index;   // TODO: bitfield candidate

    // only for built in styles
    private byte              field_2_builtin_style;
    private byte              field_3_outline_style_level;

    // only for user defined styles
    private short              field_2_name_length; //OO doc says 16 bit length, so we believe
    private byte               field_3_string_options;
    private BitField fHighByte;
    private String             field_4_name;

    public StyleRecord()
    {
    }

    /**
     * Constructs a Style record and sets its fields appropriately.
     *
     * @param id     id must be 0x293 or an exception will be throw upon validation
     * @param size  the size of the data area of the record
     * @param data  data of the record (should not contain sid/len)
     */

    public StyleRecord(short id, short size, byte [] data)
    {
        super(id, size, data);
    }

    /**
     * Constructs a Style record and sets its fields appropriately.
     *
     * @param id     id must be 0x293 or an exception will be throw upon validation
     * @param size  the size of the data area of the record
     * @param data  data of the record (should not contain sid/len)
     * @param offset
     */

    public StyleRecord(short id, short size, byte [] data, int offset)
    {
        super(id, size, data, offset);
    }

    protected void validateSid(short id)
    {
        if (id != sid)
        {
            throw new RecordFormatException("NOT A STYLE RECORD");
        }
    }

    protected void fillFields(byte [] data, short size, int offset)
    {
        fHighByte = new BitField(0x01); //have to init here, since we are being called
                                        //from super, and class level init hasnt been done. 
        field_1_xf_index = LittleEndian.getShort(data, 0 + offset);
        if (getType() == STYLE_BUILT_IN)
        {
            field_2_builtin_style       = data[ 2 + offset ];
            field_3_outline_style_level = data[ 3 + offset ];
        }
        else if (getType() == STYLE_USER_DEFINED)
        {
            field_2_name_length = LittleEndian.getShort(data, 2 + offset );
            field_3_string_options = data[4+offset];
            
            if (fHighByte.isSet(field_3_string_options)) {
                field_4_name= StringUtil.getFromUnicode(data,offset+5,field_2_name_length);
            }else {
                field_4_name=StringUtil.getFromCompressedUnicode(data,offset+5,field_2_name_length);
            }
        }

        // todo sanity check exception to make sure we're one or the other
    }

    /**
     * set the entire index field (including the type) (see bit setters that reference this method)
     *  @param index  bitmask
     */

    public void setIndex(short index)
    {
        field_1_xf_index = index;
    }

    // bitfields for field 1

    /**
     * set the type of the style (builtin or user-defined)
     * @see #STYLE_USER_DEFINED
     * @see #STYLE_BUILT_IN
     * @param type of style (userdefined/builtin)
     * @see #setIndex(short)
     */

    public void setType(short type)
    {
        field_1_xf_index = setField(field_1_xf_index, type, 0x8000, 15);
    }

    /**
     * set the actual index of the style extended format record
     * @see #setIndex(short)
     * @param index of the xf record
     */

    public void setXFIndex(short index)
    {
        field_1_xf_index = setField(field_1_xf_index, index, 0x1FFF, 0);
    }

    // end bitfields
    // only for user defined records

    /**
     * if this is a user defined record set the length of the style name
     * @param length of the style's name
     * @see #setName(String)
     */

    public void setNameLength(byte length)
    {
        field_2_name_length = length;
    }

    /**
     * set the style's name
     * @param name of the style
     * @see #setNameLength(byte)
     */

    public void setName(String name)
    {
        field_4_name = name;
        //TODO set name length and string options
    }

    // end user defined
    // only for buildin records

    /**
     * if this is a builtin style set teh number of the built in style
     * @param  builtin style number (0-7)
     *
     */

    public void setBuiltin(byte builtin)
    {
        field_2_builtin_style = builtin;
    }

    /**
     * set the row or column level of the style (if builtin 1||2)
     */

    public void setOutlineStyleLevel(byte level)
    {
        field_3_outline_style_level = level;
    }

    // end builtin records
    // field 1

    /**
     * get the entire index field (including the type) (see bit getters that reference this method)
     *  @return bitmask
     */

    public short getIndex()
    {
        return field_1_xf_index;
    }

    // bitfields for field 1

    /**
     * get the type of the style (builtin or user-defined)
     * @see #STYLE_USER_DEFINED
     * @see #STYLE_BUILT_IN
     * @return type of style (userdefined/builtin)
     * @see #getIndex()
     */

    public short getType()
    {
        return ( short ) ((field_1_xf_index & 0x8000) >> 15);
    }

    /**
     * get the actual index of the style extended format record
     * @see #getIndex()
     * @return index of the xf record
     */

    public short getXFIndex()
    {
        return ( short ) (field_1_xf_index & 0x1FFF);
    }

    // end bitfields
    // only for user defined records

    /**
     * if this is a user defined record get the length of the style name
     * @return length of the style's name
     * @see #getName()
     */

    public short getNameLength()
    {
        return field_2_name_length;
    }

    /**
     * get the style's name
     * @return name of the style
     * @see #getNameLength()
     */

    public String getName()
    {
        return field_4_name;
    }

    // end user defined
    // only for buildin records

    /**
     * if this is a builtin style get the number of the built in style
     * @return  builtin style number (0-7)
     *
     */

    public byte getBuiltin()
    {
        return field_2_builtin_style;
    }

    /**
     * get the row or column level of the style (if builtin 1||2)
     */

    public byte getOutlineStyleLevel()
    {
        return field_3_outline_style_level;
    }

    // end builtin records
    public String toString()
    {
        StringBuffer buffer = new StringBuffer();

        buffer.append("[STYLE]\n");
        buffer.append("    .xf_index_raw    = ")
            .append(Integer.toHexString(getIndex())).append("\n");
        buffer.append("        .type        = ")
            .append(Integer.toHexString(getType())).append("\n");
        buffer.append("        .xf_index    = ")
            .append(Integer.toHexString(getXFIndex())).append("\n");
        if (getType() == STYLE_BUILT_IN)
        {
            buffer.append("    .builtin_style   = ")
                .append(Integer.toHexString(getBuiltin())).append("\n");
            buffer.append("    .outline_level   = ")
                .append(Integer.toHexString(getOutlineStyleLevel()))
                .append("\n");
        }
        else if (getType() == STYLE_USER_DEFINED)
        {
            buffer.append("    .name_length     = ")
                .append(Integer.toHexString(getNameLength())).append("\n");
            buffer.append("    .name            = ").append(getName())
                .append("\n");
        }
        buffer.append("[/STYLE]\n");
        return buffer.toString();
    }

    private short setField(int fieldValue, int new_value, int mask,
                           int shiftLeft)
    {
        return ( short ) ((fieldValue & ~mask)
                          | ((new_value << shiftLeft) & mask));
    }

    public int serialize(int offset, byte [] data)
    {
        LittleEndian.putShort(data, 0 + offset, sid);
        if (getType() == STYLE_BUILT_IN)
        {
            LittleEndian.putShort(data, 2 + offset,
                                  (( short ) 0x04));   // 4 bytes (8 total)
        }
        else
        {
            LittleEndian.putShort(data, 2 + offset,
                                  (( short ) (getRecordSize()-4)));
        }
        LittleEndian.putShort(data, 4 + offset, getIndex());
        if (getType() == STYLE_BUILT_IN)
        {
            data[ 6 + offset ] = getBuiltin();
            data[ 7 + offset ] = getOutlineStyleLevel();
        }
        else
        {
            LittleEndian.putShort(data, 6 + offset , getNameLength());
            data[8+offset]=this.field_3_string_options;
            StringUtil.putCompressedUnicode(getName(), data, 9 + offset);
        }
        return getRecordSize();
    }

    public int getRecordSize()
    {
        int retval;

        if (getType() == STYLE_BUILT_IN)
        {
            retval = 8;
        }
        else
        {
             if (fHighByte.isSet(field_3_string_options))  {
                 retval= 9+2*getNameLength();
             }else {
                retval = 9 + getNameLength();
             }
        }
        return retval;
    }

    public short getSid()
    {
        return this.sid;
    }
}
