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

import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;

/**
 * The escher client anchor specifies which rows and cells the shape is bound to as well as
 * the offsets within those cells.  Each cell is 1024 units wide by 256 units long regardless
 * of the actual size of the cell.  The EscherClientAnchorRecord only applies to the top-most
 * shapes.  Shapes contained in groups are bound using the EscherChildAnchorRecords.
 *
 * @see EscherChildAnchorRecord
 */
public class EscherClientAnchorRecord
        extends EscherRecord
{
    public static final short RECORD_ID = (short) 0xF010;
    public static final String RECORD_DESCRIPTION = "MsofbtClientAnchor";

    /**
     * bit[0] -  fMove (1 bit): A bit that specifies whether the shape will be kept intact when the cells are moved.
     * bit[1] - fSize (1 bit): A bit that specifies whether the shape will be kept intact when the cells are resized. If fMove is 1, the value MUST be 1.
     * bit[2-4] - reserved, MUST be 0 and MUST be ignored
     * bit[5-15]- Undefined and MUST be ignored.
     *
     * it can take values: 0, 2, 3
     */
    private short field_1_flag;
    private short field_2_col1;
    private short field_3_dx1;
    private short field_4_row1;
    private short field_5_dy1;
    private short field_6_col2;
    private short field_7_dx2;
    private short field_8_row2;
    private short field_9_dy2;
    private byte[] remainingData = new byte[0];
    private boolean shortRecord = false;

    @Override
    public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
        int bytesRemaining = readHeader( data, offset );
        int pos            = offset + 8;
        int size           = 0;

        // Always find 4 two byte entries. Sometimes find 9
        /*if (bytesRemaining == 4) // Word format only 4 bytes
        {
            // Not sure exactly what the format is quite yet, likely a reference to a PLC
        }
        else */
        if (bytesRemaining != 4) // Word format only 4 bytes
        {
            field_1_flag   =  LittleEndian.getShort( data, pos + size );     size += 2;
            field_2_col1   =  LittleEndian.getShort( data, pos + size );     size += 2;
            field_3_dx1    =  LittleEndian.getShort( data, pos + size );     size += 2;
            field_4_row1   =  LittleEndian.getShort( data, pos + size );     size += 2;
            if(bytesRemaining >= 18) {
                field_5_dy1    =  LittleEndian.getShort( data, pos + size );     size += 2;
                field_6_col2   =  LittleEndian.getShort( data, pos + size );     size += 2;
                field_7_dx2    =  LittleEndian.getShort( data, pos + size );     size += 2;
                field_8_row2   =  LittleEndian.getShort( data, pos + size );     size += 2;
                field_9_dy2    =  LittleEndian.getShort( data, pos + size );     size += 2;
                shortRecord = false;
            } else {
                shortRecord = true;
            }
        }
        bytesRemaining -= size;
        remainingData  =  new byte[bytesRemaining];
        System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
        return 8 + size + bytesRemaining;
    }

    @Override
    public int serialize( int offset, byte[] data, EscherSerializationListener listener )
    {
        listener.beforeRecordSerialize( offset, getRecordId(), this );

        if (remainingData == null) remainingData = new byte[0];
        LittleEndian.putShort( data, offset, getOptions() );
        LittleEndian.putShort( data, offset + 2, getRecordId() );
        int remainingBytes = remainingData.length + (shortRecord ? 8 : 18);
        LittleEndian.putInt( data, offset + 4, remainingBytes );
        LittleEndian.putShort( data, offset + 8, field_1_flag );
        LittleEndian.putShort( data, offset + 10, field_2_col1 );
        LittleEndian.putShort( data, offset + 12, field_3_dx1 );
        LittleEndian.putShort( data, offset + 14, field_4_row1 );
        if(!shortRecord) {
            LittleEndian.putShort( data, offset + 16, field_5_dy1 );
            LittleEndian.putShort( data, offset + 18, field_6_col2 );
            LittleEndian.putShort( data, offset + 20, field_7_dx2 );
            LittleEndian.putShort( data, offset + 22, field_8_row2 );
            LittleEndian.putShort( data, offset + 24, field_9_dy2 );
        }
        System.arraycopy( remainingData, 0, data, offset + (shortRecord ? 16 : 26), remainingData.length );
        int pos = offset + 8 + (shortRecord ? 8 : 18) + remainingData.length;

        listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this );
        return pos - offset;
    }

    @Override
    public int getRecordSize()
    {
        return 8 + (shortRecord ? 8 : 18) + (remainingData == null ? 0 : remainingData.length);
    }

    @Override
    public short getRecordId() {
        return RECORD_ID;
    }

    @Override
    public String getRecordName() {
        return "ClientAnchor";
    }

    /**
     * Returns the string representation for this record.
     *
     * @return A string
     */
    @Override
    public String toString()
    {
        String nl = System.getProperty("line.separator");
        String extraData = HexDump.dump(this.remainingData, 0, 0);
        return getClass().getName() + ":" + nl +
                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
                "  Version: 0x" + HexDump.toHex(getVersion()) + nl +
                "  Instance: 0x" + HexDump.toHex(getInstance()) + nl +
                "  Flag: " + field_1_flag + nl +
                "  Col1: " + field_2_col1 + nl +
                "  DX1: " + field_3_dx1 + nl +
                "  Row1: " + field_4_row1 + nl +
                "  DY1: " + field_5_dy1 + nl +
                "  Col2: " + field_6_col2 + nl +
                "  DX2: " + field_7_dx2 + nl +
                "  Row2: " + field_8_row2 + nl +
                "  DY2: " + field_9_dy2 + nl +
                "  Extra Data:" + nl + extraData;

    }

    @Override
    public String toXml(String tab) {
        String extraData = HexDump.dump(this.remainingData, 0, 0).trim();
        return tab + formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance())) +
                tab + "\t" + "<Flag>" + field_1_flag + "</Flag>\n" +
                tab + "\t" + "<Col1>" + field_2_col1 + "</Col1>\n" +
                tab + "\t" + "<DX1>" + field_3_dx1 + "</DX1>\n" +
                tab + "\t" + "<Row1>" + field_4_row1 + "</Row1>\n" +
                tab + "\t" + "<DY1>" + field_5_dy1 + "</DY1>\n" +
                tab + "\t" + "<Col2>" + field_6_col2 + "</Col2>\n" +
                tab + "\t" + "<DX2>" + field_7_dx2 + "</DX2>\n" +
                tab + "\t" + "<Row2>" + field_8_row2 + "</Row2>\n" +
                tab + "\t" + "<DY2>" + field_9_dy2 + "</DY2>\n" +
                tab + "\t" + "<ExtraData>" + extraData + "</ExtraData>\n" +
                tab + "</" + getClass().getSimpleName() + ">\n";
    }

    /**
     * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
     * 
     * @return the move/size flag
     */
    public short getFlag()
    {
        return field_1_flag;
    }

    /**
     * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
     * 
     * @param field_1_flag the move/size flag
     */
    public void setFlag( short field_1_flag )
    {
        this.field_1_flag = field_1_flag;
    }

    /**
     * The column number for the top-left position.  0 based.
     * 
     * @return the column number of the top-left corner
     */
    public short getCol1()
    {
        return field_2_col1;
    }

    /**
     * The column number for the top-left position.  0 based.
     * 
     * @param field_2_col1 the column number of the top-left corner
     */
    public void setCol1( short field_2_col1 )
    {
        this.field_2_col1 = field_2_col1;
    }

    /**
     * The x offset within the top-left cell.  Range is from 0 to 1023.
     * 
     * @return the x offset of the top-left corner
     */
    public short getDx1()
    {
        return field_3_dx1;
    }

    /**
     * The x offset within the top-left cell.  Range is from 0 to 1023.
     * 
     * @param field_3_dx1 the x offset of the top-left corner
     */
    public void setDx1( short field_3_dx1 )
    {
        this.field_3_dx1 = field_3_dx1;
    }

    /**
     * The row number for the top-left corner of the shape.
     * 
     * @return the row number of the top-left corner
     */
    public short getRow1()
    {
        return field_4_row1;
    }

    /**
     * The row number of the top-left corner of the shape.
     * 
     * @param field_4_row1 the row number of the top-left corner
     */
    public void setRow1( short field_4_row1 )
    {
        this.field_4_row1 = field_4_row1;
    }

    /**
     * The y offset within the top-left corner of the current shape.
     * 
     * @return the y offset of the top-left corner
     */
    public short getDy1()
    {
        return field_5_dy1;
    }

    /**
     * The y offset within the top-left corner of the current shape.
     * 
     * @param field_5_dy1 the y offset of the top-left corner
     */
    public void setDy1( short field_5_dy1 )
    {
        shortRecord = false;
        this.field_5_dy1 = field_5_dy1;
    }

    /**
     * The column of the bottom right corner of this shape.
     * 
     * @return the column of the bottom right corner
     */
    public short getCol2()
    {
        return field_6_col2;
    }

    /**
     * The column of the bottom right corner of this shape.
     * 
     * @param field_6_col2 the column of the bottom right corner
     */
    public void setCol2( short field_6_col2 )
    {
        shortRecord = false;
        this.field_6_col2 = field_6_col2;
    }

    /**
     * The x offset withing the cell for the bottom-right corner of this shape.
     * 
     * @return the x offset of the bottom-right corner
     */
    public short getDx2()
    {
        return field_7_dx2;
    }

    /**
     * The x offset withing the cell for the bottom-right corner of this shape.
     * 
     * @param field_7_dx2 the x offset of the bottom-right corner
     */
    public void setDx2( short field_7_dx2 )
    {
        shortRecord = false;
        this.field_7_dx2 = field_7_dx2;
    }

    /**
     * The row number for the bottom-right corner of the current shape.
     * 
     * @return the row number for the bottom-right corner
     */
    public short getRow2()
    {
        return field_8_row2;
    }

    /**
     * The row number for the bottom-right corner of the current shape.
     * 
     * @param field_8_row2 the row number for the bottom-right corner
     */
    public void setRow2( short field_8_row2 )
    {
        shortRecord = false;
        this.field_8_row2 = field_8_row2;
    }

    /**
     * The y offset withing the cell for the bottom-right corner of this shape.
     * 
     * @return the y offset of the bottom-right corner
     */
    public short getDy2()
    {
        return field_9_dy2;
    }

    /**
     * The y offset withing the cell for the bottom-right corner of this shape.
     * 
     * @param field_9_dy2 the y offset of the bottom-right corner
     */
    public void setDy2( short field_9_dy2 )
    {
        shortRecord = false;
        this.field_9_dy2 = field_9_dy2;
    }

    /**
     * Any remaining data in the record
     * 
     * @return the remaining bytes
     */
    public byte[] getRemainingData()
    {
        return remainingData;
    }

    /**
     * Any remaining data in the record
     * 
     * @param remainingData the remaining bytes
     */
    public void setRemainingData( byte[] remainingData ) {
        if (remainingData == null) {
            this.remainingData = new byte[0];
        } else {
            this.remainingData = remainingData.clone();
        }
    }
}
