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

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.textproperties.*;
import org.apache.poi.util.HexDump;
import org.junit.Test;

/**
 * Tests that StyleTextPropAtom works properly
 *
 * @author Nick Burch (nick at torchbox dot com)
 */
public final class TestStyleTextPropAtom {
    /** From a real file: a paragraph with 4 different styles */
    private static final byte[] data_a = new byte[] {
      0, 0, 0xA1-256, 0x0F, 0x2A, 0, 0, 0,
      0x36, 00, 00, 00, // paragraph is 54 long
      00, 00,           // (paragraph reserved field)
      00, 00, 00, 00,   // it doesn't have any styles
      0x15, 00, 00, 00, // first char run is 21 long
      00, 00, 00, 00,   // it doesn't have any styles
      0x11, 00, 00, 00, // second char run is 17 long
      00, 00, 0x04, 00, // font.color only
      00, 00, 00, 0x05, // blue
      0x10, 00, 00, 00, // third char run is 16 long
      00, 00, 0x04, 00, // font.color only
      0xFF-256, 0x33, 00, 0xFE-256 // red
    };
    private static final int data_a_text_len = 0x36-1;

    /**
     * From a real file: 4 paragraphs with text in 4 different styles:
     * left aligned+bold (30)
     * centre aligned+italic+blue (28)
     * right aligned+red (25)
     * left aligned+underlined+larger font size (96)
     * left aligned+underlined+larger font size+red (1)
     */
    private static final byte[] data_b = new byte[] {
        0, 0, 0xA1-256, 0x0F, 0x80-256, 0, 0, 0,
        0x1E, 00, 00, 00,     // paragraph is 30 long
        00, 00,               // paragraph reserved field
        00, 0x18, 00, 00,     // mask is 0x1800
        00, 00,               // left aligned
        0x50, 00,             // line spacing 80
        0x1C, 00, 00, 00,     // paragprah is 28 long
        00, 00,               // paragraph reserved field
        00, 0x10, 00, 00,     // mask is 0x1000
        0x50, 00,             // line spacing 80
        0x19, 00, 00, 00,     // paragraph is 25 long
        00, 00,               // paragraph reserved field
        00, 0x18, 00, 00,     // mask is 0x1800
        02, 00,               // right aligned
        0x50, 00,             // line spacing 80
        0x61, 00, 00, 00,     // paragraph is 97 long
        00, 00,               // paragraph reserved field
        00, 0x18, 00, 00,     // mask is 0x1800
        00, 00,               // left aligned
        0x50, 00,             // line spacing 80

        0x1E, 00, 00, 00,     // character run is 30 long
        01, 00, 02, 00,       // mask is 0x020001
        01, 00,               // char flags 0x0001 = bold
        0x14, 00,             // font size 20
        0x1C, 00, 00, 00,     // character run is 28 long
        02, 00, 06, 00,       // mask is 0x060002
        02, 00,               // char flags 0x0002 = italic
        0x14, 00,             // font size 20
        00, 00, 00, 05,       // colour blue
        0x19, 00, 00, 00,     // character run is 25 long
        00, 00, 06, 00,       // char flags 0x060000
        0x14, 00,             // font size 20
        0xFF-256, 0x33, 00, 0xFE-256, // colour red
        0x60, 00, 00, 00,     // character run is 96 long
        04, 00, 03, 00,       // mask is 0x030004
        04, 00,               // char flags 0x0004 = underlined
        01, 00,               // font index is 1
        0x18, 00,             // font size 24

        01, 00, 00, 00,       // character run is 1 long
        04, 00, 07, 00,       // mask is 0x070004
        04, 00,               // char flags 0x0004 = underlined
        01, 00,               // font index is 1
        0x18, 00,             // font size 24
        0xFF-256, 0x33, 00, 0xFE-256 // colour red
    };
    private static final int data_b_text_len = 0xB3;

    /**
     * From a real file. Has a mask with more bits
     *  set than it actually has data for. Shouldn't do,
     *  but some real files do :(
     */
    private static final byte[] data_c = new byte[] {
        0, 0, -95, 15, 62, 0, 0, 0,
        123, 0, 0, 0, 0, 0, 48, 8,
        10, 0, 1, 0, 0, 0, 0, 0,
        1, 0, 2, 0, 1, 0, 0, 0,
        0, 0, 48, 0, 10, 0, 1, 0,
        0, 0, 0, 0, 2, 0, 123, 0,
        0, 0, 0, 0, 3, 0, 1, 0,
        28, 0, 1, 0, 0, 0, 0, 0,
        3, 0, 1, 0, 24, 0
    };
    private final int data_c_text_len = 123-1;

    /**
     * From a real file supplied for Bug 40143 by tales@great.ufc.br
     */
    private static final byte[] data_d = {
        0x00, 0x00, 0xA1-256, 0x0F, 0x1E, 0x00, 0x00, 0x00, //header
        (byte)0xA0, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 ,
        0x01 , 0x00, (byte)0xA0 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x63 , 0x00 ,
        0x01 , 0x00, 0x01 , 0x00 , 0x00, 0x00 , 0x01 , 0x00 , 0x14 , 0x00
    };
    private static final int data_d_text_len = 0xA0-1;

    @Test
    public void testRecordType() {
        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
        StyleTextPropAtom stpc = new StyleTextPropAtom(data_c,0,data_c.length);
        assertEquals(4001l, stpa.getRecordType());
        assertEquals(4001l, stpb.getRecordType());
        assertEquals(4001l, stpc.getRecordType());
    }


    @Test
    public void testCharacterStyleCounts() {
        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);

        // Set for the appropriate text sizes
        stpa.setParentTextSize(data_a_text_len);
        stpb.setParentTextSize(data_b_text_len);

        // In case A, there is a single styling of the characters
        assertEquals(3, stpa.getCharacterStyles().size());
        // In case B, there are 5 different stylings
        assertEquals(5, stpb.getCharacterStyles().size());
    }

    @Test
    public void testParagraphStyleCounts() {
        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);

        // Set for the appropriate text sizes
        stpa.setParentTextSize(data_a_text_len);
        stpb.setParentTextSize(data_b_text_len);

        // In case A, all has the same spacing and alignment
        assertEquals(1, stpa.getParagraphStyles().size());
        // In case B, all 4 sets have different alignments
        assertEquals(4, stpb.getParagraphStyles().size());
    }


    @Test
    public void testCharacterStyleLengths() {
        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);

        // Set for the appropriate text sizes
        stpa.setParentTextSize(data_a_text_len);
        stpb.setParentTextSize(data_b_text_len);

        // 54 chars, 21 + 17 + 16
        List<TextPropCollection> a_ch_l = stpa.getCharacterStyles();
        TextPropCollection a_ch_1 = a_ch_l.get(0);
        TextPropCollection a_ch_2 = a_ch_l.get(1);
        TextPropCollection a_ch_3 = a_ch_l.get(2);
        assertEquals(21, a_ch_1.getCharactersCovered());
        assertEquals(17, a_ch_2.getCharactersCovered());
        assertEquals(16, a_ch_3.getCharactersCovered());

        // 179 chars, 30 + 28 + 25
        List<TextPropCollection> b_ch_l = stpb.getCharacterStyles();
        TextPropCollection b_ch_1 = b_ch_l.get(0);
        TextPropCollection b_ch_2 = b_ch_l.get(1);
        TextPropCollection b_ch_3 = b_ch_l.get(2);
        TextPropCollection b_ch_4 = b_ch_l.get(3);
        assertEquals(30, b_ch_1.getCharactersCovered());
        assertEquals(28, b_ch_2.getCharactersCovered());
        assertEquals(25, b_ch_3.getCharactersCovered());
        assertEquals(96, b_ch_4.getCharactersCovered());
    }


    @Test
    public void testCharacterPropOrdering() {
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
        stpb.setParentTextSize(data_b_text_len);

        List<TextPropCollection> b_ch_l = stpb.getCharacterStyles();
        TextPropCollection b_ch_1 = b_ch_l.get(0);
        TextPropCollection b_ch_2 = b_ch_l.get(1);
        TextPropCollection b_ch_3 = b_ch_l.get(2);
        TextPropCollection b_ch_4 = b_ch_l.get(3);

        // In first set, we get a CharFlagsTextProp and a font.size
        assertEquals(2,b_ch_1.getTextPropList().size());
        TextProp tp_1_1 = b_ch_1.getTextPropList().get(0);
        TextProp tp_1_2 = b_ch_1.getTextPropList().get(1);
        assertEquals(true, tp_1_1 instanceof CharFlagsTextProp);
        assertEquals("font.size", tp_1_2.getName());
        assertEquals(20, tp_1_2.getValue());

        // In second set, we get a CharFlagsTextProp and a font.size and a font.color
        assertEquals(3,b_ch_2.getTextPropList().size());
        TextProp tp_2_1 = b_ch_2.getTextPropList().get(0);
        TextProp tp_2_2 = b_ch_2.getTextPropList().get(1);
        TextProp tp_2_3 = b_ch_2.getTextPropList().get(2);
        assertEquals(true, tp_2_1 instanceof CharFlagsTextProp);
        assertEquals("font.size", tp_2_2.getName());
        assertEquals("font.color", tp_2_3.getName());
        assertEquals(20, tp_2_2.getValue());

        // In third set, it's just a font.size and a font.color
        assertEquals(2,b_ch_3.getTextPropList().size());
        TextProp tp_3_1 = b_ch_3.getTextPropList().get(0);
        TextProp tp_3_2 = b_ch_3.getTextPropList().get(1);
        assertEquals("font.size", tp_3_1.getName());
        assertEquals("font.color", tp_3_2.getName());
        assertEquals(20, tp_3_1.getValue());

        // In fourth set, we get a CharFlagsTextProp and a font.index and a font.size
        assertEquals(3,b_ch_4.getTextPropList().size());
        TextProp tp_4_1 = b_ch_4.getTextPropList().get(0);
        TextProp tp_4_2 = b_ch_4.getTextPropList().get(1);
        TextProp tp_4_3 = b_ch_4.getTextPropList().get(2);
        assertEquals(true, tp_4_1 instanceof CharFlagsTextProp);
        assertEquals("font.index", tp_4_2.getName());
        assertEquals("font.size", tp_4_3.getName());
        assertEquals(24, tp_4_3.getValue());
    }

    @Test
    public void testParagraphProps() {
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
        stpb.setParentTextSize(data_b_text_len);

        List<TextPropCollection> b_p_l = stpb.getParagraphStyles();
        TextPropCollection b_p_1 = b_p_l.get(0);
        TextPropCollection b_p_2 = b_p_l.get(1);
        TextPropCollection b_p_3 = b_p_l.get(2);
        TextPropCollection b_p_4 = b_p_l.get(3);

        // 1st is left aligned + normal line spacing
        assertEquals(2,b_p_1.getTextPropList().size());
        TextProp tp_1_1 = b_p_1.getTextPropList().get(0);
        TextProp tp_1_2 = b_p_1.getTextPropList().get(1);
        assertEquals("alignment", tp_1_1.getName());
        assertEquals("linespacing", tp_1_2.getName());
        assertEquals(0, tp_1_1.getValue());
        assertEquals(80, tp_1_2.getValue());

        // 2nd is centre aligned (default) + normal line spacing
        assertEquals(1,b_p_2.getTextPropList().size());
        TextProp tp_2_1 = b_p_2.getTextPropList().get(0);
        assertEquals("linespacing", tp_2_1.getName());
        assertEquals(80, tp_2_1.getValue());

        // 3rd is right aligned + normal line spacing
        assertEquals(2,b_p_3.getTextPropList().size());
        TextProp tp_3_1 = b_p_3.getTextPropList().get(0);
        TextProp tp_3_2 = b_p_3.getTextPropList().get(1);
        assertEquals("alignment", tp_3_1.getName());
        assertEquals("linespacing", tp_3_2.getName());
        assertEquals(2, tp_3_1.getValue());
        assertEquals(80, tp_3_2.getValue());

        // 4st is left aligned + normal line spacing (despite differing font)
        assertEquals(2,b_p_4.getTextPropList().size());
        TextProp tp_4_1 = b_p_4.getTextPropList().get(0);
        TextProp tp_4_2 = b_p_4.getTextPropList().get(1);
        assertEquals("alignment", tp_4_1.getName());
        assertEquals("linespacing", tp_4_2.getName());
        assertEquals(0, tp_4_1.getValue());
        assertEquals(80, tp_4_2.getValue());
    }

    @Test
    public void testCharacterProps() {
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
        stpb.setParentTextSize(data_b_text_len);

        List<TextPropCollection> b_ch_l = stpb.getCharacterStyles();
        TextPropCollection b_ch_1 = b_ch_l.get(0);
        TextPropCollection b_ch_2 = b_ch_l.get(1);
        TextPropCollection b_ch_3 = b_ch_l.get(2);
        TextPropCollection b_ch_4 = b_ch_l.get(3);

        // 1st is bold
        CharFlagsTextProp cf_1_1 = (CharFlagsTextProp)b_ch_1.getTextPropList().get(0);
        assertEquals(true,cf_1_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));

        // 2nd is italic
        CharFlagsTextProp cf_2_1 = (CharFlagsTextProp)b_ch_2.getTextPropList().get(0);
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
        assertEquals(true,cf_2_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));

        // 3rd is normal, so lacks a CharFlagsTextProp
        assertFalse(b_ch_3.getTextPropList().get(0) instanceof CharFlagsTextProp);

        // 4th is underlined
        CharFlagsTextProp cf_4_1 = (CharFlagsTextProp)b_ch_4.getTextPropList().get(0);
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
        assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));

        // The value for this should be 4
        assertEquals(0x0004, cf_4_1.getValue());

        // Now make the 4th bold, italic and not underlined
        cf_4_1.setSubValue(true, CharFlagsTextProp.BOLD_IDX);
        cf_4_1.setSubValue(true, CharFlagsTextProp.ITALIC_IDX);
        cf_4_1.setSubValue(false, CharFlagsTextProp.UNDERLINE_IDX);

        assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
        assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));

        // The value should now be 3
        assertEquals(0x0003, cf_4_1.getValue());
    }

    @Test(expected=HSLFException.class)
    public void testFindAddTextProp() {
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
        stpb.setParentTextSize(data_b_text_len);

        List<TextPropCollection> b_p_l = stpb.getParagraphStyles();
        TextPropCollection b_p_1 = b_p_l.get(0);
        TextPropCollection b_p_2 = b_p_l.get(1);
        TextPropCollection b_p_3 = b_p_l.get(2);
        TextPropCollection b_p_4 = b_p_l.get(3);

        List<TextPropCollection> b_ch_l = stpb.getCharacterStyles();
        TextPropCollection b_ch_1 = b_ch_l.get(0);
        TextPropCollection b_ch_2 = b_ch_l.get(1);
        TextPropCollection b_ch_3 = b_ch_l.get(2);
        TextPropCollection b_ch_4 = b_ch_l.get(3);
        
        assertNotNull(b_p_1);
        assertNotNull(b_p_2);
        assertNotNull(b_p_3);
        assertNotNull(b_p_4);
        
        assertNotNull(b_ch_1);
        assertNotNull(b_ch_2);
        assertNotNull(b_ch_3);
        assertNotNull(b_ch_4);

        // CharFlagsTextProp: 3 doesn't have, 4 does
        assertNull(b_ch_3.findByName("char_flags"));
        assertNotNull(b_ch_4.findByName("char_flags"));

        // Now add in on 3, should go to front
        assertEquals(2, b_ch_3.getTextPropList().size());
        TextProp new_cftp = b_ch_3.addWithName("char_flags");
        assertEquals(3, b_ch_3.getTextPropList().size());
        assertEquals(new_cftp, b_ch_3.getTextPropList().get(0));

        // alignment: 1 does have, 2 doesn't
        assertNotNull(b_p_1.findByName("alignment"));
        assertNull(b_p_2.findByName("alignment"));

        // Now add in on 2, should go to the front
        assertEquals(1, b_p_2.getTextPropList().size());
        TextProp new_al = b_p_2.addWithName("alignment");
        assertEquals(2, b_p_2.getTextPropList().size());
        assertEquals(new_al, b_p_2.getTextPropList().get(0));

        // This should go at the end
        TextProp new_sa = b_p_2.addWithName("spaceafter");
        assertEquals(3, b_p_2.getTextPropList().size());
        assertEquals(new_sa, b_p_2.getTextPropList().get(2));

        // Check we get an error with a made up one
        b_p_2.addWithName("madeUpOne");
    }

    /**
     * Try to recreate an existing StyleTextPropAtom (a) from the empty
     *  constructor, and setting the required properties
     */
    @Test
    public void testCreateAFromScatch() throws Exception {
        // Start with an empty one
        StyleTextPropAtom stpa = new StyleTextPropAtom(54);

        // Don't need to touch the paragraph styles
        // Add two more character styles
        List<TextPropCollection> cs = stpa.getCharacterStyles();

        // First char style is boring, and 21 long
        TextPropCollection tpca = cs.get(0);
        tpca.updateTextSize(21);

        // Second char style is coloured, 00 00 00 05, and 17 long
        TextPropCollection tpcb = stpa.addCharacterTextPropCollection(17);
        TextProp tpb = tpcb.addWithName("font.color");
        tpb.setValue(0x05000000);

        // Third char style is coloured, FF 33 00 FE, and 16 long
        TextPropCollection tpcc = stpa.addCharacterTextPropCollection(16);
        TextProp tpc = tpcc.addWithName("font.color");
        tpc.setValue(0xFE0033FF);

        // Should now be the same as data_a
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        stpa.writeOut(baos);
        byte[] b = baos.toByteArray();

        assertEquals(data_a.length, b.length);
        for(int i=0; i<data_a.length; i++) {
            assertEquals(data_a[i],b[i]);
        }
    }

    /**
     * Try to recreate an existing StyleTextPropAtom (b) from the empty
     *  constructor, and setting the required properties
     */
    @Test
    public void testCreateBFromScatch() throws Exception {
        // Start with an empty one
        StyleTextPropAtom stpa = new StyleTextPropAtom(data_b_text_len);


        // Need 4 paragraph styles
        List<TextPropCollection> ps = stpa.getParagraphStyles();

        // First is 30 long, left aligned, normal spacing
        TextPropCollection tppa = ps.get(0);
        tppa.updateTextSize(30);

        TextProp tp = tppa.addWithName("alignment");
        tp.setValue(0);
        tp = tppa.addWithName("linespacing");
        tp.setValue(80);

        // Second is 28 long, centre aligned and normal spacing
        TextPropCollection tppb = stpa.addParagraphTextPropCollection(28);

        tp = tppb.addWithName("linespacing");
        tp.setValue(80);

        // Third is 25 long, right aligned and normal spacing
        TextPropCollection tppc = stpa.addParagraphTextPropCollection(25);

        tp = tppc.addWithName("alignment");
        tp.setValue(2);
        tp = tppc.addWithName("linespacing");
        tp.setValue(80);

        // Forth is left aligned + normal line spacing (despite differing font)
        TextPropCollection tppd = stpa.addParagraphTextPropCollection(97);

        tp = tppd.addWithName("alignment");
        tp.setValue(0);
        tp = tppd.addWithName("linespacing");
        tp.setValue(80);


        // Now do 4 character styles
        List<TextPropCollection> cs = stpa.getCharacterStyles();

        // First is 30 long, bold and font size
        TextPropCollection tpca = cs.get(0);
        tpca.updateTextSize(30);

        tp = tpca.addWithName("font.size");
        tp.setValue(20);
        CharFlagsTextProp cftp = (CharFlagsTextProp)
            tpca.addWithName("char_flags");
        assertEquals(0, cftp.getValue());
        cftp.setSubValue(true, CharFlagsTextProp.BOLD_IDX);
        assertEquals(1, cftp.getValue());

        // Second is 28 long, blue and italic
        TextPropCollection tpcb = stpa.addCharacterTextPropCollection(28);

        tp = tpcb.addWithName("font.size");
        tp.setValue(20);
        tp = tpcb.addWithName("font.color");
        tp.setValue(0x05000000);
        cftp = (CharFlagsTextProp)tpcb.addWithName("char_flags");
        cftp.setSubValue(true, CharFlagsTextProp.ITALIC_IDX);
        assertEquals(2, cftp.getValue());

        // Third is 25 long and red
        TextPropCollection tpcc = stpa.addCharacterTextPropCollection(25);

        tp = tpcc.addWithName("font.size");
        tp.setValue(20);
        tp = tpcc.addWithName("font.color");
        tp.setValue(0xfe0033ff);

        // Fourth is 96 long, underlined and different+bigger font
        TextPropCollection tpcd = stpa.addCharacterTextPropCollection(96);

        tp = tpcd.addWithName("font.size");
        tp.setValue(24);
        tp = tpcd.addWithName("font.index");
        tp.setValue(1);
        cftp = (CharFlagsTextProp)tpcd.addWithName("char_flags");
        cftp.setSubValue(true, CharFlagsTextProp.UNDERLINE_IDX);
        assertEquals(4, cftp.getValue());

        // Fifth is 1 long, underlined and different+bigger font + red
        TextPropCollection tpce = stpa.addCharacterTextPropCollection(1);

        tp = tpce.addWithName("font.size");
        tp.setValue(24);
        tp = tpce.addWithName("font.index");
        tp.setValue(1);
        tp = tpce.addWithName("font.color");
        tp.setValue(0xfe0033ff);
        cftp = (CharFlagsTextProp)tpce.addWithName("char_flags");
        cftp.setSubValue(true, CharFlagsTextProp.UNDERLINE_IDX);
        assertEquals(4, cftp.getValue());


        // Check it's as expected
        assertEquals(4, stpa.getParagraphStyles().size());
        assertEquals(5, stpa.getCharacterStyles().size());

        // Compare in detail to b
        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
        stpb.setParentTextSize(data_b_text_len);
        List<TextPropCollection> psb = stpb.getParagraphStyles();
        List<TextPropCollection> csb = stpb.getCharacterStyles();

        assertEquals(psb.size(), ps.size());
        assertEquals(csb.size(), cs.size());

        // Ensure Paragraph Character styles match
        for(int z=0; z<2; z++) {
            List<TextPropCollection> lla = cs;
            List<TextPropCollection> llb = csb;
            int upto = 5;
            if(z == 1) {
                lla = ps;
                llb = psb;
                upto = 4;
            }

            for(int i=0; i<upto; i++) {
                TextPropCollection ca = lla.get(i);
                TextPropCollection cb = llb.get(i);

                assertEquals(ca.getCharactersCovered(), cb.getCharactersCovered());
                assertEquals(ca.getTextPropList().size(), cb.getTextPropList().size());

                for(int j=0; j<ca.getTextPropList().size(); j++) {
                    TextProp tpa = ca.getTextPropList().get(j);
                    TextProp tpb = cb.getTextPropList().get(j);
                    //System.out.println("TP " + i + " " + j + " " + tpa.getName() + "\t" + tpa.getValue() );
                    assertEquals(tpa.getName(), tpb.getName());
                    assertEquals(tpa.getMask(), tpb.getMask());
                    assertEquals(tpa.getWriteMask(), tpb.getWriteMask());
                    assertEquals(tpa.getValue(), tpb.getValue());
                }

                ByteArrayOutputStream ba = new ByteArrayOutputStream();
                ByteArrayOutputStream bb = new ByteArrayOutputStream();

                ca.writeOut(ba);
                cb.writeOut(bb);
                byte[] cab = ba.toByteArray();
                byte[] cbb = bb.toByteArray();

                assertEquals(cbb.length, cab.length);
                for(int j=0; j<cab.length; j++) {
                    //System.out.println("On tp " + z + " " + i + " " + j + "\t" + cab[j] + "\t" + cbb[j]);
                    assertEquals(cbb[j], cab[j]);
                }
            }
        }



        // Check byte level with b
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        stpa.writeOut(baos);
        byte[] b = baos.toByteArray();

        assertEquals(data_b.length, b.length);
        for(int i=0; i<data_b.length; i++) {
            //System.out.println(i + "\t" + b[i] + "\t" + data_b[i] + "\t" + Integer.toHexString(b[i]) );
            assertEquals(data_b[i],b[i]);
        }
    }

    @Test
    public void testWriteA() {
        doReadWrite(data_a, -1);
    }

    @Test
    public void testLoadWriteA() {
        doReadWrite(data_b, data_b_text_len);
    }


    @Test
    public void testWriteB() {
        doReadWrite(data_b, -1);
    }

    @Test
    public void testLoadWriteB() {
        doReadWrite(data_b, data_b_text_len);
    }

    @Test
    public void testLoadWriteC() {
        // BitMaskTextProperties will sanitize the output
        byte expected[] = data_c.clone();
        expected[56] = 0;
        expected[68] = 0;
        doReadWrite(data_c, expected, data_c_text_len);
    }

    @Test
    public void testLoadWriteD() {
        doReadWrite(data_d, data_d_text_len);
    }

    protected void doReadWrite(byte[] data, int textlen) {
        doReadWrite(data, data, textlen);
    }
    
    protected void doReadWrite(byte[] data, byte[] expected, int textlen) {
        StyleTextPropAtom stpb = new StyleTextPropAtom(data, 0,data.length);
        if(textlen != -1) stpb.setParentTextSize(textlen);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            stpb.writeOut(out);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        byte[] bytes = out.toByteArray();

        assertEquals(expected.length, bytes.length);
        try {
            assertArrayEquals(expected, bytes);
        } catch (Throwable e){
            //print hex dump if failed
            assertEquals(HexDump.toHex(expected), HexDump.toHex(bytes));
        }
    }

    @Test
    public void testNotEnoughDataProp() {
        // We don't have enough data in the record to cover
        //  all the properties the mask says we have
        // Make sure we just do the best we can
        StyleTextPropAtom stpc = new StyleTextPropAtom(data_c,0,data_c.length);
        stpc.setParentTextSize(data_c_text_len);

        // If we get here, we didn't break
    }

    /**
     * Check the test data for Bug 40143.
     */
   @Test
   public void testBug40143() {
        StyleTextPropAtom atom = new StyleTextPropAtom(data_d, 0, data_d.length);
        atom.setParentTextSize(data_d_text_len);

        TextPropCollection prprops = atom.getParagraphStyles().get(0);
        assertEquals(data_d_text_len+1, prprops.getCharactersCovered());
        assertEquals(1, prprops.getTextPropList().size()); //1 property found
        assertEquals(1, prprops.findByName("alignment").getValue());

        TextPropCollection chprops = atom.getCharacterStyles().get(0);
        assertEquals(data_d_text_len+1, chprops.getCharactersCovered());
        assertEquals(5, chprops.getTextPropList().size()); //5 properties found
        assertEquals(1, chprops.findByName("char_flags").getValue());
        assertEquals(1, chprops.findByName("font.index").getValue());
        assertEquals(20, chprops.findByName("font.size").getValue());
        assertEquals(0, chprops.findByName("asian.font.index").getValue());
        assertEquals(1, chprops.findByName("ansi.font.index").getValue());
    }

    /**
     * Check the test data for Bug 42677.
     */
     @Test
     public void test42677() {
        int length = 18;
        byte[] data = {
            0x00, 0x00, (byte)0xA1, 0x0F, 0x28, 0x00, 0x00, 0x00,
            0x13, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , (byte)0xF1 , 0x20 , 0x00, 0x00 , 0x00 , 0x00 ,
            0x22 , 0x20 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 , 0x00 , (byte)0xFF ,
            0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x63 , 0x00 ,
            0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x0F , 0x00
        };
        doReadWrite(data, length);

    }

    /**
     *  Bug 45815: bit mask values are not preserved on read-write
     *
     * From the test file attached to the bug:
     *
     * <StyleTextPropAtom info="0" type="4001" size="94" offset="114782" header="00 00 A1 0F 5E 00 00 00 ">
     *   14 00 00 00 00 00 41 00 0A 00 06 00 50 00 07 00 01 00 00 00 00 00 00 00 02
     *   00 00 00 01 04 00 00 01 04 01 00 00 00 01 08 00 00 01 08 0C 00 00 00 01 0C
     *   00 00 01 0C 01 00 00 00 01 10 00 00 01 10 01 00 00 00 01 14 00 00 01 14 01
     *   00 00 00 01 18 00 00 01 18 01 00 00 00 01 1C 00 00 01 1C
     * </StyleTextPropAtom>
     */
     @Test
    public void test45815() {
        int length = 19;
        byte[] data = {
                0x00, 0x00, (byte)0xA1, 0x0F, 0x5E, 0x00, 0x00, 0x00, 0x14, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x0A, 0x00, 0x06, 0x00,
                0x50, 0x00, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
                0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00,
                0x01, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00,
                0x01, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00,
                0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00,
                0x01, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00,
                0x01, 0x18, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1C, 0x00, 0x00,
                0x01, 0x1C
        };

        // changed original data: ... 0x41 and 0x06 don't match
        // the bitmask text properties will sanitize the bytes and thus the bytes differ
        byte[] exptected = data.clone();
        exptected[18] = 0;
        
        doReadWrite(data, exptected, length);
    }

}
