////////////////////////////////////////////////////////////////////////////////
//
//  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.
//
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
//
// This file contains content from Ethan Brand by Nathaniel Hawthorne,
// now in the public domain.
//
////////////////////////////////////////////////////////////////////////////////

package UnitTest.Tests
{
    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.TestConfig;

    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.system.*;
    import flash.text.engine.*;

    import flashx.textLayout.compose.IFlowComposer;
    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.compose.TextFlowLine;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.container.TextContainerManager;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.EditingMode;
    import flashx.textLayout.edit.IEditManager;
    import flashx.textLayout.edit.SelectionState;
    import flashx.textLayout.elements.*;
    import flashx.textLayout.formats.ITextLayoutFormat;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.utils.NavigationUtil;

    import mx.containers.Canvas;

    import org.flexunit.asserts.assertTrue;
    import org.flexunit.asserts.fail;

    [TestCase(order=11)]
    public class ContainerTypeTest extends VellumTestCase
    {
        private var TestCanvas:Canvas = null;
        private var ItemsToRemove:Array;
        private var hostFormat:TextLayoutFormat;

        private var markup:String;

        public function ContainerTypeTest()
        {
            super("", "ContainerTypeTest2", TestConfig.getInstance());
            //super(methodName, testID, testConfig, testCaseXML);
            //reset containerType and ID
            containerType = "custom";
            metaData = {};
            // Note: These must correspond to a Watson product area (case-sensitive)
            metaData.productArea = "Text Container";
            markup = getTestMarkup();
        }

        [Before]
        override public function setUpTest():void
        {
            cleanUpTestApp();
            ItemsToRemove = [];
            TestDisplayObject = testApp.getDisplayObject();
            if (TestDisplayObject)
            {
                TestCanvas = Canvas(TestDisplayObject);
            }
            else
            {
                fail("Did not get a blank canvas to work with");
            }
        }

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

        /**
         * Have a single TextLine on the canvas instead of a vellum container
         */
        [Test]
        public function singleTextLine():void
        {
            var cf:ElementFormat = new ElementFormat();
            cf.fontSize = 24
            var fd:FontDescription = new FontDescription("Times New Roman")
            cf.fontDescription = fd
            var te:TextElement = new TextElement("A TextLine on the Canvas", cf);
            var tb:TextBlock = new TextBlock();
            tb.content = te;
            var tl1:TextLine = tb.createTextLine(null, 400);
            tl1.x = 50;
            tl1.y = 50;
            //need to keep track of what I've added in order to remove at teardown?
            TestCanvas.rawChildren.addChild(DisplayObject(tl1));
            ItemsToRemove.push(tl1);
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        /**
         * Have ten TextLines on the canvas instead of a vellum container
         */
        [Test]
        public function tenTextLines():void
        {
            for (var i:int = 0; i < 10; i++)
            {
                var cf:ElementFormat = new ElementFormat();
                cf.fontSize = 24
                var fd:FontDescription = new FontDescription("Times New Roman")
                cf.fontDescription = fd
                var te:TextElement = new TextElement("TextLine " + i, cf);
                var tb:TextBlock = new TextBlock();
                tb.content = te;
                var tl1:TextLine = tb.createTextLine(null, 400);
                tl1.x = 40;
                tl1.y = 40 + (40 * i);
                //need to keep track of what I've added in order to remove at teardown?
                TestCanvas.rawChildren.addChild(DisplayObject(tl1));
                ItemsToRemove.push(tl1);
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        /**
         * Have one hundred TextLines on the canvas instead of a vellum container
         */
        [Test]
        public function oneHundredTextLines():void
        {
            for (var i:int = 0; i < 100; i++)
            {
                var cf:ElementFormat = new ElementFormat();
                cf.fontSize = 2.4
                var fd:FontDescription = new FontDescription("Times New Roman")
                cf.fontDescription = fd
                var te:TextElement = new TextElement("TextLine " + i, cf);
                var tb:TextBlock = new TextBlock();
                tb.content = te;
                var tl1:TextLine = tb.createTextLine(null, 400);
                tl1.x = 40;
                tl1.y = 40 + (4 * i);
                //need to keep track of what I've added in order to remove at teardown?
                TestCanvas.rawChildren.addChild(DisplayObject(tl1));
                ItemsToRemove.push(tl1);
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test]
        public function singleTextLineStatic():void
        {
            singleTextLine();
            TextLine(ItemsToRemove[0]).validity = TextLineValidity.STATIC;
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test]
        public function tenTextLinesStatic():void
        {
            tenTextLines();
            for (var i:int = 0; i < ItemsToRemove.length; i++)
            {
                TextLine(ItemsToRemove[i]).validity = TextLineValidity.STATIC;
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test]
        public function oneHundredTextLinesStatic():void
        {
            oneHundredTextLines();
            for (var i:int = 0; i < ItemsToRemove.length; i++)
            {
                TextLine(ItemsToRemove[i]).validity = TextLineValidity.STATIC;
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test]
        public function clickLinkedContainerTest():void
        {
            var posOfSelection:int = TestData.posOfSelection;
            var format:TextLayoutFormat = new TextLayoutFormat();
            format = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;

            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;

            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            editManager.selectRange(0, 0);

            //create two containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var controllerOne:ContainerController = new ContainerController(container1, 200, 250);
            var controllerTwo:ContainerController = new ContainerController(container2, 150, 300);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controllerOne);
            textFlow.flowComposer.addController(controllerTwo);
            textFlow.flowComposer.updateAllControllers();

            var tfl:TextFlowLine = textFlow.flowComposer.findLineAtPosition(posOfSelection);
            var adjustedPosOfSelection:int = posOfSelection - tfl.absoluteStart;
            var tl:TextLine = tfl.getTextLine();
            var bounds:Rectangle = tl.getAtomBounds(adjustedPosOfSelection);

            var mouseX:Number = 0;
            var mouseY:Number = 0;

            if (TestData.id == "clickLeftToLinkedContainer")
            {
                mouseX = bounds.x - 1;
                mouseY = tl.y;
            }
            else if (TestData.id == "clickRightToLinkedContainer")
            {
                mouseX = bounds.x + 1;
                mouseY = tl.y;
            }
            else if (TestData.id == "clickTopLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y - 1;
            }
            else if (TestData.id == "clickBottomLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y + 1;
            }

            editManager.setFocus();
            var mEvent:MouseEvent;
            mEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, mouseX, mouseY);
            container1.dispatchEvent(mEvent);
            editManager.setFocus();

            editManager.flushPendingOperations();
            var posAfterClick:int = editManager.activePosition;

            assertTrue("Position changed after click." + " Position of selected is: " + posOfSelection
                    + " Position of after Click: " + posAfterClick,
                    posOfSelection == posAfterClick);

        }

        /**
         * linked containers,  check if attribute changed after texts insertion
         */
        [Test]
        public function checkContainerAttributesAfterTextInsertion():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;

            //create two linked containers containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var controllerOne:ContainerController = new ContainerController(container1, 200, 250);
            var controllerTwo:ContainerController = new ContainerController(container2, 150, 300);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controllerOne);
            textFlow.flowComposer.addController(controllerTwo);
            textFlow.flowComposer.updateAllControllers();

            editManager.selectRange(0, 0);
            editManager.setFocus();

            var format:TextLayoutFormat = new TextLayoutFormat();
            format = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;

            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            textFlow.flowComposer.updateAllControllers();

            //get container attributes before insertion
            var containerAtts_before:ITextLayoutFormat = controllerOne.format;
            var paddingLeft_before:Number = containerAtts_before.paddingLeft;
            var paddingRight_before:Number = containerAtts_before.paddingRight;
            var paddingTop_before:Number = containerAtts_before.paddingTop;
            var paddingBottom_before:Number = containerAtts_before.paddingBottom;

            var firstContStart:int = controllerOne.absoluteStart;
            var firstContLen:int = controllerOne.textLength;
            var firstContEnd:int = firstContStart + firstContLen;

            //get the insertion position
            if (TestData.id == "insertionEndOf1stContainer")
            {
                editManager.selectRange(firstContEnd - 1, firstContEnd - 1);
            }
            else if (TestData.id == "insertionBeginOf2ndContainer")
            {
                editManager.selectRange(firstContEnd, firstContEnd);
            }
            editManager.insertText("BBB");
            textFlow.flowComposer.updateAllControllers();

            //check attributes after insertion
            var containerAtts_after:ITextLayoutFormat = controllerOne.format;
            var paddingLeft_after:Number = containerAtts_after.paddingLeft;
            var paddingRight_after:Number = containerAtts_after.paddingRight;
            var paddingTop_after:Number = containerAtts_after.paddingTop;
            var paddingBottom_after:Number = containerAtts_after.paddingBottom;

            //check if attributes changed after insertion
            assertTrue("Attributes have been changed after insertion to end of 1st container.",
                    paddingLeft_before === paddingLeft_after &&
                            paddingRight_before === paddingRight_after &&
                            paddingTop_before === paddingTop_after &&
                            paddingBottom_before === paddingBottom_after);
        }

        private var firstFlow:TextFlow;
        private var secondFlow:TextFlow;
        private var firstController:ContainerController;
        private var secondController:ContainerController;

        private function resizeHandler(event:Event):void
        {
            const verticalGap:Number = 25;
            const stagePadding:Number = 16;
            var stageWidth:Number = TestCanvas.width - stagePadding;
            var stageHeight:Number = TestCanvas.height - stagePadding;
            var firstContaierWidth:Number = stageWidth;
            var firstContaierHeight:Number = stageHeight;
            // Initial compose to get height of headline after resize
            firstController.setCompositionSize(firstContaierWidth, firstContaierHeight);
            firstFlow.flowComposer.compose();
            var rect:Rectangle = firstController.getContentBounds();
            firstContaierHeight = rect.height;
            // Resize and place headline text container
            // Call setCompositionSize() again with updated headline height
            firstController.setCompositionSize(firstContaierWidth, firstContaierHeight);
            firstController.container.x = stagePadding / 2;
            firstController.container.y = stagePadding / 2;
            firstFlow.flowComposer.updateAllControllers();
            // Resize and place second text container
            var secondContainerHeight:Number = (stageHeight - verticalGap -
                    firstContaierHeight);
            secondController.setCompositionSize(stageWidth, secondContainerHeight);
            secondController.container.x = (stagePadding / 2);
            secondController.container.y = (stagePadding / 2) + firstContaierHeight +
                    verticalGap;
            secondFlow.flowComposer.updateAllControllers();
        }

        [Test]
        public function SelectionChangeFocusTest():void
        {

            const firstMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'>" +
                    "<flow:p>" + "<flow:span fontSize='14'>first text flow: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            const secondMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14'> " +
                    "<flow:p>" +
                    "<flow:span>second text flow: " +
                    "as it proved in the case of Ethan Brand, who had mused to such " +
                    "strange purpose, in days gone by, while the fire in this very kiln was burning.</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            var posOfSelection1:int = TestData.posOfSelection1;
            var posOfSelection2:int = TestData.posOfSelection2;

            TestCanvas.addEventListener(Event.RESIZE, resizeHandler);

            //create first text flow, import first text, and assign composer
            firstFlow = new TextFlow();
            firstFlow = TextConverter.importToFlow(firstMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            firstFlow.flowComposer = new StandardFlowComposer();
            //create second text flow, import second text, and assign flow composer
            secondFlow = new TextFlow();
            secondFlow = TextConverter.importToFlow(secondMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            secondFlow.flowComposer = new StandardFlowComposer();
            // create first container, add controller, position container and add to stage
            var firstContainer:Sprite = new Sprite();
            firstController = new ContainerController(firstContainer, 300, 50);
            var editManager1:IEditManager = new EditManager();
            firstFlow.interactionManager = editManager1;
            firstFlow.flowComposer.addController(firstController);
            firstContainer.x = 120;
            firstContainer.y = 20;
            TestCanvas.rawChildren.addChild(firstContainer);
            firstFlow.flowComposer.updateAllControllers();

            // create container for second text and position it
            var secondContainer:Sprite = new Sprite();
            secondController = new ContainerController(secondContainer, 300, 200);
            secondContainer.x = 125;
            secondContainer.y = 185;
            var editManager2:IEditManager = new EditManager();
            secondFlow.interactionManager = editManager2;
            // add controller, add container to stage, and display second text
            secondFlow.flowComposer.addController(secondController);
            TestCanvas.rawChildren.addChild(secondContainer);
            secondFlow.flowComposer.updateAllControllers();

            //get focus for first flow
            editManager1.selectRange(posOfSelection1, posOfSelection1);
            editManager1.flushPendingOperations();
            editManager1.setFocus();

            assertTrue("Selection Focus doesn't change after selection change from Text Flow 1 to Text Flow 2. ",
                    posOfSelection1 == editManager1.activePosition);

            //get focus for second flow
            editManager2.selectRange(posOfSelection2, posOfSelection2);
            editManager2.flushPendingOperations();
            editManager2.setFocus();

            assertTrue("Selection Focus doesn't change properly after selection change from Text Flow 1 to Text Flow 2. "
                    + ". The expected focus poisiton should be in second text flow at: " + posOfSelection2
                    + " and the actual text flow focus poisiton is: " + editManager2.activePosition,
                    posOfSelection2 == editManager2.activePosition);
        }

        [Test]
        public function clickMultiLinkedContainerTest():void
        {
            var posOfSelection:int = TestData.posOfSelection;
            var format:TextLayoutFormat = new TextLayoutFormat();
            format = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            editManager.selectRange(0, 0);

            //create five containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var container4:Sprite = new Sprite();
            var container5:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);
            var controller4:ContainerController = new ContainerController(container4, 200, 200);
            var controller5:ContainerController = new ContainerController(container5, 200, 200);
            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);
            TestCanvas.rawChildren.addChild(container4);
            TestCanvas.rawChildren.addChild(container5);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;
            container4.x = 790;
            container4.y = 50;
            container5.x = 1045;
            container5.y = 50;
            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.addController(controller4);
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();
            var tfl:TextFlowLine = textFlow.flowComposer.findLineAtPosition(posOfSelection);
            var adjustedPosOfSelection:int = posOfSelection - tfl.absoluteStart;
            var tl:TextLine = tfl.getTextLine();
            var bounds:Rectangle = tl.getAtomBounds(adjustedPosOfSelection);
            var mouseX:Number = 0;
            var mouseY:Number = 0;
            if (TestData.id == "clickLeftToMultiLinkedContainer")
            {
                mouseX = bounds.x - 1;
                mouseY = tl.y;
            }
            else if (TestData.id == "clickRightToMultiLinkedContainer")
            {
                mouseX = bounds.x + 1;
                mouseY = tl.y;
            }
            else if (TestData.id == "clickTopMultiLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y - 1;
            }
            else if (TestData.id == "clickBottomMultiLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y + 1;
            }
            editManager.setFocus();
            var mEvent:MouseEvent;
            mEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, mouseX, mouseY);
            container1.dispatchEvent(mEvent);
            editManager.setFocus();
            editManager.flushPendingOperations();
            var posAfterClick:int = editManager.activePosition;
            assertTrue("Position changed after click." + " Position of selected is: " + posOfSelection
                    + " Position of after Click: " + posAfterClick,
                    posOfSelection == posAfterClick);

        }

        /*****************************************************************
         Drag selection using mouse events and verify the selected range.
         ******************************************************************/
            //two text flows, two containers
        [Test]
        [Ignore]
        public function draggingSelectioinMultiFlows():void
        {
            //create the first text flow, import texts from markups, and assign flow composer to a container
            var flow_1:TextFlow = new TextFlow();
            flow_1 = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            flow_1.flowComposer = new StandardFlowComposer();
            var container_1:Sprite = new Sprite();
            var controller_1:ContainerController = new ContainerController(container_1, 300, 250);
            container_1.x = 25;
            container_1.y = 25;

            //Create EditManager to manage edting changes in TextFlow
            var eManager_1:IEditManager = new EditManager();
            flow_1.interactionManager = eManager_1;
            eManager_1.selectRange(0, 0);

            //add controllers to the first text flow and update all controller to display texts
            flow_1.flowComposer.addController(controller_1);
            TestCanvas.rawChildren.addChild(container_1);
            flow_1.flowComposer.updateAllControllers();

            //set points for the selection beginning and end
            var startFlowLine:TextFlowLine = flow_1.flowComposer.getLineAt(2);
            var startLine:TextLine = startFlowLine.getTextLine();
            var endFlowLine:TextFlowLine = flow_1.flowComposer.getLineAt(10);
            var endLine:TextLine = endFlowLine.getTextLine();
            var endRect:Rectangle = endLine.getAtomBounds(54);
            var startPoint:Point = new Point(startLine.x, startLine.y);
            var endPoint:Point = new Point(endRect.x, endLine.y);
            var x_point:Number;
            var y_point:Number;

            x_point = startPoint.x;
            y_point = startPoint.y;

            //selection start point in the first text flow
            eManager_1.setFocus();
            var downPoint:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, x_point, y_point, container_1);
            container_1.dispatchEvent(downPoint);

            var startInt:int = startFlowLine.absoluteStart;
            var activeInt:int = eManager_1.activePosition;
            var charCount:int = endLine.atomCount;
            var endLineStart:int = endFlowLine.absoluteStart;
            var endInt:int = (endLineStart + charCount) - 1;

            if (startInt == activeInt)
            {
                x_point = endPoint.x;
                y_point = endPoint.y;

                //dragging selection
                eManager_1.setFocus();
                var movePoint:MouseEvent =
                        new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, x_point, y_point, container_1, false, false, false, true);
                container_1.dispatchEvent(movePoint);

                //dragging is done
                var upPoint:MouseEvent =
                        new MouseEvent(MouseEvent.MOUSE_UP, true, false, x_point, y_point, container_1);
                container_1.dispatchEvent(upPoint);
            }

            else
            {
                fail("Mouse down event in the first text flow didn't happen!");
            }

            //create the second text flow, import texts from markups, and assign flow composer to a container
            var flow_2:TextFlow = new TextFlow();
            flow_2 = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            flow_2.flowComposer = new StandardFlowComposer();

            //Create EditManager to manage edting changes in TextFlow
            var eManager_2:IEditManager = new EditManager();
            flow_2.interactionManager = eManager_2;
            eManager_2.selectRange(0, 0);

            var container_2:Sprite = new Sprite();
            var controller_2:ContainerController = new ContainerController(container_2, 300, 250);
            container_2.x = 350;
            container_2.y = 25;

            //add controllers to the second text flow and update all controller to display texts
            flow_2.flowComposer.addController(controller_2);
            TestCanvas.rawChildren.addChild(container_2);
            flow_2.flowComposer.updateAllControllers();

            //set points for the selection beginning and end
            var startFlowLine2:TextFlowLine = flow_2.flowComposer.getLineAt(5);
            var startLine2:TextLine = startFlowLine.getTextLine();
            var endFlowLine2:TextFlowLine = flow_2.flowComposer.getLineAt(13);
            var endLine2:TextLine = endFlowLine2.getTextLine();
            var endRect2:Rectangle = endLine2.getAtomBounds(54);

            var startPoint2:Point = new Point(startLine2.x, startLine2.y);
            var endPoint2:Point = new Point(endRect2.x, endLine2.y);

            var x_point2:Number;
            var y_point2:Number;

            x_point2 = startPoint2.x;
            y_point2 = startPoint2.y;

            //selection start point in the sencond text flow
            eManager_2.setFocus();
            var downPoint2:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, x_point2, y_point2, container_2);
            container_2.dispatchEvent(downPoint2);

            x_point2 = endPoint2.x;
            y_point2 = endPoint2.y;

            //dragging selection
            eManager_2.setFocus();
            var movePoint2:MouseEvent =
                    new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, x_point2, y_point2, container_2, false, false, false, true);
            container_2.dispatchEvent(movePoint2);

            //dragging is done
            var upPoint2:MouseEvent =
                    new MouseEvent(MouseEvent.MOUSE_UP, true, false, x_point2, y_point2, container_2);
            container_2.dispatchEvent(upPoint2);

            var charCount2:int = endLine2.atomCount;
            var startInt2:int = startFlowLine2.absoluteStart;
            var endLineStart2:int = endFlowLine2.absoluteStart;
            var endInt2:int = (endLineStart2 + charCount2) - 1;

            var start:int = 101;
            var end:int = 573;
            assertTrue("Selection range for the first text flow should have been from ".concat(start, " to ", end, " but it was from ",
                    startInt, " to ", endInt, startInt == start && endInt == end));

            var start2:int = 252;
            var end2:int = 733;
            assertTrue("Selection range for the second text flow should have been from ".concat(start2, " to ", end2,
                    " but it was from ", startInt2, " to ", endInt2, startInt2 == start2 && endInt2 == end2));
        }

        /**
         * two text flows, two containers, select from one flow to another
         */
        [Test]
        public function DraggingSelectionOneFlowToAnotherTest():void
        {

            const firstMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'>" +
                    "<flow:p>" + "<flow:span fontSize='14'>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            const secondMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14'> " +
                    "<flow:p>" +
                    "<flow:span>second text flow: " +
                    "as it proved in the case of Ethan Brand, who had mused to such " +
                    "strange purpose, in days gone by, while the fire in this very kiln was burning.</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            var posOfSelection1:int = TestData.posOfSelection1;
            var posOfSelection2:int = TestData.posOfSelection2;

            //create first text flow, import first text, and assign composer
            firstFlow = new TextFlow();
            firstFlow = TextConverter.importToFlow(firstMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            firstFlow.flowComposer = new StandardFlowComposer();
            //create second text flow, import second text, and assign flow composer
            secondFlow = new TextFlow();
            secondFlow = TextConverter.importToFlow(secondMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            secondFlow.flowComposer = new StandardFlowComposer();
            // create first container, add controller, position container
            var firstContainer:Sprite = new Sprite();
            firstController = new ContainerController(firstContainer, 300, 50);
            var editManager1:IEditManager = new EditManager();
            firstFlow.interactionManager = editManager1;
            firstFlow.flowComposer.addController(firstController);
            firstContainer.x = 120;
            firstContainer.y = 20;
            TestCanvas.rawChildren.addChild(firstContainer);
            firstFlow.flowComposer.updateAllControllers();

            // create container for second text and position it
            var secondContainer:Sprite = new Sprite();
            secondController = new ContainerController(secondContainer, 300, 200);
            secondContainer.x = 125;
            secondContainer.y = 185;
            var editManager2:IEditManager = new EditManager();
            secondFlow.interactionManager = editManager2;
            // add controller, add container to stage, and display second text
            secondFlow.flowComposer.addController(secondController);
            TestCanvas.rawChildren.addChild(secondContainer);
            secondFlow.flowComposer.updateAllControllers();

            // make selection in first flow and second flow
            editManager1.selectRange(0, 0);
            var tfl1:TextFlowLine = firstFlow.flowComposer.findLineAtPosition(posOfSelection1);
            var adjustedPosOfSelection1:int = posOfSelection1 - tfl1.absoluteStart;
            var tl1:TextLine = tfl1.getTextLine();
            var bounds1:Rectangle = tl1.getAtomBounds(adjustedPosOfSelection1);
            var tfl2:TextFlowLine = secondFlow.flowComposer.findLineAtPosition(posOfSelection2);
            var adjustedPosOfSelection2:int = posOfSelection2 - tfl2.absoluteStart;
            var tl2:TextLine = tfl2.getTextLine();
            var bounds2:Rectangle = tl2.getAtomBounds(adjustedPosOfSelection2);

            var mouseX:Number = 0;
            var mouseY:Number = 0;
            mouseX = bounds1.x;
            mouseY = tl1.y;

            // mouse down in first container
            editManager1.setFocus();
            var mEventD1:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, mouseX, mouseY, firstContainer);
            firstContainer.dispatchEvent(mEventD1);

            // mouse move to second container and mouse up
            mouseX = bounds2.x;
            mouseY = tl2.y;
            editManager2.selectRange(0, 0);
            editManager2.setFocus();
            var mEventM1:MouseEvent = new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, mouseX, mouseY, secondContainer, false, false, false, true);
            secondContainer.dispatchEvent(mEventM1);
            var mEventU1:MouseEvent = new MouseEvent(MouseEvent.MOUSE_UP, true, false, mouseX, mouseY, secondContainer);
            secondContainer.dispatchEvent(mEventU1);

            var activePos:Number = editManager2.activePosition;
            assertTrue("Selection should not extend to second container. ",
                    activePos == 0);

        }

        [Test]
        public function addRemoveMulitiLinkedContainerTest():void
        {
            var format:TextLayoutFormat = new TextLayoutFormat();
            format = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            editManager.selectRange(0, 0);

            //create five containers and hid two
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var container4:Sprite = new Sprite();
            var container5:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 100, 100);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 300, 300);
            var controller4:ContainerController = new ContainerController(container4, 400, 400);
            var controller5:ContainerController = new ContainerController(container5, 500, 500);
            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);
            TestCanvas.rawChildren.addChild(container4);
            TestCanvas.rawChildren.addChild(container5);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;
            container4.x = 790;
            container4.y = 50;
            container5.x = 1045;
            container5.y = 50;
            container4.visible = false;
            container5.visible = false;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.addController(controller4);
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();

            //removeController
            textFlow.flowComposer.removeController(controller5);
            textFlow.flowComposer.updateAllControllers();
            var containerNumAfterRemove:int = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been removed correctly ", containerNumAfterRemove == 4);

            //removeControllerAt
            textFlow.flowComposer.removeControllerAt(2);
            textFlow.flowComposer.updateAllControllers();
            containerNumAfterRemove = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been removed correctly ", containerNumAfterRemove == 3);

            var c1:ContainerController = textFlow.flowComposer.getControllerAt(0);
            var c2:ContainerController = textFlow.flowComposer.getControllerAt(1);
            var c3:ContainerController = textFlow.flowComposer.getControllerAt(2);
            var w1:int = c1.compositionWidth;
            var w2:int = c2.compositionWidth;
            var w3:int = c3.compositionWidth;
            //check if removed correct containers
            assertTrue("Wrong container has been removed ", w1 == 100 && w2 == 200 && w3 == 400);

            //addController
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();
            var containerNumAfterAdd:int = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been added correctly ", containerNumAfterAdd == 4);
            //check if correct container added
            var c4:ContainerController = textFlow.flowComposer.getControllerAt(3);
            var w4:int = c4.compositionWidth;
            assertTrue("Wrong container has been removed ", w4 == 500);

            //addControllerAt
            textFlow.flowComposer.addControllerAt(controller3, 3);
            textFlow.flowComposer.updateAllControllers();
            containerNumAfterAdd = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been added correctly ", containerNumAfterAdd == 5);
            //check if correct container added at correct position
            var c5:ContainerController = textFlow.flowComposer.getControllerAt(3);
            var w5:int = c5.compositionWidth;
            assertTrue("Container has not been added at corrent position ", w5 == 300);
            c4 = textFlow.flowComposer.getControllerAt(4);
            w4 = c4.compositionWidth;
            assertTrue("Container has not been added at corrent position ", w4 == 500);
        }

        [Test]
        public function containerRecomposeAndConsistenceTest():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create five containers and hid two
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var container4:Sprite = new Sprite();
            var container5:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);
            var controller4:ContainerController = new ContainerController(container4, 200, 200);
            var controller5:ContainerController = new ContainerController(container5, 200, 200);
            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);
            TestCanvas.rawChildren.addChild(container4);
            TestCanvas.rawChildren.addChild(container5);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;
            container4.x = 790;
            container4.y = 50;
            container5.x = 1045;
            container5.y = 50;
            container4.visible = false;
            container5.visible = false;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.addController(controller4);
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();

            if (TestData.id == "recomposeContainerTest") //to test if container will be re-composed correctly after some container update
            {
                //recompose controller3
                controller3.setCompositionSize(250, 250);

                var comp0:Boolean = textFlow.flowComposer.composeToController(0);
                var comp1:Boolean = textFlow.flowComposer.composeToController(1);   // shoud be true since last line before first damaged  line will be re-composed
                var comp2:Boolean = textFlow.flowComposer.composeToController(2);	// should be true - controller3
                var comp3:Boolean = textFlow.flowComposer.composeToController(3);	// should be true
                var comp4:Boolean = textFlow.flowComposer.composeToController(4);	// true due to overflow bydesign
                textFlow.flowComposer.updateAllControllers();

                assertTrue("composeToController returns wrong flag after re-composite.",
                        comp0 == false && comp1 == true && comp2 == true && comp3 == true && comp4 == true);
            }
            else if (TestData.id == "containerConsistenceTest")
            {
                var posOfSelection:int = TestData.posOfSelection;
                var tfl:TextFlowLine = textFlow.flowComposer.findLineAtPosition(posOfSelection);
                var tfl_abs:Number = tfl.absoluteStart;
                var tfl_textLen:Number = tfl.textLength;
                var controller:ContainerController = tfl.controller;

                var index:int = textFlow.flowComposer.getControllerIndex(controller);
                var con_abs:Number = controller.absoluteStart;
                var con_textLen:Number = controller.textLength;
                var idx:Number = textFlow.flowComposer.findControllerIndexAtPosition(posOfSelection);

                assertTrue("abs start and text length are not consistent for textFlowLines in the container and the container",
                        con_abs <= tfl_abs <= con_textLen && tfl_textLen <= con_textLen && index == idx);
            }
        }

        private function findFirstAndLastVisibleLine(flowComposer:IFlowComposer, controller:ContainerController):Array
        {
            var firstLine:int = flowComposer.findLineIndexAtPosition(controller.absoluteStart);
            var lastLine:int = flowComposer.findLineIndexAtPosition(controller.absoluteStart + controller.textLength - 1);
            var lastColumn:int = 0;
            var firstVisibleLine:int = -1;
            var lastVisibleLine:int = -1;
            for (var lineIndex:int = firstLine; lineIndex <= lastLine; lineIndex++)
            {
                var curLine:TextFlowLine = flowComposer.getLineAt(lineIndex);
                if (curLine.controller != controller)
                    continue;

                // skip until we find the lines in the last column
                if (curLine.columnIndex != lastColumn)
                    continue;

                if (curLine.textLineExists && curLine.getTextLine().parent)
                {
                    if (firstVisibleLine < 0)
                        firstVisibleLine = lineIndex;

                    lastVisibleLine = lineIndex;
                }
            }

            return [firstVisibleLine, lastVisibleLine];
        }

        [Test]
        public function autoAndDragScrollingTest():void
        {

            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create three containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);

            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.updateAllControllers();

            //check first and last visible line in container1 before scrolling
            var beforePosition1:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller1);
            var beforeFirstVisibleLine1:int = beforePosition1[0];
            var beforeLastVisibleLine1:int = beforePosition1[1];

            var position1:int = controller1.textLength - 1;
            //try to scroll to end of the container
            controller1.scrollToRange(position1, position1);
            textFlow.flowComposer.updateAllControllers();

            // verify that the first and last visible lines no change after scroll
            var afterPosition1:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller1);
            var afterFirstVisibleLine1:int = afterPosition1[0];
            var afterLastVisibleLine1:int = afterPosition1[1];
            assertTrue("the container is scrollable.  Expected not scrollable.",
                    beforeFirstVisibleLine1 == afterFirstVisibleLine1 &&
                            beforeLastVisibleLine1 == afterLastVisibleLine1);

            //check first and last visible line in last container container3 before scrolling
            var beforePosition3:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller3);
            var beforeFirstVisibleLine3:int = beforePosition3[0];
            var beforeLastVisibleLine3:int = beforePosition3[1];

            var position3:int = textFlow.textLength - 1;
            var pos_start_container3:int = controller1.textLength + controller2.textLength;
            if (TestData.id == "dragScrollingTest")
            {
                editManager.selectRange(position3 - 20, position3);
                editManager.setFocus();

            }
            controller3.scrollToRange(position3 - 20, position3);
            textFlow.flowComposer.updateAllControllers();

            // verify that the first and last visible lines changed after scroll
            var afterPosition3:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller3);
            var afterFirstVisibleLine3:int = afterPosition3[0];
            var afterLastVisibleLine3:int = afterPosition3[1];
            assertTrue("the last container is not scrollable.  Expected scrollable.",
                    beforeFirstVisibleLine3 < afterFirstVisibleLine3 &&
                            beforeLastVisibleLine3 < afterLastVisibleLine3);

        }

        [Test]
        public function navigateByLineTest():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create three containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);

            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.updateAllControllers();

            //try to use previousLine to get to first container and nextLine to get to third container
            var posSecondControllerBegin:int = controller2.absoluteStart;
            var posSecondControllerEnd:int = posSecondControllerBegin + controller2.textLength;
            if (TestData.id == "navigateByPreviousLine")
            {
                //to get the selection range at beginning of second container then previousLine should go to the first container
                editManager.selectRange(posSecondControllerBegin, posSecondControllerBegin + 10);
            }
            else if (TestData.id == "navigateByNextLine")
            {
                //to get the selection range at end of second container then nextLine should go to the third container
                editManager.selectRange(posSecondControllerEnd - 10, posSecondControllerEnd);
            }
            var selRange:SelectionState = editManager.getSelectionState();
            if (TestData.id == "navigateByPreviousLine")
            {
                NavigationUtil.previousLine(selRange, true);
            }
            else if (TestData.id == "navigateByNextLine")
            {
                NavigationUtil.nextLine(selRange, true);
            }

            //composes all the text up-to date.
            textFlow.flowComposer.updateAllControllers();
            var positionAfter:int = selRange.activePosition;
            var curControllerIdx:int = textFlow.flowComposer.findControllerIndexAtPosition(positionAfter);

            if (TestData.id == "navigateByPreviousLine")
            {
                assertTrue("The previousLine didn't get to correct container.", curControllerIdx == 0);
            }
            else if (TestData.id == "navigateByNextLine")
            {
                assertTrue("The previousLine didn't get to correct container.", curControllerIdx == 2);
            }
        }

        [Test]
        public function defaultContextMenuOnTest():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create a container
            var container:Sprite = new Sprite();
            var controller:ContainerController = new ContainerController(container, 200, 200);
            TestCanvas.rawChildren.addChild(container);

            // add the controller to the text flow and update it to display the text and setFocus to attach contextMenu
            textFlow.flowComposer.addController(controller);
            editManager.setFocus();
            textFlow.flowComposer.updateAllControllers();
            assertTrue("The default Context Menu should be on when editMode=readWrite.", container.contextMenu != null);
        }

        /**
         * Check if the contectMenu is off when editMode=readOnly
         */
        [Test]
        public function contextMenuOffTest():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create a container
            var container:Sprite = new Sprite();
            var controller:ContainerController = new ContainerController(container, 200, 200);
            TestCanvas.rawChildren.addChild(container);
            textFlow.flowComposer.addController(controller);
            editManager.setFocus(); //attach default contextMenu
            textFlow.flowComposer.updateAllControllers();
            textFlow.interactionManager = null;	//make editMode=readOnly to disable contextMenu
            assertTrue("The default Context Menu should be off when editMode=readOnly.", container.contextMenu == null);
        }

        [Test]
        public function overrideContextMenuTestNull():void
        {
            var s:Sprite = createInputManagerNull(hostFormat);
            s.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
            TestCanvas.rawChildren.addChild(s);
            assertTrue("It should be no contextMenu with the override fuction.", s.contextMenu == null);
        }

        static private function createInputManagerNull(hostFormat:ITextLayoutFormat):Sprite
        {
            var s:Sprite = new Sprite();
            var tcm:CustomTextContainerManagerNull = new CustomTextContainerManagerNull(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = 100;
            tcm.setText("Hello World");
            tcm.hostFormat = hostFormat;
            tcm.updateContainer();
            return s;
        }

        [Test]
        public function overrideContextMenuTestAll():void
        {
            var s:Sprite = createInputManagerAll(hostFormat);
            s.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
            TestCanvas.rawChildren.addChild(s);
            assertTrue("The contextMenu should be all true.", s.contextMenu.customItems[0].caption == "PageUp"
                    && s.contextMenu.customItems[1].caption == "PageDown")
        }

        static private function createInputManagerAll(hostFormat:ITextLayoutFormat):Sprite
        {
            var s:Sprite = new Sprite();
            var tcm:CustomTextContainerManagerAll = new CustomTextContainerManagerAll(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = 100;
            tcm.setText("Hello World");
            tcm.hostFormat = hostFormat;
            tcm.updateContainer();
            return s;
        }

        /**
         * to test bug 2500307: TCM shouldn't have contextMenu when read-only
         */
        [Test]
        public function contextMenuReadOnly():void
        {
            var s:Sprite = new Sprite();
            s.x = 0;
            s.y = 0;
            TestCanvas.rawChildren.addChild(s);
            var tcm:TextContainerManager = new TextContainerManager(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = NaN;
            tcm.setText("Hello World, there should not be a context menu becasue field is read-only");
            var format:TextLayoutFormat = new TextLayoutFormat(TextLayoutFormat.defaultFormat);
            format.fontFamily = "Arial";
            format.fontSize = 14;
            tcm.hostFormat = format;
            tcm.editingMode = EditingMode.READ_ONLY;
            tcm.updateContainer();
            assertTrue("The default Context Menu should be off when editMode=readOnly.", tcm.container.contextMenu == null);
        }

        /**
         * to test bug 2504032: TCM contextMenu when using the factory and READ_SELECT should not enable the edit clipboard items such as cut and paste
         */
        [Test]
        public function contextMenuReadSelect():void
        {
            var s:Sprite = new Sprite();
            s.x = 0;
            s.y = 0;
            var tcm:TextContainerManager = new TextContainerManager(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = NaN;
            tcm.setText("Hello World, TCM contextMenu when using the factory and READ_SELECT should not enable the edit clipboard items such as cut and paste");
            var format:TextLayoutFormat = new TextLayoutFormat(TextLayoutFormat.defaultFormat);
            format.fontFamily = "Arial";
            format.fontSize = 14;
            tcm.hostFormat = format;
            tcm.updateContainer();

            //to make textMenu and clipboardMenu enabled
            s.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
            TestCanvas.rawChildren.addChild(s);
            assertTrue("The edit clipboard items such as cut and paste were disabled when TCM contextMenu NOT using READ_SELECT", tcm.container.contextMenu.clipboardMenu == true);

            //to make textMenu and clipboardMenu disabled
            tcm.editingMode = EditingMode.READ_SELECT;
            tcm.updateContainer();
            assertTrue("The edit clipboard items such as cut and paste were enabled when TCM contextMenu using READ_SELECT", tcm.container.contextMenu == null);
        }

        private function getTestMarkup():String
        {
           return  "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' " +
                   "textIndent='0' paragraphSpaceBefore='6' paddingTop='4' paddingBottom='4'>" +
                   "<flow:p paragraphSpaceAfter='15' >" +
                   "<flow:span>There are many </flow:span>" +
                   "<flow:span fontStyle='italic'>such</flow:span>" +
                   "<flow:span> lime-kilns in that tract of country, for the purpose of burning the white" +
                   " marble which composes a large part of the substance of the hills. Some of them, built " +
                   "years ago, and long deserted, with weeds growing in the vacant round of the interior, " +
                   "which is open to the sky, and grass and wild-flowers rooting themselves into the chinks " +
                   "of the stones, look already like relics of antiquity, and may yet be overspread with the" +
                   " lichens of centuries to come. Others, where the lime-burner still feeds his daily and " +
                   "nightlong fire, afford points of interest to the wanderer among the hills, who seats " +
                   "himself on a log of wood or a fragment of marble, to hold a chat with the solitary man. " +
                   "It is a lonesome, and, when the character is inclined to thought, may be an intensely " +
                   "thoughtful occupation; as it proved in the case of Ethan Brand, who had mused to such " +
                   "strange purpose, in days gone by, while the fire in this very kiln was burning.</flow:span>" +
                   "</flow:p>" +
                   "<flow:p paragraphSpaceAfter='15'>" +
                   "<flow:span>" +
                   "The man who now watched the fire was of a different order, and troubled himself with no " +
                   "thoughts save the very few that were requisite to his business. At frequent intervals, " +
                   "he flung back the clashing weight of the iron door, and, turning his face from the " +
                   "insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a " +
                   "long pole. Within the furnace were seen the curling and riotous flames, and the burning " +
                   "marble, almost molten with the intensity of heat; while without, the reflection of the " +
                   "fire quivered on the dark intricacy of the surrounding forest, and showed in the " +
                   "foreground a bright and ruddy little picture of the hut, the spring beside its door, the " +
                   "athletic and coal-begrimed figure of the lime-burner, and the halffrightened child, " +
                   "shrinking into the protection of his father's shadow. And when again the iron door was " +
                   "closed, then reappeared the tender light of the half-full moon, which vainly strove to " +
                   "trace out the indistinct shapes of the neighboring mountains; and, in the upper sky, " +
                   "there was a flitting congregation of clouds, still faintly tinged with the rosy sunset, " +
                   "though thus far down into the valley the sunshine had vanished long and long ago.</flow:span>" +
                   "</flow:p>" +
                   "</flow:TextFlow>";
        }
    }
}

import flash.display.Sprite;
import flash.events.ContextMenuEvent;
import flash.events.KeyboardEvent;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.ui.Keyboard;

import flashx.textLayout.container.TextContainerManager;
import flashx.textLayout.elements.IConfiguration;
import flashx.textLayout.tlf_internal;

use namespace tlf_internal;

class CustomTextContainerManagerNull extends TextContainerManager
{
    public function CustomTextContainerManagerNull(container:Sprite, configuration:IConfiguration = null)
    {
        super(container, configuration);
    }

    override protected function createContextMenu():ContextMenu
    {
        return null;
    }
}


class CustomTextContainerManagerAll extends TextContainerManager
{
    public function CustomTextContainerManagerAll(container:Sprite, configuration:IConfiguration = null)
    {
        super(container, configuration);
    }

    protected override function createContextMenu():ContextMenu
    {
        var menu:ContextMenu = super.createContextMenu();
        var item:ContextMenuItem;
        item = new ContextMenuItem("PageUp");
        menu.customItems.push(item);
        item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
        item = new ContextMenuItem("PageDown");
        menu.customItems.push(item);
        item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
        return menu;
    }

    private function menuItemSelectHandler(e:ContextMenuEvent):void
    {
        var key:KeyboardEvent;
        switch (e.currentTarget.caption)
        {
            case "PageUp":
                key = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, 0, Keyboard.PAGE_UP);
                keyDownHandler(key);
                break;
            case "PageDown":
                key = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, 0, Keyboard.PAGE_DOWN);
                keyDownHandler(key);
                break;
        }
    }


}
/******************************************************************************
 Truncation options test for truncation of text composed using TextlineFactory
 This is temporary till creating indepndent test file for truncation options.
 Most of functions are modification from ConpositionTest.as
 ******************************************************************************/
/****
 var lines:Array;
 var textLength:int;
 var bounds:Rectangle;
 var contentTextLength:int = textLength;
 var line0:TextLine = lines[0] as TextLine;
 var line0Extent:Number = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line0.y - line0.ascent : line0.y + line0.descent;
 var line0TextLen:int = line0.rawTextLength;
 var line1:TextLine = lines[1] as TextLine;
 var line1Extent:Number = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line1.y - line1.ascent : line1.y + line1.descent;
 var contentHeight:Number = bounds.height;
 var line:TextLine;
 var lineExtent:Number;
 var testTruncationIndicator:String
 var testFactory:TextLineFactory = new TextLineFactory();
 var originalContentPrefix:String;

 var singleLineText:String = "A single text line for truncation options test.";

 var rtlText:String =
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة'+
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة'+
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة'+
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة';

 var accentedText:String =
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A';


 //function to display the text object
 private function Callback(t1:TextLine):void
 {
     textLength += t1.rawTextLength ;
     lines.push(t1);
 }

 public function TruncationOptSingleLineCustom():void
 {
     var bounds:Rectangle = new Rectangle(40,40,100,NaN);
     testTruncationIndicator = "@@@"
 testFactory.text = singleLineText;
 var atMark:String = "@@@"
 var truncatedTxt:String = "A text line fo@@@";
 var truncationIndicatorLength:int;

 testFactory.textLinesFromString(Callback,bounds,new TruncationOptions(testTruncationIndicator,1));
 truncationIndicatorLength = truncatedTxt.lastIndexOf(testTruncationIndicator);
 assertTrue("Truncation indicator, was not @@@!", testTruncationIndicator == atMark);
 assertTrue("Truncation indicator didn't appear at the end of sentence!", truncatedTxt.length == truncationIndicatorLength+testTruncationIndicator.length);
 }

 public function TruncationOptSingleLineDefault():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = singleLineText;
     bounds.left = 0; bounds.top = 0;
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(null, 2));
     truncationIndicatorIndex = testFactory.truncatedText.lastIndexOf(TruncationOptions.HORIZONTAL_ELLIPSIS);
     assertTrue("Default truncation indicator not present at the end of the truncated string",
     truncationIndicatorIndex+TruncationOptions.HORIZONTAL_ELLIPSIS.length == testFactory.truncatedText.length);
     originalContentPrefix = testFactory.truncatedText.slice(0, truncationIndicatorIndex);
     assertTrue("Original content before truncation indicator mangled", singleLineText.indexOf(originalContentPrefix) == 0);
 }


 public function UnspecifiedWidthTruncation():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = NaN;	bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null,null,null,new TruncationOptions(null, 0));
     assertTrue("Caused truncation despite unspecified width", textLength == contentTextLength);
 }

 public function ExplicitLineBreakingTruncation():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     var format:TextLayoutFormat = new TextLayoutFormat();
     format.lineBreak = LineBreak.EXPLICIT;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null,null, format,new TruncationOptions(null, 0));
     assertTrue("Caused truncation despite explicit line breaks", textLength == contentTextLength);
 }

 public function ComposeHeightNoLine():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = line0Extent/2;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null,null, null,new TruncationOptions());
     assertTrue("Composed one or more lines when compose height allows none", lines.length == 0);
 }

 public function ZeroLineCountLimit():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = contentHeight;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback, singleLineText, bounds, null, null, null,new TruncationOptions(null, 0));
     assertTrue("Composed one or more lines when line count limit is 0", lines.length == 0);
 }

 public function UnfitTruncationIndicator():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = contentHeight -1;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(singleLineText));
     assertTrue("Composed one or more lines when compose height does not allow truncation indicator itself to fit", lines.length == 0);
 }

 public function ComposingFitToBounds():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 2));
     assertTrue("Invalid truncation results when composing to fit in a line count limit", lines.length == 2);
 }

 public function CompostitngFitLineCountLimit():void
 {
     lines.splice(0); textLength = 0;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 2));
     assertTrue("Invalid truncation results when multiple truncation criteria provided",lines.length == 1);
     line = lines[0] as TextLine;
     lineExtent = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
     assertTrue("Invalid truncation results when multiple truncation criteria provided", lineExtent <= line0Extent);
 }

 public function ComposingFitBoundsAndLineCountLimit():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 2));
     assertTrue("Invalid truncation results when composing to fit in a line count limit", lines.length == 2);
 }

 public function ComposingFitBoundsAndLineCountLimit_2():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = line1Extent;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 1));
     assertTrue("Invalid truncation results when multiple truncation criteria provided", lines.length == 1);
     line = lines[0] as TextLine;
     lineExtent = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
     assertTrue("Invalid truncation results when multiple truncation criteria provided", lineExtent <= line1Extent);;
 }

 public function OriginalTextReplacement():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = singleLineText;
     bounds.left = 0; bounds.top = 0;
     testTruncationIndicator = '\u200B';
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));
     assertTrue("Replacing more original content than is neccessary", testFactory.truncatedText.length == line0TextLen+customTruncationIndicator.length);
 }

 public function OriginalTextReplacementRTL():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = rtlText;
     bounds.left = 0; bounds.top = 0;
     testTruncationIndicator = '\u200B';
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));
 }

 public function TruncationAtomsBoundaries():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = accentedText;
     bounds.left = 0; bounds.top = 0;
     testTruncationIndicator = '<' + '\u200A' + '>'; // what precedes and succeeds the hair space is irrelevant
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));
     assertTrue("[Not a code bug] Fix test case so that truncation indicator itself fits", lines.length == 1); // baseline

     var initialTruncationPoint:int =  testFactory.truncatedText.length - testTruncationIndicator.length;
     assertTrue("[Not a code bug] Fix test case so that some of the original content is left behind on first truncation attempt", initialTruncationPoint > 0); // baseline
     assertTrue("Truncation in the middle of an atom!", initialTruncationPoint % 2 == 0);
     var nextTruncationPoint:int;
     do
     {
         bounds.height = NaN;
         // add another hair space in each iteration, making truncation indicator wider (ever so slightly)
         testTruncationIndicator = testTruncationIndicator.replace('\u200A', '\u200A\u200A');
         testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));

         nextTruncationPoint =  testFactory.truncatedText.length - testTruncationIndicator.length;
         if (nextTruncationPoint != initialTruncationPoint)
         {
             assertTrue("Truncation in the middle of an atom!", nextTruncationPoint % 2 == 0);
             assertTrue("Sub-optimal replacement of original content?", nextTruncationPoint == initialTruncationPoint-2);
             initialTruncationPoint = nextTruncationPoint;
         }

     } while (nextTruncationPoint);
 }
 ****/

