////////////////////////////////////////////////////////////////////////////////
//
//  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.TestSuiteExtended;
    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.TestConfig;
    import UnitTest.Validation.MD5;

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.IBitmapDrawable;
    import flash.display.Sprite;
    import flash.geom.Rectangle;
    import flash.system.*;
    import flash.text.engine.*;
    import flash.utils.ByteArray;

    import flashx.textLayout.*;
    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.compose.TextLineRecycler;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.container.ScrollPolicy;
    import flashx.textLayout.container.TextContainerManager;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.ISelectionManager;
    import flashx.textLayout.edit.SelectionManager;
    import flashx.textLayout.elements.*;
    import flashx.textLayout.factory.StringTextLineFactory;
    import flashx.textLayout.factory.TextFlowTextLineFactory;
    import flashx.textLayout.formats.TextLayoutFormat;

    import mx.containers.Canvas;
    import mx.core.ByteArrayAsset;

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

    use namespace tlf_internal;

    [TestCase(order=34)]
    public class TextLineFilterTest extends VellumTestCase
    {
        private var TestCanvas:Canvas = null;
        private var itemsToRemove:Array;
        private var bodyFlow:TextFlow;
        private var bodyController:CustomContainerController;
        private var bodyContainer:Sprite;

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

        /**
         * embed alice - this simplifies things - don't need to trust the swf and pass the xml around with it
         */
        [Embed(source="../../../../test/testFiles/markup/tlf/alice.xml", mimeType="application/octet-stream")]
        private var AliceClass:Class;

        public function TextLineFilterTest()
        {
            itemsToRemove = [];
            super("", "TextLineFilterTest", TestConfig.getInstance());
            //reset containerType and ID
            containerType = "custom";

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

        public static function suiteFromXML(testListXML:XML, testConfig:TestConfig, ts:TestSuiteExtended):void
        {
            var testCaseClass:Class = TextLineFilterTest;
            VellumTestCase.suiteFromXML(testCaseClass, testListXML, testConfig, ts);
        }

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

        }

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

        /**
         * Apply a filter to the text lines and the selection
         */
        [Test]
        public function textlineAndSelectionFilterTest():void
        {
            initApp();
            bodyFlow.interactionManager = new SelectionManager();
            var selectManager:ISelectionManager = bodyFlow.interactionManager;
            selectManager.selectRange(0, 107);
            selectManager.refreshSelection();

            // add controller, add container to stage, and display body text
            bodyFlow.flowComposer.addController(bodyController);
            bodyFlow.flowComposer.updateAllControllers();


            TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
            itemsToRemove.push(bodyContainer);
            System.gc();	//mark
            System.gc();	//sweep

        }

        /**
         * Apply a filter to the text lines, but not the selection
         */
        [Test]
        public function textlinesFilterTest():void
        {
            initApp();
            bodyFlow.interactionManager = new SelectionManager();
            var selectManager:ISelectionManager = bodyFlow.interactionManager;


            // add controller, add container to stage, and display body text
            bodyFlow.flowComposer.addController(bodyController);
            bodyFlow.flowComposer.updateAllControllers();


            TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
            itemsToRemove.push(bodyContainer);
            System.gc();	//mark
            System.gc();	//sweep
        }

        /**
         * Apply a filter to the selection, but not the textline
         */
        [Test]
        public function selectionFilterTest():void
        {
            initApp();
            bodyFlow.interactionManager = new SelectionManager();
            var selectManager:ISelectionManager = bodyFlow.interactionManager;
            selectManager.selectRange(1000, 2000);
            selectManager.refreshSelection();

            // add controller, add container to stage, and display body text
            bodyFlow.flowComposer.addController(bodyController);
            bodyFlow.flowComposer.updateAllControllers();

            TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
            itemsToRemove.push(bodyContainer);
            System.gc();	//mark
            System.gc();	//sweep
        }

        private var recycledTextLine:TextLine;
        private var composedTextLine:TextLine;
        private var _lines:Array;
        private var textLine_invalid:TextLine;

        private static function createInvalidTextLine():TextLine
        {
            var elementFormat:ElementFormat = new ElementFormat();
            var textElement:TextElement = new TextElement("aaa", elementFormat);
            var textBlock:TextBlock = new TextBlock(textElement);
            var textLine:TextLine = textBlock.createTextLine();
            textLine.validity = TextLineValidity.INVALID;
            return textLine;
        }

        [Test]
        public function recycleLineByFlowComposer():void
        {
            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();
            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            //create a TextFlow
            var textFlow:TextFlow = new TextFlow();
            textFlow.mxmlChildren = ["Hello, World"];
            var textContainer:Sprite = new Sprite();
            var textController:ContainerController = new CustomContainerController(textContainer, 800, 1000);
            textFlow.flowComposer.addController(textController);

            //compose a single line which should be from recycler
            textFlow.flowComposer.updateAllControllers();
            TestCanvas.rawChildren.addChild(DisplayObject(textContainer));

            //check if the composed line is same as the recycled one
            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
        }

        [Test]
        public function recycleLineByFlowFactory():void
        {
            _lines = [];

            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();

            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
            var flow:TextFlow = new TextFlow();
            var span:SpanElement = new SpanElement();
            span.text = "Hello World.";
            var para:ParagraphElement = new ParagraphElement();
            para.addChild(span);
            flow.addChild(para);

            //compose a single line which should be from recycler
            factory.createTextLines(useTextLines, flow);

            //check if the composed line is same as the recycled one
            composedTextLine = _lines[0];
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
        }

        [Test]
        public function recycleLineByStringFactory():void
        {
            _lines = [];

            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();

            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            var factory:StringTextLineFactory = new StringTextLineFactory();
            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
            factory.text = "Hello World";

            //compose a single line which should be from recycler
            factory.createTextLines(useTextLines);

            //check if the composed line is same as the recycled one
            composedTextLine = _lines[0];
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
        }

        [Test]
        public function stringFactoryBackgroundColor():void
        {
            _lines = [];

            var factory:StringTextLineFactory = new StringTextLineFactory();
            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
            factory.text = "Hello World";

            factory.textFlowFormat = TextLayoutFormat.createTextLayoutFormat({
                blockProgression: writingDirection[0],
                direction: writingDirection[1]
            });
            factory.spanFormat = TextLayoutFormat.createTextLayoutFormat({backgroundColor: 0xffff4F, fontSize: 48});
            factory.createTextLines(useTextLines);
        }

        private function useTextLines(tl:DisplayObject):void
        {
            _lines.push(tl);
            TestCanvas.rawChildren.addChild(tl);
        }

        [Test]
        public function recycleLineByCustomLineCreatorTextFlow():void
        {
            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();

            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            //Create a TextFlow
            var textFlow:TextFlow = new TextFlow();
            textFlow.mxmlChildren = ["Hello, World"];
            var textContainer:Sprite = new Sprite();
            var textController:ContainerController = new CustomContainerController(textContainer, 800, 1000);
            textFlow.flowComposer.addController(textController);

            //monitor if the TextLine created from recycler
            var myswfContext:MySwfContext = new MySwfContext();
            textFlow.flowComposer.swfContext = myswfContext;
            textFlow.flowComposer.updateAllControllers();

            //check if composed line is same as recycled line and if createTextLine gets the recycled line
            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
            && myswfContext.numRecycledLines == 1);

            //monitor if the TextLine created from new
            textFlow.mxmlChildren = ["Again, Hello, World "];
            textFlow.flowComposer.swfContext = myswfContext;
            textFlow.flowComposer.updateAllControllers();
            assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);

            TestCanvas.rawChildren.addChild(DisplayObject(textContainer));
        }

        [Test]
        public function recycleLineByTCM():void
        {
            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();
            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            //create a TextFlow by TCM using the recycled line
            var sprite:Sprite = new Sprite();
            sprite.x = 50;
            sprite.y = 50;
            var tcm:TextContainerManager = new TextContainerManager(sprite);
            tcm.setText("Hello World");
            tcm.updateContainer();
            var editManager:EditManager = EditManager(tcm.beginInteraction());
            editManager.selectRange(0, 0);
            var textFlow:TextFlow = tcm.getTextFlow();

            //check if the composed line is same as the recycled one
            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
            TestCanvas.rawChildren.addChild(DisplayObject(sprite));
            TestCanvas.rawChildren.addChild(sprite);
        }

        [Test]
        public function recycleLineByCustomLineCreatorFlowFactory():void
        {
            _lines = [];

            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();

            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
            factory.compositionBounds = new Rectangle(100, 100, 200, 130);

            //Create a TextFlow
            var flow:TextFlow = new TextFlow();
            flow.mxmlChildren = ["Hello, World"];

            //create custom TextLine creator
            var myswfContext:MySwfContext = new MySwfContext();
            flow.flowComposer.swfContext = myswfContext;
            factory.swfContext = flow.flowComposer.swfContext;

            //compose a single line which should be from recycler using FlowFactory
            factory.createTextLines(useTextLines, flow);

            //check if the composed line is same as the recycled one
            composedTextLine = _lines[0];
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
            && myswfContext.numRecycledLines == 1);

            //monitor if the TextLine created from new
            flow.mxmlChildren = ["Again, Hello, World "];
            factory.compositionBounds = new Rectangle(100, 200, 200, 130);
            factory.createTextLines(useTextLines, flow);
            assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
        }

        [Test]
        public function recycleLineByCustomLineCreatorStringFactory():void
        {
            _lines = [];

            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();

            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            var factory:StringTextLineFactory = new StringTextLineFactory();
            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
            factory.text = "Hello World";

            //create custom TextLine creator
            var myswfContext:MySwfContext = new MySwfContext();
            factory.swfContext = myswfContext;

            //compose a single line which should be from recycler using FlowFactory
            factory.createTextLines(useTextLines);

            //check if the composed line is same as the recycled one
            composedTextLine = _lines[0];
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
            && myswfContext.numRecycledLines == 1);

            //monitor if the TextLine created from new
            factory.text = "Again, Hello World";
            factory.compositionBounds = new Rectangle(100, 200, 200, 130);
            factory.createTextLines(useTextLines);
            assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
        }

        [Test]
        public function recycleLineByCustomLineCreatorTCM():void
        {
            _lines = [];

            //create an invald TextLine to recycle
            textLine_invalid = createInvalidTextLine();

            //recycle the invalid TextLine
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.addLineForReuse(textLine_invalid);
            recycledTextLine = textLine_invalid;

            //create a TextFlow by TCM using the recycled line
            var sprite:Sprite = new Sprite();
            sprite.x = 50;
            sprite.y = 50;
            var tcm:TextContainerManager = new TextContainerManager(sprite);
            tcm.setText("Hello World");
            tcm.updateContainer();
            var editManager:EditManager = EditManager(tcm.beginInteraction());
            editManager.selectRange(0, 0);
            var textFlow:TextFlow = tcm.getTextFlow();

            //check if the composed line is same as the recycled one
            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
            TestCanvas.rawChildren.addChild(sprite);
        }

        [Test]
        public function recycleLineInSuite():void
        {
            var alice:ByteArrayAsset = new AliceClass();
            var aliceData:String = alice.readMultiByte(alice.length, "utf-8");
            var textFlow:TextFlow = TextConverter.importToFlow(aliceData, TextConverter.TEXT_LAYOUT_FORMAT);

            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.textLineRecyclerEnabled = false;
            var s:Sprite = new Sprite();
            s.x = 50;
            s.y = 50;
            var tcm:TextContainerManager = new TextContainerManager(s);
            tcm.compositionWidth = 500;
            tcm.compositionHeight = NaN;
            tcm.setTextFlow(textFlow);
            tcm.updateContainer();

            var displayobject:DisplayObject = testApp.getDisplayObject();
            var bits:BitmapData = new BitmapData(displayobject.width, displayobject.height);
            bits.draw(TestDisplayObject as IBitmapDrawable);
            bitmapSnapshot = new Bitmap(bits);
            bits = null;
            var pixels:ByteArray = bitmapSnapshot.bitmapData.getPixels(bitmapSnapshot.bitmapData.rect);
            pixels.compress();
            pixels.position = 0;
            var checksumRecyclingOff:String = MD5.hashBinary(pixels);

            //create a bunch(100) of invald TextLines to recycle
            TextLineRecycler.emptyReusableLineCache();
            TextLineRecycler.textLineRecyclerEnabled = true;
            var i:int = 0;
            while (i <= 100)
            {
                var textLine_invalid:TextLine = createInvalidTextLine();
                TextLineRecycler.addLineForReuse(textLine_invalid);
                i++;
            }

            //recompose the text flow with the recycled lines
            tcm.updateContainer();

            //get checksum for recycling on
            var bits_2:BitmapData = new BitmapData(displayobject.width, displayobject.height);
            bits_2.draw(TestDisplayObject as IBitmapDrawable);
            bitmapSnapshot = new Bitmap(bits_2);
            bits_2 = null;
            pixels = bitmapSnapshot.bitmapData.getPixels(bitmapSnapshot.bitmapData.rect);
            pixels.compress();
            pixels.position = 0;
            var checksumRecyclingOn:String = MD5.hashBinary(pixels);

            //check if there is any rendering difference
            assertTrue("the rendering changed between recycle on and off.", checksumRecyclingOn == checksumRecyclingOff);
            TestCanvas.rawChildren.addChild(DisplayObject(s));
        }

        private function initApp():void
        {
            // create body text flow, import body text, and assign flow composer
            bodyFlow = new TextFlow();
            bodyFlow = TextConverter.importToFlow(bodyMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            bodyFlow.flowComposer = new StandardFlowComposer();
            bodyContainer = new Sprite();
            bodyController = new CustomContainerController(bodyContainer, 800, 1000);
            bodyController.updateCompositionShapes();
            //bodyController.addTextLine(tl1, 0);
            bodyContainer.x = 20;
            bodyContainer.y = 20;
            // create container format to specify columns
            var bodyContainerFormat:TextLayoutFormat = new TextLayoutFormat();
            bodyContainerFormat.columnWidth = 390;
            bodyContainerFormat.columnGap = 15;
            bodyController.format = bodyContainerFormat;
            // enable scrolling
            bodyController.verticalScrollPolicy = ScrollPolicy.AUTO;
        }
    }
}

import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Shape;
import flash.display.Sprite;
import flash.filters.*;
import flash.text.engine.TextBlock;
import flash.text.engine.TextLine;

import flashx.textLayout.compose.ISWFContext;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.elements.Configuration;
import flashx.textLayout.tlf_internal;

use namespace tlf_internal;

class CustomContainerController extends ContainerController
{

    public function CustomContainerController(container:Sprite, compositionWidth:Number = 100, compositionHeight:Number = 100)
    {
        super(container, compositionWidth, compositionHeight);

        // We'll put all text lines in a nested container
        // Filters applied to this container won't affect other objects like selection or background shapes
        _textLineContainer = new Sprite();
        //_textLineContainer.filters = [ new DropShadowFilter() ]; // apply a filter  (for illustration)
        container.addChild(_textLineContainer);
    }

    // Return the index where the first text line should appear in its parent
    // Since our _textLineContainer only holds text lines, return zero
    protected override function getFirstTextLineChildIndex():int
    {
        return 0;
    }

    // Add a text line at the specified index
    protected override function addTextLine(textLine:TextLine, index:int):void
    {
        if (index == 0)
            textLine.filters = [new BlurFilter(3, 3, BitmapFilterQuality.HIGH)];
        _textLineContainer.addChildAt(textLine, index);
    }

    protected override function addInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject, index:int):void
    {
        parent.addChildAt(inlineGraphicElement, index);

    }

    // Remove a text line, but only if it is in _textLineContainer
    // (A text line may have moved to another container because of 'shuffling')
    protected override function removeTextLine(textLine:TextLine):void
    {
        if (_textLineContainer.contains(textLine))
        {
            textLine.filters = null;
            _textLineContainer.removeChild(textLine);
        }
    }

    // Add the container for selection shapes (block or point selection)
    protected override function addSelectionContainer(selectionContainer:DisplayObjectContainer):void
    {
        // If selection container is opaque or has normal blend mode, put selection container behind the text lines, else in front
        var filter:BlurFilter = new BlurFilter(10, 10, BitmapFilterQuality.HIGH);
        var myFilters:Array = [];
        myFilters.push(filter);
        selectionContainer.filters = myFilters;
        var index:int = selectionContainer.blendMode == BlendMode.NORMAL && selectionContainer.alpha == 1 ? container.getChildIndex(_textLineContainer) : container.numChildren;
        container.addChildAt(selectionContainer, index);
    }

    // Remove the container for selection shapes
    protected override function removeSelectionContainer(selectionContainer:DisplayObjectContainer):void
    {
        container.removeChild(selectionContainer);
    }

    // Add the background shape
    protected override function addBackgroundShape(shape:Shape):void
    {
        container.addChildAt(shape, 0); // behind everything else, so use index 0
    }

    private var _textLineContainer:Sprite;

}

class MySwfContext implements ISWFContext
{
    public var numLinesCreated:int = 0;
    public var numRecycledLines:int = 0;

    public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean = true):*
    {
        var textBlock:TextBlock = thisArg as TextBlock;
        if (textBlock)
        {
            if (fn == textBlock.createTextLine)
            {
                numLinesCreated++;      // COUNT: create a new TextLine
            }
            else if (Configuration.playerEnablesArgoFeatures && fn == thisArg["recreateTextLine"])
            {
                numRecycledLines++;     // COUNT: make a TextLine using a recycled line
            }
        }
        if (returns)
            return fn.apply(thisArg, argsArray);
        fn.apply(thisArg, argsArray);
    }
}



