/* ====================================================================
   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 static org.junit.Assert.assertArrayEquals;
import junit.framework.TestCase;

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

public final class TestEscherOptRecord extends TestCase {

    public void testFillFields() {
        checkFillFieldsSimple();
        checkFillFieldsComplex();
    }

    private void checkFillFieldsComplex() {
        String dataStr = "33 00 " +
                "0B F0 " +
                "14 00 00 00 " +
                "BF 00 01 00 00 00 " +
                "01 80 02 00 00 00 " +
                "BF 00 01 00 00 00 " +
                "01 02";

        EscherOptRecord r = new EscherOptRecord();
        r.fillFields( HexRead.readFromString( dataStr ), new DefaultEscherRecordFactory() );
        assertEquals( (short) 0x0033, r.getOptions() );
        assertEquals( (short) 0xF00B, r.getRecordId() );
        assertEquals( 3, r.getEscherProperties().size() );
        EscherBoolProperty prop1 = new EscherBoolProperty( EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 1 );
        EscherComplexProperty prop2 = new EscherComplexProperty( (short) 1, false, new byte[] { 0x01, 0x02 } );
        EscherBoolProperty prop3 = new EscherBoolProperty( EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 1 );
        assertEquals( prop1, r.getEscherProperty( 0 ) );
        assertEquals( prop2, r.getEscherProperty( 1 ) );
        assertEquals( prop3, r.getEscherProperty( 2 ) );

    }

    private void checkFillFieldsSimple() {
        String dataStr = "33 00 " + // options
                        "0B F0 " + // recordid
                        "12 00 00 00 " + // remaining bytes
                        "BF 00 08 00 08 00 " +
                        "81 01 09 00 00 08 " +
                        "C0 01 40 00 00 08";

        EscherOptRecord r = new EscherOptRecord();
        r.fillFields( HexRead.readFromString( dataStr ), new DefaultEscherRecordFactory() );
        assertEquals( (short) 0x0033, r.getOptions() );
        assertEquals( (short) 0xF00B, r.getRecordId() );
        assertEquals( 3, r.getEscherProperties().size() );
        EscherBoolProperty prop1 = new EscherBoolProperty( EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 524296 );
        EscherRGBProperty prop2 = new EscherRGBProperty( EscherProperties.FILL__FILLCOLOR, 0x08000009 );
        EscherRGBProperty prop3 = new EscherRGBProperty( EscherProperties.LINESTYLE__COLOR, 0x08000040 );
        assertEquals( prop1, r.getEscherProperty( 0 ) );
        assertEquals( prop2, r.getEscherProperty( 1 ) );
        assertEquals( prop3, r.getEscherProperty( 2 ) );
    }

    public void testSerialize() {
        checkSerializeSimple();
        checkSerializeComplex();
    }

    private void checkSerializeComplex()
    {
        //Complex escher record
        EscherOptRecord r = new EscherOptRecord();
        r.setOptions( (short) 0x0033 );
        r.setRecordId( (short) 0xF00B );
        EscherBoolProperty prop1 = new EscherBoolProperty( EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 1 );
        EscherComplexProperty prop2 = new EscherComplexProperty( (short) 1, false, new byte[] { 0x01, 0x02 } );
        EscherBoolProperty prop3 = new EscherBoolProperty( EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 1 );
        r.addEscherProperty( prop1 );
        r.addEscherProperty( prop2 );
        r.addEscherProperty( prop3 );

        byte[] data = new byte[28];
        int bytesWritten = r.serialize(0, data, new NullEscherSerializationListener() );
        assertEquals( 28, bytesWritten );
        String dataStr = "[33, 00, " +
                "0B, F0, " +
                "14, 00, 00, 00, " +
                "BF, 00, 01, 00, 00, 00, " +
                "01, 80, 02, 00, 00, 00, " +
                "BF, 00, 01, 00, 00, 00, " +
                "01, 02]";
        assertEquals( dataStr, HexDump.toHex(data) );

    }

    private void checkSerializeSimple()
    {
        EscherOptRecord r = new EscherOptRecord();
        r.setOptions( (short) 0x0033 );
        r.setRecordId( (short) 0xF00B );
        EscherBoolProperty prop1 = new EscherBoolProperty( EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 1 );
        EscherRGBProperty prop2 = new EscherRGBProperty( EscherProperties.FILL__FILLCOLOR, 0x08000009 );
        EscherRGBProperty prop3 = new EscherRGBProperty( EscherProperties.LINESTYLE__COLOR, 0x08000040 );
        r.addEscherProperty( prop1 );
        r.addEscherProperty( prop2 );
        r.addEscherProperty( prop3 );

        byte[] data = new byte[26];
        int bytesWritten = r.serialize(0, data, new NullEscherSerializationListener() );
        String dataStr = "[33, 00, " +
                "0B, F0, " +
                "12, 00, 00, 00, " +
                "BF, 00, 01, 00, 00, 00, " +
                "81, 01, 09, 00, 00, 08, " +
                "C0, 01, 40, 00, 00, 08]";
        assertEquals( dataStr, HexDump.toHex(data) );
        assertEquals( 26, bytesWritten );
    }

    public void testToString() {
        String nl = System.getProperty("line.separator");
        EscherOptRecord r = new EscherOptRecord();
        // don't try to shoot in foot, please -- vlsergey
        // r.setOptions((short)0x000F);
        r.setRecordId(EscherOptRecord.RECORD_ID);
        EscherProperty prop1 = new EscherBoolProperty((short)1, 1);
        r.addEscherProperty(prop1);
        String expected = "org.apache.poi.ddf.EscherOptRecord:" + nl +
                "  isContainer: false" + nl +
                "  version: 0x0003" + nl +
                "  instance: 0x0001" + nl +
                "  recordId: 0x" + HexDump.toHex(EscherOptRecord.RECORD_ID) + nl +
                "  numchildren: 0" + nl +
                "  properties:" + nl +
                "    propNum: 1, RAW: 0x0001, propName: unknown, complex: false, blipId: false, value: 1 (0x00000001)" + nl;
        assertEquals( expected, r.toString());
    }

    /**
     * Test serialisation of a particually complex example
     * This test is currently broken!
     */
    public void testComplexSerialise() {
    	byte[] data = {
    		0x53, 0x01, 0x0B, 0xF0-256, 0x9C-256, 0x01, 0x00, 0x00,
    		// Simple data follows
    		0x42, 0x01,	0x49, 0x00, 0x00, 0x00,          // SP @ 8
    		0x43, 0x01, 0x85-256, 0x00, 0x00, 0x00,      // SP @ 14
    		0x44, 0x01, 0x04, 0x00, 0x00, 0x00,          // SP @ 20
    		0x45, 0xC1-256, 0x88-256, 0x00, 0x00, 0x00,  // SP @ 26
    		0x46, 0xC1-256, 0x90-256, 0x00, 0x00, 0x00,  // SP @ 32
    		0x7F, 0x01, 0x01, 0x00, 0x01, 0x00,
    		0x80-256, 0x01, 0x00, 0x00, 0x00, 0x00,
    		0x81-256, 0x01, 0x02, 0x00, 0x00, 0x08,
    		0xBF-256, 0x01,	0x10, 0x00, 0x10, 0x00,
    		0xC0-256, 0x01, 0x01, 0x00, 0x00, 0x08,      // SP 10
    		0xC1-256, 0x01, 0x00, 0x00, 0x01, 0x00,
    		0xC4-256, 0x01, 0x00, 0x00, 0x00, 0x00,
    		0xCB-256, 0x01, 0x38, 0x63, 0x00, 0x00,
    		0xCD-256, 0x01, 0x00, 0x00,	0x00, 0x00,
    		0xCE-256, 0x01, 0x00, 0x00, 0x00, 0x00,      // SP 15
    		0xD0-256, 0x01, 0x00, 0x00, 0x00, 0x00,
    		0xD1-256, 0x01, 0x00, 0x00, 0x00, 0x00,
    		0xD7-256, 0x01, 0x00, 0x00, 0x00, 0x00,
    		0xFF-256, 0x01, 0x18, 0x00, 0x18, 0x00,
    		0x01, 0x02, 0x02, 0x00, 0x00, 0x08,
    		0x3F, 0x02, 0x00, 0x00,	0x02, 0x00,          // SP 21

    		// Complex data follows

    		// Complex data for Array #325
    		// Array header
    		0x22, 0x00, 0x22, 0x00, 0xF0-256, 0xFF-256,
    		// Array data
    		0x18, 0x00, 0x28, 0x00, 0x04, 0x00, 0x34,
    		0x00, 0x04, 0x00, 0x28, 0x00, 0x04, 0x00,
    		0x1C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x10,
    		0x00, 0x00, 0x00, 0x1C, 0x00,
    		0x04, 0x00, 0x28, 0x00, 0x10, 0x00, 0x34, 0x00, 0x18, 0x00, 0x3C,
    		0x00, 0x24, 0x00, 0x44, 0x00,
    		0x30, 0x00, 0x48, 0x00, 0x3C, 0x00, 0x44, 0x00, 0x48, 0x00, 0x3C,
    		0x00, 0x54, 0x00, 0x38, 0x00,
    		0x60, 0x00, 0x2C, 0x00, 0x70, 0x00, 0x20, 0x00, 0x78, 0x00,
    		0x14, 0x00, 0x80-256, 0x00, 0x08, 0x00,
    		0x84-256, 0x00, 0x04, 0x00, 0x78, 0x00, 0x04, 0x00, 0x6C, 0x00,
    		0x04, 0x00, 0x60, 0x00, 0x04, 0x00,
    		0x54, 0x00, 0x08, 0x00, 0x48, 0x00, 0x0C, 0x00, 0x3C, 0x00, 0x0C,
    		0x00, 0x30, 0x00, 0x08, 0x00,
    		0x3C, 0x00, 0x08, 0x00, 0x48, 0x00, 0x08, 0x00, 0x54, 0x00, 0x00,
    		0x00, 0x48, 0x00, 0x00, 0x00,
    		0x3C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x04, 0x00, 0x24, 0x00,
    		// Complex data for Array #326
    		// Array header
    		0x45, 0x00, 0x48, 0x00, 0x02, 0x00,
    		// Array data
    		0x00, 0x40, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
    		0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
    		0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x00, 0x80-256
    	};

    	// Create the record
        EscherOptRecord r = new EscherOptRecord();
        int filled = r.fillFields( data, new DefaultEscherRecordFactory() );

        // Check it's the right length
        assertEquals(data.length, filled);
        assertEquals(data.length, r.getRecordSize());

        // Serialise it
        byte[] dest = new byte[data.length];
        int written = r.serialize(0, dest);

        // Check it serialised it back to the same data
        assertEquals(data.length, written);
        for(int i=0; i<data.length; i++) {
        	assertEquals(data[i], dest[i]);
        }
    }

    /**
     * Test read/write against an OPT record from a real ppt file.
     * In PowerPoint is is legal to have array properties with empty complex part.
     * In Glen's original implementation complex part is always 6 bytes which resulted
     * in +6 extra bytes when writing back out. As the result the ppt becomes unreadable.
     *
     * Make sure we write back the original empty complex part.
     *
     * See Bug 41946 for details.
     */
    public void test41946() {
        String dataStr1 =
                "03 08 0B F0 00 03 00 00 81 00 30 65 01 00 82 00 98 B2 00 00 83 00 30 65 01 " +
                "00 84 00 98 B2 00 00 85 00 00 00 00 00 87 00 01 00 00 00 88 00 00 00 00 00 " +
                "89 00 00 00 00 00 BF 00 00 00 0F 00 0C 01 F4 00 00 10 0D 01 00 00 00 20 0E " +
                "01 00 00 00 20 80 01 00 00 00 00 81 01 04 00 00 08 82 01 00 00 01 00 83 01 " +
                "00 00 00 08 84 01 00 00 01 00 85 01 00 00 00 20 86 41 00 00 00 00 87 C1 00 " +
                "00 00 00 88 01 00 00 00 00 89 01 00 00 00 00 8A 01 00 00 00 00 8B 01 00 00 " +
                "00 00 8C 01 00 00 00 00 8D 01 00 00 00 00 8E 01 00 00 00 00 8F 01 00 00 00 " +
                "00 90 01 00 00 00 00 91 01 00 00 00 00 92 01 00 00 00 00 93 01 00 00 00 00 " +
                "94 01 00 00 00 00 95 01 00 00 00 00 96 01 00 00 00 00 97 C1 00 00 00 00 98 " +
                "01 00 00 00 00 99 01 00 00 00 00 9A 01 00 00 00 00 9B 01 00 00 00 00 9C 01 " +
                "03 00 00 40 BF 01 0C 00 1E 00 C0 01 01 00 00 08 C1 01 00 00 01 00 C2 01 FF " +
                "FF FF 00 C3 01 00 00 00 20 C4 01 00 00 00 00 C5 41 00 00 00 00 C6 C1 00 00 " +
                "00 00 C7 01 00 00 00 00 C8 01 00 00 00 00 C9 01 00 00 00 00 CA 01 00 00 00 " +
                "00 CB 01 35 25 00 00 CC 01 00 00 08 00 CD 01 00 00 00 00 CE 01 00 00 00 00 " +
                "CF C1 00 00 00 00 D7 01 02 00 00 00 FF 01 06 00 0E 00 00 02 00 00 00 00 01 " +
                "02 02 00 00 08 02 02 CB CB CB 00 03 02 00 00 00 20 04 02 00 00 01 00 05 02 " +
                "38 63 00 00 06 02 38 63 00 00 07 02 00 00 00 00 08 02 00 00 00 00 09 02 00 " +
                "00 01 00 0A 02 00 00 00 00 0B 02 00 00 00 00 0C 02 00 00 01 00 0D 02 00 00 " +
                "00 00 0E 02 00 00 00 00 0F 02 00 01 00 00 10 02 00 00 00 00 11 02 00 00 00 " +
                "00 3F 02 00 00 03 00 80 02 00 00 00 00 81 02 00 00 01 00 82 02 05 00 00 00 " +
                "83 02 9C 31 00 00 84 02 00 00 00 00 85 02 F0 F9 06 00 86 02 00 00 00 00 87 " +
                "02 F7 00 00 10 88 02 00 00 00 20 BF 02 01 00 0F 00 C0 02 00 00 00 00 C1 02 " +
                "00 00 00 00 C2 02 64 00 00 00 C3 02 00 00 00 00 C4 02 00 00 00 00 C5 02 00 " +
                "00 00 00 C6 02 00 00 00 00 C7 02 00 00 00 00 C8 02 00 00 00 00 C9 02 00 00 " +
                "00 00 CA 02 30 75 00 00 CB 02 D0 12 13 00 CC 02 30 ED EC FF CD 02 40 54 89 " +
                "00 CE 02 00 80 00 00 CF 02 00 80 FF FF D0 02 00 00 79 FF D1 02 32 00 00 00 " +
                "D2 02 20 4E 00 00 D3 02 50 C3 00 00 D4 02 00 00 00 00 D5 02 10 27 00 00 D6 " +
                "02 70 94 00 00 D7 02 B0 3C FF FF D8 02 00 00 00 00 D9 02 10 27 00 00 DA 02 " +
                "70 94 00 00 FF 02 16 00 1F 00 04 03 01 00 00 00 41 03 A8 29 01 00 42 03 00 " +
                "00 00 00 43 03 03 00 00 00 44 03 7C BE 01 00 45 03 00 00 00 00 7F 03 00 00 " +
                "0F 00 84 03 7C BE 01 00 85 03 00 00 00 00 86 03 7C BE 01 00 87 03 00 00 00 " +
                "00";

        EscherOptRecord r = new EscherOptRecord();
        byte[] data = HexRead.readFromString( dataStr1 );
        r.fillFields( data, 0, new DefaultEscherRecordFactory() );
        assertEquals( (short) 0xF00B, r.getRecordId() );

        byte[] data1 = r.serialize();
        EscherOptRecord opt2 = new EscherOptRecord();
        opt2.fillFields( data1, new DefaultEscherRecordFactory() );

        byte[] data2 = opt2.serialize();
        assertArrayEquals(data1, data2);
    }

    /**
     * Test that EscherOptRecord can properly read/write array properties
     * with empty complex part.
     */
    public void testEmptyArrayProperty() {
        EscherOptRecord r = new EscherOptRecord();
        EscherArrayProperty p = new EscherArrayProperty((short)(EscherProperties.FILL__SHADECOLORS + 0x8000), new byte[0] );
        assertEquals(0, p.getNumberOfElementsInArray());
        r.addEscherProperty(p);

        byte[] data1 = r.serialize();
        EscherOptRecord opt2 = new EscherOptRecord();
        opt2.fillFields( data1, new DefaultEscherRecordFactory() );
        p = (EscherArrayProperty)opt2.getEscherProperties().get(0);
        assertEquals(0, p.getNumberOfElementsInArray());

        byte[] data2 = opt2.serialize();
        assertArrayEquals(data1, data2);
    }
}
