////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.html.staticControls.beads
{
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFieldType;

	import org.apache.flex.core.CSSTextField;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.ITextModel;
	import org.apache.flex.core.ValuesManager;
	import org.apache.flex.events.Event;
	import org.apache.flex.utils.SolidBorderUtil;

	public class CSSTextButtonBead implements ITextButtonBead
	{
		public function CSSTextButtonBead()
		{
			upSprite = new Sprite();
			downSprite = new Sprite();
			overSprite = new Sprite();
			upTextField = new CSSTextField();
			downTextField = new CSSTextField();
			overTextField = new CSSTextField();
			upTextField.selectable = false;
			upTextField.type = TextFieldType.DYNAMIC;
			downTextField.selectable = false;
			downTextField.type = TextFieldType.DYNAMIC;
			overTextField.selectable = false;
			overTextField.type = TextFieldType.DYNAMIC;
			upTextField.autoSize = "left";
			downTextField.autoSize = "left";
			overTextField.autoSize = "left";
			upSprite.addChild(upTextField);
			downSprite.addChild(downTextField);
			overSprite.addChild(overTextField);
		}

		private var textModel:ITextModel;

		private var _strand:IStrand;

		private var shape:Shape;

		public function set strand(value:IStrand):void
		{
			_strand = value;
			textModel = value.getBeadByType(ITextModel) as ITextModel;
			textModel.addEventListener("textChange", textChangeHandler);
			textModel.addEventListener("htmlChange", htmlChangeHandler);
			shape = new Shape();
			shape.graphics.beginFill(0xCCCCCC);
			shape.graphics.drawRect(0, 0, 10, 10);
			shape.graphics.endFill();
			SimpleButton(value).upState = upSprite;
			SimpleButton(value).downState = downSprite;
			SimpleButton(value).overState = overSprite;
			SimpleButton(value).hitTestState = shape;
			if (textModel.text !== null)
				text = textModel.text;
			if (textModel.html !== null)
				html = textModel.html;

			setupSkin(overSprite, overTextField, "hover");
			setupSkin(downSprite, downTextField, "active");
			setupSkin(upSprite, upTextField);
		}

		private function setupSkin(sprite:Sprite, textField:TextField, state:String = null):void
		{

			var backgroundImage:Object = ValuesManager.valuesImpl.getValue(_strand, "backgroundImage", state);
			if (backgroundImage)
			{
				var loader:Loader = new Loader();
				sprite.addChildAt(loader, 0);
				loader.load(new URLRequest(backgroundImage as String));
				loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, function (e:flash.events.Event):void {
					textField.y = (sprite.height - textField.height) / 2;
					textField.x = (sprite.width - textField.width) / 2;
					updateHitArea();
				});
			}
			else
			{
				var borderColor:uint;
				var borderThickness:uint;
				var borderStyle:String;
				var borderStyles:Object = ValuesManager.valuesImpl.getValue(_strand, "border", state);
				if (borderStyles is Array)
				{
					borderColor = borderStyles[2];
					borderStyle = borderStyles[1];
					borderThickness = borderStyles[0];
				}
				var padding:Object = ValuesManager.valuesImpl.getValue(_strand, "padding", state);
				var backgroundColor:Object = ValuesManager.valuesImpl.getValue(_strand, "backgroundColor", state);
				SolidBorderUtil.drawBorder(sprite.graphics,
					0, 0, textField.textWidth + Number(padding) * 2, textField.textHeight + Number(padding) * 2,
					borderColor, backgroundColor, borderThickness);
				textField.y = (sprite.height - textField.height) / 2;
				textField.x = (sprite.width - textField.width) / 2;
			}
		}

		private function textChangeHandler(event:org.apache.flex.events.Event):void
		{
			text = textModel.text;
		}

		private function htmlChangeHandler(event:org.apache.flex.events.Event):void
		{
			html = textModel.html;
		}

		private var upTextField:CSSTextField;
		private var downTextField:CSSTextField;
		private var overTextField:CSSTextField;
		private var upSprite:Sprite;
		private var downSprite:Sprite;
		private var overSprite:Sprite;

		public function get text():String
		{
			return upTextField.text;
		}
		public function set text(value:String):void
		{
			upTextField.text = value;
			downTextField.text = value;
			overTextField.text = value;
			updateHitArea();
		}

		private function updateHitArea():void
		{
			shape.graphics.clear();
			shape.graphics.beginFill(0xCCCCCC);
			shape.graphics.drawRect(0, 0, upSprite.width, upSprite.height);
			shape.graphics.endFill();

		}

		public function get html():String
		{
			return upTextField.htmlText;
		}

		public function set html(value:String):void
		{
			upTextField.htmlText = value;
			downTextField.htmlText = value;
			overTextField.htmlText = value;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.html.staticControls.beads
{
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFieldType;

	import org.apache.flex.core.CSSTextField;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.ITextModel;
	import org.apache.flex.core.ValuesManager;
	import org.apache.flex.events.Event;
	import org.apache.flex.utils.SolidBorderUtil;

	public class CSSTextButtonBead implements ITextButtonBead
	{
		public function CSSTextButtonBead()
		{
			upSprite = new Sprite();
			downSprite = new Sprite();
			overSprite = new Sprite();
			upTextField = new CSSTextField();
			downTextField = new CSSTextField();
			overTextField = new CSSTextField();
			upTextField.selectable = false;
			upTextField.type = TextFieldType.DYNAMIC;
			downTextField.selectable = false;
			downTextField.type = TextFieldType.DYNAMIC;
			overTextField.selectable = false;
			overTextField.type = TextFieldType.DYNAMIC;
			upTextField.autoSize = "left";
			downTextField.autoSize = "left";
			overTextField.autoSize = "left";
			upSprite.addChild(upTextField);
			downSprite.addChild(downTextField);
			overSprite.addChild(overTextField);
		}

		private var textModel:ITextModel;

		private var _strand:IStrand;

		private var shape:Shape;

		public function set strand(value:IStrand):void
		{
			_strand = value;
			textModel = value.getBeadByType(ITextModel) as ITextModel;
			textModel.addEventListener("textChange", textChangeHandler);
			textModel.addEventListener("htmlChange", htmlChangeHandler);
			shape = new Shape();
			shape.graphics.beginFill(0xCCCCCC);
			shape.graphics.drawRect(0, 0, 10, 10);
			shape.graphics.endFill();
			SimpleButton(value).upState = upSprite;
			SimpleButton(value).downState = downSprite;
			SimpleButton(value).overState = overSprite;
			SimpleButton(value).hitTestState = shape;
			if (textModel.text !== null)
				text = textModel.text;
			if (textModel.html !== null)
				html = textModel.html;

			setupSkin(overSprite, overTextField, "hover");
			setupSkin(downSprite, downTextField, "active");
			setupSkin(upSprite, upTextField);
		}

		private function setupSkin(sprite:Sprite, textField:TextField, state:String = null):void
		{
			var borderColor:uint;
			var borderThickness:uint;
			var borderStyle:String;
			var borderStyles:Object = ValuesManager.valuesImpl.getValue(_strand, "border", state);
			if (borderStyles is Array)
			{
				borderColor = borderStyles[2];
				borderStyle = borderStyles[1];
				borderThickness = borderStyles[0];
			}
			var value:Object = ValuesManager.valuesImpl.getValue(_strand, "border-style", state);
			if (value != null)
				borderStyle = value as String;
			value = ValuesManager.valuesImpl.getValue(_strand, "border-color", state);
			if (value != null)
				borderColor = value as uint;
			value = ValuesManager.valuesImpl.getValue(_strand, "border-thickness", state);
			if (value != null)
				borderThickness = value as uint;
			var padding:Object = ValuesManager.valuesImpl.getValue(_strand, "padding", state);
			var backgroundColor:Object = ValuesManager.valuesImpl.getValue(_strand, "backgroundColor", state);
			if (borderStyle == "solid")
			{
				SolidBorderUtil.drawBorder(sprite.graphics,
					0, 0, textField.textWidth + Number(padding) * 2, textField.textHeight + Number(padding) * 2,
					borderColor, backgroundColor, borderThickness);
				textField.y = (sprite.height - textField.height) / 2;
				textField.x = (sprite.width - textField.width) / 2;
			}
			var backgroundImage:Object = ValuesManager.valuesImpl.getValue(_strand, "backgroundImage", state);
			if (backgroundImage)
			{
				var loader:Loader = new Loader();
				sprite.addChildAt(loader, 0);
				var url:String = backgroundImage as String;
				loader.load(new URLRequest(url));
				loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, function (e:flash.events.Event):void {
					textField.y = (sprite.height - textField.height) / 2;
					textField.x = (sprite.width - textField.width) / 2;
					updateHitArea();
				});
			}
		}

		private function textChangeHandler(event:org.apache.flex.events.Event):void
		{
			text = textModel.text;
		}

		private function htmlChangeHandler(event:org.apache.flex.events.Event):void
		{
			html = textModel.html;
		}

		private var upTextField:CSSTextField;
		private var downTextField:CSSTextField;
		private var overTextField:CSSTextField;
		private var upSprite:Sprite;
		private var downSprite:Sprite;
		private var overSprite:Sprite;

		public function get text():String
		{
			return upTextField.text;
		}
		public function set text(value:String):void
		{
			upTextField.text = value;
			downTextField.text = value;
			overTextField.text = value;
			updateHitArea();
		}

		private function updateHitArea():void
		{
			shape.graphics.clear();
			shape.graphics.beginFill(0xCCCCCC);
			shape.graphics.drawRect(0, 0, upSprite.width, upSprite.height);
			shape.graphics.endFill();

		}

		public function get html():String
		{
			return upTextField.htmlText;
		}

		public function set html(value:String):void
		{
			upTextField.htmlText = value;
			downTextField.htmlText = value;
			overTextField.htmlText = value;
		}
	}
}

support png/gif/jpg skinning of a buton

support png/gif/jpg skinning of a buton


////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.html.beads
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;

	import org.apache.flex.core.CSSTextField;
	import org.apache.flex.core.IBeadView;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.ITextModel;
	import org.apache.flex.core.IUIBase;
	import org.apache.flex.core.UIBase;
	import org.apache.flex.core.ValuesManager;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.IEventDispatcher;

    /**
     *  The TextFieldViewBase class is the base class for
     *  the components that display text.
     *  It displays text using a TextField, so there is no
     *  right-to-left text support in this view.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class TextFieldViewBase implements IBeadView, ITextFieldView
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function TextFieldViewBase()
		{
			_textField = new CSSTextField();
		}

		private var _textField:CSSTextField;

        /**
         *  @copy org.apache.flex.core.ITextModel#textField
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get textField() : CSSTextField
		{
			return _textField;
		}

		private var _textModel:ITextModel;

		protected var _strand:IStrand;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function set strand(value:IStrand):void
		{
			_strand = value;
			_textModel = value.getBeadByType(ITextModel) as ITextModel;
            _textModel.addEventListener("textChange", textChangeHandler);
            _textModel.addEventListener("htmlChange", htmlChangeHandler);
            IEventDispatcher(_strand).addEventListener("widthChanged", widthChangeHandler);
            IEventDispatcher(_strand).addEventListener("heightChanged", heightChangeHandler);
			DisplayObjectContainer(value).addChild(_textField);
			if (_textModel.text !== null)
				text = _textModel.text;
			if (_textModel.html !== null)
				html = _textModel.html;
		}

        /**
         *  @private
         */
		public function get host() : IUIBase
		{
			return _strand as IUIBase;
		}

        /**
         *  @copy org.apache.flex.core.ITextModel#text
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get text():String
		{
			return _textField.text;
		}

        /**
         *  @private
         */
        public function set text(value:String):void
		{
            if (value == null)
                value = "";
			_textField.text = value;
            autoSizeIfNeeded();
		}

        private function autoSizeIfNeeded():void
        {
            var host:UIBase = UIBase(_strand);
            if (autoHeight)
            {
                if (textField.height != textField.textHeight + 4)
                {
                    textField.height = textField.textHeight + 4;
                    inHeightChange = true;
                    host.dispatchEvent(new Event("heightChanged"));
                    inHeightChange = false;
                }
            }
            if (autoWidth)
            {
                if (textField.width != textField.textWidth + 4)
                {
                    textField.width = textField.textWidth + 4;
                    inWidthChange = true;
                    host.dispatchEvent(new Event("widthChanged"));
                    inWidthChange = false;
                }
            }
        }

        /**
         *  @copy org.apache.flex.core.ITextModel#html
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get html():String
		{
			return _textField.htmlText;
		}

        /**
         *  @private
         */
        public function set html(value:String):void
		{
			_textField.htmlText = value;
            autoSizeIfNeeded();
		}

		private function textChangeHandler(event:Event):void
		{
			text = _textModel.text;
		}

		private function htmlChangeHandler(event:Event):void
		{
			html = _textModel.html;
		}

        private var autoHeight:Boolean = true;
        private var autoWidth:Boolean = true;
        private var inHeightChange:Boolean = false;
        private var inWidthChange:Boolean = false;

		private function widthChangeHandler(event:Event):void
		{
            if (!inWidthChange)
            {
                textField.autoSize = "none";
                autoWidth = false;
    			textField.width = DisplayObject(_strand).width;
                if (autoHeight)
        	        autoSizeIfNeeded()
                else
                    textField.height = DisplayObject(_strand).height;
            }
		}

        private function heightChangeHandler(event:Event):void
        {
            if (!inHeightChange)
            {
                textField.autoSize = "none";
                autoHeight = false;
                textField.height = DisplayObject(_strand).height;
                if (autoWidth)
                    autoSizeIfNeeded();
                else
                    textField.width = DisplayObject(_strand).width;
            }
        }

        /**
         *  @copy org.apache.flex.core.IBeadView#viewHeight
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function get viewHeight():Number
        {
            // textfields with autosize collapse if no text
            if (_textField.text == "" && _textField.autoSize != "none")
                return ValuesManager.valuesImpl.getValue(_strand, "fontSize") + 4;

            return _textField.height;
        }

        /**
         *  @copy org.apache.flex.core.IBeadView#viewWidth
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function get viewWidth():Number
        {
            // textfields with autosize collapse if no text
            if (_textField.text == "" && _textField.autoSize != "none")
                return 0;

            return _textField.width;
        }

    }
}

////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.html.beads
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;

	import org.apache.flex.core.CSSTextField;
	import org.apache.flex.core.IBeadView;
    import org.apache.flex.core.ILayoutChild;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.ITextModel;
	import org.apache.flex.core.IUIBase;
	import org.apache.flex.core.UIBase;
	import org.apache.flex.core.ValuesManager;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.IEventDispatcher;

    /**
     *  The TextFieldViewBase class is the base class for
     *  the components that display text.
     *  It displays text using a TextField, so there is no
     *  right-to-left text support in this view.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class TextFieldViewBase implements IBeadView, ITextFieldView
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function TextFieldViewBase()
		{
			_textField = new CSSTextField();
		}

		private var _textField:CSSTextField;

        /**
         *  @copy org.apache.flex.core.ITextModel#textField
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get textField() : CSSTextField
		{
			return _textField;
		}

		private var _textModel:ITextModel;

		protected var _strand:IStrand;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function set strand(value:IStrand):void
		{
			_strand = value;
			_textModel = value.getBeadByType(ITextModel) as ITextModel;
            _textModel.addEventListener("textChange", textChangeHandler);
            _textModel.addEventListener("htmlChange", htmlChangeHandler);
            IEventDispatcher(_strand).addEventListener("widthChanged", widthChangeHandler);
            IEventDispatcher(_strand).addEventListener("heightChanged", heightChangeHandler);
            IEventDispatcher(_strand).addEventListener("sizeChanged", sizeChangeHandler);
			DisplayObjectContainer(value).addChild(_textField);
			if (_textModel.text !== null)
				text = _textModel.text;
			if (_textModel.html !== null)
				html = _textModel.html;

            var ilc:ILayoutChild = host as ILayoutChild;

            autoHeight = ilc.isHeightSizedToContent();
            autoWidth = ilc.isWidthSizedToContent();

		}

        /**
         *  @private
         */
		public function get host() : IUIBase
		{
			return _strand as IUIBase;
		}

        /**
         *  @copy org.apache.flex.core.ITextModel#text
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get text():String
		{
			return _textField.text;
		}

        /**
         *  @private
         */
        public function set text(value:String):void
		{
            if (value == null)
                value = "";
			_textField.text = value;
            autoSizeIfNeeded();
		}

        private function autoSizeIfNeeded():void
        {
            var host:UIBase = UIBase(_strand);
            if (autoHeight)
            {
                if (textField.height != textField.textHeight + 4)
                {
                    textField.height = textField.textHeight + 4;
                    inHeightChange = true;
                    host.dispatchEvent(new Event("heightChanged"));
                    inHeightChange = false;
                }
            }
            if (autoWidth)
            {
                if (textField.width != textField.textWidth + 4)
                {
                    textField.width = textField.textWidth + 4;
                    inWidthChange = true;
                    host.dispatchEvent(new Event("widthChanged"));
                    inWidthChange = false;
                }
            }
        }

        /**
         *  @copy org.apache.flex.core.ITextModel#html
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get html():String
		{
			return _textField.htmlText;
		}

        /**
         *  @private
         */
        public function set html(value:String):void
		{
			_textField.htmlText = value;
            autoSizeIfNeeded();
		}

		private function textChangeHandler(event:Event):void
		{
			text = _textModel.text;
		}

		private function htmlChangeHandler(event:Event):void
		{
			html = _textModel.html;
		}

        private var autoHeight:Boolean;
        private var autoWidth:Boolean;
        private var inHeightChange:Boolean = false;
        private var inWidthChange:Boolean = false;

		private function widthChangeHandler(event:Event):void
		{
            if (!inWidthChange)
            {
                textField.autoSize = "none";
                autoWidth = false;
    			textField.width = DisplayObject(_strand).width;
                if (autoHeight)
        	        autoSizeIfNeeded()
                else
                    textField.height = DisplayObject(_strand).height;
            }
		}

        private function heightChangeHandler(event:Event):void
        {
            if (!inHeightChange)
            {
                textField.autoSize = "none";
                autoHeight = false;
                textField.height = DisplayObject(_strand).height;
                if (autoWidth)
                    autoSizeIfNeeded();
                else
                    textField.width = DisplayObject(_strand).width;
            }
        }

        private function sizeChangeHandler(event:Event):void
        {
            var ilc:ILayoutChild = host as ILayoutChild;

            autoHeight = ilc.isHeightSizedToContent();
            if (!autoHeight)
            {
                textField.autoSize = "none";
                textField.height = DisplayObject(_strand).height;
            }

            autoWidth = ilc.isWidthSizedToContent();
            if (!autoWidth)
            {
                textField.autoSize = "none";
                textField.width = DisplayObject(_strand).width;
            }
        }

        /**
         *  @copy org.apache.flex.core.IBeadView#viewHeight
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function get viewHeight():Number
        {
            // textfields with autosize collapse if no text
            if (_textField.text == "" && _textField.autoSize != "none")
                return ValuesManager.valuesImpl.getValue(_strand, "fontSize") + 4;

            return _textField.height;
        }

        /**
         *  @copy org.apache.flex.core.IBeadView#viewWidth
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function get viewWidth():Number
        {
            // textfields with autosize collapse if no text
            if (_textField.text == "" && _textField.autoSize != "none")
                return 0;

            return _textField.width;
        }

    }
}

fix autosizing

fix autosizing


/**
 * KListPlugin
 *
 * @langversion 3.0
 * @playerversion Flash 9.0.28.0
 * @author Dan Bacon / www.baconoppenheim.com
 */
package
{
	import com.kaltura.kdpfl.plugin.IPlugin;
	import com.kaltura.kdpfl.plugin.component.IDataProvider;
	import com.kaltura.kdpfl.plugin.component.KList;
	import com.kaltura.kdpfl.plugin.component.KListItem;

	import fl.core.UIComponent;
	import fl.data.DataProvider;

	import flash.events.Event;
	import flash.events.MouseEvent;

	import org.puremvc.as3.interfaces.IFacade;

	public class listPluginCode extends UIComponent implements IPlugin
	{
		private var _facade:IFacade;
		private var _klist:KList;
		private var _dataProvider:IDataProvider;
		private var _itemRendererId:String;
		public var rowHeight:Number = 80;
		public var listDisabledAlpha:Number = 0.3;
		public var excludeFromDisableGUI:Boolean = true;

		/**
		 * by fixing hard-coded styles we broke backward compatibility, so if we are using old templates we will
		 * ignore the styleName
		 */
		public var supportNewStyle:Boolean = false;

		private var _styleName:String;
		/**
		 * should the scrollbar be on the left side
		 */
		public var useLeftScrollbar:Boolean = false;
		/**
		 * Constructor
		 *
		 */
		public function listPluginCode()
		{
			_klist = new KList();

			_klist.addEventListener( MouseEvent.CLICK , onListItemClick, false, 0, true );
			this.addEventListener( MouseEvent.CLICK , onListPluginClick, false, 0, true );
			_klist.addEventListener( Event.CHANGE, onListChange, false, 0, true );
			_klist.addEventListener( Event.ADDED_TO_STAGE , resizeKdp );

			addChild( _klist );
		}

		public function setSkin( styleName:String, setSkinSize:Boolean=false ):void
		{
			_styleName = styleName;
			_klist.setSkin( styleName, setSkinSize );
		}

		/**
		 *
		 * @param facade
		 *
		 */
		public function initializePlugin( facade:IFacade ):void
		{
			_facade = facade;
			if (supportNewStyle && _styleName)
			 	KListItem.stylName = _styleName;
			_klist.setStyle('cellRenderer', KListItem );
			_klist.rowHeight = rowHeight;
			_klist.setDisabledAlpha(listDisabledAlpha);

			// TODO error handling
			var buildLayout:Function = facade.retrieveProxy("layoutProxy")["buildLayout"];
			var kml:XML = facade.retrieveProxy("layoutProxy")["vo"]["layoutXML"];
			var itemLayout:XML = kml.descendants().renderer.(@id == this.itemRenderer)[0];
			itemLayout = itemLayout.children()[0];

			_klist.itemContentFactory = buildLayout;
			_klist.itemContentLayout = itemLayout;
			_klist.leftScrollBar = useLeftScrollbar;

			resizeKdp();
		}

		public function onListChange( evt:Event ):void
		{
			_dataProvider.selectedIndex = _klist.selectedIndex;
			_klist.scrollToSelected();

		}

		public function onListItemClick( evt:MouseEvent ):void
		{

		}

		private function onListPluginClick (evt : MouseEvent ) : void
		{

		}

		public function set itemRenderer( value:String ):void
		{
			_itemRendererId = value;
		}

		public function get itemRenderer():String
		{
			return( _itemRendererId )
		}

		[Bindable]
		public function set dataProvider( data:DataProvider ):void
		{
			if( data )
			{
				_dataProvider = data as IDataProvider;
				_dataProvider.addEventListener( Event.CHANGE, onDataProviderItemChange, false, 0, true );
				_klist.dataProvider = data;

			}
		}

		public function onDataProviderItemChange( evt:Event = null ):void
		{
			if(_dataProvider&&_dataProvider.selectedIndex<_klist.length){
				_klist.selectedIndex = _dataProvider.selectedIndex;
			    _klist.scrollToIndex(_dataProvider.selectedIndex);
			}
		}

		public function get dataProvider():DataProvider
		{
			return _klist.dataProvider;
		}

 		override public function set width( value:Number ):void
		{
			 _klist.width = super.width = value;
		}

		override public function set height( value:Number ):void
		{
			_klist.height = super.height = value;
		}

		override public function toString():String
		{
			return( "ListPlugin" );
		}

		/**
		 * Hack...fix the bug of sizing...
		 * @param event
		 *
		 */
		private function resizeKdp( event : Event = null ) : void
		{
			if(_facade)
				_facade.retrieveMediator("stageMediator")["onResize"]();
		}

		override public function set enabled(value:Boolean):void
		{
			_klist.enabled = value;

		}

	}
}

remove spaces

qnd: remove spaces

git-svn-id: 3f608e5a9a704dd448217c0a64c508e7f145cfa1@82444 6b8eccd3-e8c5-4e7d-8186-e12b5326b719


package dolly {
import dolly.core.dolly_internal;
import dolly.data.ClassLevelCloneable;
import dolly.data.ClassLevelCopyableCloneable;
import dolly.data.PropertyLevelCloneable;
import dolly.data.PropertyLevelCopyableCloneable;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertNull;

use namespace dolly_internal;

public class ClonerTest {

	private var classLevelCloneable:ClassLevelCloneable;
	private var classLevelCloneableType:Type;

	private var classLevelCopyableCloneable:ClassLevelCopyableCloneable;
	private var classLevelCopyableCloneableType:Type;

	private var propertyLevelCloneable:PropertyLevelCloneable;
	private var propertyLevelCloneableType:Type;

	private var propertyLevelCopyableCloneable:PropertyLevelCopyableCloneable;
	private var propertyLevelCopyableCloneableType:Type;

	[Before]
	public function before():void {
		classLevelCloneable = new ClassLevelCloneable();
		classLevelCloneable.property1 = "value 1";
		classLevelCloneable.property2 = "value 2";
		classLevelCloneable.property3 = "value 3";
		classLevelCloneable.writableField = "value 4";
		classLevelCloneableType = Type.forInstance(classLevelCloneable);

		classLevelCopyableCloneable = new ClassLevelCopyableCloneable();
		classLevelCopyableCloneable.property1 = "value 1";
		classLevelCopyableCloneable.property2 = "value 2";
		classLevelCopyableCloneable.property3 = "value 3";
		classLevelCopyableCloneable.writableField = "value 4";
		classLevelCopyableCloneableType = Type.forInstance(classLevelCopyableCloneable);

		propertyLevelCloneable = new PropertyLevelCloneable();
		propertyLevelCloneable.property1 = "value 1";
		propertyLevelCloneable.property2 = "value 2";
		propertyLevelCloneable.property3 = "value 3";
		propertyLevelCloneable.writableField = "value 4";
		propertyLevelCloneableType = Type.forInstance(propertyLevelCloneable);

		propertyLevelCopyableCloneable = new PropertyLevelCopyableCloneable();
		propertyLevelCopyableCloneable.property1 = "value 1";
		propertyLevelCopyableCloneable.property2 = "value 2";
		propertyLevelCopyableCloneable.property3 = "value 3";
		propertyLevelCopyableCloneable.writableField = "value 4";
		propertyLevelCopyableCloneableType = Type.forInstance(propertyLevelCopyableCloneable);
	}

	[After]
	public function after():void {
		classLevelCloneable = null;
		classLevelCloneableType = null;

		classLevelCopyableCloneable = null;
		classLevelCopyableCloneableType = null;

		propertyLevelCloneable = null;
		propertyLevelCloneableType = null;

		propertyLevelCopyableCloneable = null;
		propertyLevelCopyableCloneableType = null;
	}

	[Test]
	public function testGetCloneableFieldsForTypeClassLevelCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(classLevelCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);
	}

	[Test]
	public function testGetCloneableFieldsForTypeClassLevelCopyableCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(classLevelCopyableCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);
	}

	[Test]
	public function testGetCloneableFieldsForTypePropertyLevelCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(propertyLevelCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(3, cloneableFields.length);
	}

	[Test]
	public function testGetCloneableFieldsForTypePropertyLevelCopyableCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(propertyLevelCopyableCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);
	}

	[Test]
	public function testCloneClassLevelCloneable():void {
		const clone:ClassLevelCloneable = Cloner.clone(classLevelCloneable);
		assertNotNull(clone);
		assertNotNull(clone.property1);
		assertEquals(clone.property1, classLevelCloneable.property1);
		assertNotNull(clone.property2);
		assertEquals(clone.property2, classLevelCloneable.property2);
		assertNotNull(clone.property3);
		assertEquals(clone.property3, classLevelCloneable.property3);
		assertNotNull(clone.writableField);
		assertEquals(clone.writableField, classLevelCloneable.writableField);
	}

	[Test]
	public function testCloneClassLevelCopyableCloneable():void {
		const clone:ClassLevelCopyableCloneable = Cloner.clone(classLevelCopyableCloneable);
		assertNotNull(clone);
		assertNotNull(clone.property1);
		assertEquals(clone.property1, classLevelCloneable.property1);
		assertNotNull(clone.property2);
		assertEquals(clone.property2, classLevelCloneable.property2);
		assertNotNull(clone.property3);
		assertEquals(clone.property3, classLevelCloneable.property3);
		assertNotNull(clone.writableField);
		assertEquals(clone.writableField, classLevelCloneable.writableField);
	}

	[Test]
	public function testCloneWithPropertyLevelMetadata():void {
		const clone1:PropertyLevelCloneable = Cloner.clone(propertyLevelCloneable);
		assertNotNull(clone1);
		assertNull(clone1.property1);
		assertNotNull(clone1.property2);
		assertEquals(clone1.property2, propertyLevelCloneable.property2);
		assertNotNull(clone1.property3);
		assertEquals(clone1.property3, propertyLevelCloneable.property3);
		assertNotNull(clone1.writableField);
		assertEquals(clone1.writableField, propertyLevelCloneable.writableField);

		const clone2:PropertyLevelCopyableCloneable = Cloner.clone(propertyLevelCopyableCloneable);
		assertNotNull(clone2);
		assertNotNull(clone2.property1);
		assertEquals(clone2.property1, propertyLevelCloneable.property1);
		assertNotNull(clone2.property2);
		assertEquals(clone2.property2, propertyLevelCloneable.property2);
		assertNotNull(clone2.property3);
		assertEquals(clone2.property3, propertyLevelCloneable.property3);
		assertNotNull(clone2.writableField);
		assertEquals(clone2.writableField, propertyLevelCloneable.writableField);
	}
}
}

package dolly {
import dolly.core.dolly_internal;
import dolly.data.ClassLevelCloneable;
import dolly.data.ClassLevelCopyableCloneable;
import dolly.data.PropertyLevelCloneable;
import dolly.data.PropertyLevelCopyableCloneable;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertNull;

use namespace dolly_internal;

public class ClonerTest {

	private var classLevelCloneable:ClassLevelCloneable;
	private var classLevelCloneableType:Type;

	private var classLevelCopyableCloneable:ClassLevelCopyableCloneable;
	private var classLevelCopyableCloneableType:Type;

	private var propertyLevelCloneable:PropertyLevelCloneable;
	private var propertyLevelCloneableType:Type;

	private var propertyLevelCopyableCloneable:PropertyLevelCopyableCloneable;
	private var propertyLevelCopyableCloneableType:Type;

	[Before]
	public function before():void {
		classLevelCloneable = new ClassLevelCloneable();
		classLevelCloneable.property1 = "value 1";
		classLevelCloneable.property2 = "value 2";
		classLevelCloneable.property3 = "value 3";
		classLevelCloneable.writableField = "value 4";
		classLevelCloneableType = Type.forInstance(classLevelCloneable);

		classLevelCopyableCloneable = new ClassLevelCopyableCloneable();
		classLevelCopyableCloneable.property1 = "value 1";
		classLevelCopyableCloneable.property2 = "value 2";
		classLevelCopyableCloneable.property3 = "value 3";
		classLevelCopyableCloneable.writableField = "value 4";
		classLevelCopyableCloneableType = Type.forInstance(classLevelCopyableCloneable);

		propertyLevelCloneable = new PropertyLevelCloneable();
		propertyLevelCloneable.property1 = "value 1";
		propertyLevelCloneable.property2 = "value 2";
		propertyLevelCloneable.property3 = "value 3";
		propertyLevelCloneable.writableField = "value 4";
		propertyLevelCloneableType = Type.forInstance(propertyLevelCloneable);

		propertyLevelCopyableCloneable = new PropertyLevelCopyableCloneable();
		propertyLevelCopyableCloneable.property1 = "value 1";
		propertyLevelCopyableCloneable.property2 = "value 2";
		propertyLevelCopyableCloneable.property3 = "value 3";
		propertyLevelCopyableCloneable.writableField = "value 4";
		propertyLevelCopyableCloneableType = Type.forInstance(propertyLevelCopyableCloneable);
	}

	[After]
	public function after():void {
		classLevelCloneable = null;
		classLevelCloneableType = null;

		classLevelCopyableCloneable = null;
		classLevelCopyableCloneableType = null;

		propertyLevelCloneable = null;
		propertyLevelCloneableType = null;

		propertyLevelCopyableCloneable = null;
		propertyLevelCopyableCloneableType = null;
	}

	[Test]
	public function testGetCloneableFieldsForTypeClassLevelCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(classLevelCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);
	}

	[Test]
	public function testGetCloneableFieldsForTypeClassLevelCopyableCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(classLevelCopyableCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);
	}

	[Test]
	public function testGetCloneableFieldsForTypePropertyLevelCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(propertyLevelCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(3, cloneableFields.length);
	}

	[Test]
	public function testGetCloneableFieldsForTypePropertyLevelCopyableCloneable():void {
		const cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(propertyLevelCopyableCloneableType);
		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);
	}

	[Test]
	public function testCloneClassLevelCloneable():void {
		const clone:ClassLevelCloneable = Cloner.clone(classLevelCloneable);
		assertNotNull(clone);
		assertNotNull(clone.property1);
		assertEquals(clone.property1, classLevelCloneable.property1);
		assertNotNull(clone.property2);
		assertEquals(clone.property2, classLevelCloneable.property2);
		assertNotNull(clone.property3);
		assertEquals(clone.property3, classLevelCloneable.property3);
		assertNotNull(clone.writableField);
		assertEquals(clone.writableField, classLevelCloneable.writableField);
	}

	[Test]
	public function testCloneClassLevelCopyableCloneable():void {
		const clone:ClassLevelCopyableCloneable = Cloner.clone(classLevelCopyableCloneable);
		assertNotNull(clone);
		assertNotNull(clone.property1);
		assertEquals(clone.property1, classLevelCloneable.property1);
		assertNotNull(clone.property2);
		assertEquals(clone.property2, classLevelCloneable.property2);
		assertNotNull(clone.property3);
		assertEquals(clone.property3, classLevelCloneable.property3);
		assertNotNull(clone.writableField);
		assertEquals(clone.writableField, classLevelCloneable.writableField);
	}

	[Test]
	public function testClonePropertyLevelCloneable():void {
		const clone:PropertyLevelCloneable = Cloner.clone(propertyLevelCloneable);
		assertNotNull(clone);
		assertNull(clone.property1);
		assertNotNull(clone.property2);
		assertEquals(clone.property2, propertyLevelCloneable.property2);
		assertNotNull(clone.property3);
		assertEquals(clone.property3, propertyLevelCloneable.property3);
		assertNotNull(clone.writableField);
		assertEquals(clone.writableField, propertyLevelCloneable.writableField);
	}

	[Test]
	public function testClonePropertyLevelCopyableCloneable():void {
		const clone:PropertyLevelCopyableCloneable = Cloner.clone(propertyLevelCopyableCloneable);
		assertNotNull(clone);
		assertNotNull(clone.property1);
		assertEquals(clone.property1, propertyLevelCloneable.property1);
		assertNotNull(clone.property2);
		assertEquals(clone.property2, propertyLevelCloneable.property2);
		assertNotNull(clone.property3);
		assertEquals(clone.property3, propertyLevelCloneable.property3);
		assertNotNull(clone.writableField);
		assertEquals(clone.writableField, propertyLevelCloneable.writableField);
	}
}
}

Split method "testCloneWithPropertyLevelMetadata" to a few.


package dolly {
import dolly.core.dolly_internal;
import dolly.data.ClassLevelCopyable;
import dolly.data.ClassLevelCopyableCloneable;
import dolly.data.PropertyLevelCopyable;
import dolly.data.PropertyLevelCopyableCloneable;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertNull;

use namespace dolly_internal;

public class CopierTest {

	private var classLevelCopyable:ClassLevelCopyable;
	private var classLevelCopyableType:Type;

	private var classLevelCopyableCloneable:ClassLevelCopyableCloneable;
	private var classLevelCopyableCloneableType:Type;

	private var propertyLevelCopyable:PropertyLevelCopyable;
	private var propertyLevelCopyableType:Type;

	private var propertyLevelCopyableCloneable:PropertyLevelCopyableCloneable;
	private var propertyLevelCopyableCloneableType:Type;

	[Before]
	public function before():void {
		classLevelCopyable = new ClassLevelCopyable();
		classLevelCopyable.property1 = "value 1";
		classLevelCopyable.property2 = "value 2";
		classLevelCopyable.property3 = "value 3";
		classLevelCopyable.writableField = "value 4";
		classLevelCopyableType = Type.forInstance(classLevelCopyable);

		classLevelCopyableCloneable = new ClassLevelCopyableCloneable();
		classLevelCopyableCloneable.property1 = "value 1";
		classLevelCopyableCloneable.property2 = "value 2";
		classLevelCopyableCloneable.property3 = "value 3";
		classLevelCopyableCloneable.writableField = "value 4";
		classLevelCopyableCloneableType = Type.forInstance(classLevelCopyableCloneable);

		propertyLevelCopyable = new PropertyLevelCopyable();
		propertyLevelCopyable.property1 = "value 1";
		propertyLevelCopyable.property2 = "value 2";
		propertyLevelCopyable.property3 = "value 3";
		propertyLevelCopyable.writableField = "value 4";
		propertyLevelCopyableType = Type.forInstance(propertyLevelCopyable);

		propertyLevelCopyableCloneable = new PropertyLevelCopyableCloneable();
		propertyLevelCopyableCloneable.property1 = "value 1";
		propertyLevelCopyableCloneable.property2 = "value 2";
		propertyLevelCopyableCloneable.property3 = "value 3";
		propertyLevelCopyableCloneable.writableField = "value 4";
		propertyLevelCopyableCloneableType = Type.forInstance(propertyLevelCopyableCloneable);
	}

	[After]
	public function after():void {
		classLevelCopyable = null;
		classLevelCopyableType = null;

		classLevelCopyableCloneable = null;
		classLevelCopyableCloneableType = null;

		propertyLevelCopyable = null;
		propertyLevelCopyableType = null;

		propertyLevelCopyableCloneable = null;
		propertyLevelCopyableCloneableType = null;
	}

	[Test]
	public function testGetCopyableFieldsForType():void {
		var copyableFields:Vector.<Field> = Copier.getCopyableFieldsForType(classLevelCopyableType);
		assertNotNull(copyableFields);
		assertEquals(4, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
		assertNotNull(copyableFields[3]);

		copyableFields = Copier.getCopyableFieldsForType(classLevelCopyableCloneableType);
		assertNotNull(copyableFields);
		assertEquals(4, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
		assertNotNull(copyableFields[3]);

		copyableFields = Copier.getCopyableFieldsForType(propertyLevelCopyableType);
		assertNotNull(copyableFields);
		assertEquals(3, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);

		copyableFields = Copier.getCopyableFieldsForType(propertyLevelCopyableCloneableType);
		assertNotNull(copyableFields);
		assertEquals(3, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
	}

	[Test]
	public function testCopyWithClassLevelMetadata():void {
		const copy1:ClassLevelCopyable = Copier.copy(classLevelCopyable);
		assertNotNull(copy1);
		assertNotNull(copy1.property1);
		assertEquals(copy1.property1, classLevelCopyable.property1);
		assertNotNull(copy1.property2);
		assertEquals(copy1.property2, classLevelCopyable.property2);
		assertNotNull(copy1.property3);
		assertEquals(copy1.property3, classLevelCopyable.property3);
		assertNotNull(copy1.writableField);
		assertEquals(copy1.writableField, classLevelCopyable.writableField);

		const copy2:ClassLevelCopyableCloneable = Copier.copy(classLevelCopyableCloneable);
		assertNotNull(copy2);
		assertNotNull(copy2.property1);
		assertEquals(copy2.property1, classLevelCopyable.property1);
		assertNotNull(copy2.property2);
		assertEquals(copy2.property2, classLevelCopyable.property2);
		assertNotNull(copy2.property3);
		assertEquals(copy2.property3, classLevelCopyable.property3);
		assertNotNull(copy2.writableField);
		assertEquals(copy2.writableField, classLevelCopyable.writableField);
	}

	[Test]
	public function testCopyWithPropertyLevelMetadata():void {
		const copy1:PropertyLevelCopyable = Copier.copy(propertyLevelCopyable);
		assertNotNull(copy1);
		assertNull(copy1.property1);
		assertNotNull(copy1.property2);
		assertEquals(copy1.property2, classLevelCopyable.property2);
		assertNotNull(copy1.property3);
		assertEquals(copy1.property3, classLevelCopyable.property3);
		assertNotNull(copy1.writableField);
		assertEquals(copy1.writableField, classLevelCopyable.writableField);

		const copy2:PropertyLevelCopyableCloneable = Copier.copy(propertyLevelCopyableCloneable);
		assertNotNull(copy2);
		assertNull(copy2.property1);
		assertNotNull(copy2.property2);
		assertEquals(copy2.property2, classLevelCopyable.property2);
		assertNotNull(copy2.property3);
		assertEquals(copy2.property3, classLevelCopyable.property3);
		assertNotNull(copy2.writableField);
		assertEquals(copy2.writableField, classLevelCopyable.writableField);
	}
}
}

package dolly {
import dolly.core.dolly_internal;
import dolly.data.ClassLevelCopyable;
import dolly.data.ClassLevelCopyableCloneable;
import dolly.data.PropertyLevelCopyable;
import dolly.data.PropertyLevelCopyableCloneable;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertNull;

use namespace dolly_internal;

public class CopierTest {

	private var classLevelCopyable:ClassLevelCopyable;
	private var classLevelCopyableType:Type;

	private var classLevelCopyableCloneable:ClassLevelCopyableCloneable;
	private var classLevelCopyableCloneableType:Type;

	private var propertyLevelCopyable:PropertyLevelCopyable;
	private var propertyLevelCopyableType:Type;

	private var propertyLevelCopyableCloneable:PropertyLevelCopyableCloneable;
	private var propertyLevelCopyableCloneableType:Type;

	[Before]
	public function before():void {
		classLevelCopyable = new ClassLevelCopyable();
		classLevelCopyable.property1 = "value 1";
		classLevelCopyable.property2 = "value 2";
		classLevelCopyable.property3 = "value 3";
		classLevelCopyable.writableField = "value 4";
		classLevelCopyableType = Type.forInstance(classLevelCopyable);

		classLevelCopyableCloneable = new ClassLevelCopyableCloneable();
		classLevelCopyableCloneable.property1 = "value 1";
		classLevelCopyableCloneable.property2 = "value 2";
		classLevelCopyableCloneable.property3 = "value 3";
		classLevelCopyableCloneable.writableField = "value 4";
		classLevelCopyableCloneableType = Type.forInstance(classLevelCopyableCloneable);

		propertyLevelCopyable = new PropertyLevelCopyable();
		propertyLevelCopyable.property1 = "value 1";
		propertyLevelCopyable.property2 = "value 2";
		propertyLevelCopyable.property3 = "value 3";
		propertyLevelCopyable.writableField = "value 4";
		propertyLevelCopyableType = Type.forInstance(propertyLevelCopyable);

		propertyLevelCopyableCloneable = new PropertyLevelCopyableCloneable();
		propertyLevelCopyableCloneable.property1 = "value 1";
		propertyLevelCopyableCloneable.property2 = "value 2";
		propertyLevelCopyableCloneable.property3 = "value 3";
		propertyLevelCopyableCloneable.writableField = "value 4";
		propertyLevelCopyableCloneableType = Type.forInstance(propertyLevelCopyableCloneable);
	}

	[After]
	public function after():void {
		classLevelCopyable = null;
		classLevelCopyableType = null;

		classLevelCopyableCloneable = null;
		classLevelCopyableCloneableType = null;

		propertyLevelCopyable = null;
		propertyLevelCopyableType = null;

		propertyLevelCopyableCloneable = null;
		propertyLevelCopyableCloneableType = null;
	}

	[Test]
	public function testGetCopyableFieldsForTypeClassLevelCopyable():void {
		const copyableFields:Vector.<Field> = Copier.getCopyableFieldsForType(classLevelCopyableType);
		assertNotNull(copyableFields);
		assertEquals(4, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
		assertNotNull(copyableFields[3]);
	}

	[Test]
	public function testGetCopyableFieldsForTypeClassLevelCopyableCloneable():void {
		const copyableFields:Vector.<Field> = Copier.getCopyableFieldsForType(classLevelCopyableCloneableType);
		assertNotNull(copyableFields);
		assertEquals(4, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
		assertNotNull(copyableFields[3]);
	}

	[Test]
	public function testGetCopyableFieldsForTypePropertyLevelCopyable():void {
		const copyableFields:Vector.<Field> = Copier.getCopyableFieldsForType(propertyLevelCopyableType);
		assertNotNull(copyableFields);
		assertEquals(3, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
	}

	[Test]
	public function testGetCopyableFieldsForTypePropertyLevelCopyableCloneable():void {
		const copyableFields:Vector.<Field> = Copier.getCopyableFieldsForType(propertyLevelCopyableCloneableType);
		assertNotNull(copyableFields);
		assertEquals(3, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
	}

	[Test]
	public function testCopyWithClassLevelMetadata():void {
		const copy1:ClassLevelCopyable = Copier.copy(classLevelCopyable);
		assertNotNull(copy1);
		assertNotNull(copy1.property1);
		assertEquals(copy1.property1, classLevelCopyable.property1);
		assertNotNull(copy1.property2);
		assertEquals(copy1.property2, classLevelCopyable.property2);
		assertNotNull(copy1.property3);
		assertEquals(copy1.property3, classLevelCopyable.property3);
		assertNotNull(copy1.writableField);
		assertEquals(copy1.writableField, classLevelCopyable.writableField);

		const copy2:ClassLevelCopyableCloneable = Copier.copy(classLevelCopyableCloneable);
		assertNotNull(copy2);
		assertNotNull(copy2.property1);
		assertEquals(copy2.property1, classLevelCopyable.property1);
		assertNotNull(copy2.property2);
		assertEquals(copy2.property2, classLevelCopyable.property2);
		assertNotNull(copy2.property3);
		assertEquals(copy2.property3, classLevelCopyable.property3);
		assertNotNull(copy2.writableField);
		assertEquals(copy2.writableField, classLevelCopyable.writableField);
	}

	[Test]
	public function testCopyWithPropertyLevelMetadata():void {
		const copy1:PropertyLevelCopyable = Copier.copy(propertyLevelCopyable);
		assertNotNull(copy1);
		assertNull(copy1.property1);
		assertNotNull(copy1.property2);
		assertEquals(copy1.property2, classLevelCopyable.property2);
		assertNotNull(copy1.property3);
		assertEquals(copy1.property3, classLevelCopyable.property3);
		assertNotNull(copy1.writableField);
		assertEquals(copy1.writableField, classLevelCopyable.writableField);

		const copy2:PropertyLevelCopyableCloneable = Copier.copy(propertyLevelCopyableCloneable);
		assertNotNull(copy2);
		assertNull(copy2.property1);
		assertNotNull(copy2.property2);
		assertEquals(copy2.property2, classLevelCopyable.property2);
		assertNotNull(copy2.property3);
		assertEquals(copy2.property3, classLevelCopyable.property3);
		assertNotNull(copy2.writableField);
		assertEquals(copy2.writableField, classLevelCopyable.writableField);
	}
}
}

Split method "testGetCopyableFieldsForType" to a few.


package org.servebox.cafe.core.command
{
	import flash.events.IEventDispatcher;

	public interface IStateCommand extends ICommand, IEventDispatcher
	{
		[Bindable("executable_Change")]
		function get executable() : Boolean;

		function set executable( value :Boolean ) : void;
	}
}

package org.servebox.cafe.core.command
{
	import flash.events.IEventDispatcher;

	public interface IStateCommand extends ICommand, IEventDispatcher
	{
		[Bindable("executable_Change")]
		function get executable() : Boolean;

		function set executable( value :Boolean ) : void;

		function addParameter( key : String , value : Object ) : void;
	}
}

add addParameter to interface.

add addParameter to interface.


/*
 * Copyright
 * Watchtower stream.jw.org Team
 *
 */

 package org.denivip.osmf.net.httpstreaming.hls
{
	import __AS3__.vec.Vector;

	import org.osmf.logging.Logger;
	import org.osmf.logging.Log;

	import flash.utils.ByteArray;

	import org.osmf.net.httpstreaming.flv.FLVTagAudio;

	internal class HTTPStreamingMp3Audio2ToPESAudio extends HTTPStreamingMP2PESBase
	{
		private var _state:int;
		private var _haveNewTimestamp:Boolean = false;
		private var _audioTime:Number;
		private var _audioTimeIncr:Number;

		private var _frameLength:int;
		private var _remaining:int;
		private var _audioData:ByteArray;

		private var _version:int;
		private var _layer:int;
		private var _bitRate:int;
		private var _sampleRate:int;
		private var _padding:int;
		private var _channel:int;

		public function HTTPStreamingMp3Audio2ToPESAudio():void
		{
			_state = 0;
		}

		private static const MPEG1:int  = 0x03;
		private static const MPEG2:int  = 0x02;
		private static const MPEG25:int = 0x01;

		private static const LAYER_1:int = 0x03;
		private static const LAYER_2:int = 0x02;
		private static const LAYER_3:int = 0x01;

		private var BITREATE_MAP_FOR_MPEG1_LAYER1:Array = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0];
		private var BITREATE_MAP_FOR_MPEG1_LAYER2:Array = [0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, 0];
		private var BITREATE_MAP_FOR_MPEG1_LAYER3:Array = [0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 0];
		private var BITREATE_MAP_FOR_MPEG2_LAYER1:Array = [0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256, 0];
		private var BITREATE_MAP_FOR_MPEG2_LAYER2:Array = [0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, 0]; // LAYER3 is same

		private var SAMPLERATE_MAP_FOR_MPEG1:Array  = [44100, 48000, 32000, 0];
		private var SAMPLERATE_MAP_FOR_MPEG2:Array  = [22050, 24000, 16000, 0];
		private var SAMPLERATE_MAP_FOR_MPEG25:Array = [11025, 12000,  8000, 0];

		private function GetBitRate(version:int, layer:int, index:int):int
		{
			if (version == MPEG1) {
				if (layer == LAYER_1) {
					return BITREATE_MAP_FOR_MPEG1_LAYER1[index];
				}
				else if (layer == LAYER_2) {
					return BITREATE_MAP_FOR_MPEG1_LAYER2[index];
				}
				else if (layer == LAYER_3) {
					return BITREATE_MAP_FOR_MPEG1_LAYER3[index];
				}
			}
			else if (version == MPEG2) {
				if (layer == LAYER_1) {
					return BITREATE_MAP_FOR_MPEG2_LAYER1[index];
				}
				else if (layer == LAYER_2 || layer == LAYER_3) {
					return BITREATE_MAP_FOR_MPEG2_LAYER2[index];
				}
			}
			return 0;
		}

		private function GetSampleRate(version:int, no:int):int
		{
			if (version == MPEG1) {
				return SAMPLERATE_MAP_FOR_MPEG1[no];
			} else if (version == MPEG2) {
				return SAMPLERATE_MAP_FOR_MPEG2[no];
			} else if (version == MPEG25) {
				return SAMPLERATE_MAP_FOR_MPEG25[no];
			}

			return 0;
		}

		override public function processES(pusi:Boolean, packet:ByteArray, flush:Boolean = false): ByteArray {
			if(pusi)
			{
				// start of a new PES packet

				// Start code prefix and packet ID.

				value = packet.readUnsignedInt();
				packet.position -= 4;
				if(packet.readUnsignedInt() != 0x1c0)
				{
						throw new Error("PES start code not found or not ~");
				}
				// Ignore packet length and marker bits.
				packet.position += 3;
				// need PTS only
				var flags:uint = (packet.readUnsignedByte() & 0xc0) >> 6;
				if(flags != 0x02 && flags != 0x03)
				{
					throw new Error("No PTS in this audio PES packet");
				}

				var length:uint = packet.readUnsignedByte();

				var pts:Number =
					((packet.readUnsignedByte() & 0x0e) << 29) +
					((packet.readUnsignedShort() & 0xfffe) << 14) +
					((packet.readUnsignedShort() & 0xfffe) >> 1);

				var timestamp:Number = Math.round(pts/90);
				_haveNewTimestamp = true;

				if(!_timestampReseted){
					_offset += timestamp - _prevTimestamp;
				}
				_timestamp = _initialTimestamp + _offset;
				_prevTimestamp = timestamp;
				_timestampReseted = false;

				length -= 5;
				// no comp time for audio
				// Skip other header data.
				packet.position += length;
			}

			var value:uint;

			var tag:FLVTagAudio;
			var tagData:ByteArray = new ByteArray();

			if(!flush)
			{
				var dStart:uint = packet.position;
			}

			if(flush)
			{
				trace("audio flush at state "+_state.toString());
			}
			else while(packet.bytesAvailable > 0)
			{
				if(_state < 7)
				{
					value = packet.readUnsignedByte();
				}

				switch(_state)
				{
					case 0: // first 0x01
						if(_haveNewTimestamp)
						{
							_audioTime = _timestamp;
							_haveNewTimestamp = false;
						}

						if(value == 0xff)
						{
							_state = 1;
						}
						break;
					case 1:
						if (value & 0xe0 == 0xe0) { // 1110 0000

							_version = ((value >> 3) & 0x03);
							_layer = ((value >> 1) & 0x03);
							var crc:int = (value & 0x01);

							_state = 2;
						} else {
							_state = 0;
						}
						break;
					case 2:
						var bitrateIndex:int = ((value >> 4) & 0x0f);
						var sampleRate:int = ((value >> 2) & 0x03);
						_padding = ((value >> 1) & 0x01);
						var bit:int = ((value & 0x01));

						_state = 3;

						_bitRate = GetBitRate(_version, _layer, bitrateIndex);
						if (_bitRate == 0) {
							_state = 0;
						}

						_sampleRate = GetSampleRate(_version, sampleRate);
						//_audioTimeIncr = 1024000.0 / _sampleRate;
						_audioTimeIncr = 144 * 8 * 1000 / _sampleRate;

						if (_sampleRate == 0) {
							_state = 0;
						}

						break;
					case 3:
						_channel = ((value >>6) & 0x03);
						var modeExt:int = ((value >> 4) & 0x03);
						var copyright:int = ((value >> 3) & 0x01);
						var original:int = ((value >> 2) & 0x01);
						var emphasis:int = (value & 0x03);

						_frameLength = int((144 * _bitRate * 1000 / _sampleRate ) + _padding);

						packet.position -= 4

						dStart = packet.position;
						_audioData = new ByteArray();
						_remaining = _frameLength;

						_state = 4;
						break;
					case 4:
						var avail:int = packet.length - dStart;

						if(avail >= _remaining)
						{
							_audioData.writeBytes(packet, dStart, _remaining);
							packet.position += _remaining - 1;
							_remaining = 0;
						}
						else if(avail > 0)
						{
							_audioData.writeBytes(packet, dStart, avail);
							packet.position += avail;
							_remaining -= avail;
						}

						if(_remaining > 0)
						{
							//
						}
						else
						{
							tag = new FLVTagAudio();
							tag.timestamp = _audioTime;
							_audioTime += _audioTimeIncr;
							tag.soundChannels = (_channel == 0x03 ? FLVTagAudio.SOUND_CHANNELS_MONO : FLVTagAudio.SOUND_CHANNELS_STEREO);
							tag.soundFormat = FLVTagAudio.SOUND_FORMAT_MP3;
							tag.soundRate = FLVTagAudio.SOUND_RATE_44K; // rather than what is reported
							tag.soundSize = FLVTagAudio.SOUND_SIZE_16BITS;

							_state = 0;

							tag.data = _audioData;

							tag.write(tagData); // unrolled out the vector for audio tags
						}
						break;
				} // switch
			} // while

			/*
			var text:String = new String();
			for(var i:int = 0; i<tagData.length; i++)
				text += uint(tagData[i]).toString(16)+" ";

			trace(text);
			//*/

			tagData.position = 0;

			return tagData;
		}

		CONFIG::LOGGING
		{
			private var logger:Logger = Log.getLogger('org.denivip.osmf.net.httpstreaming.hls.HTTPStreamingMp3Audio2ToPESAudio') as Logger;
		}
	}
}

/*
 * Copyright
 * hangulee@gmail.com
 *
 */

 package org.denivip.osmf.net.httpstreaming.hls
{
	import __AS3__.vec.Vector;

	import org.osmf.logging.Logger;
	import org.osmf.logging.Log;

	import flash.utils.ByteArray;

	import org.osmf.net.httpstreaming.flv.FLVTagAudio;

	internal class HTTPStreamingMp3Audio2ToPESAudio extends HTTPStreamingMP2PESBase
	{
		private var _state:int;
		private var _haveNewTimestamp:Boolean = false;
		private var _audioTime:Number;
		private var _audioTimeIncr:Number;

		private var _frameLength:int;
		private var _remaining:int;
		private var _audioData:ByteArray;

		private var _version:int;
		private var _layer:int;
		private var _bitRate:int;
		private var _sampleRate:int;
		private var _padding:int;
		private var _channel:int;

		public function HTTPStreamingMp3Audio2ToPESAudio():void
		{
			_state = 0;
		}

		private static const MPEG1:int  = 0x03;
		private static const MPEG2:int  = 0x02;
		private static const MPEG25:int = 0x01;

		private static const LAYER_1:int = 0x03;
		private static const LAYER_2:int = 0x02;
		private static const LAYER_3:int = 0x01;

		private var BITREATE_MAP_FOR_MPEG1_LAYER1:Array = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0];
		private var BITREATE_MAP_FOR_MPEG1_LAYER2:Array = [0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, 0];
		private var BITREATE_MAP_FOR_MPEG1_LAYER3:Array = [0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 0];
		private var BITREATE_MAP_FOR_MPEG2_LAYER1:Array = [0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256, 0];
		private var BITREATE_MAP_FOR_MPEG2_LAYER2:Array = [0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, 0]; // LAYER3 is same

		private var SAMPLERATE_MAP_FOR_MPEG1:Array  = [44100, 48000, 32000, 0];
		private var SAMPLERATE_MAP_FOR_MPEG2:Array  = [22050, 24000, 16000, 0];
		private var SAMPLERATE_MAP_FOR_MPEG25:Array = [11025, 12000,  8000, 0];

		private function GetBitRate(version:int, layer:int, index:int):int
		{
			if (version == MPEG1) {
				if (layer == LAYER_1) {
					return BITREATE_MAP_FOR_MPEG1_LAYER1[index];
				}
				else if (layer == LAYER_2) {
					return BITREATE_MAP_FOR_MPEG1_LAYER2[index];
				}
				else if (layer == LAYER_3) {
					return BITREATE_MAP_FOR_MPEG1_LAYER3[index];
				}
			}
			else if (version == MPEG2) {
				if (layer == LAYER_1) {
					return BITREATE_MAP_FOR_MPEG2_LAYER1[index];
				}
				else if (layer == LAYER_2 || layer == LAYER_3) {
					return BITREATE_MAP_FOR_MPEG2_LAYER2[index];
				}
			}
			return 0;
		}

		private function GetSampleRate(version:int, no:int):int
		{
			if (version == MPEG1) {
				return SAMPLERATE_MAP_FOR_MPEG1[no];
			} else if (version == MPEG2) {
				return SAMPLERATE_MAP_FOR_MPEG2[no];
			} else if (version == MPEG25) {
				return SAMPLERATE_MAP_FOR_MPEG25[no];
			}

			return 0;
		}

		override public function processES(pusi:Boolean, packet:ByteArray, flush:Boolean = false): ByteArray {
			if(pusi)
			{
				// start of a new PES packet

				// Start code prefix and packet ID.

				value = packet.readUnsignedInt();
				packet.position -= 4;
				if(packet.readUnsignedInt() != 0x1c0)
				{
						throw new Error("PES start code not found or not ~");
				}
				// Ignore packet length and marker bits.
				packet.position += 3;
				// need PTS only
				var flags:uint = (packet.readUnsignedByte() & 0xc0) >> 6;
				if(flags != 0x02 && flags != 0x03)
				{
					throw new Error("No PTS in this audio PES packet");
				}

				var length:uint = packet.readUnsignedByte();

				var pts:Number =
					((packet.readUnsignedByte() & 0x0e) << 29) +
					((packet.readUnsignedShort() & 0xfffe) << 14) +
					((packet.readUnsignedShort() & 0xfffe) >> 1);

				var timestamp:Number = Math.round(pts/90);
				_haveNewTimestamp = true;

				if(!_timestampReseted){
					_offset += timestamp - _prevTimestamp;
				}
				_timestamp = _initialTimestamp + _offset;
				_prevTimestamp = timestamp;
				_timestampReseted = false;

				length -= 5;
				// no comp time for audio
				// Skip other header data.
				packet.position += length;
			}

			var value:uint;

			var tag:FLVTagAudio;
			var tagData:ByteArray = new ByteArray();

			if(!flush)
			{
				var dStart:uint = packet.position;
			}

			if(flush)
			{
				trace("audio flush at state "+_state.toString());
			}
			else while(packet.bytesAvailable > 0)
			{
				if(_state < 7)
				{
					value = packet.readUnsignedByte();
				}

				switch(_state)
				{
					case 0: // first 0x01
						if(_haveNewTimestamp)
						{
							_audioTime = _timestamp;
							_haveNewTimestamp = false;
						}

						if(value == 0xff)
						{
							_state = 1;
						}
						break;
					case 1:
						if (value & 0xe0 == 0xe0) { // 1110 0000

							_version = ((value >> 3) & 0x03);
							_layer = ((value >> 1) & 0x03);
							var crc:int = (value & 0x01);

							_state = 2;
						} else {
							_state = 0;
						}
						break;
					case 2:
						var bitrateIndex:int = ((value >> 4) & 0x0f);
						var sampleRate:int = ((value >> 2) & 0x03);
						_padding = ((value >> 1) & 0x01);
						var bit:int = ((value & 0x01));

						_state = 3;

						_bitRate = GetBitRate(_version, _layer, bitrateIndex);
						if (_bitRate == 0) {
							_state = 0;
						}

						_sampleRate = GetSampleRate(_version, sampleRate);
						//_audioTimeIncr = 1024000.0 / _sampleRate;
						_audioTimeIncr = 144 * 8 * 1000 / _sampleRate;

						if (_sampleRate == 0) {
							_state = 0;
						}

						break;
					case 3:
						_channel = ((value >>6) & 0x03);
						var modeExt:int = ((value >> 4) & 0x03);
						var copyright:int = ((value >> 3) & 0x01);
						var original:int = ((value >> 2) & 0x01);
						var emphasis:int = (value & 0x03);

						_frameLength = int((144 * _bitRate * 1000 / _sampleRate ) + _padding);

						packet.position -= 4

						dStart = packet.position;
						_audioData = new ByteArray();
						_remaining = _frameLength;

						_state = 4;
						break;
					case 4:
						var avail:int = packet.length - dStart;

						if(avail >= _remaining)
						{
							_audioData.writeBytes(packet, dStart, _remaining);
							packet.position += _remaining - 1;
							_remaining = 0;
						}
						else if(avail > 0)
						{
							_audioData.writeBytes(packet, dStart, avail);
							packet.position += avail;
							_remaining -= avail;
						}

						if(_remaining > 0)
						{
							//
						}
						else
						{
							tag = new FLVTagAudio();
							tag.timestamp = _audioTime;
							_audioTime += _audioTimeIncr;
							tag.soundChannels = (_channel == 0x03 ? FLVTagAudio.SOUND_CHANNELS_MONO : FLVTagAudio.SOUND_CHANNELS_STEREO);
							tag.soundFormat = FLVTagAudio.SOUND_FORMAT_MP3;
							tag.soundRate = FLVTagAudio.SOUND_RATE_44K; // rather than what is reported
							tag.soundSize = FLVTagAudio.SOUND_SIZE_16BITS;

							_state = 0;

							tag.data = _audioData;

							tag.write(tagData); // unrolled out the vector for audio tags
						}
						break;
				} // switch
			} // while

			tagData.position = 0;

			return tagData;
		}

		CONFIG::LOGGING
		{
			private var logger:Logger = Log.getLogger('org.denivip.osmf.net.httpstreaming.hls.HTTPStreamingMp3Audio2ToPESAudio') as Logger;
		}
	}
}

Update HTTPStreamingMp3Audio2ToPESAudio.as


package htmlelements
{
	import flash.display.Sprite;
	import flash.events.*;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.media.Video;
	import flash.media.SoundTransform;
	import flash.utils.Timer;

	import FlashMediaElement;
	import HtmlMediaEvent;

	public class VideoElement extends Sprite implements IMediaElement
	{
		private var _currentUrl:String = "";
		private var _autoplay:Boolean = true;
		private var _preload:String = "";
		private var _isPreloading:Boolean = false;

		private var _connection:NetConnection;
		private var _stream:NetStream;
		private var _video:Video;
		private var _element:FlashMediaElement;
		private var _soundTransform;
		private var _oldVolume:Number = 1;

		// event values
		private var _duration:Number = 0;
		private var _framerate:Number;
		private var _isPaused:Boolean = true;
		private var _isEnded:Boolean = false;
		private var _volume:Number = 1;
		private var _isMuted:Boolean = false;

		private var _bytesLoaded:Number = 0;
		private var _bytesTotal:Number = 0;
		private var _bufferedTime:Number = 0;
		private var _bufferEmpty:Boolean = false;

		private var _videoWidth:Number = -1;
		private var _videoHeight:Number = -1;

		private var _timer:Timer;

		private var _isRTMP:Boolean = false;
		private var _isConnected:Boolean = false;
		private var _playWhenConnected:Boolean = false;
		private var _hasStartedPlaying:Boolean = false;

		private var _parentReference:Object;

		public function setReference(arg:Object):void {
			_parentReference = arg;
		}

		public function get video():Video {
			return _video;
		}

		public function get videoHeight():Number {
			return _videoHeight;
		}

		public function get videoWidth():Number {
			return _videoWidth;
		}

		public function duration():Number {
			return _duration;
		}

		public function currentProgress():Number {
			if(_stream != null) {
				return Math.round(_stream.bytesLoaded/_stream.bytesTotal*100);
			} else {
				return 0;
			}
		}

		public function currentTime():Number {
			if (_stream != null) {
				return _stream.time;
			} else {
				return 0;
			}
		}

		// (1) load()
		// calls _connection.connect();
		// waits for NetConnection.Connect.Success
		// _stream gets created

		public function VideoElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number)
		{
			_element = element;
			_autoplay = autoplay;
			_volume = startVolume;
			_preload = preload;

			_video = new Video();
			addChild(_video);

			_connection = new NetConnection();
			_connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			_connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			//_connection.connect(null);

			_timer = new Timer(timerRate);
			_timer.addEventListener("timer", timerHandler);

		}

		private function timerHandler(e:TimerEvent) {

			_bytesLoaded = _stream.bytesLoaded;
			_bytesTotal = _stream.bytesTotal;

			if (!_isPaused)
				sendEvent(HtmlMediaEvent.TIMEUPDATE);

			//trace("bytes", _bytesLoaded, _bytesTotal);

			if (_bytesLoaded < _bytesTotal)
				sendEvent(HtmlMediaEvent.PROGRESS);
		}

		// internal events
		private function netStatusHandler(event:NetStatusEvent):void {
			trace("netStatus", event.info.code);

			switch (event.info.code) {

				case "NetStream.Buffer.Empty":
					_bufferEmpty = true;
					_isEnded ? sendEvent(HtmlMediaEvent.ENDED) : null;
					break;

				case "NetStream.Buffer.Full":
					_bytesLoaded = _stream.bytesLoaded;
					_bytesTotal = _stream.bytesTotal;
					_bufferEmpty = false;

					sendEvent(HtmlMediaEvent.PROGRESS);
					break;

				case "NetConnection.Connect.Success":
					connectStream();
					break;
				case "NetStream.Play.StreamNotFound":
					trace("Unable to locate video");
					break;

				// STREAM
				case "NetStream.Play.Start":

					_isPaused = false;
					sendEvent(HtmlMediaEvent.LOADEDDATA);
					sendEvent(HtmlMediaEvent.CANPLAY);

					if (!_isPreloading) {

						sendEvent(HtmlMediaEvent.PLAY);
						sendEvent(HtmlMediaEvent.PLAYING);

					}

					_timer.start();

					break;

				case "NetStream.Seek.Notify":
					sendEvent(HtmlMediaEvent.SEEKED);
					break;

				case "NetStream.Pause.Notify":
					_isPaused = true;
					sendEvent(HtmlMediaEvent.PAUSE);
					break;

				case "NetStream.Play.Stop":
					_isEnded = true;
					_isPaused = false;
					_timer.stop();
					_bufferEmpty ? sendEvent(HtmlMediaEvent.ENDED) : null;
					break;

			}
		}

		private function securityErrorHandler(event:SecurityErrorEvent):void {
			trace("securityErrorHandler: " + event);
		}

		private function asyncErrorHandler(event:AsyncErrorEvent):void {
			// ignore AsyncErrorEvent events.
		}

		private function onMetaDataHandler(info:Object):void {
			_duration = info.duration;
			_framerate = info.framerate;
			_videoWidth = info.width;
			_videoHeight = info.height;

			// set size?

			sendEvent(HtmlMediaEvent.LOADEDMETADATA);

			if (_isPreloading) {

				_stream.pause();
				_isPaused = true;
				_isPreloading = false;

				sendEvent(HtmlMediaEvent.PROGRESS);
				sendEvent(HtmlMediaEvent.TIMEUPDATE);

			}
		}

		// interface members
		public function setSrc(url:String):void {
			if (_isConnected && _stream) {
				// stop and restart
				_stream.pause();
			}

			_currentUrl = url;
			_isRTMP = !!_currentUrl.match(/^rtmp(s|t|e|te)?\:\/\//);
			_isConnected = false;
			_hasStartedPlaying = false;
		}

		public function load():void {
			// disconnect existing stream and connection
			if (_isConnected && _stream) {
				_stream.pause();
				_stream.close();
				_connection.close();
			}
			_isConnected = false;
			_isPreloading = false;

			// start new connection
			if (_isRTMP) {
				_connection.connect(_currentUrl.replace(/\/[^\/]+$/,"/"));
			} else {
				_connection.connect(null);
			}

			// in a few moments the "NetConnection.Connect.Success" event will fire
			// and call createConnection which finishes the "load" sequence
			sendEvent(HtmlMediaEvent.LOADSTART);
		}

		private function connectStream():void {
			trace("connectStream");
			_stream = new NetStream(_connection);

			// explicitly set the sound since it could have come before the connection was made
			_soundTransform = new SoundTransform(_volume);
			_stream.soundTransform = _soundTransform;

			_stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); // same event as connection
			_stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);

			var customClient:Object = new Object();
			customClient.onMetaData = onMetaDataHandler;
			_stream.client = customClient;

			_video.attachNetStream(_stream);

			// start downloading without playing )based on preload and play() hasn't been called)
			// I wish flash had a load() command to make this less awkward
			if (_preload != "none" && !_playWhenConnected) {
				_isPaused = true;
				//stream.bufferTime = 20;
				_stream.play(_currentUrl, 0, 0);
				_stream.pause();

				_isPreloading = true;

				//_stream.pause();
				//
				//sendEvent(HtmlMediaEvent.PAUSE); // have to send this because the "playing" event gets sent via event handlers
			}

			_isConnected = true;

			if (_playWhenConnected && !_hasStartedPlaying) {
				play();
				_playWhenConnected = false;
			}

		}

		public function play():void {

			if (!_hasStartedPlaying && !_isConnected) {
				_playWhenConnected = true;
				load();
				return;
			}

			if (_hasStartedPlaying) {
				if (_isPaused) {
					_stream.resume();
					_timer.start();
					_isPaused = false;
					sendEvent(HtmlMediaEvent.PLAY);
					sendEvent(HtmlMediaEvent.PLAYING);
				}
			} else {

				if (_isRTMP) {
					_stream.play(_currentUrl.split("/").pop());
				} else {
					_stream.play(_currentUrl);
				}
				_timer.start();
				_isPaused = false;
				_hasStartedPlaying = true;

				// don't toss play/playing events here, because we haven't sent a
				// canplay / loadeddata event yet. that'll be handled in the net
				// event listener
			}

		}

		public function pause():void {
			if (_stream == null)
				return;

			_stream.pause();
			_isPaused = true;

			if (_bytesLoaded == _bytesTotal) {
				_timer.stop();
			}

			_isPaused = true;
			sendEvent(HtmlMediaEvent.PAUSE);
		}

		public function stop():void {
			if (_stream == null)
				return;

			_stream.close();
			_isPaused = false;
			_timer.stop();
			sendEvent(HtmlMediaEvent.STOP);
		}

		public function setCurrentTime(pos:Number):void {
			if (_stream == null)
				return;

			sendEvent(HtmlMediaEvent.SEEKING);
			_stream.seek(pos);
			sendEvent(HtmlMediaEvent.TIMEUPDATE);
		}

		public function setVolume(volume:Number):void {
			if (_stream != null) {
				_soundTransform = new SoundTransform(volume);
				_stream.soundTransform = _soundTransform;
			}

			_volume = volume;

			_isMuted = (_volume == 0);

			sendEvent(HtmlMediaEvent.VOLUMECHANGE);
		}

		public function getVolume():Number {
			if(_isMuted) {
				return 0;
			} else {
				return _volume;
			}
		}

		public function setMuted(muted:Boolean):void {

			if (_isMuted == muted)
				return;

			if (muted) {
				_oldVolume = (_stream == null) ? _oldVolume : _stream.soundTransform.volume;
				setVolume(0);
			} else {
				setVolume(_oldVolume);
			}

			_isMuted = muted;
		}

		private function sendEvent(eventName:String) {

			// calculate this to mimic HTML5
			_bufferedTime = _bytesLoaded / _bytesTotal * _duration;

			// build JSON
			var values:String =
							"duration:" + _duration +
							",framerate:" + _framerate +
							",currentTime:" + (_stream != null ? _stream.time : 0) +
							",muted:" + _isMuted +
							",paused:" + _isPaused +
							",ended:" + _isEnded +
							",volume:" + _volume +
							",src:\"" + _currentUrl + "\"" +
							",bytesTotal:" + _bytesTotal +
							",bufferedBytes:" + _bytesLoaded +
							",bufferedTime:" + _bufferedTime +
							",videoWidth:" + _videoWidth +
							",videoHeight:" + _videoHeight +
							"";

			_element.sendEvent(eventName, values);
		}
	}
}

package htmlelements
{
	import flash.display.Sprite;
	import flash.events.*;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.media.Video;
	import flash.media.SoundTransform;
	import flash.utils.Timer;

	import FlashMediaElement;
	import HtmlMediaEvent;

	public class VideoElement extends Sprite implements IMediaElement
	{
		private var _currentUrl:String = "";
		private var _autoplay:Boolean = true;
		private var _preload:String = "";
		private var _isPreloading:Boolean = false;

		private var _connection:NetConnection;
		private var _stream:NetStream;
		private var _video:Video;
		private var _element:FlashMediaElement;
		private var _soundTransform;
		private var _oldVolume:Number = 1;

		// event values
		private var _duration:Number = 0;
		private var _framerate:Number;
		private var _isPaused:Boolean = true;
		private var _isEnded:Boolean = false;
		private var _volume:Number = 1;
		private var _isMuted:Boolean = false;

		private var _bytesLoaded:Number = 0;
		private var _bytesTotal:Number = 0;
		private var _bufferedTime:Number = 0;
		private var _bufferEmpty:Boolean = false;

		private var _videoWidth:Number = -1;
		private var _videoHeight:Number = -1;

		private var _timer:Timer;

		private var _isRTMP:Boolean = false;
		private var _isConnected:Boolean = false;
		private var _playWhenConnected:Boolean = false;
		private var _hasStartedPlaying:Boolean = false;

		private var _parentReference:Object;

		public function setReference(arg:Object):void {
			_parentReference = arg;
		}

		public function get video():Video {
			return _video;
		}

		public function get videoHeight():Number {
			return _videoHeight;
		}

		public function get videoWidth():Number {
			return _videoWidth;
		}

		public function duration():Number {
			return _duration;
		}

		public function currentProgress():Number {
			if(_stream != null) {
				return Math.round(_stream.bytesLoaded/_stream.bytesTotal*100);
			} else {
				return 0;
			}
		}

		public function currentTime():Number {
			if (_stream != null) {
				return _stream.time;
			} else {
				return 0;
			}
		}

		// (1) load()
		// calls _connection.connect();
		// waits for NetConnection.Connect.Success
		// _stream gets created

		public function VideoElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number)
		{
			_element = element;
			_autoplay = autoplay;
			_volume = startVolume;
			_preload = preload;

			_video = new Video();
			addChild(_video);

			_connection = new NetConnection();
			_connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			_connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			//_connection.connect(null);

			_timer = new Timer(timerRate);
			_timer.addEventListener("timer", timerHandler);

		}

		private function timerHandler(e:TimerEvent) {

			_bytesLoaded = _stream.bytesLoaded;
			_bytesTotal = _stream.bytesTotal;

			if (!_isPaused)
				sendEvent(HtmlMediaEvent.TIMEUPDATE);

			//trace("bytes", _bytesLoaded, _bytesTotal);

			if (_bytesLoaded < _bytesTotal)
				sendEvent(HtmlMediaEvent.PROGRESS);
		}

		// internal events
		private function netStatusHandler(event:NetStatusEvent):void {
			trace("netStatus", event.info.code);

			switch (event.info.code) {

				case "NetStream.Buffer.Empty":
					_bufferEmpty = true;
					_isEnded ? sendEvent(HtmlMediaEvent.ENDED) : null;
					break;

				case "NetStream.Buffer.Full":
					_bytesLoaded = _stream.bytesLoaded;
					_bytesTotal = _stream.bytesTotal;
					_bufferEmpty = false;

					sendEvent(HtmlMediaEvent.PROGRESS);
					break;

				case "NetConnection.Connect.Success":
					connectStream();
					break;
				case "NetStream.Play.StreamNotFound":
					trace("Unable to locate video");
					break;

				// STREAM
				case "NetStream.Play.Start":

					_isPaused = false;
					sendEvent(HtmlMediaEvent.LOADEDDATA);
					sendEvent(HtmlMediaEvent.CANPLAY);

					if (!_isPreloading) {

						sendEvent(HtmlMediaEvent.PLAY);
						sendEvent(HtmlMediaEvent.PLAYING);

					}

					_timer.start();

					break;

				case "NetStream.Seek.Notify":
					sendEvent(HtmlMediaEvent.SEEKED);
					break;

				case "NetStream.Pause.Notify":
					_isPaused = true;
					sendEvent(HtmlMediaEvent.PAUSE);
					break;

				case "NetStream.Play.Stop":
					_isEnded = true;
					_isPaused = false;
					_timer.stop();
					_bufferEmpty ? sendEvent(HtmlMediaEvent.ENDED) : null;
					break;

			}
		}

		private function securityErrorHandler(event:SecurityErrorEvent):void {
			trace("securityErrorHandler: " + event);
		}

		private function asyncErrorHandler(event:AsyncErrorEvent):void {
			// ignore AsyncErrorEvent events.
		}

		private function onMetaDataHandler(info:Object):void {
			_duration = info.duration;
			_framerate = info.framerate;
			_videoWidth = info.width;
			_videoHeight = info.height;

			// set size?

			sendEvent(HtmlMediaEvent.LOADEDMETADATA);

			if (_isPreloading) {

				_stream.pause();
				_isPaused = true;
				_isPreloading = false;

				sendEvent(HtmlMediaEvent.PROGRESS);
				sendEvent(HtmlMediaEvent.TIMEUPDATE);

			}
		}

		// interface members
		public function setSrc(url:String):void {
			if (_isConnected && _stream) {
				// stop and restart
				_stream.pause();
			}

			_currentUrl = url;
			_isRTMP = !!_currentUrl.match(/^rtmp(s|t|e|te)?\:\/\//);
			_isConnected = false;
			_hasStartedPlaying = false;
		}

		public function load():void {
			// disconnect existing stream and connection
			if (_isConnected && _stream) {
				_stream.pause();
				_stream.close();
				_connection.close();
			}
			_isConnected = false;
			_isPreloading = false;

			_isEnded = false;
			_bufferEmpty = false;

			// start new connection
			if (_isRTMP) {
				_connection.connect(_currentUrl.replace(/\/[^\/]+$/,"/"));
			} else {
				_connection.connect(null);
			}

			// in a few moments the "NetConnection.Connect.Success" event will fire
			// and call createConnection which finishes the "load" sequence
			sendEvent(HtmlMediaEvent.LOADSTART);
		}

		private function connectStream():void {
			trace("connectStream");
			_stream = new NetStream(_connection);

			// explicitly set the sound since it could have come before the connection was made
			_soundTransform = new SoundTransform(_volume);
			_stream.soundTransform = _soundTransform;

			_stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); // same event as connection
			_stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);

			var customClient:Object = new Object();
			customClient.onMetaData = onMetaDataHandler;
			_stream.client = customClient;

			_video.attachNetStream(_stream);

			// start downloading without playing )based on preload and play() hasn't been called)
			// I wish flash had a load() command to make this less awkward
			if (_preload != "none" && !_playWhenConnected) {
				_isPaused = true;
				//stream.bufferTime = 20;
				_stream.play(_currentUrl, 0, 0);
				_stream.pause();

				_isPreloading = true;

				//_stream.pause();
				//
				//sendEvent(HtmlMediaEvent.PAUSE); // have to send this because the "playing" event gets sent via event handlers
			}

			_isConnected = true;

			if (_playWhenConnected && !_hasStartedPlaying) {
				play();
				_playWhenConnected = false;
			}

		}

		public function play():void {

			if (!_hasStartedPlaying && !_isConnected) {
				_playWhenConnected = true;
				load();
				return;
			}

			if (_hasStartedPlaying) {
				if (_isPaused) {
					_stream.resume();
					_timer.start();
					_isPaused = false;
					sendEvent(HtmlMediaEvent.PLAY);
					sendEvent(HtmlMediaEvent.PLAYING);
				}
			} else {

				if (_isRTMP) {
					_stream.play(_currentUrl.split("/").pop());
				} else {
					_stream.play(_currentUrl);
				}
				_timer.start();
				_isPaused = false;
				_hasStartedPlaying = true;

				// don't toss play/playing events here, because we haven't sent a
				// canplay / loadeddata event yet. that'll be handled in the net
				// event listener
			}

		}

		public function pause():void {
			if (_stream == null)
				return;

			_stream.pause();
			_isPaused = true;

			if (_bytesLoaded == _bytesTotal) {
				_timer.stop();
			}

			_isPaused = true;
			sendEvent(HtmlMediaEvent.PAUSE);
		}

		public function stop():void {
			if (_stream == null)
				return;

			_stream.close();
			_isPaused = false;
			_timer.stop();
			sendEvent(HtmlMediaEvent.STOP);
		}

		public function setCurrentTime(pos:Number):void {
			if (_stream == null)
				return;

			sendEvent(HtmlMediaEvent.SEEKING);
			_stream.seek(pos);
			sendEvent(HtmlMediaEvent.TIMEUPDATE);
		}

		public function setVolume(volume:Number):void {
			if (_stream != null) {
				_soundTransform = new SoundTransform(volume);
				_stream.soundTransform = _soundTransform;
			}

			_volume = volume;

			_isMuted = (_volume == 0);

			sendEvent(HtmlMediaEvent.VOLUMECHANGE);
		}

		public function getVolume():Number {
			if(_isMuted) {
				return 0;
			} else {
				return _volume;
			}
		}

		public function setMuted(muted:Boolean):void {

			if (_isMuted == muted)
				return;

			if (muted) {
				_oldVolume = (_stream == null) ? _oldVolume : _stream.soundTransform.volume;
				setVolume(0);
			} else {
				setVolume(_oldVolume);
			}

			_isMuted = muted;
		}

		private function sendEvent(eventName:String) {

			// calculate this to mimic HTML5
			_bufferedTime = _bytesLoaded / _bytesTotal * _duration;

			// build JSON
			var values:String =
							"duration:" + _duration +
							",framerate:" + _framerate +
							",currentTime:" + (_stream != null ? _stream.time : 0) +
							",muted:" + _isMuted +
							",paused:" + _isPaused +
							",ended:" + _isEnded +
							",volume:" + _volume +
							",src:\"" + _currentUrl + "\"" +
							",bytesTotal:" + _bytesTotal +
							",bufferedBytes:" + _bytesLoaded +
							",bufferedTime:" + _bufferedTime +
							",videoWidth:" + _videoWidth +
							",videoHeight:" + _videoHeight +
							"";

			_element.sendEvent(eventName, values);
		}
	}
}

reset variables upon load

reset variables upon load