////////////////////////////////////////////////////////////////////////////////
//
//  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.TestConfigurationLoader;
    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.FileRepository;
    import UnitTest.Fixtures.TestCaseVo;
    import UnitTest.Fixtures.TestConfig;
    import UnitTest.Validation.*;

    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.geom.Rectangle;
    import flash.text.engine.TextLine;

    import flashx.textLayout.compose.IFlowComposer;
    import flashx.textLayout.compose.TextFlowLine;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.container.ScrollPolicy;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.IEditManager;
    import flashx.textLayout.edit.SelectionManager;
    import flashx.textLayout.edit.SelectionState;
    import flashx.textLayout.edit.TextScrap;
    import flashx.textLayout.elements.*;
    import flashx.textLayout.events.CompositionCompleteEvent;
    import flashx.textLayout.events.DamageEvent;
    import flashx.textLayout.events.FlowElementMouseEvent;
    import flashx.textLayout.events.FlowOperationEvent;
    import flashx.textLayout.events.ScrollEvent;
    import flashx.textLayout.events.ScrollEventDirection;
    import flashx.textLayout.events.SelectionEvent;
    import flashx.textLayout.events.StatusChangeEvent;
    import flashx.textLayout.events.TextLayoutEvent;
    import flashx.textLayout.formats.BlockProgression;
    import flashx.textLayout.formats.LineBreak;
    import flashx.textLayout.formats.TextAlign;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.operations.FlowOperation;
    import flashx.textLayout.operations.InsertInlineGraphicOperation;
    import flashx.textLayout.operations.RedoOperation;
    import flashx.textLayout.operations.UndoOperation;
    import flashx.textLayout.tlf_internal;
    import flashx.textLayout.utils.GeometryUtil;

    import mx.utils.LoaderUtil;

    import org.flexunit.asserts.assertTrue;

    use namespace tlf_internal;

    [TestCase(order=6)]
    [RunWith("org.flexunit.runners.Parameterized")]
    public class AllEventTest extends VellumTestCase
    {
        [DataPoints(loader="shortTextMouseEventTBLTRTestLoader")]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var shortTextMouseEventTBLTRTestDp:Array;

        public static var shortTextMouseEventTBLTRTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/AllEventTest.xml", "ShortTextMouseEventTBLTRTest");

        [DataPoints(loader="shortTextMouseEventTBRTLTestLoader")]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var shortTextMouseEventTBRTLTestDp:Array;

        public static var shortTextMouseEventTBRTLTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/AllEventTest.xml", "ShortTextMouseEventTBRTLTest");

        [DataPoints(loader="shortTextMouseEventRLLTRTestLoader")]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var shortTextMouseEventRLLTRTestDp:Array;

        public static var shortTextMouseEventRLLTRTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/AllEventTest.xml", "ShortTextMouseEventRLLTRTest");

        [DataPoints(loader="shortTextMouseEventRLRTLTestLoader")]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var shortTextMouseEventRLRTLTestDp:Array;

        public static var shortTextMouseEventRLRTLTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/AllEventTest.xml", "ShortTextMouseEventRLRTLTest");

        [DataPoints(loader="flowElementMouseEventTestLoader")]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var flowElementMouseEventTestDp:Array;

        public static var flowElementMouseEventTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/AllEventTest.xml", "FlowElementMouseEventTest");

        [Embed(source="../../../../test/testFiles/assets/smiley.gif")]
        private var embeddedGIF:Class;

        private var textTBLTR:String = "<TextFlow blockProgression='tb' direction='ltr' lineBreak='explicit' version='3.0.0' xmlns='http://ns.adobe.com/textLayout/2008\'><p paddingLeft='15' paragraphSpaceBefore='15' paragraphSpaceAfter='15'><span>MIA - </span><a href='http://www.adobe.com/go/flashplayer' target='_self'><span>MENU</span></a><span> - DEN</span></p></TextFlow>";

        public function AllEventTest():void
        {
            super("", "AllEventTest2", TestConfig.getInstance());
            metaData = {};
            // Note: These must correspond to a Watson product area (case-sensitive)
            metaData.productArea = "Text Composition";
        }

        [BeforeClass]
        public static function setUpClass():void
        {
            var testConfig:TestConfig = TestConfig.getInstance();
            FileRepository.readFile(testConfig.baseURL, "../../test/testFiles/markup/tlf/ShortTextMouseEventTBLTR.xml");
            FileRepository.readFile(testConfig.baseURL, "../../test/testFiles/markup/tlf/ShortTextMouseEventTBRTL.xml");
            FileRepository.readFile(testConfig.baseURL, "../../test/testFiles/markup/tlf/ShortTextMouseEventRLLTR.xml");
            FileRepository.readFile(testConfig.baseURL, "../../test/testFiles/markup/tlf/ShortTextMouseEventRLRTL.xml");
        }

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

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

        //SelectionEvent Test Cases
        [Test]
        public function selectionEventTest():void
        {
            metaData.productArea = "Editing";

            this.SelManager.selectRange(0, 0);

            var textFlow:TextFlow = this.SelManager.textFlow;
            var endIdx:int = 200;
            var startIdx:int = 100;

            var theRects:Array = GeometryUtil.getHighlightBounds(new TextRange(textFlow, startIdx, endIdx));
            for each(var lineRectPair:Object in theRects)
            {
                var theLine:TextLine = lineRectPair.textLine as TextLine;
                var rect:Rectangle = lineRectPair.rect as Rectangle;
                var tfl:TextFlowLine = theLine.userData as TextFlowLine;
                assertTrue("userData on a textLine should be a TextFlowLine!", tfl);

                //first "click" inside the bounds of the rect and make sure we have a point within the selection range:
                var index:int = SelectionManager.tlf_internal::computeSelectionIndex(textFlow, theLine, null, rect.x + (rect.width / 2), rect.y + (rect.height / 2));

                //validate using a calculated index.  If this is a partial line selection, then using the abs start and end isn't valid.
                var checkStart:int = tfl.absoluteStart >= startIdx ? tfl.absoluteStart : startIdx;
                var checkEnd:int = (tfl.absoluteStart + tfl.textLength) <= endIdx ? (tfl.absoluteStart + tfl.textLength) : endIdx;

                //validate
                assertTrue("the computed index derived from the selection shape must be within the line!", checkStart <= index && checkEnd >= index);
            }

            // Select All
            var validator:SelectionEventValidator = new SelectionEventValidator(TestFrame.textFlow,
                    new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, new SelectionState(TestFrame.textFlow, 0, TestFrame.textFlow.textLength - 1)));
            SelManager.selectAll();
            assertTrue("Expected selection event showing entire flow selected", validator.validate(1));

            // Select range
            validator.reset(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, new SelectionState(TestFrame.textFlow, 10, 100)));
            SelManager.selectRange(10, 100);
            SelManager.refreshSelection();
            assertTrue("Expected selection event showing range selected", validator.validate(1));

            // Apply format -- expects selection changed on selected area b/c the contents changed
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.fontSize = 48;
            validator.reset();
            (SelManager as IEditManager).applyLeafFormat(format);
            assertTrue("Expected selection event after formatting applied", validator.validate(1));

            // Insert text -- expects selection changed on selected area b/c the contents changed
            const textToInsert:String = "FOO";
            validator.reset(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false,
                    new SelectionState(TestFrame.textFlow, 20 + textToInsert.length, 20 + textToInsert.length)));
            SelManager.selectRange(20, 20);
            (SelManager as IEditManager).insertText("FOO");
            SelManager.flushPendingOperations();  // force insert to happen right away
            assertTrue("Expected selection event after text insertion", validator.validate(1));

            // Change select range - test that client code can change the selection from within a selection event handler
            textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE, changeSelectionHandler);
            SelManager.selectRange(10, 100);
            SelManager.refreshSelection();
            assertTrue("Expected entire flow selected", SelManager.absoluteStart == 0 && SelManager.absoluteEnd == textFlow.textLength - 1);

            // Test selection by mouse. We should get one and only one event from this.
            SelManager.selectRange(10, 11);
            theRects = GeometryUtil.getHighlightBounds(new TextRange(textFlow, SelManager.absoluteStart, SelManager.absoluteEnd));
            theLine = theRects[0].textLine as TextLine;
            rect = theRects[0].rect as Rectangle;
            var mouseEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, true, rect.x, rect.y, theLine, false, false, false, false);
            validator.reset(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false,
                    new SelectionState(TestFrame.textFlow, 10, 10)));
            theLine.dispatchEvent(mouseEvent);
            assertTrue("Expected single selection event after mouse click", validator.validate(1));
        }

        /**
         * DamageEvent Test Cases
         */
        [Test]
        public function damageEventTest():void
        {
            //Change Color Test
            var selectionBegin:int = 20;
            var selectionEnd:int = 400;
            SelManager.selectRange(selectionBegin, selectionEnd);
            var validator:DamageEventValidator = new DamageEventValidator(TestFrame.textFlow,
                    new DamageEvent(DamageEvent.DAMAGE, false, false, null, SelManager.absoluteStart, SelManager.absoluteEnd - SelManager.absoluteStart));
            const fontColor:int = 0xFF0000;
            var ca:TextLayoutFormat = new TextLayoutFormat();

            ca.color = fontColor;
            SelManager.applyLeafFormat(ca);
            SelManager.flushPendingOperations();
            assertTrue("Expected damage event showing after color change", validator.validate(1));

            //Delete Text Test
            validator.reset(new DamageEvent(DamageEvent.DAMAGE, false, false, null, SelManager.absoluteStart, SelManager.absoluteEnd - SelManager.absoluteStart));
            SelManager.cutTextScrap(SelManager.getSelectionState());
            SelManager.flushPendingOperations();
            assertTrue("Expected damage event showing after text deletion", validator.validate(1));

            //Delete Character Test
            SelManager.selectRange(90, 91);
            validator.reset(new DamageEvent(DamageEvent.DAMAGE, false, false, null, SelManager.absoluteStart, SelManager.absoluteEnd - SelManager.absoluteStart));
            SelManager.cutTextScrap(SelManager.getSelectionState());
            SelManager.flushPendingOperations();
            assertTrue("Expected damage event showing after character deletion", validator.validate(1));

            //Change Geometry Test
            validator.reset(new DamageEvent(DamageEvent.DAMAGE, false, false, TestFrame.textFlow, 0, TestFrame.textFlow.textLength));
            TestFrame.setCompositionSize(500, 500);
            TestFrame.textFlow.flowComposer.updateAllControllers();
            assertTrue("Expected damage event showing after Geometry change", validator.validate(1));

            //Change Block Progression Test
            validator.reset(new DamageEvent(DamageEvent.DAMAGE, false, false, TestFrame.textFlow, 0, TestFrame.textFlow.textLength));
            TestFrame.textFlow.blockProgression = "rl";
            TestFrame.textFlow.flowComposer.updateAllControllers();
            assertTrue("Expected damage event showing after Block Progression change", validator.validate(1));

            //Change Font Size Test
            validator.reset(new DamageEvent(DamageEvent.DAMAGE, false, false, TestFrame.textFlow, 0, TestFrame.textFlow.textLength));
            TestFrame.textFlow.fontSize = 32;
            TestFrame.textFlow.flowComposer.updateAllControllers();
            assertTrue("Expected DamageEvent showing after Font Size change", validator.validate(1));
        }

        [Test]
        public function statusChangeEventTest():void
        {
            metaData.productArea = "Editing";

            //Insert Picture Test
            var src:String = LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/leaves.jpg");
            var element:InlineGraphicElement = new InlineGraphicElement();
            element.source = src;
            element.width = 30;
            element.height = 30;
            var validator:StatusChangeEventValidator = new StatusChangeEventValidator(TestFrame.textFlow,
                    new StatusChangeEvent(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, false, false, element, "loading", null));

            var width:int = 30;
            var height:int = 30;
            var selectionBegin:int = 10;
            var selectionEnd:int = 10;
            SelManager.selectRange(selectionBegin, selectionEnd);
            SelManager.insertInlineGraphic(src, width, height);
            SelManager.flushPendingOperations();

            assertTrue("Expected StatusChangeEvent showing after picture insertion", validator.validate(1));
        }

        /**
         * The following test case is designed to test bug#2929161
         */
        [Test]
        public function statusChangeEventHandlerTest():void
        {
            metaData.productArea = "Editing";

            TestFrame.textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, onStatusChangeHandler);
            function onStatusChangeHandler(event:StatusChangeEvent):void
            {
                var ilg:InlineGraphicElement = event.element as InlineGraphicElement;
                if (ilg && event.status == InlineGraphicElementStatus.READY)
                {
                    assertTrue("Expected inline graphic is not null", ilg.graphic != null);
                }
            }

            //Insert Display Object
            var yellowCircle:Sprite = new Sprite();
            yellowCircle.graphics.beginFill(0xFFFF33);	// yellow
            yellowCircle.graphics.drawCircle(10, 12, 10);
            yellowCircle.graphics.endFill();

            var width:int = 30;
            var height:int = 30;
            var selectionBegin:int = 10;
            var selectionEnd:int = 10;
            SelManager.selectRange(selectionBegin, selectionEnd);
            SelManager.insertInlineGraphic(yellowCircle, width, height);
            SelManager.flushPendingOperations();

            //Insert Class
            selectionBegin = 15;
            selectionEnd = 15;
            SelManager.selectRange(selectionBegin, selectionEnd);
            SelManager.insertInlineGraphic(embeddedGIF, width, height);
            SelManager.flushPendingOperations();

            //Insert null object
            selectionBegin = 20;
            selectionEnd = 20;
            SelManager.selectRange(selectionBegin, selectionEnd);
            SelManager.insertInlineGraphic(null, width, height);
            SelManager.flushPendingOperations();
        }

        [Test]
        public function FlowOperationEventTest():void
        {
            metaData.productArea = "Editing";

            var src:String = LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/leaves.jpg");
            var width:int = 30;
            var height:int = 30;
            var selectionBegin:int = 10;
            var selectionEnd:int = 10;
            SelManager.selectRange(selectionBegin, selectionEnd);
            var operation:InsertInlineGraphicOperation = new InsertInlineGraphicOperation(SelManager.getSelectionState(),
                    src, width, height, "none");
            var beginValidator:FlowOperationEventValidator = new FlowOperationEventValidator(TestFrame.textFlow,
                    new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN, false, false, operation, 0, null));
            var endValidator:FlowOperationEventValidator = new FlowOperationEventValidator(TestFrame.textFlow,
                    new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END, false, false, operation, 0, null));
            var completeValidator:FlowOperationEventValidator = new FlowOperationEventValidator(TestFrame.textFlow,
                    new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE, false, false, operation, 0, null));
            var compositionValidator:CompositionCompleteEventValidator = new CompositionCompleteEventValidator(TestFrame.textFlow,
                    new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE, false, false, TestFrame.textFlow, 0, TestFrame.textFlow.textLength + 1));
            SelManager.insertInlineGraphic(src, width, height);
            assertTrue("Expected FlowOperationBeginEvent during picture insertion", beginValidator.validate(1));
            assertTrue("Expected FlowOperationEndEvent during picture insertion", endValidator.validate(1));
            assertTrue("Expected FlowOperationCompleteEvent during picture insertion", completeValidator.validate(1));
            assertTrue("Expected CompositionCompleEvent during picture insertion", compositionValidator.validate(1));

            // Check undo
            var pseudoUndoOperation:UndoOperation = new UndoOperation(operation);
            beginValidator.reset(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN, false, false, pseudoUndoOperation, 0, null));
            endValidator.reset(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END, false, false, pseudoUndoOperation, 0, null));
            completeValidator.reset(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE, false, false, pseudoUndoOperation, 0, null));

            SelManager.undo();

            assertTrue("Expected FlowOperationBeginEvent during undo picture insertion", beginValidator.validate(1));
            assertTrue("Pseudo undo event should have been broadcast", FlowOperationEvent(beginValidator.lastEvent).operation is UndoOperation);
            assertTrue("Expected FlowOperationEndEvent during undo picture insertion", endValidator.validate(1));
            assertTrue("Pseudo undo event should have been broadcast", FlowOperationEvent(endValidator.lastEvent).operation is UndoOperation);
            assertTrue("Expected FlowOperationCompleteEvent undo during picture insertion", completeValidator.validate(1));
            assertTrue("Pseudo undo event should have been broadcast", FlowOperationEvent(completeValidator.lastEvent).operation is UndoOperation);

            // Check redo
            var pseudoRedoOperation:RedoOperation = new RedoOperation(operation);
            beginValidator.reset(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN, false, false, pseudoRedoOperation, 0, null));
            endValidator.reset(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END, false, false, pseudoRedoOperation, 0, null));
            completeValidator.reset(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE, false, false, pseudoRedoOperation, 0, null));

            SelManager.redo();

            assertTrue("Expected FlowOperationBeginEvent during redo picture insertion", beginValidator.validate(1));
            assertTrue("Pseudo redo event should have been broadcast", FlowOperationEvent(beginValidator.lastEvent).operation is RedoOperation);
            assertTrue("Expected FlowOperationEndEvent during redo picture insertion", endValidator.validate(1));
            assertTrue("Pseudo redo event should have been broadcast", FlowOperationEvent(endValidator.lastEvent).operation is RedoOperation);
            assertTrue("Expected FlowOperationCompleteEvent redo during picture insertion", completeValidator.validate(1));
            assertTrue("Pseudo redo event should have been broadcast", FlowOperationEvent(completeValidator.lastEvent).operation is RedoOperation);

        }

        [Test]
        public function FlowCompositeOperationEventTest():void
        {
            metaData.productArea = "Editing";

            var beginValidator:FlowOperationEventValidator = new FlowOperationEventValidator(TestFrame.textFlow,
                    new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN, false, false, new FlowOperation(TestFrame.textFlow), 1, null));
            var endValidator:FlowOperationEventValidator = new FlowOperationEventValidator(TestFrame.textFlow,
                    new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END, false, false, new FlowOperation(TestFrame.textFlow), 1, null));
            var completeValidator:FlowOperationEventValidator = new FlowOperationEventValidator(TestFrame.textFlow,
                    new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE, false, false, new FlowOperation(TestFrame.textFlow), 0, null));
            var compositionValidator:CompositionCompleteEventValidator = new CompositionCompleteEventValidator(TestFrame.textFlow,
                    new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE, false, false, TestFrame.textFlow, 0, TestFrame.textFlow.textLength));

            SelManager.selectAll();
            SelManager.beginCompositeOperation();
            var leafFormat:TextLayoutFormat = new TextLayoutFormat();
            leafFormat.fontSize = 18;
            SelManager.applyLeafFormat(leafFormat);
            var paraFormat:TextLayoutFormat = new TextLayoutFormat();
            paraFormat.textAlign = TextAlign.CENTER;
            SelManager.applyParagraphFormat(paraFormat);
            SelManager.endCompositeOperation();

            assertTrue("Expected FlowOperationBeginEvent during composite operation", beginValidator.validate(2));
            assertTrue("Expected FlowOperationEndEvent during composite operation", endValidator.validate(2));
            assertTrue("Expected FlowOperationCompleteEvent during composite operation", completeValidator.validate(1));
            assertTrue("Expected CompositionCompleEvent during composite operation", compositionValidator.validate(1));
        }

        [Test]
        public function CompositionCompleteEventTest():void
        {
            var validator:CompositionCompleteEventValidator;

            if (TestFrame.textFlow.blockProgression == BlockProgression.RL)
            {
                validator = new CompositionCompleteEventValidator(TestFrame.textFlow,
                        new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE, false, false, TestFrame.textFlow, 0, 744));
            }
            else
            {
                validator = new CompositionCompleteEventValidator(TestFrame.textFlow,
                        new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE, false, false, TestFrame.textFlow, 0, 831));

            }

            TestFrame.textFlow.fontSize = 30;
            TestFrame.textFlow.flowComposer.updateAllControllers();
            assertTrue("Expected CompositionCompleEvent showing after font size changing", validator.validate(1));
        }

        [Test(dataProvider=shortTextMouseEventTBLTRTestDp)]
        public function ShortTextMouseEventTBLTRTest(dpData:TestCaseVo):void
        {
            SelManager.textFlow = getTextFlowTBLTR(dpData);
            ShortTextMouseEventTest();
        }

        [Test(dataProvider=shortTextMouseEventTBRTLTestDp)]
        public function ShortTextMouseEventTBRTLTest(dpData:TestCaseVo):void
        {
            SelManager.textFlow = getTextFlowTBLTR(dpData);
            ShortTextMouseEventTest();
        }

        [Test(dataProvider=shortTextMouseEventRLLTRTestDp)]
        public function ShortTextMouseEventRLLTRTest(dpData:TestCaseVo):void
        {
            SelManager.textFlow = getTextFlowTBLTR(dpData);
            ShortTextMouseEventTest();
        }

        [Test(dataProvider=shortTextMouseEventRLRTLTestDp)]
        public function ShortTextMouseEventRLRTLTest(dpData:TestCaseVo):void
        {
            SelManager.textFlow = getTextFlowTBLTR(dpData);
            ShortTextMouseEventTest();
        }

        // Test cases that should be covered
        // The link on a short text which is less wide than a line
        private function ShortTextMouseEventTest():void
        {
            var validator:FlowElementMouseEventValidator;
            SelManager.selectRange(6, 10);

            //get the bounds of the link
            var selectionState:SelectionState = SelManager.getSelectionState();
            var highlightBounds:Array = GeometryUtil.getHighlightBounds(selectionState);
            var boundsInfo:Object = highlightBounds[0];
            var bounds:Rectangle = boundsInfo.rect as Rectangle;
            var textLine:TextLine = boundsInfo.textLine;

            //get the link element
            var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(SelManager.absoluteStart);
            var link:LinkElement = leaf.parent as LinkElement;

            var cc:ContainerController = SelManager.textFlow.flowComposer.getControllerAt(0);
            var textFlow:TextFlow = SelManager.textFlow;		// save it for later
            SelManager.textFlow.interactionManager = null;		// turn off editing
            var mouseOverEvent:MouseEvent;
            var mouseOutEvent:MouseEvent;

            //Make sure it works when scroll policy AUTO case
            cc.horizontalScrollPolicy = ScrollPolicy.AUTO;
            cc.verticalScrollPolicy = ScrollPolicy.AUTO;
            // listen for rollOver event on the link, send an ersatz mouse_over, which will cause a rollOver
            // after mouseOver, link should be in hover state
            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.ROLL_OVER, false, true, link, null));
            mouseOverEvent = new MouseEvent(MouseEvent.MOUSE_OVER, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseOverEvent);
            validator.validate(1);
            assertTrue("after mouseOver, link should be in hover state", link.linkState == LinkState.HOVER);

            mouseOutEvent = new MouseEvent(MouseEvent.MOUSE_OUT, true, false,
                    bounds.right + 1, bounds.bottom + 1, textLine);
            textLine.dispatchEvent(mouseOutEvent);

            //Make sure it works when scroll policy off case
            cc.horizontalScrollPolicy = ScrollPolicy.OFF;
            cc.verticalScrollPolicy = ScrollPolicy.OFF;
            textFlow.flowComposer.updateAllControllers();

            textFlow.interactionManager = SelManager;
            SelManager.selectRange(6, 10);
            boundsInfo = GeometryUtil.getHighlightBounds(SelManager.getSelectionState())[0];
            bounds = boundsInfo.rect as Rectangle;
            textLine = boundsInfo.textLine;

            textFlow = SelManager.textFlow;		// save it for later
            SelManager.textFlow.interactionManager = null;		// turn off editing

            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.ROLL_OVER, false, true, link, null));
            mouseOverEvent = new MouseEvent(MouseEvent.MOUSE_OVER, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseOverEvent);
            validator.validate(1);
            assertTrue("after mouseOver, link should be in hover state", link.linkState == LinkState.HOVER);

            mouseOutEvent = new MouseEvent(MouseEvent.MOUSE_OUT, true, false,
                    bounds.right + 1, bounds.bottom + 1, textLine);
            textLine.dispatchEvent(mouseOutEvent);

            //Test if it works when lineBreak == "toFit";
            cc.horizontalScrollPolicy = ScrollPolicy.AUTO;
            cc.verticalScrollPolicy = ScrollPolicy.AUTO;
            textFlow.lineBreak = LineBreak.TO_FIT;
            textFlow.flowComposer.updateAllControllers();

            textFlow.interactionManager = SelManager;
            SelManager.selectRange(6, 10);
            boundsInfo = GeometryUtil.getHighlightBounds(SelManager.getSelectionState())[0];
            bounds = boundsInfo.rect as Rectangle;
            textLine = boundsInfo.textLine;

            textFlow = SelManager.textFlow;		// save it for later
            SelManager.textFlow.interactionManager = null;		// turn off editing

            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.ROLL_OVER, false, true, link, null));
            mouseOverEvent = new MouseEvent(MouseEvent.MOUSE_OVER, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseOverEvent);
            validator.validate(1);
            assertTrue("after mouseOver, link should be in hover state", link.linkState == LinkState.HOVER);

            mouseOutEvent = new MouseEvent(MouseEvent.MOUSE_OUT, true, false,
                    bounds.right + 1, bounds.bottom + 1, textLine);
            textLine.dispatchEvent(mouseOutEvent);

            //Test if it works when doing measurement for width and/or height
            cc.horizontalScrollPolicy = ScrollPolicy.OFF;
            cc.verticalScrollPolicy = ScrollPolicy.OFF;
            cc.setCompositionSize(300, 300);

            textFlow.interactionManager = SelManager;
            SelManager.selectRange(6, 10);
            boundsInfo = GeometryUtil.getHighlightBounds(SelManager.getSelectionState())[0];
            bounds = boundsInfo.rect as Rectangle;
            textLine = boundsInfo.textLine;

            textFlow = SelManager.textFlow;		// save it for later
            SelManager.textFlow.interactionManager = null;		// turn off editing

            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.ROLL_OVER, false, true, link, null));
            mouseOverEvent = new MouseEvent(MouseEvent.MOUSE_OVER, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseOverEvent);
            validator.validate(1);
            assertTrue("after mouseOver, link should be in hover state", link.linkState == LinkState.HOVER);


            // avoid tearDown assert about no Selectionmanager
            textFlow.interactionManager = SelManager;
            SelManager.selectRange(0, 0);
        }

        // Test cases that should be covered
        // 1. link on part of the line
        // 2. link across several lines
        // For now, only covering first line in link
        [Test(dataProvider=flowElementMouseEventTestDp)]
        public function FlowElementMouseEventTest(dpData:TestCaseVo):void
        {
            var validator:FlowElementMouseEventValidator;

            var cc:ContainerController = SelManager.textFlow.flowComposer.getControllerAt(0);
            if (dpData.id == "FlowElementMouseEventTestScrollingOn")
            {
                cc.verticalScrollPolicy = ScrollPolicy.ON;
                cc.horizontalScrollPolicy = ScrollPolicy.ON;
            }
            else if (dpData.id == "FlowElementMouseEventTestScrolled")
            {
                cc.verticalScrollPolicy = ScrollPolicy.ON;
                cc.horizontalScrollPolicy = ScrollPolicy.ON;
                var originalXScroll:Number = cc.horizontalScrollPosition;
                var originalYScroll:Number = cc.verticalScrollPosition;

                // Copy and paste the entire text, which should cause a scroll event
                SelManager.selectRange(0, int.MAX_VALUE);
                var scrap:TextScrap = TextScrap.createTextScrap(new TextRange(SelManager.textFlow, 0, SelManager.textFlow.textLength));
                var validator1:EventValidator = new EventValidator(SelManager.textFlow, new ScrollEvent(TextLayoutEvent.SCROLL, false, false));
                SelManager.selectRange(int.MAX_VALUE, int.MAX_VALUE);
                SelManager.pasteTextScrap(scrap);
                assertTrue("Expected to get a scroll event, but didn't", validator1.validate(1));

                // Verify that the direction and delta in the event are correct
                validateScrollEvent(validator1.lastEvent as ScrollEvent, originalXScroll, originalYScroll);

                // scroll to a new position, and check that works as expected
                originalXScroll = cc.horizontalScrollPosition;
                originalYScroll = cc.verticalScrollPosition;
                validator1.reset(new ScrollEvent(TextLayoutEvent.SCROLL, false, false));
                validateScrollEvent(validator1.lastEvent as ScrollEvent, originalXScroll, originalYScroll);
                TestFrame.textFlow.flowComposer.updateAllControllers();
            }

            SelManager.selectRange(76, 85);
            SelManager.applyLink("http://www.adobe.com/go/flashplayer", "_self", false);
            TestFrame.textFlow.flowComposer.updateAllControllers();

            var container:DisplayObjectContainer = SelManager.textFlow.flowComposer.getControllerAt(0).container;
            if (dpData.id == "FlowElementMouseEventTestMeasure")
            {
                container.height = NaN;
                container.width = NaN;
            }
            // Get the bounds of the link in TextLine coordinates
            var boundsInfo:Object = GeometryUtil.getHighlightBounds(SelManager.getSelectionState())[0];
            var bounds:Rectangle = boundsInfo.rect as Rectangle;
            var textLine:TextLine = boundsInfo.textLine;

            // get the event mirror off the link
            var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(SelManager.absoluteStart);
            var link:LinkElement = leaf.parent as LinkElement;
            var textFlow:TextFlow = SelManager.textFlow;		// save it for later
            SelManager.textFlow.interactionManager = null;		// turn off editing

            // before we've done anything, link in normal state
            assertTrue("before we've done anything, link should be in normal state", link.linkState == LinkState.LINK);

            // listen for rollOver event on the link, send an ersatz mouse_over, which will cause a rollOver
            // after mouseOver, link should be in hover state
            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.ROLL_OVER, false, true, link, null));
            var mouseOverEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_OVER, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseOverEvent);
            validator.validate(1);
            assertTrue("after mouseOver, link should be in hover state", link.linkState == LinkState.HOVER);

            // mouseMove
            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.MOUSE_MOVE, false, true, link, null));
            var mouseMoveEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_MOVE, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseMoveEvent);
            validator.validate(1);

            // mouseDown
            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.MOUSE_DOWN, false, true, link, null));
            var mouseDownEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseDownEvent);
            validator.validate(1);
            assertTrue("after mouseDown, link should be in active state", link.linkState == LinkState.ACTIVE);

            // mouseUp -- also generates click
            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.MOUSE_UP, false, true, link, null));
            var clickValidator:FlowElementMouseEventValidator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.CLICK, false, true, link, null));
            var mouseUpEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_UP, true, false,
                    (bounds.left + bounds.right) / 2, (bounds.top + bounds.bottom) / 2, textLine);
            textLine.dispatchEvent(mouseUpEvent);
            validator.validate(1);
            clickValidator.validate(1);
            assertTrue("after mouseUp, link should be in hover state", link.linkState == LinkState.HOVER);

            // mouseOut
            validator = new FlowElementMouseEventValidator(link, new FlowElementMouseEvent(FlowElementMouseEvent.ROLL_OUT, false, true, link, null));
            var mouseOutEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_OUT, true, false,
                    bounds.right + 1, bounds.bottom + 1, textLine);
            textLine.dispatchEvent(mouseOutEvent);
            validator.validate(1);
            assertTrue("after mouseOut, link should be in default (normal) state", link.linkState == LinkState.LINK);

            // avoid tearDown assert about no Selectionmanager
            textFlow.interactionManager = SelManager;
            SelManager.selectRange(0, 0);
        }

        [Test]
        public function scrollEventTest():void
        {
            var textFlow:TextFlow = SelManager.textFlow;
            var controller:ContainerController = textFlow.flowComposer.getControllerAt(0);
            controller.verticalScrollPolicy = ScrollPolicy.ON;
            controller.horizontalScrollPolicy = ScrollPolicy.ON;
            var originalXScroll:Number = controller.horizontalScrollPosition;
            var originalYScroll:Number = controller.verticalScrollPosition;

            // Copy and paste the entire text, which should cause a scroll event
            SelManager.selectRange(0, int.MAX_VALUE);
            var scrap:TextScrap = TextScrap.createTextScrap(new TextRange(textFlow, 0, textFlow.textLength));
            var validator:EventValidator = new EventValidator(SelManager.textFlow, new ScrollEvent(TextLayoutEvent.SCROLL, false, false));
            SelManager.selectRange(int.MAX_VALUE, int.MAX_VALUE);
            SelManager.pasteTextScrap(scrap);
            assertTrue("Expected to get a scroll event, but didn't", validator.validate(1));

            // Verify that the direction and delta in the event are correct
            validateScrollEvent(validator.lastEvent as ScrollEvent, originalXScroll, originalYScroll);

            // Now scroll up, and check that works as expected
            originalXScroll = controller.horizontalScrollPosition;
            originalYScroll = controller.verticalScrollPosition;
            var verticalText:Boolean = textFlow.computedFormat.blockProgression == BlockProgression.RL;
            validator.reset(new ScrollEvent(TextLayoutEvent.SCROLL, false, false));
            if (verticalText)
                controller.horizontalScrollPosition = 0;
            else
                controller.verticalScrollPosition = 0;
            validateScrollEvent(validator.lastEvent as ScrollEvent, originalXScroll, originalYScroll);
        }

        private function validateScrollEvent(scrollEvent:ScrollEvent, originalXScroll:Number, originalYScroll:Number):void
        {
            var flowComposer:IFlowComposer = SelManager.textFlow.flowComposer;
            var controller:ContainerController = flowComposer.getControllerAt(flowComposer.numControllers - 1);
            if (originalXScroll != controller.horizontalScrollPosition)
            {
                assertTrue("Scrolled horizontally, but got vertical scroll event", scrollEvent.direction == ScrollEventDirection.HORIZONTAL);
                assertTrue("Scroll delta doesn't match expected", scrollEvent.delta == controller.horizontalScrollPosition - originalXScroll);
            }
            if (originalYScroll != controller.verticalScrollPosition)
            {
                assertTrue("Scrolled vertically, but got horizontal scroll event", scrollEvent.direction == ScrollEventDirection.VERTICAL);
                assertTrue("Scroll delta doesn't match expected", scrollEvent.delta == controller.verticalScrollPosition - originalYScroll);
            }
        }

        private function changeSelectionHandler(event:SelectionEvent):void
        {
            var textFlow:TextFlow = event.selectionState.textFlow;
            textFlow.removeEventListener(SelectionEvent.SELECTION_CHANGE, changeSelectionHandler);
            textFlow.interactionManager.selectRange(0, textFlow.textLength);
        }

        private function getTextFlowTBLTR(testCase:TestCaseVo = null):TextFlow
        {
            if (testCase && testCase.fileName)
            {
                var path:String = "../../test/testFiles/markup/tlf/".concat(testCase.fileName);
                textTBLTR = FileRepository.getFile(TestConfig.getInstance().baseURL, path);
            }

            var configuration:Configuration = TextFlow.defaultConfiguration.clone();
            return TextConverter.importToFlow(textTBLTR, TextConverter.TEXT_LAYOUT_FORMAT, configuration);
        }
    }
}



