////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.core.BeadViewBase;
	import org.apache.flex.core.IBead;
    import org.apache.flex.core.IBeadLayout;
	import org.apache.flex.core.IBeadView;
	import org.apache.flex.core.ILayoutParent;
    import org.apache.flex.core.IParentIUIBase;
	import org.apache.flex.core.IStrand;
    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;
	import org.apache.flex.html.Container;
	import org.apache.flex.html.supportClasses.Border;
	import org.apache.flex.html.supportClasses.ContainerContentArea;
	import org.apache.flex.html.supportClasses.ScrollBar;

    /**
     *  The ContainerView class is the default view for
     *  the org.apache.flex.html.Container class.
     *  It lets you use some CSS styles to manage the border, background
     *  and padding around the content area.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class ContainerView extends BeadViewBase implements IBeadView, ILayoutParent
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function ContainerView()
		{
		}

        /**
         *  The actual parent that parents the children.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var actualParent:UIBase;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;

            var host:UIBase = value as UIBase;

            if (_strand.getBeadByType(IBeadLayout) == null)
            {
                var c:Class = ValuesManager.valuesImpl.getValue(host, "iBeadLayout");
                if (c)
                {
                    var layout:IBeadLayout = new c() as IBeadLayout;
                    _strand.addBead(layout);
                }
            }

            if (host.isWidthSizedToContent() && host.isHeightSizedToContent())
            {
                host.addEventListener("childrenAdded", changeHandler);
                checkActualParent();
            }
            else
            {
                host.addEventListener("widthChanged", changeHandler);
                host.addEventListener("heightChanged", changeHandler);
                host.addEventListener("sizeChanged", sizeChangeHandler);
                if (!isNaN(host.explicitWidth) && !isNaN(host.explicitHeight))
                    sizeChangeHandler(null);
                else
                    checkActualParent();
            }
        }

        private function checkActualParent():Boolean
        {
            var host:UIBase = UIBase(_strand);
            if (contentAreaNeeded())
            {
                if (actualParent == null || actualParent == host)
                {
                    actualParent = new ContainerContentArea();
                    host.addElement(actualParent);
                    Container(host).setActualParent(actualParent);
                }
                return true;
            }
            else
            {
                actualParent = host;
            }
            return false;
        }

        private function sizeChangeHandler(event:Event):void
        {
            var host:UIBase = UIBase(_strand);
            host.addEventListener("childrenAdded", changeHandler);
            host.addEventListener("layoutNeeded", changeHandler);
            changeHandler(event);
        }

        private var inChangeHandler:Boolean;

        /**
         *  React if the size changed or content changed
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        protected function changeHandler(event:Event):void
        {
            if (inChangeHandler) return;

            inChangeHandler = true;

            var host:UIBase = UIBase(_strand);

			var padding:Object = determinePadding();

			if (checkActualParent())
			{
				actualParent.x = padding.paddingLeft;
				actualParent.y = padding.paddingTop;
                var pb:Number = padding.paddingBottom;
                if (isNaN(pb))
                    pb = 0;
                var pr:Number = padding.paddingRight;
                if (isNaN(pr))
                    pr = 0;
                if (!isNaN(host.explicitWidth) || !isNaN(host.percentWidth))
                    actualParent.setWidth(host.width - padding.paddingLeft - pr);
                else
                    host.dispatchEvent(new Event("widthChanged"));

                if (!isNaN(host.explicitHeight) || !isNaN(host.percentHeight))
                    actualParent.setHeight(host.height - padding.paddingTop - pb);
                else
                    host.dispatchEvent(new Event("heightChanged"));
			}

			var backgroundColor:Object = ValuesManager.valuesImpl.getValue(host, "background-color");
			var backgroundImage:Object = ValuesManager.valuesImpl.getValue(host, "background-image");
			if (backgroundColor != null || backgroundImage != null)
			{
				if (host.getBeadByType(IBackgroundBead) == null)
                    host.addBead(new (ValuesManager.valuesImpl.getValue(host, "iBackgroundBead")) as IBead);
			}

			var borderStyle:String;
			var borderStyles:Object = ValuesManager.valuesImpl.getValue(host, "border");
			if (borderStyles is Array)
			{
				borderStyle = borderStyles[1];
			}
			if (borderStyle == null)
			{
				borderStyle = ValuesManager.valuesImpl.getValue(host, "border-style") as String;
			}
			if (borderStyle != null && borderStyle != "none")
			{
				if (host.getBeadByType(IBorderBead) == null)
                    host.addBead(new (ValuesManager.valuesImpl.getValue(host, "iBorderBead")) as IBead);
			}

            inChangeHandler = false;
		}

		/**
		 *  Determines the top and left padding values, if any, as set by
		 *  padding style values. This includes "padding" for all padding values
		 *  as well as "padding-left" and "padding-top".
		 *
		 *  Returns an object with paddingLeft and paddingTop properties.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		protected function determinePadding():Object
		{
			var paddingLeft:Object;
			var paddingTop:Object;
			var padding:Object = ValuesManager.valuesImpl.getValue(_strand, "padding");
			if (padding is Array)
			{
				if (padding.length == 1)
					paddingLeft = paddingTop = padding[0];
				else if (padding.length <= 3)
				{
					paddingLeft = padding[1];
					paddingTop = padding[0];
				}
				else if (padding.length == 4)
				{
					paddingLeft = padding[3];
					paddingTop = padding[0];
				}
			}
			else if (padding == null)
			{
				paddingLeft = ValuesManager.valuesImpl.getValue(_strand, "padding-left");
				paddingTop = ValuesManager.valuesImpl.getValue(_strand, "padding-top");
			}
			else
			{
				paddingLeft = paddingTop = padding;
			}
			var pl:Number = Number(paddingLeft);
			var pt:Number = Number(paddingTop);

			return {paddingLeft:pl, paddingTop:pt};
		}

		/**
		 *  Returns true if container to create a separate ContainerContentArea.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		protected function contentAreaNeeded():Boolean
		{
			var padding:Object = determinePadding();

			return (!isNaN(padding.paddingLeft) && padding.paddingLeft > 0 ||
				    !isNaN(padding.paddingTop) && padding.paddingTop > 0);
		}

        /**
         *  The parent of the children.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get contentView():IParentIUIBase
		{
			return actualParent;
		}

        /**
         *  The host component, which can resize to different slots.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get resizableView():IUIBase
		{
			return _strand as IUIBase;
		}

	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.core.BeadViewBase;
	import org.apache.flex.core.IBead;
    import org.apache.flex.core.IBeadLayout;
	import org.apache.flex.core.IBeadView;
	import org.apache.flex.core.ILayoutParent;
    import org.apache.flex.core.IParentIUIBase;
	import org.apache.flex.core.IStrand;
    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;
	import org.apache.flex.html.Container;
	import org.apache.flex.html.supportClasses.Border;
	import org.apache.flex.html.supportClasses.ContainerContentArea;
	import org.apache.flex.html.supportClasses.ScrollBar;

    /**
     *  The ContainerView class is the default view for
     *  the org.apache.flex.html.Container class.
     *  It lets you use some CSS styles to manage the border, background
     *  and padding around the content area.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class ContainerView extends BeadViewBase implements IBeadView, ILayoutParent
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function ContainerView()
		{
		}

        /**
         *  The actual parent that parents the children.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var actualParent:UIBase;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;

            var host:UIBase = value as UIBase;

            if (host.isWidthSizedToContent() && host.isHeightSizedToContent())
            {
                host.addEventListener("childrenAdded", changeHandler);
                checkActualParent();
            }
            else
            {
                host.addEventListener("widthChanged", changeHandler);
                host.addEventListener("heightChanged", changeHandler);
                host.addEventListener("sizeChanged", sizeChangeHandler);
                if (!isNaN(host.explicitWidth) && !isNaN(host.explicitHeight))
                    sizeChangeHandler(null);
                else
                    checkActualParent();
            }

            if (_strand.getBeadByType(IBeadLayout) == null)
            {
                var c:Class = ValuesManager.valuesImpl.getValue(host, "iBeadLayout");
                if (c)
                {
                    var layout:IBeadLayout = new c() as IBeadLayout;
                    _strand.addBead(layout);
                }
            }
        }

        private function checkActualParent():Boolean
        {
            var host:UIBase = UIBase(_strand);
            if (contentAreaNeeded())
            {
                if (actualParent == null || actualParent == host)
                {
                    actualParent = new ContainerContentArea();
                    host.addElement(actualParent);
                    Container(host).setActualParent(actualParent);
                }
                return true;
            }
            else
            {
                actualParent = host;
            }
            return false;
        }

        private function sizeChangeHandler(event:Event):void
        {
            var host:UIBase = UIBase(_strand);
            host.addEventListener("childrenAdded", changeHandler);
            host.addEventListener("layoutNeeded", changeHandler);
            changeHandler(event);
        }

        private var inChangeHandler:Boolean;

        /**
         *  React if the size changed or content changed
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        protected function changeHandler(event:Event):void
        {
            if (inChangeHandler) return;

            inChangeHandler = true;

            var host:UIBase = UIBase(_strand);

			var padding:Object = determinePadding();

			if (checkActualParent())
			{
				actualParent.x = padding.paddingLeft;
				actualParent.y = padding.paddingTop;
                var pb:Number = padding.paddingBottom;
                if (isNaN(pb))
                    pb = 0;
                var pr:Number = padding.paddingRight;
                if (isNaN(pr))
                    pr = 0;
                if (!isNaN(host.explicitWidth) || !isNaN(host.percentWidth))
                    actualParent.setWidth(host.width - padding.paddingLeft - pr);
                else
                    host.dispatchEvent(new Event("widthChanged"));

                if (!isNaN(host.explicitHeight) || !isNaN(host.percentHeight))
                    actualParent.setHeight(host.height - padding.paddingTop - pb);
                else
                    host.dispatchEvent(new Event("heightChanged"));
			}

			var backgroundColor:Object = ValuesManager.valuesImpl.getValue(host, "background-color");
			var backgroundImage:Object = ValuesManager.valuesImpl.getValue(host, "background-image");
			if (backgroundColor != null || backgroundImage != null)
			{
				if (host.getBeadByType(IBackgroundBead) == null)
                    host.addBead(new (ValuesManager.valuesImpl.getValue(host, "iBackgroundBead")) as IBead);
			}

			var borderStyle:String;
			var borderStyles:Object = ValuesManager.valuesImpl.getValue(host, "border");
			if (borderStyles is Array)
			{
				borderStyle = borderStyles[1];
			}
			if (borderStyle == null)
			{
				borderStyle = ValuesManager.valuesImpl.getValue(host, "border-style") as String;
			}
			if (borderStyle != null && borderStyle != "none")
			{
				if (host.getBeadByType(IBorderBead) == null)
                    host.addBead(new (ValuesManager.valuesImpl.getValue(host, "iBorderBead")) as IBead);
			}

            inChangeHandler = false;
		}

		/**
		 *  Determines the top and left padding values, if any, as set by
		 *  padding style values. This includes "padding" for all padding values
		 *  as well as "padding-left" and "padding-top".
		 *
		 *  Returns an object with paddingLeft and paddingTop properties.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		protected function determinePadding():Object
		{
			var paddingLeft:Object;
			var paddingTop:Object;
			var padding:Object = ValuesManager.valuesImpl.getValue(_strand, "padding");
			if (padding is Array)
			{
				if (padding.length == 1)
					paddingLeft = paddingTop = padding[0];
				else if (padding.length <= 3)
				{
					paddingLeft = padding[1];
					paddingTop = padding[0];
				}
				else if (padding.length == 4)
				{
					paddingLeft = padding[3];
					paddingTop = padding[0];
				}
			}
			else if (padding == null)
			{
				paddingLeft = ValuesManager.valuesImpl.getValue(_strand, "padding-left");
				paddingTop = ValuesManager.valuesImpl.getValue(_strand, "padding-top");
			}
			else
			{
				paddingLeft = paddingTop = padding;
			}
			var pl:Number = Number(paddingLeft);
			var pt:Number = Number(paddingTop);

			return {paddingLeft:pl, paddingTop:pt};
		}

		/**
		 *  Returns true if container to create a separate ContainerContentArea.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		protected function contentAreaNeeded():Boolean
		{
			var padding:Object = determinePadding();

			return (!isNaN(padding.paddingLeft) && padding.paddingLeft > 0 ||
				    !isNaN(padding.paddingTop) && padding.paddingTop > 0);
		}

        /**
         *  The parent of the children.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get contentView():IParentIUIBase
		{
			return actualParent;
		}

        /**
         *  The host component, which can resize to different slots.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get resizableView():IUIBase
		{
			return _strand as IUIBase;
		}

	}
}

move when beads attached so that containerview can resize contentarea before layout


package com.mangui.HLS.streaming {

    import com.mangui.HLS.*;
    import com.mangui.HLS.muxing.*;
    import com.mangui.HLS.streaming.*;
    import com.mangui.HLS.parsing.*;
    import com.mangui.HLS.utils.*;

    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;

    /** Class that keeps the buffer filled. **/
    public class Buffer {
        /** Reference to the framework controller. **/
        private var _hls:HLS;
        /** The buffer with video tags. **/
        private var _buffer:Vector.<Tag>;
        /** NetConnection legacy stuff. **/
        private var _connection:NetConnection;
        /** The fragment loader. **/
        private var _loader:Loader;
        /** Store that a fragment load is in progress. **/
        private var _loading:Boolean;
        /** Interval for checking buffer and position. **/
        private var _interval:Number;
        /** Next loading fragment sequence number. **/
        /** The start position of the stream. **/
        public var PlaybackStartPosition:Number = 0;
         /** start play time **/
        private var _playback_start_time:Number;
        /** playback start PTS. **/
        private var _playback_start_pts:Number;
        /** playlist start PTS when playback started. **/
        private var _playlist_start_pts:Number;
        /** Current play position (relative position from beginning of sliding window) **/
        private var _playback_current_position:Number;
        /** buffer last PTS. **/
        private var _buffer_last_pts:Number;
         /** next buffer time. **/
        private var _buffer_next_time:Number;
         /** previous buffer time. **/
        private var _last_buffer:Number;
        /** Current playback state. **/
        private var _state:String;
        /** Netstream instance used for playing the stream. **/
        private var _stream:NetStream;
        /** The last tag that was appended to the buffer. **/
        private var _tag:Number;
        /** soundtransform object. **/
        private var _transform:SoundTransform;
        /** Reference to the video object. **/
        private var _video:Object;

        /** Create the buffer. **/
        public function Buffer(hls:HLS, loader:Loader, video:Object):void {
            _hls = hls;
            _loader = loader;
            _video = video;
            _hls.addEventListener(HLSEvent.MANIFEST,_manifestHandler);
            _connection = new NetConnection();
            _connection.connect(null);
            _transform = new SoundTransform();
            _transform.volume = 0.9;
            _setState(HLSStates.IDLE);
        };

        /** Check the bufferlength. **/
        private function _checkBuffer():void {
            var reachedend:Boolean = false;
            var buffer:Number = 0;
            // Calculate the buffer and position.
            if(_buffer.length) {
               buffer = (_buffer_last_pts - _playback_start_pts)/1000 - _stream.time;
               /** Current play time (time since beginning of playback) **/
               var playback_current_time:Number = (Math.round(_stream.time*100 + _playback_start_time*100)/100);
               var playliststartpts:Number = _loader.getPlayListStartPTS();
               var play_position:Number;
               if(playliststartpts < 0) {
                  play_position = 0;
               } else {
                  play_position = playback_current_time -(playliststartpts-_playlist_start_pts)/1000;
                }
               if(play_position != _playback_current_position || buffer !=_last_buffer) {
                  if (play_position <0) {
                     play_position = 0;
                  }
                  _playback_current_position = play_position;
                  _last_buffer = buffer;
                  _hls.dispatchEvent(new HLSEvent(HLSEvent.MEDIA_TIME,{ position:_playback_current_position, buffer:buffer, duration:_loader.getPlayListDuration()}));
               }
            }

            // Load new tags from fragment.
            if(buffer < _loader.getBufferLength() && !_loading) {
               var loadstatus:Number = _loader.loadfragment(_buffer_next_time,_buffer_last_pts,buffer,_loaderCallback,(_buffer.length == 0));
               if (loadstatus == 0) {
                  // good, new fragment being loaded
                  _loading = true;
               } else  if (loadstatus < 0) {
                  /* it means PTS requested is smaller than playlist start PTS.
                     it could happen on live playlist :
                     - if bandwidth available is lower than lowest quality needed bandwidth
                     - after long pause
                     seek to offset 0 to force a restart of the playback session  */
                  Log.txt("long pause on live stream or bad network quality");
                  seek(0);
                  return;
               } else if(loadstatus > 0) {
                  //seqnum not available in playlist
                  if (_hls.getType() == HLSTypes.VOD) {
                     // if VOD playlist, it means we reached the end, on live playlist do nothing and wait ...
                     reachedend = true;
                  }
               }
            }
            // Append tags to buffer.
            if((_state == HLSStates.PLAYING && _stream.bufferLength < _loader.getSegmentMaxDuration()) ||
               (_state == HLSStates.BUFFERING && buffer > _loader.getSegmentMaxDuration()))
             {
                //Log.txt("appending data");
                while(_tag < _buffer.length && _stream.bufferLength < 2*_loader.getSegmentMaxDuration()) {
                    try {
                        _stream.appendBytes(_buffer[_tag].data);
                    } catch (error:Error) {
                        _errorHandler(new Error(_buffer[_tag].type+": "+ error.message));
                    }
                    // Last tag done? Then append sequence end.
                    if (reachedend ==true && _tag == _buffer.length - 1) {
                        _stream.appendBytesAction(NetStreamAppendBytesAction.END_SEQUENCE);
                        _stream.appendBytes(new ByteArray());
                    }
                    _tag++;
                }
            }
            // Set playback state and complete.
            if(_stream.bufferLength < 3) {
                if(reachedend ==true) {
                    if(_stream.bufferLength == 0) {
                        _complete();
                    }
                } else if(_state == HLSStates.PLAYING) {
                    _setState(HLSStates.BUFFERING);
                }
            } else if (_state == HLSStates.BUFFERING) {
                _setState(HLSStates.PLAYING);
            }
        };

        /** The video completed playback. **/
        private function _complete():void {
            _setState(HLSStates.IDLE);
            clearInterval(_interval);
            // _stream.pause();
            _hls.dispatchEvent(new HLSEvent(HLSEvent.COMPLETE));
        };

        /** Dispatch an error to the controller. **/
        private function _errorHandler(error:Error):void {
            _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,error.toString()));
        };

        /** Return the current playback state. **/
        public function getPosition():Number {
            return _playback_current_position;
        };

        /** Return the current playback state. **/
        public function getState():String {
            return _state;
        };

        /** Add a fragment to the buffer. **/
        private function _loaderCallback(tags:Vector.<Tag>,min_pts:Number,max_pts:Number):void {
            _buffer = _buffer.slice(_tag);
            _tag = 0;
            if (_playback_start_pts == 0) {
               _playback_start_pts = min_pts;
               _playlist_start_pts = _loader.getPlayListStartPTS();
               _playback_start_time = (_playback_start_pts-_playlist_start_pts)/1000;
            }
            _buffer_last_pts = max_pts;
            tags.sort(_sortTagsbyDTS);
            for each (var t:Tag in tags) {
               _buffer.push(t);
            }
            _buffer_next_time=_playback_start_time+(_buffer_last_pts-_playback_start_pts)/1000;
            Log.txt("_loaderCallback,_buffer_next_time:"+ _buffer_next_time);
            _loading = false;
        };

        /** Start streaming on manifest load. **/
        private function _manifestHandler(event:HLSEvent):void {
            if(_state == HLSStates.IDLE) {
                _stream = new NetStream(_connection);
                _video.attachNetStream(_stream);
                _stream.play(null);
                _stream.soundTransform = _transform;
                _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
                _stream.appendBytes(FLV.getHeader());
                seek(PlaybackStartPosition);
            }
        };

        /** Toggle playback. **/
        public function pause():void {
            clearInterval(_interval);
            if(_state == HLSStates.PAUSED) {
                _setState(HLSStates.BUFFERING);
                _stream.resume();
                _interval = setInterval(_checkBuffer,100);
            } else if(_state == HLSStates.PLAYING) {
                _setState(HLSStates.PAUSED);
                _stream.pause();
            }
        };

        /** Change playback state. **/
        private function _setState(state:String):void {
            if(state != _state) {
                _state = state;
                _hls.dispatchEvent(new HLSEvent(HLSEvent.STATE,_state));
            }
        };

        /** Sort the buffer by tag. **/
        private function _sortTagsbyDTS(x:Tag,y:Tag):Number {
            if(x.dts < y.dts) {
                return -1;
            } else if (x.dts > y.dts) {
                return 1;
            } else {
                if(x.type == Tag.AVC_HEADER || x.type == Tag.AAC_HEADER) {
                    return -1;
                } else if (y.type == Tag.AVC_HEADER || y.type == Tag.AAC_HEADER) {
                    return 1;
                } else {
                    if(x.type == Tag.AVC_NALU) {
                        return -1;
                    } else if (y.type == Tag.AVC_NALU) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        };

        /** Start playing data in the buffer. **/
        public function seek(position:Number):void {
               _buffer = new Vector.<Tag>();
               _loader.clearLoader();
               _loading = false;
               _tag = 0;
                PlaybackStartPosition = position;
               _stream.seek(0);
               _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
               _playback_start_time = position;
               _playback_start_pts = 0;
               _buffer_next_time = _playback_start_time;
               _buffer_last_pts = 0;
               _last_buffer = 0;
               _setState(HLSStates.BUFFERING);
               clearInterval(_interval);
               _interval = setInterval(_checkBuffer,100);
        };

        /** Stop playback. **/
        public function stop():void {
            if(_stream) {
                _stream.pause();
            }
            _loading = false;
            clearInterval(_interval);
            _setState(HLSStates.IDLE);
        };

        /** Change the volume (set in the NetStream). **/
        public function volume(percent:Number):void {
            _transform.volume = percent/100;
            if(_stream) {
                _stream.soundTransform = _transform;
            }
        };

    }

}

package com.mangui.HLS.streaming {

    import com.mangui.HLS.*;
    import com.mangui.HLS.muxing.*;
    import com.mangui.HLS.streaming.*;
    import com.mangui.HLS.parsing.*;
    import com.mangui.HLS.utils.*;

    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;

    /** Class that keeps the buffer filled. **/
    public class Buffer {
        /** Reference to the framework controller. **/
        private var _hls:HLS;
        /** The buffer with video tags. **/
        private var _buffer:Vector.<Tag>;
        /** NetConnection legacy stuff. **/
        private var _connection:NetConnection;
        /** The fragment loader. **/
        private var _loader:Loader;
        /** Store that a fragment load is in progress. **/
        private var _loading:Boolean;
        /** Interval for checking buffer and position. **/
        private var _interval:Number;
        /** Next loading fragment sequence number. **/
        /** The start position of the stream. **/
        public var PlaybackStartPosition:Number = 0;
         /** start play time **/
        private var _playback_start_time:Number;
        /** playback start PTS. **/
        private var _playback_start_pts:Number;
        /** playlist start PTS when playback started. **/
        private var _playlist_start_pts:Number;
        /** Current play position (relative position from beginning of sliding window) **/
        private var _playback_current_position:Number;
        /** buffer last PTS. **/
        private var _buffer_last_pts:Number;
         /** next buffer time. **/
        private var _buffer_next_time:Number;
         /** previous buffer time. **/
        private var _last_buffer:Number;
        /** Current playback state. **/
        private var _state:String;
        /** Netstream instance used for playing the stream. **/
        private var _stream:NetStream;
        /** The last tag that was appended to the buffer. **/
        private var _tag:Number;
        /** soundtransform object. **/
        private var _transform:SoundTransform;
        /** Reference to the video object. **/
        private var _video:Object;

        /** Create the buffer. **/
        public function Buffer(hls:HLS, loader:Loader, video:Object):void {
            _hls = hls;
            _loader = loader;
            _video = video;
            _hls.addEventListener(HLSEvent.MANIFEST,_manifestHandler);
            _connection = new NetConnection();
            _connection.connect(null);
            _transform = new SoundTransform();
            _transform.volume = 0.9;
            _setState(HLSStates.IDLE);
        };

        /** Check the bufferlength. **/
        private function _checkBuffer():void {
            var reachedend:Boolean = false;
            var buffer:Number = 0;
            // Calculate the buffer and position.
            if(_buffer.length) {
               buffer = (_buffer_last_pts - _playback_start_pts)/1000 - _stream.time;
               /** Current play time (time since beginning of playback) **/
               var playback_current_time:Number = (Math.round(_stream.time*100 + _playback_start_time*100)/100);
               var current_playlist_start_pts:Number = _loader.getPlayListStartPTS();
               var play_position:Number;
               if(current_playlist_start_pts < 0) {
                  play_position = 0;
               } else {
                  play_position = playback_current_time -(current_playlist_start_pts-_playlist_start_pts)/1000;
                }
               if(play_position != _playback_current_position || buffer !=_last_buffer) {
                  if (play_position <0) {
                     play_position = 0;
                  }
                  _playback_current_position = play_position;
                  _last_buffer = buffer;
                  _hls.dispatchEvent(new HLSEvent(HLSEvent.MEDIA_TIME,{ position:_playback_current_position, buffer:buffer, duration:_loader.getPlayListDuration()}));
               }
            }

            // Load new tags from fragment.
            if(buffer < _loader.getBufferLength() && !_loading) {
               var loadstatus:Number = _loader.loadfragment(_buffer_next_time,_buffer_last_pts,buffer,_loaderCallback,(_buffer.length == 0));
               if (loadstatus == 0) {
                  // good, new fragment being loaded
                  _loading = true;
               } else  if (loadstatus < 0) {
                  /* it means PTS requested is smaller than playlist start PTS.
                     it could happen on live playlist :
                     - if bandwidth available is lower than lowest quality needed bandwidth
                     - after long pause
                     seek to offset 0 to force a restart of the playback session  */
                  Log.txt("long pause on live stream or bad network quality");
                  seek(0);
                  return;
               } else if(loadstatus > 0) {
                  //seqnum not available in playlist
                  if (_hls.getType() == HLSTypes.VOD) {
                     // if VOD playlist, it means we reached the end, on live playlist do nothing and wait ...
                     reachedend = true;
                  }
               }
            }
            // Append tags to buffer.
            if((_state == HLSStates.PLAYING && _stream.bufferLength < _loader.getSegmentMaxDuration()) ||
               (_state == HLSStates.BUFFERING && buffer > _loader.getSegmentMaxDuration()))
             {
                //Log.txt("appending data");
                while(_tag < _buffer.length && _stream.bufferLength < 2*_loader.getSegmentMaxDuration()) {
                    try {
                        _stream.appendBytes(_buffer[_tag].data);
                    } catch (error:Error) {
                        _errorHandler(new Error(_buffer[_tag].type+": "+ error.message));
                    }
                    // Last tag done? Then append sequence end.
                    if (reachedend ==true && _tag == _buffer.length - 1) {
                        _stream.appendBytesAction(NetStreamAppendBytesAction.END_SEQUENCE);
                        _stream.appendBytes(new ByteArray());
                    }
                    _tag++;
                }
            }
            // Set playback state and complete.
            if(_stream.bufferLength < 3) {
                if(reachedend ==true) {
                    if(_stream.bufferLength == 0) {
                        _complete();
                    }
                } else if(_state == HLSStates.PLAYING) {
                    _setState(HLSStates.BUFFERING);
                }
            } else if (_state == HLSStates.BUFFERING) {
                _setState(HLSStates.PLAYING);
            }
        };

        /** The video completed playback. **/
        private function _complete():void {
            _setState(HLSStates.IDLE);
            clearInterval(_interval);
            // _stream.pause();
            _hls.dispatchEvent(new HLSEvent(HLSEvent.COMPLETE));
        };

        /** Dispatch an error to the controller. **/
        private function _errorHandler(error:Error):void {
            _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,error.toString()));
        };

        /** Return the current playback state. **/
        public function getPosition():Number {
            return _playback_current_position;
        };

        /** Return the current playback state. **/
        public function getState():String {
            return _state;
        };

        /** Add a fragment to the buffer. **/
        private function _loaderCallback(tags:Vector.<Tag>,min_pts:Number,max_pts:Number):void {
            _buffer = _buffer.slice(_tag);
            _tag = 0;
            if (_playback_start_pts == 0) {
               _playback_start_pts = min_pts;
               _playlist_start_pts = _loader.getPlayListStartPTS();
               _playback_start_time = (_playback_start_pts-_playlist_start_pts)/1000;
            }
            _buffer_last_pts = max_pts;
            tags.sort(_sortTagsbyDTS);
            for each (var t:Tag in tags) {
               _buffer.push(t);
            }
            _buffer_next_time=_playback_start_time+(_buffer_last_pts-_playback_start_pts)/1000;
            Log.txt("_loaderCallback,_buffer_next_time:"+ _buffer_next_time);
            _loading = false;
        };

        /** Start streaming on manifest load. **/
        private function _manifestHandler(event:HLSEvent):void {
            if(_state == HLSStates.IDLE) {
                _stream = new NetStream(_connection);
                _video.attachNetStream(_stream);
                _stream.play(null);
                _stream.soundTransform = _transform;
                _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
                _stream.appendBytes(FLV.getHeader());
                seek(PlaybackStartPosition);
            }
        };

        /** Toggle playback. **/
        public function pause():void {
            clearInterval(_interval);
            if(_state == HLSStates.PAUSED) {
                _setState(HLSStates.BUFFERING);
                _stream.resume();
                _interval = setInterval(_checkBuffer,100);
            } else if(_state == HLSStates.PLAYING) {
                _setState(HLSStates.PAUSED);
                _stream.pause();
            }
        };

        /** Change playback state. **/
        private function _setState(state:String):void {
            if(state != _state) {
                _state = state;
                _hls.dispatchEvent(new HLSEvent(HLSEvent.STATE,_state));
            }
        };

        /** Sort the buffer by tag. **/
        private function _sortTagsbyDTS(x:Tag,y:Tag):Number {
            if(x.dts < y.dts) {
                return -1;
            } else if (x.dts > y.dts) {
                return 1;
            } else {
                if(x.type == Tag.AVC_HEADER || x.type == Tag.AAC_HEADER) {
                    return -1;
                } else if (y.type == Tag.AVC_HEADER || y.type == Tag.AAC_HEADER) {
                    return 1;
                } else {
                    if(x.type == Tag.AVC_NALU) {
                        return -1;
                    } else if (y.type == Tag.AVC_NALU) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        };

        /** Start playing data in the buffer. **/
        public function seek(position:Number):void {
               _buffer = new Vector.<Tag>();
               _loader.clearLoader();
               _loading = false;
               _tag = 0;
                PlaybackStartPosition = position;
               _stream.seek(0);
               _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
               _playback_start_pts = 0;
               _buffer_next_time = position;
               _buffer_last_pts = 0;
               _last_buffer = 0;
               _setState(HLSStates.BUFFERING);
               clearInterval(_interval);
               _interval = setInterval(_checkBuffer,100);
        };

        /** Stop playback. **/
        public function stop():void {
            if(_stream) {
                _stream.pause();
            }
            _loading = false;
            clearInterval(_interval);
            _setState(HLSStates.IDLE);
        };

        /** Change the volume (set in the NetStream). **/
        public function volume(percent:Number):void {
            _transform.volume = percent/100;
            if(_stream) {
                _stream.soundTransform = _transform;
            }
        };

    }

}

rename variable

rename variable


import mx.transitions.easing.*;
import com.mosesSupposes.fuse.*;

class com.segonquart.idiomesAnimation extends Movieclip
        {

  	private var arrayLang_arr:Array = new Array ("cat", "es", "en", "fr");

	function idiomesAnimation():Void
		{
			this.stop();
			this.onEnterFrame = this.enterSlide;

		}

	private function enterSlide()
                {

			arrayLang_arr[0].slideTo('0', '-40', 0.6, 'easeInOutBack', 1);
			arrayLang_arr[1].slideTo('0', '-40', 0.8, 'easeInOutBack', 1.1);
			arrayLang_arr[2].slideTo('0', '-40', 0.9, 'easeInOutBack', 1.2);
			arrayLang_arr[3].slideTo('0', '-40', 1, 'easeInOutBack', 1.3);

		}

	public function IdiomesColour()
		{

			this.onRelease = this arrayColour;

			target = this.arrayLang_arr[i];
			target._tint = 0x8DC60D;

			return this;

		}

	private function arrayColour()
		{

			for ( var:i:Number=0 ; arrayLang_arr[i].length <4; i++)
			{
				this.colorTo("#628D22", 0.3, "easeOutCirc");
				_parent.colorTo('#4b4b4b', 1, 'linear', .2);

			}

		}

	}

import mx.transitions.easing.*;
import com.mosesSupposes.fuse.*;

class com.segonquart.idiomesAnimation extends Movieclip
        {

  	private var arrayLang_arr:Array = new Array ("cat", "es", "en", "fr");

	public function idiomesAnimation()
		{
			this.stop();
			this.onEnterFrame = this.enterSlide;

		}

	private function enterSlide()
                {
			arrayLang_arr[0].slideTo('0', '-40', 0.6, 'easeInOutBack', 1);
			arrayLang_arr[1].slideTo('0', '-40', 0.8, 'easeInOutBack', 1.1);
			arrayLang_arr[2].slideTo('0', '-40', 0.9, 'easeInOutBack', 1.2);
			arrayLang_arr[3].slideTo('0', '-40', 1, 'easeInOutBack', 1.3);

		}

	public function IdiomesColour()
		{
			this.onRelease = this.arrayColour;

			target = this.arrayLang_arr[i];
			target._tint = 0x8DC60D;

			return this;

		}

	private function arrayColour()
		{

			for ( var:i:Number=0 ; arrayLang_arr[i].length <4; i++)
			{
				this.colorTo("#628D22", 0.3, "easeOutCirc");
				_parent.colorTo('#4b4b4b', 1, 'linear', .2);

			}

		}

	}

Update idiomesAnimation.as

Update idiomesAnimation.as


/*
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed 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 flash.display {
[native(cls='MovieClipClass')]
public dynamic class MovieClip extends Sprite {
  public function MovieClip() {}
  public native function get currentFrame():int;
  public native function get framesLoaded():int;
  public native function get totalFrames():int;
  public native function get trackAsMenu():Boolean;
  public native function set trackAsMenu(value:Boolean):void;
  public native function get scenes():Array;
  public native function get currentScene():Scene;
  public native function get currentLabel():String;
  public native function get currentFrameLabel():String;
  public function get currentLabels():Array {
    return currentScene.labels;
  }
  public native function get enabled():Boolean;
  public native function set enabled(value:Boolean):void;
  public native function get isPlaying():Boolean;
  public native function play():void;
  public native function stop():void;
  public native function nextFrame():void;
  public native function prevFrame():void;
  public native function gotoAndPlay(frame:Object, scene:String = null):void;
  public native function gotoAndStop(frame:Object, scene:String = null):void;
  public native function addFrameScript():void;
  public native function prevScene():void;
  public native function nextScene():void;
}
}

/*
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed 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 flash.display {
[native(cls='MovieClipClass')]
public dynamic class MovieClip extends Sprite {
  public native function MovieClip();
  public native function get currentFrame():int;
  public native function get framesLoaded():int;
  public native function get totalFrames():int;
  public native function get trackAsMenu():Boolean;
  public native function set trackAsMenu(value:Boolean):void;
  public native function get scenes():Array;
  public native function get currentScene():Scene;
  public native function get currentLabel():String;
  public native function get currentFrameLabel():String;
  public function get currentLabels():Array {
    return currentScene.labels;
  }
  public native function get enabled():Boolean;
  public native function set enabled(value:Boolean):void;
  public native function get isPlaying():Boolean;
  public native function play():void;
  public native function stop():void;
  public native function nextFrame():void;
  public native function prevFrame():void;
  public native function gotoAndPlay(frame:Object, scene:String = null):void;
  public native function gotoAndStop(frame:Object, scene:String = null):void;
  public native function addFrameScript():void;
  public native function prevScene():void;
  public native function nextScene():void;
}
}

Make the MovieClip constructor native

Make the MovieClip constructor native

No need to generate code for this: we already have the correct native ctor in place.


// This ActionScript file defines a list of values that are considered
// important for checking various ActionScript operations.
// It defines 2 variables:
// - "values": The array of values to be checked
// - "names": The array of corresponding string representations for values.
//            It's suggested to use these instead of using values directly to
//            avoid spurious toString and valueOf calls.

printall = new Object ();
printall.valueOf = function () {
  trace ("valueOf called");
  return this;
};
printall.toString = function () {
  trace ("toString called");
  return this;
};

printtostring = new Object ();
printtostring.toString = function () {
  trace ("toString called with " + arguments);
  return this;
};

printvalueof = new Object ();
printvalueof.valueOf = function () {
  trace ("valueOf called with " + arguments);
  return this;
};

nothing = new Object ();
nothing.__proto__ = undefined;
values = [
  undefined,
  null,
  true, false,
  0, 1, 0.5, -1, -0.5, Infinity, -Infinity, NaN,
  "", "0", "-0", "0.0", "1", "Hello World!", "true", "_level0",
  this, new Object (), Function, printall, printtostring, printvalueof, nothing ];

var l = values.length;
var v = function () {
  trace (this.nr + ": valueOf!");
  return this.v;
};
var s = function () {
  trace (this.nr + ": toString!");
  return this.v;
};
for (i = 0; i < l; i++) {
  var o = new Object ();
  o.nr = i;
  o.valueOf = v;
  o.toString = s;
  o.v = values[i];
  values.push (o);
};

names = [];
for (i = 0; i < values.length; i++) {
  names[i] = "(" + i + ") " + values[i] + " (" + typeof (values[i]) + ")";
};

// This ActionScript file defines a list of values that are considered
// important for checking various ActionScript operations.
// It defines 2 variables:
// - "values": The array of values to be checked
// - "names": The array of corresponding string representations for values.
//            It's suggested to use these instead of using values directly to
//            avoid spurious toString and valueOf calls.

printall = new Object ();
printall.valueOf = function () {
  trace ("valueOf called");
  return this;
};
printall.toString = function () {
  trace ("toString called");
  return this;
};

printtostring = new Object ();
printtostring.toString = function () {
  trace ("toString called with " + arguments);
  return this;
};

printvalueof = new Object ();
printvalueof.valueOf = function () {
  trace ("valueOf called with " + arguments);
  return this;
};

nothing = new Object ();
nothing.__proto__ = undefined;
values = [
  undefined,
  null,
  true, false,
  0, 1, 0.5, -1, -0.5, Infinity, -Infinity, NaN,
  "", "0", "-0", "0.0", "1", "Hello World!", "true", "_level0", "äöü",
  this, new Object (), Function, printall, printtostring, printvalueof, nothing ];

var l = values.length;
var v = function () {
  trace (this.nr + ": valueOf!");
  return this.v;
};
var s = function () {
  trace (this.nr + ": toString!");
  return this.v;
};
for (i = 0; i < l; i++) {
  var o = new Object ();
  o.nr = i;
  o.valueOf = v;
  o.toString = s;
  o.v = values[i];
  values.push (o);
};

names = [];
for (i = 0; i < values.length; i++) {
  names[i] = "(" + i + ") " + values[i] + " (" + typeof (values[i]) + ")";
};

include a UTF-8 string in values.as

include a UTF-8 string in values.as


////////////////////////////////////////////////////////////////////////////////
//
//  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.layouts
{
	import org.apache.flex.core.IBeadLayout;
	import org.apache.flex.core.IContainer;
	import org.apache.flex.core.IMeasurementBead;
	import org.apache.flex.core.IStrand;
	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;
	import org.apache.flex.utils.CSSUtils;

	/**
	 * ColumnLayout is a class that organizes the positioning of children
	 * of a container into a set of columns where each column's width is set to
	 * the maximum size of all of the children in that column.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class VerticalColumnLayout implements IBeadLayout
	{
		/**
		 *  constructor
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function VerticalColumnLayout()
		{
		}

		private 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;
		}

		private var _numColumns:int;

		/**
		 * The number of columns.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get numColumns():int
		{
			return _numColumns;
		}
		public function set numColumns(value:int):void
		{
			_numColumns = value;
		}

        /**
         * @copy org.apache.flex.core.IBeadLayout#layout
         */
		public function layout():Boolean
		{
            var host:UIBase = UIBase(_strand);
			var sw:Number = host.width;
			var sh:Number = host.height;

			var e:IUIBase;
			var i:int;
			var col:int = 0;
			var columns:Array = [];
            var rows:Array = [];
            var data:Array = [];
			for (i = 0; i < numColumns; i++)
				columns[i] = 0;

            var marginLeft:Object;
            var marginRight:Object;
            var marginTop:Object;
            var marginBottom:Object;
            var margin:Object;
            var ml:Number;
            var mr:Number;
            var mt:Number;
            var mb:Number;
			var children:Array = IContainer(_strand).getChildren();
			var n:int = children.length;
            var rowData:Object = { rowHeight: 0 };

			// determine max widths of columns
			for (i = 0; i < n; i++) {
				e = children[i];
                margin = ValuesManager.valuesImpl.getValue(e, "margin");
                marginLeft = ValuesManager.valuesImpl.getValue(e, "margin-left");
                marginTop = ValuesManager.valuesImpl.getValue(e, "margin-top");
                marginRight = ValuesManager.valuesImpl.getValue(e, "margin-right");
                marginBottom = ValuesManager.valuesImpl.getValue(e, "margin-bottom");
                mt = CSSUtils.getTopValue(marginTop, margin, sh);
                mb = CSSUtils.getBottomValue(marginBottom, margin, sh);
                mr = CSSUtils.getRightValue(marginRight, margin, sw);
                ml = CSSUtils.getLeftValue(marginLeft, margin, sw);
                data.push({ mt: mt, mb: mb, mr: mr, ml: ml});
				var thisPrefWidth:int = 0;
				if (e is IStrand)
				{
					var measure:IMeasurementBead = e.getBeadByType(IMeasurementBead) as IMeasurementBead;
					if (measure)
						thisPrefWidth = measure.measuredWidth + ml + mr;
					else
						thisPrefWidth = e.width + ml + mr;
				}
				else
					thisPrefWidth = e.width + ml + mr;

                rowData.rowHeight = Math.max(rowData.rowHeight, e.height + mt + mb);
				columns[col] = Math.max(columns[col], thisPrefWidth);
                col = col + 1;
                if (col == numColumns)
                {
                    rows.push(rowData);
                    rowData = {rowHeight: 0};
                    col = 0;
                }
			}

            var lastmb:Number = 0;
			var curx:int = 0;
			var cury:int = 0;
			var maxHeight:int = 0;
			col = 0;
			for (i = 0; i < n; i++)
            {
				e = children[i];
				e.x = curx + ml;
				e.y = cury + data[i].mt;
				curx += columns[col++];
                maxHeight = Math.max(maxHeight, e.y + e.height + data[i].mb);
				if (col == numColumns)
				{
					cury += rows[0].rowHeight;
                    rows.shift();
					col = 0;
					curx = 0;
				}
			}

			return true;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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.layouts
{
	import org.apache.flex.core.IBeadLayout;
	import org.apache.flex.core.IContainer;
	import org.apache.flex.core.IMeasurementBead;
	import org.apache.flex.core.IStrand;
	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;
	import org.apache.flex.utils.CSSUtils;

	/**
	 * ColumnLayout is a class that organizes the positioning of children
	 * of a container into a set of columns where each column's width is set to
	 * the maximum size of all of the children in that column.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class VerticalColumnLayout implements IBeadLayout
	{
		/**
		 *  constructor
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function VerticalColumnLayout()
		{
		}

		private 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;
		}

		private var _numColumns:int;

		/**
		 * The number of columns.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get numColumns():int
		{
			return _numColumns;
		}
		public function set numColumns(value:int):void
		{
			_numColumns = value;
		}

        private var lastWidth:Number = 0;
        private var lastHeight:Number = 0;

        /**
         * @copy org.apache.flex.core.IBeadLayout#layout
         */
		public function layout():Boolean
		{
            var host:UIBase = UIBase(_strand);
			var sw:Number = host.width;
			var sh:Number = host.height;

            var hostWidth:* = ValuesManager.valuesImpl.getValue(host, "width");
            var hasWidth:Boolean = (hostWidth !== undefined) && hostWidth != lastWidth;
            var hostHeight:* = ValuesManager.valuesImpl.getValue(host, "height");
            var hasHeight:Boolean = (hostHeight !== undefined) && hostHeight != lastHeight;
			var e:IUIBase;
			var i:int;
			var col:int = 0;
			var columns:Array = [];
            var rows:Array = [];
            var data:Array = [];
			for (i = 0; i < numColumns; i++)
				columns[i] = 0;

            var marginLeft:Object;
            var marginRight:Object;
            var marginTop:Object;
            var marginBottom:Object;
            var margin:Object;
            var ml:Number;
            var mr:Number;
            var mt:Number;
            var mb:Number;
			var children:Array = IContainer(_strand).getChildren();
			var n:int = children.length;
            var rowData:Object = { rowHeight: 0 };

			// determine max widths of columns
			for (i = 0; i < n; i++) {
				e = children[i];
                margin = ValuesManager.valuesImpl.getValue(e, "margin");
                marginLeft = ValuesManager.valuesImpl.getValue(e, "margin-left");
                marginTop = ValuesManager.valuesImpl.getValue(e, "margin-top");
                marginRight = ValuesManager.valuesImpl.getValue(e, "margin-right");
                marginBottom = ValuesManager.valuesImpl.getValue(e, "margin-bottom");
                mt = CSSUtils.getTopValue(marginTop, margin, sh);
                mb = CSSUtils.getBottomValue(marginBottom, margin, sh);
                mr = CSSUtils.getRightValue(marginRight, margin, sw);
                ml = CSSUtils.getLeftValue(marginLeft, margin, sw);
                data.push({ mt: mt, mb: mb, mr: mr, ml: ml});
				var thisPrefWidth:int = 0;
				if (e is IStrand)
				{
					var measure:IMeasurementBead = e.getBeadByType(IMeasurementBead) as IMeasurementBead;
					if (measure)
						thisPrefWidth = measure.measuredWidth + ml + mr;
					else
						thisPrefWidth = e.width + ml + mr;
				}
				else
					thisPrefWidth = e.width + ml + mr;

                rowData.rowHeight = Math.max(rowData.rowHeight, e.height + mt + mb);
				columns[col] = Math.max(columns[col], thisPrefWidth);
                col = col + 1;
                if (col == numColumns)
                {
                    rows.push(rowData);
                    rowData = {rowHeight: 0};
                    col = 0;
                }
			}

            var lastmb:Number = 0;
			var curx:int = 0;
			var cury:int = 0;
			var maxHeight:int = 0;
            var maxWidth:int = 0;
			col = 0;
			for (i = 0; i < n; i++)
            {
				e = children[i];
				e.x = curx + ml;
				e.y = cury + data[i].mt;
				curx += columns[col++];
                maxHeight = Math.max(maxHeight, e.y + e.height + data[i].mb);
                maxWidth = Math.max(maxWidth, e.x + e.width + data[i].mr);
				if (col == numColumns)
				{
					cury += rows[0].rowHeight;
                    rows.shift();
					col = 0;
					curx = 0;
				}
			}
			if (!hasWidth && n > 0 && !isNaN(maxWidth) &&
                (!(ValuesManager.valuesImpl.getValue(host, "left") !== undefined) &&
                  (ValuesManager.valuesImpl.getValue(host, "right") !== undefined)))
            {
                lastWidth = maxWidth;
                host.setWidth(maxWidth, true);
            }
            if (!hasHeight && n > 0 && !isNaN(maxHeight) &&
                (!(ValuesManager.valuesImpl.getValue(host, "top") !== undefined) &&
                    (ValuesManager.valuesImpl.getValue(host, "bottom") !== undefined)))
            {
                lastHeight = maxHeight;
                host.setHeight(maxHeight, true);
            }
			return true;
		}
	}
}

set width/height if not specified

set width/height if not specified


//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2009 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.io {

import flash.errors.IOError;
import flash.errors.MemoryError;

import flash.utils.ByteArray;
import flash.utils.IDataInput;

import com.threerings.util.ClassUtil;
import com.threerings.util.Log;
import com.threerings.util.Long;

public class ObjectInputStream
{
    /** Enables verbose object I/O debugging. */
    public static const DEBUG :Boolean = false;

    public static const log :Log = Log.getLog(ObjectInputStream);

    public function ObjectInputStream (source :IDataInput = null, clientProps :Object = null)
    {
        _source = source || new ByteArray();
        _cliProps = clientProps || {};
    }

    /**
     * Set a new source from which to read our data.
     */
    public function setSource (source :IDataInput) :void
    {
        _source = source;
    }

    /**
     * Return a "client property" with the specified name.
     * Actionscript only.
     */
    public function getClientProperty (name :String) :*
    {
        return _cliProps[name];
    }

    /**
     * Reads the next Object (or null) from the stream and returns it as * so that you may assign
     * to any variable without casting. It is strongly recommended that you pass a 'checkType'
     * parameter so that the type of the Object is verified to be what you believe it to be,
     * thus helping you detect streaming errors as quickly as possible.
     *
     * @param checkType optional type to check the read object against
     * @return the Object read, or null.
     * @throws TypeError if the object is read successfully but is the wrong type
     */
    public function readObject (checkType :Class = null) :*
        //throws IOError
    {
        var DEBUG_ID :String = "[" + (++_debugObjectCounter) + "] ";
        try {
            // read in the class code for this instance
            var code :int = readShort();

            // a zero code indicates a null value
            if (code == 0) {
                if (DEBUG) log.debug(DEBUG_ID + "Read null");
                return null;
            }

            var cmap :ClassMapping;

            // if the code is negative, that means we've never seen it
            // before and class metadata follows
            if (code < 0) {
                // first swap the code into positive land
                code *= -1;

                // read in the class metadata
                var jname :String = readUTF();
//                log.debug("read jname: " + jname);
                var streamer :Streamer = Streamer.getStreamerByJavaName(jname);
                if (streamer == null) {
                    log.warning("OMG, cannot stream " + jname);
                    return null;
                }
                if (DEBUG) log.debug(DEBUG_ID + "Got streamer (" + streamer + ")");

                cmap = new ClassMapping(code, streamer);
                _classMap[code] = cmap;
                if (DEBUG) log.debug(DEBUG_ID + "Created mapping: (" + code + "): " + jname);

            } else {
                cmap = (_classMap[code] as ClassMapping);
                if (null == cmap) {
                    throw new IOError("Read object for which we have no " +
                        "registered class metadata [code=" + code + "].");
                }
                if (DEBUG) {
                    log.debug(DEBUG_ID + "Read known code: (" + code + ": " +
                        cmap.streamer.getJavaClassName() + ")");
                }
            }

//            log.debug("Creating object sleeve...");
            var target :Object = cmap.streamer.createObject(this);
            //log.debug("Reading object...");
            readBareObjectImpl(target, cmap.streamer);
            if (DEBUG) log.debug(DEBUG_ID + "Read object: " + target);
            if (checkType != null && !(target is checkType)) {
                throw new TypeError(
                    "Cannot convert " + ClassUtil.getClass(target) + " to " + checkType);
            }
            return target;

        } catch (me :MemoryError) {
            throw new IOError("out of memory" + me.message);
        }
        return null; // not reached: compiler dumb
    }

    public function readBareObject (obj :Object) :void
        //throws IOError
    {
        readBareObjectImpl(obj, Streamer.getStreamer(obj));
    }

    public function readBareObjectImpl (obj :Object, streamer :Streamer) :void
    {
        _current = obj;
        _streamer = streamer;
        try {
            _streamer.readObject(obj, this);

        } finally {
            // clear out our current object references
            _current = null;
            _streamer = null;
        }
    }

    /**
     * Called to read an Object of a known final type into a Streamable object.
     *
     * @param type either a String representing the java type,
     *             or a Class object representing the actionscript type.
     */
    public function readField (type :Object) :Object
        //throws IOError
    {
        if (!readBoolean()) {
            return null;
        }

        var jname :String = type as String;
        if (type is Class) {
            jname = Translations.getToServer(ClassUtil.getClassName(type));
        }
        var streamer :Streamer = Streamer.getStreamerByJavaName(jname);
        if (streamer == null) {
            throw new Error("Cannot field stream " + type);
        }

        var obj :Object = streamer.createObject(this);
        readBareObjectImpl(obj, streamer);
        return obj;
    }

    public function defaultReadObject () :void
        //throws IOError
    {
        _streamer.readObject(_current, this);
    }

    public function readBoolean () :Boolean
        //throws IOError
    {
        return _source.readBoolean();
    }

    public function readByte () :int
        //throws IOError
    {
        return _source.readByte();
    }

    /**
     * Read bytes into the byte array. If length is not specified, then
     * enough bytes to fill the array (from the offset) are read.
     */
    public function readBytes (
        bytes :ByteArray, offset :uint = 0, length :uint = uint.MAX_VALUE) :void
        //throws IOError
    {
        // if no length specified then fill the ByteArray
        if (length == uint.MAX_VALUE) {
            length = bytes.length - offset;
        }
        // And, if we really want to read 0 bytes then just don't do anything, because an
        // IDataInput will read *all available bytes* when the specified length is 0.
        if (length > 0) {
            _source.readBytes(bytes, offset, length);
        }
    }

    public function readDouble () :Number
        //throws IOError
    {
        return _source.readDouble();
    }

    public function readFloat () :Number
        //throws IOError
    {
        return _source.readFloat();
    }

    public function readLong () :Long
    {
        const result :Long = new Long();
        readBareObject(result);
        return result;
    }

    public function readInt () :int
        //throws IOError
    {
        return _source.readInt();
    }

    public function readShort () :int
        //throws IOError
    {
        return _source.readShort();
    }

    public function readUTF () :String
        //throws IOError
    {
        return _source.readUTF();
    }

    /** Named "client properties" that we can provide to deserialized objects. */
    protected var _cliProps :Object;

    /** The target DataInput that we route input from. */
    protected var _source :IDataInput;

    /** The object currently being read from the stream. */
    protected var _current :Object;

    /** The stramer being used currently. */
    protected var _streamer :Streamer;

    /** A map of short class code to ClassMapping info. */
    protected var _classMap :Array = new Array();

    private static var _debugObjectCounter :int = 0;
}
}

//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2009 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.io {

import flash.errors.IOError;
import flash.errors.MemoryError;

import flash.utils.ByteArray;
import flash.utils.IDataInput;

import com.threerings.util.ClassUtil;
import com.threerings.util.Log;
import com.threerings.util.Long;

public class ObjectInputStream
{
    /** Enables verbose object I/O debugging. */
    public static const DEBUG :Boolean = false;

    public static const log :Log = Log.getLog(ObjectInputStream);

    public function ObjectInputStream (source :IDataInput = null, clientProps :Object = null)
    {
        _source = source || new ByteArray();
        _cliProps = clientProps || {};
    }

    /**
     * Set a new source from which to read our data.
     */
    public function setSource (source :IDataInput) :void
    {
        _source = source;
    }

    /**
     * Return a "client property" with the specified name.
     * Actionscript only.
     */
    public function getClientProperty (name :String) :*
    {
        return _cliProps[name];
    }

    /**
     * Reads the next Object (or null) from the stream and returns it as * so that you may assign
     * to any variable without casting. It is strongly recommended that you pass a 'checkType'
     * parameter so that the type of the Object is verified to be what you believe it to be,
     * thus helping you detect streaming errors as quickly as possible.
     *
     * @param checkType optional type to check the read object against
     * @return the Object read, or null.
     * @throws TypeError if the object is read successfully but is the wrong type
     *
     * @example
     * <listing version="3.0">
     *
     * public function readObject (ins :ObjectInputStream) :void
     * {
     *     _scoops = ins.readObject(Array);
     *     _coneType = ins.readObject(Cone);
     * }
     *
     * protected var _scoops :Array;
     * protected var _coneType :Cone;
     * </listing>
     */
    public function readObject (checkType :Class = null) :*
        //throws IOError
    {
        var DEBUG_ID :String = "[" + (++_debugObjectCounter) + "] ";
        try {
            // read in the class code for this instance
            var code :int = readShort();

            // a zero code indicates a null value
            if (code == 0) {
                if (DEBUG) log.debug(DEBUG_ID + "Read null");
                return null;
            }

            var cmap :ClassMapping;

            // if the code is negative, that means we've never seen it
            // before and class metadata follows
            if (code < 0) {
                // first swap the code into positive land
                code *= -1;

                // read in the class metadata
                var jname :String = readUTF();
//                log.debug("read jname: " + jname);
                var streamer :Streamer = Streamer.getStreamerByJavaName(jname);
                if (streamer == null) {
                    log.warning("OMG, cannot stream " + jname);
                    return null;
                }
                if (DEBUG) log.debug(DEBUG_ID + "Got streamer (" + streamer + ")");

                cmap = new ClassMapping(code, streamer);
                _classMap[code] = cmap;
                if (DEBUG) log.debug(DEBUG_ID + "Created mapping: (" + code + "): " + jname);

            } else {
                cmap = (_classMap[code] as ClassMapping);
                if (null == cmap) {
                    throw new IOError("Read object for which we have no " +
                        "registered class metadata [code=" + code + "].");
                }
                if (DEBUG) {
                    log.debug(DEBUG_ID + "Read known code: (" + code + ": " +
                        cmap.streamer.getJavaClassName() + ")");
                }
            }

//            log.debug("Creating object sleeve...");
            var target :Object = cmap.streamer.createObject(this);
            //log.debug("Reading object...");
            readBareObjectImpl(target, cmap.streamer);
            if (DEBUG) log.debug(DEBUG_ID + "Read object: " + target);
            if (checkType != null && !(target is checkType)) {
                throw new TypeError(
                    "Cannot convert " + ClassUtil.getClass(target) + " to " + checkType);
            }
            return target;

        } catch (me :MemoryError) {
            throw new IOError("out of memory" + me.message);
        }
        return null; // not reached: compiler dumb
    }

    public function readBareObject (obj :Object) :void
        //throws IOError
    {
        readBareObjectImpl(obj, Streamer.getStreamer(obj));
    }

    public function readBareObjectImpl (obj :Object, streamer :Streamer) :void
    {
        _current = obj;
        _streamer = streamer;
        try {
            _streamer.readObject(obj, this);

        } finally {
            // clear out our current object references
            _current = null;
            _streamer = null;
        }
    }

    /**
     * Called to read an Object of a known final type into a Streamable object.
     *
     * @param type either a String representing the java type,
     *             or a Class object representing the actionscript type.
     */
    public function readField (type :Object) :Object
        //throws IOError
    {
        if (!readBoolean()) {
            return null;
        }

        var jname :String = type as String;
        if (type is Class) {
            jname = Translations.getToServer(ClassUtil.getClassName(type));
        }
        var streamer :Streamer = Streamer.getStreamerByJavaName(jname);
        if (streamer == null) {
            throw new Error("Cannot field stream " + type);
        }

        var obj :Object = streamer.createObject(this);
        readBareObjectImpl(obj, streamer);
        return obj;
    }

    public function defaultReadObject () :void
        //throws IOError
    {
        _streamer.readObject(_current, this);
    }

    public function readBoolean () :Boolean
        //throws IOError
    {
        return _source.readBoolean();
    }

    public function readByte () :int
        //throws IOError
    {
        return _source.readByte();
    }

    /**
     * Read bytes into the byte array. If length is not specified, then
     * enough bytes to fill the array (from the offset) are read.
     */
    public function readBytes (
        bytes :ByteArray, offset :uint = 0, length :uint = uint.MAX_VALUE) :void
        //throws IOError
    {
        // if no length specified then fill the ByteArray
        if (length == uint.MAX_VALUE) {
            length = bytes.length - offset;
        }
        // And, if we really want to read 0 bytes then just don't do anything, because an
        // IDataInput will read *all available bytes* when the specified length is 0.
        if (length > 0) {
            _source.readBytes(bytes, offset, length);
        }
    }

    public function readDouble () :Number
        //throws IOError
    {
        return _source.readDouble();
    }

    public function readFloat () :Number
        //throws IOError
    {
        return _source.readFloat();
    }

    public function readLong () :Long
    {
        const result :Long = new Long();
        readBareObject(result);
        return result;
    }

    public function readInt () :int
        //throws IOError
    {
        return _source.readInt();
    }

    public function readShort () :int
        //throws IOError
    {
        return _source.readShort();
    }

    public function readUTF () :String
        //throws IOError
    {
        return _source.readUTF();
    }

    /** Named "client properties" that we can provide to deserialized objects. */
    protected var _cliProps :Object;

    /** The target DataInput that we route input from. */
    protected var _source :IDataInput;

    /** The object currently being read from the stream. */
    protected var _current :Object;

    /** The stramer being used currently. */
    protected var _streamer :Streamer;

    /** A map of short class code to ClassMapping info. */
    protected var _classMap :Array = new Array();

    private static var _debugObjectCounter :int = 0;
}
}

Add an example to the docs.

Add an example to the docs.

git-svn-id: a1a4b28b82a3276cc491891159dd9963a0a72fae@5986 542714f4-19e9-0310-aa3c-eee0fc999fb1


////////////////////////////////////////////////////////////////////////////////
//
//  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.layouts
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.geom.Rectangle;

	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IBorderModel;
	import org.apache.flex.core.IScrollBarModel;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.html.staticControls.beads.IListBead;
	import org.apache.flex.html.staticControls.supportClasses.Border;
	import org.apache.flex.html.staticControls.supportClasses.ScrollBar;

	public class NonVirtualVerticalScrollingLayout implements IBead
	{
		public function NonVirtualVerticalScrollingLayout()
		{
		}

		public var dataGroup:DisplayObjectContainer;

        private var border:Border;
        private var borderModel:IBorderModel
        private var vScrollBar:ScrollBar;
		private var listBead:IListBead;

		private var _strand:IStrand;

		public function set strand(value:IStrand):void
		{
			_strand = value;
			listBead = value as IListBead;
			dataGroup = listBead.dataGroup as DisplayObjectContainer;
            border = listBead.border;
            borderModel = border.model as IBorderModel;
			IEventDispatcher(listBead.strand).addEventListener("heightChanged", changeHandler);
			IEventDispatcher(listBead.strand).addEventListener("widthChanged", changeHandler);
			changeHandler(null);
		}

		private function changeHandler(event:Event):void
		{
            var ww:Number = DisplayObject(listBead.strand).width;
            var hh:Number = DisplayObject(listBead.strand).height;
            border.width = ww;
            border.height = hh;

			dataGroup.width = ww - borderModel.offsets.left - borderModel.offsets.right;
			dataGroup.height = hh - borderModel.offsets.top - borderModel.offsets.bottom;
            dataGroup.x = borderModel.offsets.left;
            dataGroup.y = borderModel.offsets.top;

			var n:int = dataGroup.numChildren;
			var yy:Number = 0;
			for (var i:int = 0; i < n; i++)
			{
				var ir:DisplayObject = dataGroup.getChildAt(i);
				ir.y = yy;
				ir.width = dataGroup.width;
				yy += ir.height;
			}
			if (yy > dataGroup.height)
			{
                vScrollBar = listBead.vScrollBar;
				dataGroup.width -= vScrollBar.width;
				IScrollBarModel(vScrollBar.model).maximum = yy;
				IScrollBarModel(vScrollBar.model).pageSize = dataGroup.height;
				IScrollBarModel(vScrollBar.model).pageStepSize = dataGroup.height;
				vScrollBar.visible = true;
				vScrollBar.height = dataGroup.height;
				vScrollBar.y = dataGroup.y;
				vScrollBar.x = dataGroup.width;
                var vpos:Number = IScrollBarModel(vScrollBar.model).value;
                dataGroup.scrollRect = new Rectangle(0, vpos, dataGroup.width, vpos + dataGroup.height);
                vScrollBar.addEventListener("scroll", scrollHandler);
			}
			else if (vScrollBar)
				vScrollBar.visible = false;
		}

        private function scrollHandler(event:Event):void
        {
            var vpos:Number = IScrollBarModel(vScrollBar.model).value;
            dataGroup.scrollRect = new Rectangle(0, vpos, dataGroup.width, vpos + dataGroup.height);
        }
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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.layouts
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.geom.Rectangle;

	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IBorderModel;
	import org.apache.flex.core.IScrollBarModel;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.html.staticControls.beads.IListBead;
	import org.apache.flex.html.staticControls.supportClasses.Border;
	import org.apache.flex.html.staticControls.supportClasses.ScrollBar;

	public class NonVirtualVerticalScrollingLayout implements IBead
	{
		public function NonVirtualVerticalScrollingLayout()
		{
		}

		public var dataGroup:DisplayObjectContainer;

        private var border:Border;
        private var borderModel:IBorderModel
        private var vScrollBar:ScrollBar;
		private var listBead:IListBead;

		private var _strand:IStrand;

		public function set strand(value:IStrand):void
		{
			_strand = value;
			listBead = value as IListBead;
			dataGroup = listBead.dataGroup as DisplayObjectContainer;
            border = listBead.border;
            borderModel = border.model as IBorderModel;
			IEventDispatcher(listBead.strand).addEventListener("heightChanged", changeHandler);
			IEventDispatcher(listBead.strand).addEventListener("widthChanged", changeHandler);
			changeHandler(null);
		}

		private function changeHandler(event:Event):void
		{
            var ww:Number = DisplayObject(listBead.strand).width;
            var hh:Number = DisplayObject(listBead.strand).height;
            border.width = ww;
            border.height = hh;

			dataGroup.width = ww - borderModel.offsets.left - borderModel.offsets.right;
			dataGroup.height = hh - borderModel.offsets.top - borderModel.offsets.bottom;
            dataGroup.x = borderModel.offsets.left;
            dataGroup.y = borderModel.offsets.top;

			var n:int = dataGroup.numChildren;
			var yy:Number = 0;
			for (var i:int = 0; i < n; i++)
			{
				var ir:DisplayObject = dataGroup.getChildAt(i);
				ir.y = yy;
				ir.width = dataGroup.width;
				yy += ir.height;
			}
			if (yy > dataGroup.height)
			{
                vScrollBar = listBead.vScrollBar;
				dataGroup.width -= vScrollBar.width;
				IScrollBarModel(vScrollBar.model).maximum = yy;
				IScrollBarModel(vScrollBar.model).pageSize = dataGroup.height;
				IScrollBarModel(vScrollBar.model).pageStepSize = dataGroup.height;
				vScrollBar.visible = true;
				vScrollBar.height = dataGroup.height;
				vScrollBar.y = dataGroup.y;
				vScrollBar.x = dataGroup.width;
                var vpos:Number = IScrollBarModel(vScrollBar.model).value;
                dataGroup.scrollRect = new Rectangle(0, vpos, dataGroup.width, vpos + dataGroup.height);
                vScrollBar.addEventListener("scroll", scrollHandler);
			}
			else if (vScrollBar)
			{
				dataGroup.scrollRect = null;
				vScrollBar.visible = false;
			}
		}

        private function scrollHandler(event:Event):void
        {
            var vpos:Number = IScrollBarModel(vScrollBar.model).value;
            dataGroup.scrollRect = new Rectangle(0, vpos, dataGroup.width, vpos + dataGroup.height);
        }
	}
}

Remove scrollrect when scrollbar goes away