////////////////////////////////////////////////////////////////////////////////
//
//  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 UnitTest.Tests
{
    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.TestConfig;

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;
    import flash.geom.Rectangle;
    import flash.text.engine.FontDescription;
    import flash.text.engine.FontWeight;
    import flash.text.engine.TextLine;
    import flash.utils.ByteArray;
    import flash.utils.getTimer;

    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.compose.TextFlowLine;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.IEditManager;
    import flashx.textLayout.elements.Configuration;
    import flashx.textLayout.elements.DivElement;
    import flashx.textLayout.elements.FlowElement;
    import flashx.textLayout.elements.FlowLeafElement;
    import flashx.textLayout.elements.GlobalSettings;
    import flashx.textLayout.elements.InlineGraphicElement;
    import flashx.textLayout.elements.LinkElement;
    import flashx.textLayout.elements.ListElement;
    import flashx.textLayout.elements.ListItemElement;
    import flashx.textLayout.elements.ParagraphElement;
    import flashx.textLayout.elements.SpanElement;
    import flashx.textLayout.elements.TCYElement;
    import flashx.textLayout.elements.TextFlow;
    import flashx.textLayout.formats.FormatValue;
    import flashx.textLayout.formats.ITextLayoutFormat;
    import flashx.textLayout.formats.ListStyleType;
    import flashx.textLayout.formats.TextAlign;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.property.*;
    import flashx.textLayout.tlf_internal;
    import flashx.undo.IUndoManager;
    import flashx.undo.UndoManager;

    import mx.core.FTETextField;
    import mx.utils.LoaderUtil;

    import org.flexunit.asserts.assertTrue;

    use namespace tlf_internal;

    [TestCase(order=20)]
    public class FlowModelTest extends VellumTestCase
    {
        private var beginTime:int;

        public function FlowModelTest()
        {
            super("", "FlowModelTest", TestConfig.getInstance());

            metaData = {};
            // Note: These must correspond to a Watson product area (case-sensitive)
            metaData.productArea = "Text Container";
            metaData.productSubArea = "Flow";
        }

        [Before]
        override public function setUpTest():void
        {
            super.setUpTest();
        }

        [After]
        override public function tearDownTest():void
        {
            super.tearDownTest();
        }

        [Test]
        /**
         * Direct usage of the flow APIs. No validation - just look for crashes.
         * This test changes the color of the entire text.
         */
        public function basicAPITest1():void
        {
            // set the color on the entire flow
            beginAPITest();
            SelManager.textFlow.color = 0xff0000;
            endAPITest();
        }

        [Test]
        /**
         * Direct usage of the flow APIs. No validation - just look for crashes.
         * This test deletes every other character in the entire text.
         */
        public function basicAPITest2():void
        {
            // delete every other character in the textflow
            beginAPITest();

            var idx:int = 0;
            while (idx < SelManager.textFlow.textLength)
            {
                var span:SpanElement = SelManager.textFlow.findLeaf(idx) as SpanElement;
                if (span)
                {
                    var spanStart:int = span.getAbsoluteStart();
                    span.replaceText(idx - spanStart, idx - spanStart + 1, null);
                }
                idx++;

            }
            endAPITest();
        }

        [Test]
        /**
         * Direct usage of the flow APIs. No validation - just look for crashes.
         * This test adds another paragraph to the flow containing the text "Hello World"
         * in 24 point font.
         */
        public function basicAPITest3():void
        {
            // add a paragraph
            beginAPITest();
            var p:ParagraphElement = new ParagraphElement();
            var s:SpanElement = new SpanElement();
            s.text = "Hello world";
            s.fontSize = 24;
            p.replaceChildren(0, 0, s);
            SelManager.textFlow.replaceChildren(SelManager.textFlow.numChildren, SelManager.textFlow.numChildren, p);
            endAPITest();
        }

        [Test]
        /**
         * This test performs a series of changes and validates the changes after they're performed.
         */
        public function basicAPITest4():void
        {
            // more comprehensive set of tests - several manipulations to the flow and then display it

            // generic begin to an API test
            beginAPITest();

            // get the textflow
            var textFlow:TextFlow = SelManager.textFlow;

            // remove all the textflow children
            textFlow.replaceChildren(0, textFlow.numChildren);
            assertTrue("expected no elements on the flow, but found " + textFlow.numChildren,
                    textFlow.numChildren == 0);

            // create a paragraph
            var p:ParagraphElement = new ParagraphElement();

            // create a span
            var s:SpanElement = new SpanElement();
            s.text = "Hello world. ";
            s.fontSize = 24;

            // split the span
            var nextSpan:SpanElement = s.splitAtPosition(6) as SpanElement;
            // set the color - color can be a string or an unsigned integer
            nextSpan.color = "0xff";
            assertTrue("expected that the color would be 255, but found " + uint(nextSpan.format.color),
                    uint(nextSpan.format.color) == 255);

            // put the two spans in the paragraph
            p.replaceChildren(0, 0, s);
            p.replaceChildren(1, 1, nextSpan);

            assertTrue("expected the element count to be 2, but it was " + p.numChildren,
                    p.numChildren == 2);

            // add another span
            s = new SpanElement();
            s.text = "Start:"
            p.replaceChildren(0, 0, s);

            // put the paragraph in the TextFlow
            textFlow.replaceChildren(0, 0, p);
            assertTrue("text flow should have one element but has " + textFlow.numChildren,
                    textFlow.numChildren == 1);

            // make another paragraph
            p = new ParagraphElement();
            s = new SpanElement();
            p.replaceChildren(0, 0, s);
            s.text = "NEW FIRST PARAGRAPH";

            // set the paragraph attributes directly
            p.textIndent = 20;
            // set the paragraph attributes via clone and set
            var pa:TextLayoutFormat = new TextLayoutFormat(p.format);
            pa.textAlign = TextAlign.RIGHT;
            p.format = pa;

            // into the textFlow at the beginning
            textFlow.replaceChildren(0, 0, p);

            // generic end to an API test
            endAPITest();
        }

        [Test]
        /**
         * This test inserts an FE in the middle of a paragraph
         */
        public function basicAPITest5():void
        {
            // more comprehensive set of tests - several manipulations to the flow and then display it

            // generic begin to an API test
            beginAPITest();

            // get the textflow
            var textFlow:TextFlow = SelManager.textFlow;

            // create a paragraph empty the flow and insert it
            var p:ParagraphElement = new ParagraphElement();
            textFlow.replaceChildren(0, textFlow.numChildren, p);

            // create a span
            var s:SpanElement = new SpanElement();
            s.text = "Hello world. ";
            s.fontSize = 24;

            // put it in the paragraph
            p.replaceChildren(0, 0, s);

            // split the span
            var nextSpanElement:SpanElement = s.splitAtPosition(6) as SpanElement;
            assertTrue("Incorrect elementCount after split", p.numChildren == 2);

            // create and insert an image between the spans
            var image:InlineGraphicElement = new InlineGraphicElement();
            image.width = 19;
            image.height = 19;
            image.source = LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/surprised.png");
            p.replaceChildren(1, 1, image);

            assertTrue("failed length on new InlineGraphicElement", image.textLength == 1);
            assertTrue("failed elementCount after image insert", p.numChildren == 3);
            assertTrue("bad first child", p.getChildAt(0) is SpanElement);
            assertTrue("bad first child", p.getChildAt(1) is InlineGraphicElement);
            assertTrue("bad first child", p.getChildAt(2) is SpanElement);

            // set a userStyle on a ContainerController
            var saveFormat:ITextLayoutFormat = ContainerController.containerControllerInitialFormat;
            try
            {
                ContainerController.containerControllerInitialFormat = null;
                var controller:ContainerController = new ContainerController(new Sprite());
                controller.setStyle("foo", "blah");
            }
            catch (e:Error)
            {
                ContainerController.containerControllerInitialFormat = saveFormat;
                throw(e);
            }
            ContainerController.containerControllerInitialFormat = saveFormat;

            // generic end to an API test
            endAPITest();
        }

        [Test]
        /**
         * Test setting hostCharacterFormat on the TextFlow
         */
        public function textFlowHostCharacterFormat():void
        {
            // generic begin to an API test
            beginAPITest();

            // get the textflow
            var textFlow:TextFlow = SelManager.textFlow;
            var leaf:FlowLeafElement = textFlow.getFirstLeaf();

            // make it red
            var cf:TextLayoutFormat = new TextLayoutFormat();
            cf.color = 0xff0000;
            textFlow.hostFormat = cf;
            assertTrue("host character format set color failed", leaf.computedFormat.color == 0xff0000);

            // make it blue
            textFlow.color = 0xff;
            assertTrue("textFlow character format color override failed", leaf.computedFormat.color == 0xff);

            // clear the blue
            textFlow.color = undefined;
            assertTrue("textFlow color clear failed", leaf.computedFormat.color == 0xff0000);

            // clear the hostCharacterFormat
            textFlow.hostFormat = null;
            assertTrue("host character format clear failed", leaf.computedFormat.color == 0);

            endAPITest();
        }

        [Test]
        /**
         * Insert a link to a paragraph that hasn't ever been updated.
         */
        public function insertLinkNoUpdateAPI():void
        {
            var textFlow:TextFlow = new TextFlow();
            var p:ParagraphElement = new ParagraphElement();
            var link:LinkElement = new LinkElement();
            link.href = "http://www.cnn.com";
            link.target = "_self";
            var span:SpanElement = new SpanElement();
            span.text = "aaa";
            link.replaceChildren(0, 0, span);
            p.replaceChildren(0, 0, link);
            textFlow.replaceChildren(0, 0, p);
        }

        [Test]
        /**
         *
         */
        public function insertLinkNoUpdateViaEditManager():void
        {
            var textFlow:TextFlow = initTextFlowAAA();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;

            editManager.selectRange(1, 2);
            editManager.applyLink("http://livedocs.adobe.com/", "_self", true);
        }

        [Test]
        /**
         * undo in a flow that has no controllers
         */
        public function testUndo():void
        {
            var textFlow:TextFlow = initTextFlowAAA();
            var undoManager:IUndoManager = new UndoManager();
            var editManager:IEditManager = new EditManager(undoManager);
            textFlow.interactionManager = editManager;

            editManager.selectRange(1, 2);
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.fontWeight = FontWeight.BOLD;
            editManager.applyLeafFormat(format);

            undoManager.undo();
        }

        [Test]
        public function iterateParagraphForward():void
        {
            var flow:TextFlow = createParaIterationModel();
            var para:ParagraphElement = flow.getFirstLeaf().getParagraph();
            var i:int = 0;
            while (para != null)
            {
                var cStr:String = para.getText();
                assertTrue("Text not as expected", int(cStr) == i);
                para = para.getNextParagraph();
                i++;
            }
            assertTrue("Unexpected paragraph count", i == 12);
        }

        [Test]
        public function iterateParagraphBackward():void
        {
            //const kParaTerminator:String = '\u2029';

            var flow:TextFlow = createParaIterationModel();
            var para:ParagraphElement = flow.getLastLeaf().getParagraph();
            var i:int = 11;
            //These two tests are no longer valid due to PARB changes to removed the terminator
            //parameter from getText on a paragraph element.
            //
            //var terminatorTestStr:String = para.getText("\n");
            //assertTrue("Should have newline as terminator", terminatorTestStr.substr(terminatorTestStr.length - 1, 1) == '\n');
            //terminatorTestStr = para.getText();
            //assertTrue("Should have paragraph terminator as terminator", terminatorTestStr.substr(terminatorTestStr.length - 1, 1) == kParaTerminator);
            while (para != null)
            {
                var cStr:String = para.getText();
                assertTrue("Text not as expected", int(cStr) == i);
                para = para.getPreviousParagraph();
                i--;
            }
            assertTrue("Unexpected paragraph count", i == -1);
        }

        [Test]
        public function cascadeValidation():void
        {
            var flow:TextFlow = new TextFlow();
            var para:ParagraphElement = new ParagraphElement();
            var span:SpanElement = new SpanElement();
            flow.addChild(para);
            para.addChild(span);
            flow.backgroundColor = 0xff;
            assertTrue("backgroundColor should not inherit", TextLayoutFormat.backgroundColorProperty.inherited == false);
            assertTrue("bad flow backGroundColor", flow.computedFormat.backgroundColor == 0xff);
            assertTrue("bad para backGroundColor", para.computedFormat.backgroundColor == TextLayoutFormat.backgroundColorProperty.defaultValue);
            assertTrue("bad span backGroundColor", span.computedFormat.backgroundColor == TextLayoutFormat.backgroundColorProperty.defaultValue);
        }

        [Test]
        /**
         * tests api change to automatically remove a flowelements children when using replaceChildren
         */
        public function elementMovingTest():void
        {
            var lengthBefore:int;

            // this flow should have two paragraphs as children
            var flow:TextFlow = SelManager.textFlow.deepCopy() as TextFlow;	// clone the flow

            var firstPara:FlowElement = flow.getChildAt(0);
            lengthBefore = flow.textLength;
            //firstPara.parent.removeChild(firstPara);	// soon to no longer be needed
            //assertTrue("elementMovingTest: removing para incorrect lengths",flow.textLength == lengthBefore-firstPara.textLength);

            lengthBefore = SelManager.textFlow.textLength;
            SelManager.textFlow.addChild(firstPara);
            assertTrue("elementMovingTest: adding para incorrect lengths", SelManager.textFlow.textLength == lengthBefore + firstPara.textLength);

            var lastLeaf:FlowElement = flow.getLastLeaf();
            var lastLeafLength:int = lastLeaf.textLength;
            //lastLeaf.parent.removeChild(lastLeaf);	// soon to no longer be needed
            lengthBefore = SelManager.textFlow.textLength;
            SelManager.textFlow.getLastLeaf().parent.addChild(lastLeaf);
            assertTrue("elementMovingTest: adding span incorrect lengths", SelManager.textFlow.textLength == lengthBefore + lastLeafLength - 1);
        }

        [Test]
        /**
         * Empty Flow Tests - verify that empty/partially empty TextFlow's are normalized correctly
         */
        public function emptyTextFlowTests():void
        {
            var tf:TextFlow;

            // just an empty TextFlow
            tf = new TextFlow();
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();

            // empty TextFlow with paragraph
            tf = new TextFlow();
            tf.addChild(new ParagraphElement());
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();

            // empty TextFlow with paragraph and ILG
            tf = new TextFlow();
            var p:ParagraphElement = new ParagraphElement();
            p.addChild(new InlineGraphicElement());
            tf.addChild(p);
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();

            // empty TextFlow with paragraph and empty LinkElement
            tf = new TextFlow();
            p = new ParagraphElement();
            p.addChild(new LinkElement());
            tf.addChild(p);
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();

            // empty TextFlow with paragraph and empty TCYElement
            tf = new TextFlow();
            p = new ParagraphElement();
            p.addChild(new TCYElement());
            tf.addChild(p);
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();

            // a more complex example
            tf = new TextFlow();
            p = new ParagraphElement();
            var tcy:TCYElement = new TCYElement();
            tcy.addChild(new InlineGraphicElement());
            tcy.addChild(new SpanElement());
            p.addChild(tcy);
            tf.addChild(p);
            tcy.removeChildAt(1);
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();

            // several empty spans
            tf = new TextFlow();
            p = new ParagraphElement();
            tf.addChild(p);
            p.addChild(new SpanElement());
            p.addChild(new SpanElement());
            p.addChild(new SpanElement());
            tf.flowComposer.addController(new ContainerController(new Sprite()));
            tf.flowComposer.updateAllControllers();
        }

        [Test]
        public function emptyElementCopyTests():void
        {
            var elemList:Array = GeneralFunctionsTest.childParentTable[0];
            for (var idx:int = 1; idx < elemList.length; idx++)
            {
                var elem:FlowElement = new elemList[idx];
                elem.shallowCopy();
                elem.deepCopy();
            }
        }

        [Test]
        /**
         * Tests fontMapping
         */
        public function fontMappingTest():void
        {
            var textFlow:TextFlow = SelManager.textFlow;
            var container:DisplayObjectContainer = DisplayObjectContainer(textFlow.flowComposer.getControllerAt(0).container);

            textFlow.fontFamily = "Arial";
            textFlow.fontWeight = FontWeight.BOLD;
            textFlow.flowComposer.updateAllControllers();

            var arialBoldBits:BitmapData = new BitmapData(container.width, container.height);
            arialBoldBits.draw(container as DisplayObjectContainer);
            var arialBoldData:Bitmap = new Bitmap(arialBoldBits);

            textFlow.fontFamily = "Arial Black";
            textFlow.fontWeight = undefined;
            textFlow.flowComposer.updateAllControllers();

            var arialBlackBits:BitmapData = new BitmapData(container.width, container.height);
            arialBlackBits.draw(container as DisplayObjectContainer);
            var arialBlackData:Bitmap = new Bitmap(arialBlackBits);

            GlobalSettings.fontMapperFunction = myFontMapper;
            textFlow.invalidateAllFormats();

            try
            {
                textFlow.flowComposer.updateAllControllers();
            }
            finally
            {
                GlobalSettings.fontMapperFunction = null;
                textFlow.invalidateAllFormats();
            }

            var mappedBits:BitmapData = new BitmapData(container.width, container.height);
            mappedBits.draw(container as DisplayObjectContainer);
            var mappedData:Bitmap = new Bitmap(mappedBits);

            assertTrue("font mapping failed", validateBitmap(mappedData, arialBoldData));

            textFlow.flowComposer.updateAllControllers();

            var mappingClearedBits:BitmapData = new BitmapData(container.width, container.height);
            mappingClearedBits.draw(container as DisplayObjectContainer);
            var mappingClearedData:Bitmap = new Bitmap(mappingClearedBits);

            assertTrue("clearing font mapping failed", validateBitmap(mappingClearedData, arialBlackData));

        }

        [Test]
        /**
         * test the binary search algorithm which in findControllerIndexAtPosition - tricky bits wrt handling of zero length containers
         */
        public function testFindControllerIndexAtPosition():void
        {
            var s:Sprite = new Sprite();	// scratch
            var controller:ContainerController;	// scratch
            var composer:StandardFlowComposer = new StandardFlowComposer();
            // ideally shouldn't need TextFlow but because containercontrollers find their owning composer via the textflow its needed
            var textFlow:TextFlow = new TextFlow();
            textFlow.flowComposer = composer;
            textFlow.mxmlChildren = ["012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"];

            controller = new ContainerController(s);
            controller.verticalScrollPolicy = "off";
            composer.addController(controller);
            controller.setTextLength(100);
            controller.verticalScrollPolicy = "off";

            assertTrue("Bad result in findControllerIndexAtPosition 9", composer.findControllerIndexAtPosition(0) == 0);
            assertTrue("Bad result in findControllerIndexAtPosition 10", composer.findControllerIndexAtPosition(100, true) == 0);
            assertTrue("Bad result in findControllerIndexAtPosition 11", composer.findControllerIndexAtPosition(100, false) == -1);

            for (var idx1:int = 0; idx1 < 4; idx1++)
            {
                for (var idx2:int = 0; idx2 < 4; idx2++)
                {
                    var idx:int;

                    composer = new StandardFlowComposer();
                    textFlow = new TextFlow();
                    textFlow.flowComposer = composer;
                    textFlow.mxmlChildren = ["012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"];

                    // add some empties
                    for (idx = 0; idx < idx1; idx++)
                        composer.addController(new ContainerController(s));
                    // add one of length one
                    controller = new ContainerController(s);
                    controller.verticalScrollPolicy = "off";	// scrolling confuses it
                    composer.addController(controller);
                    controller.setTextLength(100);				// internal API
                    // add some empties
                    for (idx = 0; idx < idx2; idx++)
                        composer.addController(new ContainerController(s));
                    assertTrue("Bad result in findControllerIndexAtPosition 1", composer.findControllerIndexAtPosition(0) == 0);
                    assertTrue("Bad result in findControllerIndexAtPosition 2", composer.findControllerIndexAtPosition(0, true) == 0);
                    assertTrue("Bad result in findControllerIndexAtPosition 3", composer.findControllerIndexAtPosition(100, true) == idx1);
                    assertTrue("Bad result in findControllerIndexAtPosition 4", composer.findControllerIndexAtPosition(100, false) == -1);
                    // add one with some length
                    textFlow.mxmlChildren = ["0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"];
                    controller.setTextLength(100);
                    controller = new ContainerController(s);
                    controller.verticalScrollPolicy = "off";	// scrolling confuses it
                    composer.addController(controller);
                    controller.setTextLength(100);				// internal API
                    assertTrue("Bad result in findControllerIndexAtPosition 5", composer.findControllerIndexAtPosition(100, true) == idx1);
                    assertTrue("Bad result in findControllerIndexAtPosition 6", composer.findControllerIndexAtPosition(100, false) == idx1 + 1);
                    assertTrue("Bad result in findControllerIndexAtPosition 7", composer.findControllerIndexAtPosition(200, true) == idx1 + idx2 + 1);
                    assertTrue("Bad result in findControllerIndexAtPosition 8", composer.findControllerIndexAtPosition(200, false) == -1);
                }
            }

        }

        [Test]
        public function listItemInsertion():void
        {
            // some validations that ensure ListElement is correctly setup for list processing

            // every ListStyleType must have an entry in ListElement.listSuffixes
            var handler:EnumPropertyHandler = TextLayoutFormat.listStyleTypeProperty.findHandler(EnumPropertyHandler) as EnumPropertyHandler;
            assertTrue("listItemInsertion: missing handler for ListStyleType", handler != null && handler.range != null);

            var range:Object = handler.range;
            var value:String;

            var numberedListStyles:Object = {};
            for (value in ListElement.algorithmicListStyles)
            {
                assertTrue("listItemInsertion: table entry duplicated", numberedListStyles[value] === undefined);
                numberedListStyles[value] = ListElement.algorithmicListStyles[value];
            }
            for (value in ListElement.numericListStyles)
            {
                assertTrue("listItemInsertion: table entry duplicated", numberedListStyles[value] === undefined);
                numberedListStyles[value] = ListElement.numericListStyles[value];
            }
            for (value in ListElement.alphabeticListStyles)
            {
                assertTrue("listItemInsertion: table entry duplicated", numberedListStyles[value] === undefined);
                numberedListStyles[value] = ListElement.alphabeticListStyles[value];
            }

            for (value in range)
            {
                if (value != FormatValue.INHERIT)
                {
                    // must be a numbered list or an unnumbered list but not both
                    assertTrue("listItemInsertion: listStyleType must be numbered or unnumbered but not both: " + value,
                            numberedListStyles[value] !== undefined && ListElement.constantListStyles[value] === undefined
                            || numberedListStyles[value] === undefined && ListElement.constantListStyles[value] !== undefined)
                    // numbered lists must have a suffix
                    if (ListElement.constantListStyles[value] === undefined)
                        assertTrue("listItemInsertion: missing suffix property: " + value, ListElement.listSuffixes[value] !== undefined);
                }
            }

            // verify that all constantListStyles are in range
            for (value in ListElement.constantListStyles)
                assertTrue("listItemInsertion: invalid value in constantListStyles: " + value, range[value] !== undefined);
            // verify that all numberedListStyles are in range
            for (value in numberedListStyles)
                assertTrue("listItemInsertion: invalid value in numberedListStyles: " + value, range[value] !== undefined);
            // verify that all listSuffixes are in range
            for (value in ListElement.listSuffixes)
                assertTrue("listItemInsertion: invalid value in listSuffixes: " + value, range[value] !== undefined);

            SelManager.selectRange(0, 0);

            // remove all the children and put in a list
            var textFlow:TextFlow = SelManager.textFlow;

            textFlow.replaceChildren(0, textFlow.numChildren);

            var list:ListElement = new ListElement();
            list.listStyleType = ListStyleType.DECIMAL;

            textFlow.addChild(list);
            var item:ListItemElement = new ListItemElement();
            list.addChild(item);

            textFlow.flowComposer.updateAllControllers();

            assertTrue("listItemInsertion: incorrect normalize", textFlow.findAbsoluteParagraph(0).parent == item);

            // append two items and compose
            list.addChild(new ListItemElement());
            list.addChild(new ListItemElement());
            textFlow.flowComposer.updateAllControllers();

            // check the three textlines
            checkListLines(textFlow, 3, "listItemInsertion1");

            // now insert a brand new ListItem at the head and verify
            list.replaceChildren(0, 0, new ListItemElement());
            textFlow.flowComposer.updateAllControllers();

            // check four textlines
            checkListLines(textFlow, 4, "listItemInsertion2");

            // remove a list item
            list.removeChildAt(1);
            textFlow.flowComposer.updateAllControllers();

            // check three textLines
            checkListLines(textFlow, 3, "listItemInsertion3");

            // add another list in the first ListItemElement
            item = list.getChildAt(0) as ListItemElement;
            var newList:ListElement = new ListElement();
            item.addChild(newList);
            textFlow.flowComposer.updateAllControllers();

            // assert the empty list is deleted
            assertTrue("listItemInsertion: newList not normalized", newList.numChildren == 1);

        }

        [Test]
        public function testFTETextField():void
        {
            // use the TextFlow's container
            var fieldParent:Sprite = SelManager.textFlow.flowComposer.getControllerAt(0).container;
            // remove the controller so the the textFlow isn't displayed in it
            SelManager.textFlow.flowComposer.removeControllerAt(0);

            var field:FTETextField = new FTETextField();
            field.htmlText = "Hello world";
            fieldParent.addChild(field);
        }

        [Test]
        public function replaceChildrenTest():void
        {
            SelManager.selectRange(0, 0);

            // remove all the children
            var textFlow:TextFlow = SelManager.textFlow;
            textFlow.replaceChildren(0, textFlow.numChildren);

            var p:ParagraphElement = new ParagraphElement();
            textFlow.addChild(p);

            var link:LinkElement = new LinkElement();
            link.href = "XXX";
            p.addChild(link);
            var span:SpanElement = new SpanElement();
            span.text = "Hello, ";
            span.fontSize = 24;
            link.addChild(span);

            var link2:LinkElement = new LinkElement();
            link2.href = "YYY";
            p.addChild(link2);

            var span2:SpanElement = new SpanElement();
            span2.text = "world ";
            span2.fontSize = 24;
            link2.addChild(span2);

            textFlow.flowComposer.updateAllControllers();

            link.replaceChildren(link2.numChildren, link2.numChildren, link2.mxmlChildren);
            p.removeChild(link2);
            textFlow.flowComposer.updateAllControllers();

            assertTrue("replaceChildrenTest: extra line - look for extra terminator", textFlow.flowComposer.numLines == 1);
        }

        [Test]
        public function resolveFontLookupTest():void
        {
            var textFlow:TextFlow = SelManager.textFlow;

            textFlow.fontFamily = "Arial";
            textFlow.fontWeight = FontWeight.BOLD;
            textFlow.fontLookup = "device";
            textFlow.flowComposer.updateAllControllers();

            var swfContext:mySwfContext = new mySwfContext();
            try
            {
                GlobalSettings.resolveFontLookupFunction = myFontLookup(swfContext, textFlow.format);
                textFlow.flowComposer.updateAllControllers();
                assertTrue("fontLookup not matched.", textFlow.fontLookup = swfContext.myFontlookup);
            }
            finally
            {
                GlobalSettings.resolveFontLookupFunction = null;
            }
        }

        [Test]
        public function bindableSpan():void
        {
            // Bindable span should not lose its formatting
            var textFlow:TextFlow = new TextFlow();
            var paragraph:ParagraphElement = new ParagraphElement();
            var span1:SpanElement = new SpanElement();
            var span2:SpanElement = new SpanElement();
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.fontWeight = FontWeight.BOLD;
            span2.format = format;
            paragraph.mxmlChildren = [span1, span2];
            textFlow.mxmlChildren = [paragraph];
            textFlow.flowComposer.addController(new ContainerController(new Sprite()));
            textFlow.flowComposer.compose();		// force normalize
            assertTrue("Spans should not be merged!", span2.parent == span1.parent && paragraph.numChildren == 2);
            assertTrue("Formatting on second span should be preserved!", span2.fontWeight == FontWeight.BOLD);
        }

        [Test]
        /**
         *  This test does not work in our current build environment, since playerEnablesSpicyFeatures will always be false.
         *  Once we have a method of compiling VellumUnit as a 10.2 swf, this test should be enabled.
         */
        public function softKeyboardFlagTest():void
        {
            if (Configuration.playerEnablesSpicyFeatures)	// only run the rest of the test if we're in 10.2 or higher
            {
                // test 1 - add controller, then interaction manager
                var sprite:Sprite = new Sprite();
                var textFlow:TextFlow = new TextFlow();
                textFlow.flowComposer.addController(new ContainerController(sprite));
                textFlow.interactionManager = new EditManager();
                assertTrue("needsSoftKeyboard should be true after adding EditManager", sprite["needsSoftKeyboard"] == true);
                // test 2 - add another controller
                var sprite1:Sprite = new Sprite();
                textFlow.flowComposer.addController(new ContainerController(sprite1));
                assertTrue("needsSoftKeyboard should be true for a second container", sprite1["needsSoftKeyboard"] == true);

                // test 3 - add interaction manager, then controller
                var sprite2:Sprite = new Sprite();
                var textFlow2:TextFlow = new TextFlow();
                textFlow2.interactionManager = new EditManager();
                textFlow2.flowComposer.addController(new ContainerController(sprite2));
                assertTrue("needsSoftKeyboard should be true after adding controller", sprite2["needsSoftKeyboard"] == true);
            }
        }


        private function beginAPITest():void
        {
            beginTime = getTimer();
            SelManager.selectRange(-1, -1);
        }

        private function endAPITest():void
        {
            SelManager.selectRange(0, 0);
            SelManager.textFlow.flowComposer.updateAllControllers();
        }

        private function initTextFlowAAA():TextFlow
        {
            var textFlow:TextFlow = new TextFlow();
            var p:ParagraphElement = new ParagraphElement();
            var span:SpanElement = new SpanElement();
            span.text = "aaa";
            p.replaceChildren(0, 0, span);
            textFlow.replaceChildren(0, 0, p);
            return textFlow;
        }

        private function createParaIterationModel():TextFlow
        {
            // Creates 3 divs, each have 4 paras
            const paraTotal:int = 4;
            var paraCount:int;
            const divTotal:int = 3;
            var divCount:int;

            var flow:TextFlow = new TextFlow();
            for (var j:int = 0; j < divTotal; j++)
            {
                var div:DivElement = new DivElement();
                for (var i:int = 0; i < paraTotal; i++)
                {
                    var para:ParagraphElement = new ParagraphElement();
                    var span:SpanElement = new SpanElement();
                    span.text = paraCount.toString();
                    para.addChild(span);
                    div.addChild(para);
                    paraCount++;
                }
                flow.addChild(div);
            }
            return flow;
        }

        private function myFontLookup(context:mySwfContext, tlf:ITextLayoutFormat):Function
        {
            return myFontLookup;
        }


        private static function checkListLines(textFlow:TextFlow, numLines:int, prefix:String):void
        {
            for (var idx:int = 0; idx < numLines; idx++)
            {
                var tfl:TextFlowLine = textFlow.flowComposer.getLineAt(idx);
                assertTrue(prefix + ": Missing TextFlowLine: " + idx, tfl != null);
                var textLine:TextLine = tfl.getTextLine();
                assertTrue(prefix + ": Missing TextLine: " + idx, textLine != null);
                var numberLine:TextLine = textLine.getChildAt(0) as TextLine;
                assertTrue(prefix + ": Missing NumberLine: " + idx, numberLine != null);
                /* var numberString:String = numberLine.userData as String;
                 var expectedString:String = (idx+1).toString() + ".";	// for numeric lists
                 assertTrue(prefix+": NumberLine missing userData: "+idx,numberString != null);
                 assertTrue(prefix+": Incorrect NumberLine userData: "+idx,numberLine.userData as String == expectedString);
                 assertTrue(prefix+": Incorrect NumberLine rawTextLength: "+idx,numberString.length+1 == numberLine.rawTextLength); */
            }
        }


        private function validateBitmap(actual:Bitmap, expected:Bitmap):Boolean
        {
            actual.bitmapData.draw(expected, null, null, "difference");
            var bounds:Rectangle = new Rectangle(0, 0, actual.width, actual.height);
            var diffPixels:ByteArray = actual.bitmapData.getPixels(bounds);
            diffPixels.position = 0;
            while (diffPixels.bytesAvailable > 0)
            {
                if (diffPixels.readByte() > 0)
                    return false;
            }

            return true;
        }

        private function myFontMapper(fd:FontDescription):void
        {
            if (fd.fontName == "Arial Black")
            {
                fd.fontName = "Arial";
                fd.fontWeight = FontWeight.BOLD;
            }
        }
    }
}

import flash.text.engine.FontLookup;

import flashx.textLayout.compose.ISWFContext;
import flashx.textLayout.elements.TextFlow;

class mySwfContext implements ISWFContext
{
    public var myFontlookup:String = FontLookup.EMBEDDED_CFF;

    public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean = true):*
    {
        var tf:TextFlow = thisArg as TextFlow;
        tf.fontLookup = FontLookup.EMBEDDED_CFF;
        if (returns)
            return fn.apply(thisArg, argsArray);
        fn.apply(thisArg, argsArray);
    }

}
