////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package UnitTest.Tests
{
    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.TestConfig;

    import flash.display.Sprite;
    import flash.geom.Rectangle;
    import flash.text.engine.TextLine;
    import flash.text.engine.TextLineValidity;

    import flashx.textLayout.*;
    import flashx.textLayout.compose.IFlowComposer;
    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.compose.TextFlowLine;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.TextScrap;
    import flashx.textLayout.elements.*;
    import flashx.textLayout.events.CompositionCompleteEvent;
    import flashx.textLayout.factory.StringTextLineFactory;
    import flashx.textLayout.factory.TruncationOptions;
    import flashx.textLayout.formats.BlockProgression;
    import flashx.textLayout.formats.LineBreak;
    import flashx.textLayout.formats.TextAlign;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.formats.VerticalAlign;

    import mx.core.Container;
    import mx.utils.UIDUtil;

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

    use namespace tlf_internal;


    [RunWith("org.flexunit.runners.Parameterized")]
    public class CompositionTest extends VellumTestCase
    {
        [Parameters]
        public static var parameters:Array = [
            ["simple.xml", false],
            ["asknot.xml", true]
        ];

        private var _lines:Array;
        private var _textLen:int;
        private const numberOfLinesBack:int = 5;

        public function CompositionTest(fileName:String, testSettings:Boolean)
        {
            super("", "CompositionTest", TestConfig.getInstance());

            TestData.fileName = fileName;
            addDefaultTestSettings = testSettings;

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

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

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

        /**
         * First, find two back to back paragraphs. Second, record the first line of the
         * second paragraph; if the first paragraph is changed and the second gets recomposed
         * (i.e. what we don't want) this line will be re-created (also, the first line of
         * the second paragraph is the easiest to find). Third, make an insertion
         * point at the end of the first paragraph. Fourth, place a bunch of text at the end
         * of the paragraph to force it to recompose. Finally, find the first line in the
         * second paragraph again and see if it is the same as the line you recorded in step
         * (using "===").
         */
        [Test]
        public function checkParagraphShufflingTest():void
        {
            var startLength:int = TestFrame.rootElement.textLength;

            var flow1:FlowElement;
            var flow2:FlowElement;

            //Look for two back to back paragraphs.
            for (var i:int = 0; i < TestFrame.rootElement.numChildren - 1; i++)
            {
                flow1 = TestFrame.rootElement.getChildAt(i);
                flow2 = TestFrame.rootElement.getChildAt(i + 1);

                if (flow1 is ParagraphElement && flow2 is ParagraphElement)
                {
                    break;
                }
            }

            assertTrue("either flow1 or flow2 are null", flow1 != null && flow2 != null);

            var para1:ParagraphElement = flow1 as ParagraphElement;
            var para2:ParagraphElement = flow2 as ParagraphElement;

            var lines:Array = StandardFlowComposer(SelManager.textFlow.flowComposer).lines;

            var refLine:Object;
            for each (var line:TextFlowLine in lines)
            {
                if (line.paragraph == para2)
                {
                    refLine = line;
                    break;
                }
            }

            var para1end:int = para1.textLength - 1;
            SelManager.selectRange(para1end, para1end);

            var longString:String = "Far be it from me to interrupt such an important " +
                    "discussion, but it's come to my attention that the behavior of " +
                    "line shuffling has yet to be fully investigated within this context. " +
                    "So please allow me but a few lines with which to test whether or not " +
                    "the aforementioned is indeed working. Thank you.";
            SelManager.insertText(longString);

            SelManager.flushPendingOperations();

            lines = StandardFlowComposer(SelManager.textFlow.flowComposer).lines;

            for each (var line2:TextFlowLine in lines)
            {
                if (line2.paragraph == para2)
                {
                    assertTrue("the next paragraph got recomposed instead of shuffling", line2 === refLine);
                    break;
                }
            }
        }

        /**
         * This very complicated test inserts some text in the middle of the flow after
         * determining which lines will be affected by the change (in terms of which
         * will need to recompose). It then checks to see if only those that should
         * be effected by the change have been changed.
         */
        [Test]
        [Ignore]
        public function partialCompositionTest():void
        {
            var lines:Array = StandardFlowComposer(SelManager.textFlow.flowComposer).lines;

            var linenum:int = lines.length / 2;
            var initLength:int = lines.length;

            var good:Boolean = false;
            for (var i:int = 0; i < lines.length - 1; i++)
            {
                if (
                        (lines[linenum + i] as TextFlowLine).paragraph ==
                                (lines[linenum + i + 1] as TextFlowLine).paragraph
                        )
                {
                    good = true;
                    linenum = linenum + i;
                    break;
                }
            }

            if (!good)
            {
                for (var j:int = 0; j > 1; j--)
                {
                    if (
                            (lines[linenum - j] as TextFlowLine).paragraph ==
                                    (lines[linenum - j - 1] as TextFlowLine).paragraph
                            )
                    {
                        good = true;
                        linenum = linenum - j;
                        break;
                    }
                }
            }

            if (!good)
            {
                fail("No starting place could be found");
            }

            //Register all the lines that shouldn't be damaged.
            var undamagedUIDs:Array = new Array();
            for (var k:int = 0; k < linenum; k++)
            {
                undamagedUIDs[k] = UIDUtil.getUID(lines[k]);
            }

            for (var l:int = lines.length - 1;
                 l > linenum &&
                         (lines[l] as TextFlowLine).paragraph != (lines[linenum] as TextFlowLine).paragraph;
                 l--)
            {
                undamagedUIDs[l] = UIDUtil.getUID(lines[l]);
            }

            //Register all the lines that should be damaged.
            var damagedUIDs:Array = new Array();
            for (var n:int = linenum;
                 n < lines.length &&
                         (lines[n] as TextFlowLine).paragraph != null &&
                         (lines[n] as TextFlowLine).paragraph == (lines[linenum] as TextFlowLine).paragraph;
                 n++)
            {
                damagedUIDs[n] = UIDUtil.getUID(lines[n]);
            }

            var lineToDamage:TextFlowLine = lines[linenum] as TextFlowLine;
            var ip:int = lineToDamage.absoluteStart + lineToDamage.textLength;

            SelManager.selectRange(ip, ip + 9);

            var longString:String = "Line Break";
            SelManager.insertText(longString);

            SelManager.flushPendingOperations();

            for (var m:int = 0; m < initLength; m++)
            {
                var UID:String = undamagedUIDs[m];

                if (UID != null)
                {
                    assertTrue("Expected line " + m + " not to recompose." +
                            " Break was at " + linenum + ".",
                            UID == UIDUtil.getUID(lines[m])
                    );
                } else
                {
                    UID = damagedUIDs[m];
                    assertTrue("Expected line " + m + " to recompose." +
                            " Break was at " + linenum + ".",
                            UID != UIDUtil.getUID(lines[m])
                    );
                }
            }
        }

        // For benchmark: read in Alice and display one screenfull
        [Test]
        public function composeOneScreen():void
        {
            loadTestFile("aliceExcerpt.xml");
        }

        // Tests that lines that aren't in view are released, and that composition didn't run to the end
        public function releasedLineTest():void
        {
            loadTestFile("aliceExcerpt.xml");

            var flowComposer:IFlowComposer = SelManager.textFlow.flowComposer;
            assertTrue("Composed to the end, should leave text that is not in view uncomposed", flowComposer.damageAbsoluteStart < SelManager.textFlow.textLength);

            var controller:ContainerController = flowComposer.getControllerAt(0);
            var originalEstimatedHeight:Number = controller.contentHeight;
            controller.verticalScrollPosition += 500;		// scroll ahead so we have some lines generated that can be released

            var lineSummary:Object = createLineSummary(flowComposer);

            assertTrue("Expected some invalid lines -- composition not complete", lineSummary["invalidLineCount"] > 0);
            // NOTE: Released lines not in view can be garbage collected. This assertion is not necessarily valid.
            assertTrue("Expected some released lines -- not all lines in view", lineSummary["releasedLineCount"] > 0);
            assertTrue("Expected some valid and parented lines", lineSummary["parentedLineCount"] > 0);

            // This will force composition
            flowComposer.composeToPosition();
            var actualContentHeight:Number = controller.contentHeight;
            assertTrue("Expected full compose", flowComposer.damageAbsoluteStart == SelManager.textFlow.textLength);

            var afterFullCompose:Object = createLineSummary(flowComposer);
            assertTrue("Expected no invalid lines -- composition complete", afterFullCompose["invalidLineCount"] == 0);

            assertTrue("Expected estimated is correct after full composition!", flowComposer.getControllerAt(0).contentHeight == actualContentHeight);

            /*		Can't seem to get gc to release the textlines, although they get released when run through the profiler.
             var eventCount:int = 0;
             System.gc();System.gc();
             var sprite:Sprite = Sprite(flowComposer.getControllerAt(0).container);
             sprite.stage.addEventListener(Event.ENTER_FRAME, checkSummary);
             // Wait for next enterFrame event, because gc is delayed

             function checkSummary():void
             {
             if (eventCount > 50)
             {
             var afterGC:Object = createLineSummary(flowComposer);

             // Test that lines are really getting gc'd
             assertTrue("Expected lines to be gc'd!", afterGC["nonexistentLineCount"] > lineSummary["nonexistentLineCount"]);
             assertTrue("Released lines expected 0", afterGC["releasedLineCount"] == 0);
             sprite.stage.removeEventListener(Event.ENTER_FRAME, checkSummary);
             }
             System.gc();System.gc();
             ++eventCount;
             } */
        }

        [Test]
        public function truncationTest():void
        {
            var bounds:Rectangle = new Rectangle();
            var text:String = 'There are many such 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.';

            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';

            var formatForRtlTest:TextLayoutFormat = new TextLayoutFormat();
            formatForRtlTest.fontFamily = 'Adobe Arabic';

            // Get stats used later
            _lines = new Array();
            _textLen = 0;
            bounds.width = 200;
            bounds.height = NaN;
            var factory:StringTextLineFactory = new StringTextLineFactory();
            factory.text = text;
            factory.compositionBounds = bounds;
            factory.createTextLines(truncationTestCallback);
            bounds = factory.getContentBounds();
            assertTrue("[Not a code bug] Fix test case so that text occupies at least three lines when composed in specified bounds.", _lines.length >= 3);
            var line0:TextLine = _lines[0] as TextLine;
            var line0Extent:Number = StringTextLineFactory.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 = StringTextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line1.y - line1.ascent : line1.y + line1.descent;
            var line2:TextLine = _lines[2] as TextLine;
            var line2Extent:Number = StringTextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line2.y - line2.ascent : line2.y + line2.descent;
            var contentHeight:Number = bounds.height;
            var contentTextLength:int = _textLen;

            _lines.splice(0);
            _textLen = 0; // reset
            bounds.width = 200;
            bounds.height = NaN;
            factory.compositionBounds = bounds;
            factory.text = rtlText;
            factory.spanFormat = formatForRtlTest;
            factory.createTextLines(truncationTestCallback);
            assertTrue("[Not a code bug] Fix test case so that RTL text occupies at least two lines when composed in specified bounds.", _lines.length >= 2);
            var rtlLine0TextLen:int = _lines[0].rawTextLength;

            _lines.splice(0);
            _textLen = 0; // Reset
            bounds.width = 200;
            bounds.height = NaN;
            factory.compositionBounds = bounds;
            factory.text = accentedText;
            factory.spanFormat = null;
            factory.createTextLines(truncationTestCallback);
            assertTrue("[Not a code bug] Fix test case so that accented text occupies at least two lines when composed in specified bounds.", _lines.length >= 2);

            var line:TextLine;
            var lineExtent:Number;
            var truncationIndicatorIndex:int;
            var originalContentPrefix:String;
            var customTruncationIndicator:String;
            var customFactory:StringTextLineFactory = new StringTextLineFactory();

            // Verify that text is truncated even if width is not specified
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = NaN;
            bounds.height = NaN;
            factory.text = "A\nB"; // has an explicit new line character to ensure two lines
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions(null, 1);
            factory.createTextLines(truncationTestCallback);
            assertTrue("Did not truncate when width is unspecified", factory.isTruncated);

            // Verify that text is truncated even if explicit line breaking is used
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = NaN;
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.lineBreak = LineBreak.EXPLICIT;
            factory.textFlowFormat = format;
            factory.text = "A\nB"; // has an explicit new line character to ensure two lines
            factory.compositionBounds = bounds;
            factory.createTextLines(truncationTestCallback);
            assertTrue("Did not truncate when explicit line breaking is used", factory.isTruncated);

            // No lines case 1: compose height allows no line
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = line0Extent / 2; // less than what one line requires
            factory.textFlowFormat = null;
            factory.text = text;
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions();
            factory.createTextLines(truncationTestCallback);
            assertTrue("Composed one or more lines when compose height allows none", _lines.length == 0 && factory.isTruncated);

            // No lines case 2: 0 line count limit
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = contentHeight; // enough to fit all content
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions(null, 0);
            factory.createTextLines(truncationTestCallback);
            assertTrue("Composed one or more lines when line count limit is 0", _lines.length == 0 && factory.isTruncated);

            // No lines case 3: truncation indicator is too large
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = contentHeight - 1; // just shy of what the truncation indicator (same as original text) requires
            factory.compositionBounds = bounds;
            factory.text = text;
            factory.truncationOptions = new TruncationOptions(text);
            factory.textFlowFormat = null;
            factory.createTextLines(truncationTestCallback);
            assertTrue("Composed one or more lines when compose height does not allow truncation indicator itself to fit", _lines.length == 0 && factory.isTruncated);

            // Verify truncation if composing to fit in bounds
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = line1Extent; // should fit two lines
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions();
            factory.createTextLines(truncationTestCallback);
            assertTrue("Invalid truncation results when composing to fit in bounds (lineCount)", _lines.length == 2 && factory.isTruncated);
            line = _lines[1] as TextLine;
            lineExtent = StringTextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
            assertTrue("Invalid truncation results when composing to fit in bounds", lineExtent <= line1Extent);

            // Verify truncation if composing to fit in a line count limit
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.width = 200;
            bounds.height = NaN;
            bounds.left = 0;
            bounds.top = 0;
            factory.text = text;
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions(null, 2);
            factory.createTextLines(truncationTestCallback);
            assertTrue("Invalid truncation results when composing to fit in a line count limit", _lines.length == 2 && factory.isTruncated);

            // Verify truncation if composing to fit in bounds and a line count limit; the former dominates
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = line0Extent; // should fit one line
            factory.text = text;
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions(null, 2);
            factory.createTextLines(truncationTestCallback); // line count limit of 2
            assertTrue("Invalid truncation results when multiple truncation criteria provided", _lines.length == 1 && factory.isTruncated);
            line = _lines[0] as TextLine;
            lineExtent = StringTextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
            assertTrue("Invalid truncation results when multiple truncation criteria provided", lineExtent <= line0Extent);

            // Verify truncation if composing to fit in bounds and a line count limit; the latter dominates
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = line1Extent; // should fit two lines
            factory.text = text;
            factory.compositionBounds = bounds;
            factory.truncationOptions = new TruncationOptions(null, 1);
            factory.createTextLines(truncationTestCallback); // line count limit of 1
            assertTrue("Invalid truncation results when multiple truncation criteria provided", _lines.length == 1 && factory.isTruncated);
            line = _lines[0] as TextLine;
            lineExtent = StringTextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
            assertTrue("Invalid truncation results when multiple truncation criteria provided", lineExtent <= line1Extent);

            // Verify truncated text content with default truncation indicator (line count limit)
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = NaN;
            customFactory.text = text;
            customFactory.compositionBounds = bounds;
            customFactory.truncationOptions = new TruncationOptions(null, 2);
            customFactory.createTextLines(truncationTestCallback);
            truncationIndicatorIndex = customFactory.truncatedText.lastIndexOf(TruncationOptions.HORIZONTAL_ELLIPSIS);
            assertTrue("Default truncation indicator not present at the end of the truncated string", truncationIndicatorIndex + TruncationOptions.HORIZONTAL_ELLIPSIS.length == customFactory.truncatedText.length && factory.isTruncated);
            originalContentPrefix = customFactory.truncatedText.slice(0, truncationIndicatorIndex);
            assertTrue("Original content before truncation indicator mangled", text.indexOf(originalContentPrefix) == 0);

            // Verify truncated text content with default truncation indicator (fit in bounds)
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = line1Extent; // should fit two lines;
            customFactory.text = text;
            customFactory.compositionBounds = bounds;
            customFactory.truncationOptions = new TruncationOptions();
            customFactory.createTextLines(truncationTestCallback);
            truncationIndicatorIndex = customFactory.truncatedText.lastIndexOf(TruncationOptions.HORIZONTAL_ELLIPSIS);
            assertTrue("Default truncation indicator not present at the end of the truncated string", truncationIndicatorIndex + TruncationOptions.HORIZONTAL_ELLIPSIS.length == customFactory.truncatedText.length && factory.isTruncated);
            originalContentPrefix = customFactory.truncatedText.slice(0, truncationIndicatorIndex);
            assertTrue("Original content before truncation indicator mangled", text.indexOf(originalContentPrefix) == 0);

            // Verify truncated text content with custom truncation indicator
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = NaN;
            customFactory.text = text;
            customTruncationIndicator = "<SNIP>";
            customFactory.compositionBounds = bounds;
            customFactory.truncationOptions = new TruncationOptions(customTruncationIndicator, 2);
            customFactory.createTextLines(truncationTestCallback);
            truncationIndicatorIndex = customFactory.truncatedText.lastIndexOf(customTruncationIndicator);
            assertTrue("Truncation indicator not present at the end of the truncated string", truncationIndicatorIndex + customTruncationIndicator.length == customFactory.truncatedText.length && factory.isTruncated);
            originalContentPrefix = customFactory.truncatedText.slice(0, truncationIndicatorIndex);
            assertTrue("Original content before truncation indicator mangled", text.indexOf(originalContentPrefix) == 0);

            // Verify original text replacement is optimal
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = NaN;
            customFactory.text = text;
            customFactory.text = text;
            customFactory.compositionBounds = bounds;
            customTruncationIndicator = '\u200B'; // Zero-width space : should not require *any* original content that fits to be replaced
            customFactory.truncationOptions = new TruncationOptions(customTruncationIndicator, 1);
            customFactory.createTextLines(truncationTestCallback);
            assertTrue("Replacing more original content than is neccessary", customFactory.truncatedText.length == line0TextLen + customTruncationIndicator.length && factory.isTruncated);

            // Verify original text replacement is optimal (RTL text)
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = NaN;
            customFactory.text = rtlText;
            customFactory.compositionBounds = bounds;
            customTruncationIndicator = '\u200B'; // Zero-width space : should not require *any* original content that fits to be replaced
            customFactory.spanFormat = formatForRtlTest;
            customFactory.truncationOptions = new TruncationOptions(customTruncationIndicator, 1);
            customFactory.createTextLines(truncationTestCallback);
            assertTrue("Replacing more original content than is neccessary (RTL text)", customFactory.truncatedText.length == rtlLine0TextLen + customTruncationIndicator.length && factory.isTruncated);
            customFactory.spanFormat = null;

            // Verify truncation happens at atom boundaries
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = NaN;
            customFactory.text = accentedText;
            customTruncationIndicator = '<' + '\u200A' /* Hair space */ + '>'; // what precedes and succeeds the hair space is irrelevant
            customFactory.compositionBounds = bounds;
            customFactory.truncationOptions = new TruncationOptions(customTruncationIndicator, 1);
            customFactory.createTextLines(truncationTestCallback);
            assertTrue("[Not a code bug] Fix test case so that truncation indicator itself fits", _lines.length == 1 && factory.isTruncated); // baseline

            var initialTruncationPoint:int = customFactory.truncatedText.length - customTruncationIndicator.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;
                customTruncationIndicator = customTruncationIndicator.replace('\u200A', '\u200A\u200A'); // add another hair space in each iteration, making truncation indicator wider (ever so slightly)
                customFactory.compositionBounds = bounds;
                customFactory.truncationOptions = new TruncationOptions(customTruncationIndicator, 1);
                customFactory.createTextLines(truncationTestCallback);

                nextTruncationPoint = customFactory.truncatedText.length - customTruncationIndicator.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);

            // Verify scrolling behavior when truncation options are set
            _lines.splice(0);
            _textLen = 0; // reset
            bounds.left = 0;
            bounds.top = 0;
            bounds.width = 200;
            bounds.height = line1Extent; // should fit two lines
            factory.compositionBounds = bounds;
            factory.verticalScrollPolicy = "on";
            var vaFormat:TextLayoutFormat = new TextLayoutFormat();
            vaFormat.verticalAlign = VerticalAlign.BOTTOM;
            factory.textFlowFormat = vaFormat;
            factory.truncationOptions = new TruncationOptions(); // should override scroll policy
            factory.createTextLines(truncationTestCallback);
            assertTrue("When verticalAlign is Bottom, and scrolling is on, but truncation options are set, only text that fits should be generated",
                    _textLen < contentTextLength && factory.isTruncated);
        }

        [Test]
        public function CompositionCompleteEventTest():void
        {
            var gotEvent:Boolean = false;
            var textFlow:TextFlow = SelManager.textFlow;
            textFlow.addEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE, completionHandler);
            var charFormat:TextLayoutFormat = new TextLayoutFormat();
            charFormat.fontSize = 48;
            SelManager.selectAll();
            (SelManager as EditManager).applyLeafFormat(charFormat);
            assertTrue("Didn't get the CompositionCompleteEvent", gotEvent == true);

            function completionHandler(event:CompositionCompleteEvent):void
            {
                gotEvent = true;
                textFlow.removeEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE, completionHandler);
            }
        }

        private function setUpMultipleLinkedContainers(numberOfContainers:int):Sprite
        {
            var flexContainer:Container;
            var textFlow:TextFlow = SelManager.textFlow;
            var flowComposer:IFlowComposer = textFlow.flowComposer;
            var firstController:ContainerController = textFlow.flowComposer.getControllerAt(0);
            var totalWidth:Number = firstController.compositionWidth;
            var containerWidth:Number = totalWidth / numberOfContainers;
            var containerHeight:Number = firstController.compositionHeight;
            firstController.setCompositionSize(containerWidth, firstController.compositionHeight);
            var containerParent:Sprite = firstController.container.parent as Sprite;
            if (containerParent is Container)
            {
                flexContainer = Container(containerParent);
                var newContainerParent:Sprite = new Sprite();
                flexContainer.rawChildren.addChild(newContainerParent);
                flexContainer.rawChildren.removeChild(firstController.container);
                newContainerParent.addChild(firstController.container);
                containerParent = newContainerParent;
            }
            var pos:int = containerWidth;
            while (flowComposer.numControllers < numberOfContainers)
            {
                var s:Sprite = new Sprite();
                s.x = pos;
                pos += containerWidth;
                containerParent.addChild(s);
                flowComposer.addController(new ContainerController(s, containerWidth, containerHeight));
            }
            return containerParent;
        }

        private function restoreToSingleContainer(containerParent:Sprite):void
        {
            var flexContainer:Container = containerParent.parent as Container;

            if (flexContainer)
            {
                flexContainer.rawChildren.removeChild(containerParent);
                flexContainer.rawChildren.addChild(containerParent.getChildAt(0));
            }
            var flowComposer:IFlowComposer = SelManager.textFlow.flowComposer;
            while (flowComposer.numControllers > 1)
                flowComposer.removeControllerAt(flowComposer.numControllers - 1);
        }

        // Test case with multiple containers, where the last container is scrolled down, and update will cause a scroll
        // Watson 2583969
        [Test]
        public function scrolledRedrawPartialCompose():void
        {
            var multiContainerParent:Sprite;

            try
            {
                var textFlow:TextFlow = SelManager.textFlow;
                var flowComposer:IFlowComposer = textFlow.flowComposer;
                multiContainerParent = setUpMultipleLinkedContainers(5);

                // Paste all the text again, so all containers are full, and there is text scrolled out
                var textScrap:TextScrap = TextScrap.createTextScrap(new TextRange(textFlow, 0, textFlow.textLength));
                EditManager(SelManager).pasteTextScrap(textScrap);
                flowComposer.updateAllControllers();


                // Set selection to the last two lines of the flow, and scroll to the new selection, and then delete the text
                var lastController:ContainerController = flowComposer.getControllerAt(flowComposer.numControllers - 1);
                flowComposer.composeToPosition();	// force all text to compose
                var nextToLastLine:TextFlowLine = flowComposer.getLineAt(flowComposer.numLines - 2);
                SelManager.selectRange(nextToLastLine.absoluteStart, textFlow.textLength);
                lastController.scrollToRange(SelManager.absoluteStart, SelManager.absoluteEnd);
                var firstVisibleChar:int = lastController.getFirstVisibleLine().absoluteStart; // save off the current scrolled-to text pos
                flowComposer.updateAllControllers();
                EditManager(SelManager).deleteText();

                // The delete (and subsequent redraw) should have caused a scroll during the ContainerController updateCompositionShapes.
                // Check that this happened correctly.
                var firstVisibleCharAfterPaste:int = lastController.getFirstVisibleLine().absoluteStart;
                assertTrue("Expected scroll during update", firstVisibleChar != firstVisibleCharAfterPaste);
            }
            finally
            {
                // restore how containers were set up before
                restoreToSingleContainer(multiContainerParent);
            }
        }

        // Test case with multiple containers, where the last container is scrolled down, and update will cause a scroll
        // Watson 2583969
        [Test]
        public function multipleContainersWithPadding():void
        {
            var multiContainerParent:Sprite;

            try
            {
                var textFlow:TextFlow = SelManager.textFlow;
                var flowComposer:IFlowComposer = textFlow.flowComposer;
                multiContainerParent = setUpMultipleLinkedContainers(2);

                var firstController:ContainerController = flowComposer.getControllerAt(0);
                var format:TextLayoutFormat = new TextLayoutFormat(firstController.format);
                format.paddingTop = firstController.compositionHeight;
                firstController.format = format;
                flowComposer.updateAllControllers();

                assertTrue("Expected no lines in first container", firstController.getFirstVisibleLine() == null && firstController.getLastVisibleLine() == null);
            }
            finally
            {
                // restore how containers were set up before
                restoreToSingleContainer(multiContainerParent);
            }
        }

        [Test]
        [Ignore]
        public function deleteAtContainerStart():void
        {
            var multiContainerParent:Sprite;

            try
            {
                var textFlow:TextFlow = SelManager.textFlow;
                var flowComposer:IFlowComposer = textFlow.flowComposer;
                multiContainerParent = setUpMultipleLinkedContainers(2);

                flowComposer.composeToPosition();
                var controller:ContainerController = flowComposer.getControllerAt(0);

                var lastLineIndex:int = flowComposer.findLineIndexAtPosition(controller.absoluteStart + controller.textLength);
                var startIndex:int = flowComposer.getLineAt(lastLineIndex - numberOfLinesBack).absoluteStart;
                SelManager.selectRange(startIndex, startIndex);
                for (var i:int = 0; i < numberOfLinesBack + 1; ++i)
                    SelManager.splitParagraph();
                flowComposer.updateAllControllers();
                var textLengthBefore:int = controller.textLength;

                assertTrue("Selection should be at the start of the next container", SelManager.absoluteStart == controller.absoluteStart + controller.textLength);
                SelManager.deletePreviousCharacter();
                flowComposer.composeToPosition();
                assertTrue("Expected first line of following container to be sucked in", controller.textLength > textLengthBefore);
            }
            finally
            {
                // restore how containers were set up before
                restoreToSingleContainer(multiContainerParent);
            }
        }

        [Test]
        public function resizeController2644361():void
        {
            var textFlow:TextFlow = SelManager.textFlow;
            var controller:ContainerController = textFlow.flowComposer.getControllerAt(0);

            var scrap:TextScrap = TextScrap.createTextScrap(new TextRange(textFlow, 0, textFlow.textLength));
            SelManager.selectRange(textFlow.textLength - 1, textFlow.textLength - 1);
            SelManager.splitParagraph();
            SelManager.pasteTextScrap(scrap);
            SelManager.pasteTextScrap(scrap);
            textFlow.flowComposer.updateAllControllers();
            controller.setCompositionSize(825, 471)
            SelManager.updateAllControllers();
            controller.setCompositionSize(808, 464)
            SelManager.updateAllControllers();
            controller.setCompositionSize(791, 462)
            SelManager.updateAllControllers();
            controller.setCompositionSize(768, 461)
            SelManager.updateAllControllers();
        }

        [Test]
        public function resizeEmptyController():void
        {
            var textFlow:TextFlow = new TextFlow();
            var p:ParagraphElement = new ParagraphElement();
            textFlow.addChild(p);

            var span:SpanElement = new SpanElement();
            span.text = "Hello world";
            span.fontSize = 40;
            p.addChild(span);

            var sprite1:Sprite = new Sprite();
            var cc1:ContainerController = new ContainerController(sprite1, 100, 50);
            sprite1.x = 100;
            var sprite2:Sprite = new Sprite();
            var cc2:ContainerController = new ContainerController(sprite2, 100, 50);
            sprite2.x = 300;
            //	addChild(sprite1);
            //	addChild(sprite2);
            textFlow.flowComposer.addController(cc1);
            textFlow.flowComposer.addController(cc2);
            textFlow.flowComposer.updateAllControllers();
            var originalLength:int = cc1.textLength;
            cc1.setCompositionSize(100, 10);
            textFlow.flowComposer.updateAllControllers();
            cc1.setCompositionSize(100, 50);
            textFlow.flowComposer.updateAllControllers();
            assertTrue("Expected text to recompose into controller", cc1.textLength == originalLength);
        }

        [Test]
        public function emptyController():void
        {
            var s:Sprite = new Sprite();
            var textFlow:TextFlow = new TextFlow();
            textFlow.flowComposer.addController(new ContainerController(s, 0, 0));
            textFlow.flowComposer.updateAllControllers();
        }

        // Check that the content bounds includes all parcels when composition starts from a column that is not the first
        // See Watson 2769670
        [Test]
        public function contentBoundsOnComposeFromMiddle():void
        {
            TestFrame.rootElement.blockProgression = writingDirection[0];
            TestFrame.rootElement.direction = writingDirection[1];

            var textFlow:TextFlow = SelManager.textFlow;
            var controller:ContainerController = textFlow.flowComposer.getControllerAt(0);
            var composeSpace:Rectangle = new Rectangle(0, 0, controller.compositionWidth, controller.compositionHeight);

            var lastLine:TextFlowLine = controller.getLastVisibleLine();
            var lastVisiblePosition:int = lastLine.absoluteStart + lastLine.textLength - 1;
            var charPos:int = lastVisiblePosition - 100;

            // Trim off the unseen portion of the flow to a little before the end, so we aren't
            // affected by content height estimation, and so we can check that height from previous
            // columns is included.
            SelManager.selectRange(charPos, textFlow.textLength - 1);
            SelManager.deleteText();

            // Change format to 3 columns justified text, and get the bounds. This time we composed from the start.
            var format:TextLayoutFormat = new TextLayoutFormat(textFlow.format);
            format.columnCount = 3;
            format.textAlign = TextAlign.JUSTIFY;
            textFlow.format = format;
            textFlow.flowComposer.updateAllControllers();
            var bounds:Rectangle = controller.getContentBounds();

            // Force partial composition in the last column. The bounds may be slightly different in height because we aren't
            // iterating all the lines to get height. If it doesn't match, it should be equal to the (logical) compositionHeight.
            charPos = textFlow.textLength - 3;
            var leafFormat:TextLayoutFormat = new TextLayoutFormat();
            leafFormat.color = 0xFF0000;
            SelManager.selectRange(charPos, charPos + 1);
            SelManager.applyLeafFormat(leafFormat);
            var boundsAfterPartialCompose:Rectangle = controller.getContentBounds();

            var boundsMatch:Boolean = boundsAfterPartialCompose.equals(bounds);
            if (!boundsMatch &&
                    bounds.y == boundsAfterPartialCompose.y)
            {
                if (controller.effectiveBlockProgression == BlockProgression.TB)
                    boundsMatch = Math.abs(boundsAfterPartialCompose.x - bounds.x) < 1 && Math.abs(boundsAfterPartialCompose.width - bounds.width) < 1 && boundsAfterPartialCompose.height == controller.compositionHeight;
                else
                    boundsMatch = Math.abs(boundsAfterPartialCompose.x - -controller.compositionWidth) < 1 && Math.abs(boundsAfterPartialCompose.height - bounds.height) < 1 && boundsAfterPartialCompose.width == controller.compositionWidth;
            }

            assertTrue("Expected bounds after partial compose to match bounds from previous full compose", boundsMatch);
        }

        private function truncationTestCallback(textLine:TextLine):void
        {
            _textLen += textLine.rawTextLength;
            _lines.push(textLine);
        }

        private function createLineSummary(flowComposer:IFlowComposer):Object
        {
            // Lines that are referenced should go first
            var releasedLineCount:int = 0;
            var invalidLineCount:int = 0;
            var validLineCount:int = 0;
            var parentedLineCount:int = 0;
            var nonexistentLineCount:int = 0;
            var lineIndex:int = 0;
            while (lineIndex < flowComposer.numLines)
            {
                var line:TextFlowLine = flowComposer.getLineAt(lineIndex);
                if (line.validity == TextLineValidity.VALID)
                {
                    assertTrue("Expecting valid referenced lines before invalid lines", invalidLineCount == 0);
                    var textLine:TextLine = line.peekTextLine();
                    assertTrue(!textLine || textLine.userData == line, "TextLine userData doesn't point back to TextFlowLine");
                    if (!textLine || !textLine.textBlock || textLine.textBlock.firstLine == null)
                        releasedLineCount++;
                    else if (textLine.parent)
                        parentedLineCount++;
                    else if (textLine.validity == TextLineValidity.VALID)
                        validLineCount++;
                    else assertTrue(false, "Found damaged unreleased TextLine for valid TextFlowLine");
                }
                else
                    invalidLineCount++;
                lineIndex++;
            }

            var result:Object = new Object();
            result["releasedLineCount"] = releasedLineCount;
            result["invalidLineCount"] = invalidLineCount;
            result["validLineCount"] = validLineCount;
            result["parentedLineCount"] = parentedLineCount;
            result["nonexistentLineCount"] = nonexistentLineCount;
            return result;
        }
    }
}
