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

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

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

    import flash.display.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;


    [TestCase(order=10)]
    [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 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 = [];
            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 = [];
            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);
            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 = [];
            _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 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 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 = {};
            result["releasedLineCount"] = releasedLineCount;
            result["invalidLineCount"] = invalidLineCount;
            result["validLineCount"] = validLineCount;
            result["parentedLineCount"] = parentedLineCount;
            result["nonexistentLineCount"] = nonexistentLineCount;
            return result;
        }
    }
}
