////////////////////////////////////////////////////////////////////////////////
//
//  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", "ShortTextMouseEventRLLTRTestDp");

        [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);
        }
    }
}



