/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hssf.record.chart;

import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.StandardRecord;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;

/**
 * Describes a linked data record.  This record refers to the series data or text.
 */
public final class LinkedDataRecord extends StandardRecord implements Cloneable {
    public final static short sid  = 0x1051;

    private static final BitField customNumberFormat= BitFieldFactory.getInstance(0x1);

    private  byte       field_1_linkType;
    public final static byte        LINK_TYPE_TITLE_OR_TEXT        = 0;
    public final static byte        LINK_TYPE_VALUES               = 1;
    public final static byte        LINK_TYPE_CATEGORIES           = 2;
    public final static byte        LINK_TYPE_SECONDARY_CATEGORIES = 3;
    private  byte       field_2_referenceType;
    public final static byte        REFERENCE_TYPE_DEFAULT_CATEGORIES = 0;
    public final static byte        REFERENCE_TYPE_DIRECT          = 1;
    public final static byte        REFERENCE_TYPE_WORKSHEET       = 2;
    public final static byte        REFERENCE_TYPE_NOT_USED        = 3;
    public final static byte        REFERENCE_TYPE_ERROR_REPORTED  = 4;
    private  short      field_3_options;
    private  short      field_4_indexNumberFmtRecord;
    private  Formula field_5_formulaOfLink;


    public LinkedDataRecord()
    {

    }

    public LinkedDataRecord(RecordInputStream in)
    {
        field_1_linkType               = in.readByte();
        field_2_referenceType          = in.readByte();
        field_3_options                = in.readShort();
        field_4_indexNumberFmtRecord   = in.readShort();
        int encodedTokenLen = in.readUShort();
        field_5_formulaOfLink = Formula.read(encodedTokenLen, in);
    }

    public String toString() {
        StringBuffer buffer = new StringBuffer();

        buffer.append("[AI]\n");
        buffer.append("    .linkType             = ").append(HexDump.byteToHex(getLinkType())).append('\n');
        buffer.append("    .referenceType        = ").append(HexDump.byteToHex(getReferenceType())).append('\n');
        buffer.append("    .options              = ").append(HexDump.shortToHex(getOptions())).append('\n');
        buffer.append("    .customNumberFormat   = ").append(isCustomNumberFormat()).append('\n');
        buffer.append("    .indexNumberFmtRecord = ").append(HexDump.shortToHex(getIndexNumberFmtRecord())).append('\n');
        buffer.append("    .formulaOfLink        = ").append('\n');
        Ptg[] ptgs = field_5_formulaOfLink.getTokens();
        for (int i = 0; i < ptgs.length; i++) {
            Ptg ptg = ptgs[i];
            buffer.append(ptg.toString()).append(ptg.getRVAType()).append('\n');
        }

        buffer.append("[/AI]\n");
        return buffer.toString();
    }

    public void serialize(LittleEndianOutput out) {
        out.writeByte(field_1_linkType);
        out.writeByte(field_2_referenceType);
        out.writeShort(field_3_options);
        out.writeShort(field_4_indexNumberFmtRecord);
        field_5_formulaOfLink.serialize(out);
    }

    protected int getDataSize() {
        return 1 + 1 + 2 + 2 + field_5_formulaOfLink.getEncodedSize();
    }

    public short getSid() {
        return sid;
    }

    @Override
    public LinkedDataRecord clone() {
        LinkedDataRecord rec = new LinkedDataRecord();

        rec.field_1_linkType = field_1_linkType;
        rec.field_2_referenceType = field_2_referenceType;
        rec.field_3_options = field_3_options;
        rec.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord;
        rec.field_5_formulaOfLink = field_5_formulaOfLink.copy();
        return rec;
    }




    /**
     * Get the link type field for the LinkedData record.
     *
     * @return  One of
     *        {@link #LINK_TYPE_TITLE_OR_TEXT},
     *        {@link #LINK_TYPE_VALUES}, 
     *        {@link #LINK_TYPE_CATEGORIES}, or
     *        {@link #LINK_TYPE_SECONDARY_CATEGORIES}
     */
    public byte getLinkType()
    {
        return field_1_linkType;
    }

    /**
     * Set the link type field for the LinkedData record.
     *
     * @param field_1_linkType
     *        One of
     *        {@link #LINK_TYPE_TITLE_OR_TEXT},
     *        {@link #LINK_TYPE_VALUES},
     *        {@link #LINK_TYPE_CATEGORIES}, or
     *        {@link #LINK_TYPE_SECONDARY_CATEGORIES}
     */
    public void setLinkType(byte field_1_linkType)
    {
        this.field_1_linkType = field_1_linkType;
    }

    /**
     * Get the reference type field for the LinkedData record.
     *
     * @return  One of
     *        {@link #REFERENCE_TYPE_DEFAULT_CATEGORIES}
     *        {@link #REFERENCE_TYPE_DIRECT}
     *        {@link #REFERENCE_TYPE_WORKSHEET}
     *        {@link #REFERENCE_TYPE_NOT_USED}
     *        {@link #REFERENCE_TYPE_ERROR_REPORTED}
     */
    public byte getReferenceType()
    {
        return field_2_referenceType;
    }

    /**
     * Set the reference type field for the LinkedData record.
     *
     * @param field_2_referenceType
     *        One of
     *        {@link #REFERENCE_TYPE_DEFAULT_CATEGORIES}
     *        {@link #REFERENCE_TYPE_DIRECT}
     *        {@link #REFERENCE_TYPE_WORKSHEET}
     *        {@link #REFERENCE_TYPE_NOT_USED}
     *        {@link #REFERENCE_TYPE_ERROR_REPORTED}
     */
    public void setReferenceType(byte field_2_referenceType)
    {
        this.field_2_referenceType = field_2_referenceType;
    }

    /**
     * Get the options field for the LinkedData record.
     */
    public short getOptions()
    {
        return field_3_options;
    }

    /**
     * Set the options field for the LinkedData record.
     */
    public void setOptions(short field_3_options)
    {
        this.field_3_options = field_3_options;
    }

    /**
     * Get the index number fmt record field for the LinkedData record.
     */
    public short getIndexNumberFmtRecord()
    {
        return field_4_indexNumberFmtRecord;
    }

    /**
     * Set the index number fmt record field for the LinkedData record.
     */
    public void setIndexNumberFmtRecord(short field_4_indexNumberFmtRecord)
    {
        this.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord;
    }

    /**
     * Get the formula of link field for the LinkedData record.
     */
    public Ptg[] getFormulaOfLink() {
        return field_5_formulaOfLink.getTokens();
    }

    /**
     * Set the formula of link field for the LinkedData record.
     */
    public void setFormulaOfLink(Ptg[] ptgs)
    {
        this.field_5_formulaOfLink = Formula.create(ptgs);
    }

    /**
     * Sets the custom number format field value.
     * true if this object has a custom number format
     */
    public void setCustomNumberFormat(boolean value)
    {
        field_3_options = customNumberFormat.setShortBoolean(field_3_options, value);
    }

    /**
     * true if this object has a custom number format
     * @return  the custom number format field value.
     */
    public boolean isCustomNumberFormat()
    {
        return customNumberFormat.isSet(field_3_options);
    }
}
