package aerys.minko.render.material.basic
{
	import aerys.minko.render.Effect;
	import aerys.minko.render.material.Material;
	import aerys.minko.render.resource.texture.TextureResource;

	public class BasicMaterial extends Material
	{
		public static const DEFAULT_NAME			: String		= 'BasicMaterial';
		public static const DEFAULT_BASIC_SHADER	: BasicShader	= new BasicShader();
		public static const DEFAULT_EFFECT			: Effect		= new Effect(DEFAULT_BASIC_SHADER);

		public function get blending() : uint
		{
			return getProperty(BasicProperties.BLENDING);
		}
		public function set blending(value : uint) : void
		{
			setProperty(BasicProperties.BLENDING, value);
		}

		public function get triangleCulling() : uint
		{
			return getProperty(BasicProperties.TRIANGLE_CULLING);
		}
		public function set triangleCulling(value : uint) : void
		{
			setProperty(BasicProperties.TRIANGLE_CULLING, value);
		}

		public function get diffuseColor() : uint
		{
			return getProperty(BasicProperties.DIFFUSE_COLOR);
		}
		public function set diffuseColor(value : uint) : void
		{
			setProperty(BasicProperties.DIFFUSE_COLOR, value);
		}

		public function get diffuseMap() : TextureResource
		{
			return getProperty(BasicProperties.DIFFUSE_MAP);
		}
		public function set diffuseMap(value : TextureResource) : void
		{
			setProperty(BasicProperties.DIFFUSE_MAP, value);
		}

		public function get alphaThreshold() : Number
		{
			return getProperty(BasicProperties.ALPHA_THRESHOLD);
		}
		public function set alphaThreshold(value : Number) : void
		{
			setProperty(BasicProperties.ALPHA_THRESHOLD, value);
		}

		public function get depthTest() : uint
		{
			return getProperty(BasicProperties.DEPTH_TEST);
		}
		public function set depthTest(value : uint) : void
		{
			setProperty(BasicProperties.DEPTH_TEST, value);
		}

		public function get depthWriteEnabled() : Boolean
		{
			return getProperty(BasicProperties.DEPTH_WRITE_ENABLED);
		}
		public function set depthWriteEnabled(value : Boolean) : void
		{
			setProperty(BasicProperties.DEPTH_WRITE_ENABLED, value);
		}

		public function get stencilTriangleFace() : uint
		{
			return getProperty(BasicProperties.STENCIL_TRIANGLE_FACE);
		}
		public function set stencilTriangleFace(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_TRIANGLE_FACE, value);
		}

		public function get stencilCompareMode() : uint
		{
			return getProperty(BasicProperties.STENCIL_COMPARE_MODE);
		}
		public function set stencilCompareMode(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_COMPARE_MODE, value);
		}

		public function get stencilActionBothPass() : uint
		{
			return getProperty(BasicProperties.STENCIL_ACTION_BOTH_PASS);
		}
		public function set stencilActionBothPass(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_ACTION_BOTH_PASS, value);
		}

		public function get stencilActionDepthFail() : uint
		{
			return getProperty(BasicProperties.STENCIL_ACTION_DEPTH_FAIL);
		}
		public function set stencilActionDepthFail(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_ACTION_DEPTH_FAIL, value);
		}

		public function get stencilActionDepthPassStencilFail() : uint
		{
			return getProperty(BasicProperties.STENCIL_ACTION_DEPTH_PASS_STENCIL_FAIL);
		}
		public function set stencilActionDepthPassStencilFail(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_ACTION_DEPTH_PASS_STENCIL_FAIL, value);
		}

		public function get stencilReferenceValue() : Number
		{
			return getProperty(BasicProperties.STENCIL_REFERENCE_VALUE);
		}
		public function set stencilReferenceValue(value : Number) : void
		{
			setProperty(BasicProperties.STENCIL_REFERENCE_VALUE, value);
		}

		public function get stencilReadMask() : uint
		{
			return getProperty(BasicProperties.STENCIL_READ_MASK);
		}
		public function set stencilReadMask(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_READ_MASK, value);
		}

		public function get stencilWriteMask() : uint
		{
			return getProperty(BasicProperties.STENCIL_WRITE_MASK);
		}
		public function set stencilWriteMask(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_WRITE_MASK, value);
		}

		public function BasicMaterial(properties : Object = null, name : String = DEFAULT_NAME)
		{
			super(DEFAULT_EFFECT, properties, name);
		}
	}
}

package aerys.minko.render.material.basic
{
	import aerys.minko.render.Effect;
	import aerys.minko.render.material.Material;
	import aerys.minko.render.resource.texture.TextureResource;

	public class BasicMaterial extends Material
	{
		public static const DEFAULT_NAME			: String		= 'BasicMaterial';
		public static const DEFAULT_BASIC_SHADER	: BasicShader	= new BasicShader();
		public static const DEFAULT_EFFECT			: Effect		= new Effect(DEFAULT_BASIC_SHADER);

		public function get blending() : uint
		{
			return getProperty(BasicProperties.BLENDING);
		}
		public function set blending(value : uint) : void
		{
			setProperty(BasicProperties.BLENDING, value);
		}

		public function get triangleCulling() : uint
		{
			return getProperty(BasicProperties.TRIANGLE_CULLING);
		}
		public function set triangleCulling(value : uint) : void
		{
			setProperty(BasicProperties.TRIANGLE_CULLING, value);
		}

		public function get diffuseColor() : uint
		{
			return getProperty(BasicProperties.DIFFUSE_COLOR);
		}
		public function set diffuseColor(value : uint) : void
		{
			setProperty(BasicProperties.DIFFUSE_COLOR, value);
		}

		public function get diffuseMap() : TextureResource
		{
			return getProperty(BasicProperties.DIFFUSE_MAP);
		}
		public function set diffuseMap(value : TextureResource) : void
		{
			setProperty(BasicProperties.DIFFUSE_MAP, value);
		}

		public function get alphaThreshold() : Number
		{
			return getProperty(BasicProperties.ALPHA_THRESHOLD);
		}
		public function set alphaThreshold(value : Number) : void
		{
			setProperty(BasicProperties.ALPHA_THRESHOLD, value);
		}

		public function get depthTest() : uint
		{
			return getProperty(BasicProperties.DEPTH_TEST);
		}
		public function set depthTest(value : uint) : void
		{
			setProperty(BasicProperties.DEPTH_TEST, value);
		}

		public function get depthWriteEnabled() : Boolean
		{
			return getProperty(BasicProperties.DEPTH_WRITE_ENABLED);
		}
		public function set depthWriteEnabled(value : Boolean) : void
		{
			setProperty(BasicProperties.DEPTH_WRITE_ENABLED, value);
		}

		public function get stencilTriangleFace() : uint
		{
			return getProperty(BasicProperties.STENCIL_TRIANGLE_FACE);
		}
		public function set stencilTriangleFace(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_TRIANGLE_FACE, value);
		}

		public function get stencilCompareMode() : uint
		{
			return getProperty(BasicProperties.STENCIL_COMPARE_MODE);
		}
		public function set stencilCompareMode(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_COMPARE_MODE, value);
		}

		public function get stencilActionBothPass() : uint
		{
			return getProperty(BasicProperties.STENCIL_ACTION_BOTH_PASS);
		}
		public function set stencilActionBothPass(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_ACTION_BOTH_PASS, value);
		}

		public function get stencilActionDepthFail() : uint
		{
			return getProperty(BasicProperties.STENCIL_ACTION_DEPTH_FAIL);
		}
		public function set stencilActionDepthFail(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_ACTION_DEPTH_FAIL, value);
		}

		public function get stencilActionDepthPassStencilFail() : uint
		{
			return getProperty(BasicProperties.STENCIL_ACTION_DEPTH_PASS_STENCIL_FAIL);
		}
		public function set stencilActionDepthPassStencilFail(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_ACTION_DEPTH_PASS_STENCIL_FAIL, value);
		}

		public function get stencilReferenceValue() : Number
		{
			return getProperty(BasicProperties.STENCIL_REFERENCE_VALUE);
		}
		public function set stencilReferenceValue(value : Number) : void
		{
			setProperty(BasicProperties.STENCIL_REFERENCE_VALUE, value);
		}

		public function get stencilReadMask() : uint
		{
			return getProperty(BasicProperties.STENCIL_READ_MASK);
		}
		public function set stencilReadMask(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_READ_MASK, value);
		}

		public function get stencilWriteMask() : uint
		{
			return getProperty(BasicProperties.STENCIL_WRITE_MASK);
		}
		public function set stencilWriteMask(value : uint) : void
		{
			setProperty(BasicProperties.STENCIL_WRITE_MASK, value);
		}

		public function BasicMaterial(properties : Object = null, effect : Effect = null, name : String = DEFAULT_NAME)
		{
			super(effect || DEFAULT_EFFECT, properties, name);
		}
	}
}

add optional Effect argument to BasicMaterial constructor


package org.mangui.hls
{
    import flash.external.ExternalInterface;
    import org.hola.ZExternalInterface;
    import org.hola.JSAPI;
    import org.hola.HSettings;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.constant.HLSPlayStates;
    import org.mangui.hls.model.Level;
    import org.mangui.hls.model.Fragment;
    import flash.utils.setTimeout;
    import flash.net.NetStreamAppendBytesAction;

    public class HLSJS
    {
        private static var _inited:Boolean = false;
        private static var _duration:Number;
        private static var _bandwidth:Number = -1;
        private static var _url:String;
        private static var _state:String;
        private static var _hls:HLS;
	private static var _silence: Boolean = false;

        public static function init():void{
            if (_inited || !ZExternalInterface.avail())
                return;
            _inited = true;
            JSAPI.init();
            ExternalInterface.addCallback("hola_version", hola_version);
            ExternalInterface.addCallback("hola_hls_get_video_url",
                hola_hls_get_video_url);
            ExternalInterface.addCallback("hola_hls_get_position",
                hola_hls_get_position);
            ExternalInterface.addCallback("hola_hls_get_duration",
                hola_hls_get_duration);
            ExternalInterface.addCallback("hola_hls_get_buffer_sec",
                hola_hls_get_buffer_sec);
            ExternalInterface.addCallback("hola_hls_get_state",
                hola_hls_get_state);
            ExternalInterface.addCallback("hola_hls_get_levels",
                hola_hls_get_levels);
	    ExternalInterface.addCallback("hola_hls_get_levels_async",
	        hola_hls_get_levels_async);
            ExternalInterface.addCallback("hola_hls_get_segment_info",
                hola_hls_get_segment_info);
            ExternalInterface.addCallback("hola_hls_get_level",
                hola_hls_get_level);
	    ExternalInterface.addCallback("hola_hls_get_bitrate",
	        hola_hls_get_bitrate);
	    ExternalInterface.addCallback("hola_hls_get_decoded_frames",
	        hola_hls_get_decoded_frames);
            ExternalInterface.addCallback("hola_setBandwidth",
                hola_setBandwidth);
            ExternalInterface.addCallback("hola_hls_get_type",
                hola_hls_get_type);
            ExternalInterface.addCallback("hola_hls_load_fragment", hola_hls_load_fragment);
	    ExternalInterface.addCallback("hola_hls_abort_fragment", hola_hls_abort_fragment);
	    ExternalInterface.addCallback("hola_hls_load_level", hola_hls_load_level);
	    ExternalInterface.addCallback('hola_hls_flush_stream', hola_hls_flush_stream);
        }

        public static function HLSnew(hls:HLS):void{
            _hls = hls;
            _state = HLSPlayStates.IDLE;
            // track duration events
            hls.addEventListener(HLSEvent.MANIFEST_LOADED,
	        on_manifest_loaded);
            hls.addEventListener(HLSEvent.PLAYLIST_DURATION_UPDATED,
                on_playlist_duration_updated);
            // track playlist-url/state
            hls.addEventListener(HLSEvent.MANIFEST_LOADING,
	        on_manifest_loading);
            hls.addEventListener(HLSEvent.PLAYBACK_STATE, on_playback_state);
            // notify js events
            hls.addEventListener(HLSEvent.MANIFEST_LOADING, on_event);
            hls.addEventListener(HLSEvent.MANIFEST_PARSED, on_event);
            hls.addEventListener(HLSEvent.MANIFEST_LOADED, on_event);
            hls.addEventListener(HLSEvent.LEVEL_LOADING, on_event);
            hls.addEventListener(HLSEvent.LEVEL_LOADING_ABORTED, on_event);
            hls.addEventListener(HLSEvent.LEVEL_LOADED, on_level_loaded);
            hls.addEventListener(HLSEvent.LEVEL_SWITCH, on_event);
            hls.addEventListener(HLSEvent.LEVEL_ENDLIST, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_LOADING, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_LOADED, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_LOAD_EMERGENCY_ABORTED,
                on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_PLAYING, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_SKIPPED, on_event);
            hls.addEventListener(HLSEvent.AUDIO_TRACKS_LIST_CHANGE, on_event);
            hls.addEventListener(HLSEvent.AUDIO_TRACK_SWITCH, on_event);
            hls.addEventListener(HLSEvent.AUDIO_LEVEL_LOADING, on_event);
            hls.addEventListener(HLSEvent.AUDIO_LEVEL_LOADED, on_event);
            hls.addEventListener(HLSEvent.TAGS_LOADED, on_event);
            hls.addEventListener(HLSEvent.LAST_VOD_FRAGMENT_LOADED, on_event);
            hls.addEventListener(HLSEvent.WARNING, on_event);
            hls.addEventListener(HLSEvent.ERROR, on_event);
            hls.addEventListener(HLSEvent.MEDIA_TIME, on_event);
            hls.addEventListener(HLSEvent.PLAYBACK_STATE, on_event);
            hls.addEventListener(HLSEvent.SEEK_STATE, on_event);
            hls.addEventListener(HLSEvent.STREAM_TYPE_DID_CHANGE, on_event);
            hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, on_event);
            hls.addEventListener(HLSEvent.PLAYLIST_DURATION_UPDATED,
                on_event);
            hls.addEventListener(HLSEvent.ID3_UPDATED, on_event);
            hls.addEventListener(HLSEvent.FPS_DROP, on_event);
            hls.addEventListener(HLSEvent.FPS_DROP_LEVEL_CAPPING, on_event);
            hls.addEventListener(HLSEvent.FPS_DROP_SMOOTH_LEVEL_SWITCH,
                on_event);
            hls.addEventListener(HLSEvent.LIVE_LOADING_STALLED, on_event);
            JSAPI.postMessage('flashls.hlsNew');
        }

        public static function HLSdispose(hls:HLS):void{
            JSAPI.postMessage('flashls.hlsDispose');
            _duration = 0;
            _bandwidth = -1;
            _url = null;
            _state = HLSPlayStates.IDLE;
            _hls = null;
        }

        public static function get bandwidth():Number{
            return HSettings.gets('mode')=='adaptive' ? _bandwidth : -1;
        }

        private static function on_manifest_loaded(e:HLSEvent):void{
            _duration = e.levels[_hls.startLevel].duration;
        }

        private static function on_playlist_duration_updated(e:HLSEvent):void{
            _duration = e.duration;
        }

        private static function on_manifest_loading(e:HLSEvent):void{
            _url = e.url;
            _state = "LOADING";
            on_event(new HLSEvent(HLSEvent.PLAYBACK_STATE, _state));
        }

        private static function on_playback_state(e:HLSEvent):void{
            _state = e.state;
        }

	private static function on_level_loaded(e: HLSEvent): void
	{
            JSAPI.postMessage('flashls.'+e.type, {level: level_to_object(_hls.levels[e.loadMetrics.level])});
	}

        private static function on_event(e:HLSEvent):void{
	    if (_silence)
	        return;
            JSAPI.postMessage('flashls.'+e.type, {url: e.url, level: e.level,
		duration: e.duration, levels: e.levels, error: e.error,
		loadMetrics: e.loadMetrics, playMetrics: e.playMetrics,
		mediatime: e.mediatime, state: e.state,
		audioTrack: e.audioTrack, streamType: e.streamType});
        }

        private static function hola_version():Object{
            return {
                flashls_version: '0.4.4.20',
                patch_version: '2.0.13'
            };
        }

        private static function hola_hls_get_video_url():String{
            return _url;
        }

        private static function hola_hls_get_position():Number{
            return _hls.position;
        }

        private static function hola_hls_get_duration():Number{
            return _duration;
        }

        private static function hola_hls_get_decoded_frames(): Number
	{
            return _hls.stream.decodedFrames;
        }

        private static function hola_hls_get_buffer_sec():Number{
            return _hls.stream.bufferLength;
        }

        private static function hola_hls_get_state():String{
            return _state;
        }

        private static function hola_hls_get_type():String{
            return _hls.type;
        }

        private static function hola_hls_load_fragment(level: Number, frag: Number, url: String): Object
	{
	    if (HSettings.gets('mode')!='hola_adaptive')
	        return 0;
	    return _hls.loadFragment(level, frag, url);
        }

	private static function hola_hls_flush_stream(): void
	{
	    _silence = true;
	    _hls.stream.close();
	    _hls.stream.play();
            _hls.stream.pause();
	    _silence = false;
	}

        private static function hola_hls_abort_fragment(ldr_id: String): void
	{
	    if (HSettings.gets('mode')!='hola_adaptive')
	        return;
	    _hls.abortFragment(ldr_id);
        }

	private static function hola_hls_load_level(level: Number): void
	{
	    if (HSettings.gets('mode')!='hola_adaptive')
	        return;
	    _hls.dispatchEvent(new HLSEvent(HLSEvent.LEVEL_SWITCH, level));
        }

        private static function level_to_object(l: Level): Object
	{
            var fragments: Array = [];
	    for (var i: int = 0; i<l.fragments.length; i++)
	    {
	        var fragment: Fragment = l.fragments[i];
	        fragments.push({url: fragment.url,
		    duration: fragment.duration, seqnum: fragment.seqnum});
	    }
	    return {url: l.url, bitrate: l.bitrate, fragments: fragments,
	        index: l.index, width: l.width, height: l.height, audio: l.audio};
	}

        private static function hola_hls_get_levels():Object{
            var levels:Vector.<Object> =
                new Vector.<Object>(_hls.levels.length);
            for (var i:int = 0; i<_hls.levels.length; i++)
            {
                var l:Level = _hls.levels[i];
                // no fragments returned, use get_segment_info for fragm.info
                levels[i] = Object({url: l.url, bitrate: l.bitrate,
                    index: l.index, fragments: []});
            }
            return levels;
        }

        private static function hola_hls_get_levels_async(): void
	{
	    setTimeout(function(): void
	    {
                var levels: Array = [];
                for (var i: int = 0; i<_hls.levels.length; i++)
                    levels.push(level_to_object(_hls.levels[i]));
		JSAPI.postMessage('flashls.hlsAsyncMessage', {type: 'get_levels', msg: levels});
	    }, 0);
        }

        private static function hola_hls_get_segment_info(url:String):Object{
            for (var i:int = 0; i<_hls.levels.length; i++)
            {
                var l:Level = _hls.levels[i];
                for (var j:int = 0; j<l.fragments.length; j++)
                {
                    if (url==l.fragments[j].url)
                    {
                        return Object({fragment: l.fragments[j],
                            level: Object({url: l.url, bitrate: l.bitrate,
                            index: l.index})});
                    }
                }
            }
            return undefined;
        }

        private static function hola_hls_get_bitrate(): Number
	{
   	    return _hls.loadLevel<_hls.levels.length ? _hls.levels[_hls.loadLevel].bitrate : 0;
	}

        private static function hola_hls_get_level(): String
	{
            return _hls.loadLevel<_hls.levels.length ? _hls.levels[_hls.loadLevel].url : undefined;
        }

        private static function hola_setBandwidth(bandwidth:Number):void{
            _bandwidth = bandwidth;
        }
    }
}

package org.mangui.hls
{
    import flash.external.ExternalInterface;
    import org.hola.ZExternalInterface;
    import org.hola.JSAPI;
    import org.hola.HSettings;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.constant.HLSPlayStates;
    import org.mangui.hls.model.Level;
    import org.mangui.hls.model.Fragment;
    import flash.utils.setTimeout;
    import flash.net.NetStreamAppendBytesAction;

    public class HLSJS
    {
        private static var _inited:Boolean = false;
        private static var _duration:Number;
        private static var _bandwidth:Number = -1;
        private static var _url:String;
        private static var _state:String;
        private static var _hls:HLS;
	private static var _silence: Boolean = false;

        public static function init():void{
            if (_inited || !ZExternalInterface.avail())
                return;
            _inited = true;
            JSAPI.init();
            ExternalInterface.addCallback("hola_version", hola_version);
            ExternalInterface.addCallback("hola_hls_get_video_url",
                hola_hls_get_video_url);
            ExternalInterface.addCallback("hola_hls_get_position",
                hola_hls_get_position);
            ExternalInterface.addCallback("hola_hls_get_duration",
                hola_hls_get_duration);
            ExternalInterface.addCallback("hola_hls_get_buffer_sec",
                hola_hls_get_buffer_sec);
            ExternalInterface.addCallback("hola_hls_get_state",
                hola_hls_get_state);
            ExternalInterface.addCallback("hola_hls_get_levels",
                hola_hls_get_levels);
	    ExternalInterface.addCallback("hola_hls_get_levels_async",
	        hola_hls_get_levels_async);
            ExternalInterface.addCallback("hola_hls_get_segment_info",
                hola_hls_get_segment_info);
            ExternalInterface.addCallback("hola_hls_get_level",
                hola_hls_get_level);
	    ExternalInterface.addCallback("hola_hls_get_bitrate",
	        hola_hls_get_bitrate);
	    ExternalInterface.addCallback("hola_hls_get_decoded_frames",
	        hola_hls_get_decoded_frames);
            ExternalInterface.addCallback("hola_setBandwidth",
                hola_setBandwidth);
            ExternalInterface.addCallback("hola_hls_get_type",
                hola_hls_get_type);
            ExternalInterface.addCallback("hola_hls_load_fragment", hola_hls_load_fragment);
	    ExternalInterface.addCallback("hola_hls_abort_fragment", hola_hls_abort_fragment);
	    ExternalInterface.addCallback("hola_hls_load_level", hola_hls_load_level);
	    ExternalInterface.addCallback('hola_hls_flush_stream', hola_hls_flush_stream);
        }

        public static function HLSnew(hls:HLS):void{
            _hls = hls;
            _state = HLSPlayStates.IDLE;
            // track duration events
            hls.addEventListener(HLSEvent.MANIFEST_LOADED,
	        on_manifest_loaded);
            hls.addEventListener(HLSEvent.PLAYLIST_DURATION_UPDATED,
                on_playlist_duration_updated);
            // track playlist-url/state
            hls.addEventListener(HLSEvent.MANIFEST_LOADING,
	        on_manifest_loading);
            hls.addEventListener(HLSEvent.PLAYBACK_STATE, on_playback_state);
            hls.addEventListener(HLSEvent.SEEK_STATE, on_seek_state);
            // notify js events
            hls.addEventListener(HLSEvent.MANIFEST_LOADING, on_event);
            hls.addEventListener(HLSEvent.MANIFEST_PARSED, on_event);
            hls.addEventListener(HLSEvent.MANIFEST_LOADED, on_event);
            hls.addEventListener(HLSEvent.LEVEL_LOADING, on_event);
            hls.addEventListener(HLSEvent.LEVEL_LOADING_ABORTED, on_event);
            hls.addEventListener(HLSEvent.LEVEL_LOADED, on_level_loaded);
            hls.addEventListener(HLSEvent.LEVEL_SWITCH, on_event);
            hls.addEventListener(HLSEvent.LEVEL_ENDLIST, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_LOADING, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_LOADED, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_LOAD_EMERGENCY_ABORTED,
                on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_PLAYING, on_event);
            hls.addEventListener(HLSEvent.FRAGMENT_SKIPPED, on_event);
            hls.addEventListener(HLSEvent.AUDIO_TRACKS_LIST_CHANGE, on_event);
            hls.addEventListener(HLSEvent.AUDIO_TRACK_SWITCH, on_event);
            hls.addEventListener(HLSEvent.AUDIO_LEVEL_LOADING, on_event);
            hls.addEventListener(HLSEvent.AUDIO_LEVEL_LOADED, on_event);
            hls.addEventListener(HLSEvent.TAGS_LOADED, on_event);
            hls.addEventListener(HLSEvent.LAST_VOD_FRAGMENT_LOADED, on_event);
            hls.addEventListener(HLSEvent.WARNING, on_event);
            hls.addEventListener(HLSEvent.ERROR, on_event);
            hls.addEventListener(HLSEvent.MEDIA_TIME, on_event);
            hls.addEventListener(HLSEvent.PLAYBACK_STATE, on_event);
            hls.addEventListener(HLSEvent.STREAM_TYPE_DID_CHANGE, on_event);
            hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, on_event);
            hls.addEventListener(HLSEvent.PLAYLIST_DURATION_UPDATED,
                on_event);
            hls.addEventListener(HLSEvent.ID3_UPDATED, on_event);
            hls.addEventListener(HLSEvent.FPS_DROP, on_event);
            hls.addEventListener(HLSEvent.FPS_DROP_LEVEL_CAPPING, on_event);
            hls.addEventListener(HLSEvent.FPS_DROP_SMOOTH_LEVEL_SWITCH,
                on_event);
            hls.addEventListener(HLSEvent.LIVE_LOADING_STALLED, on_event);
            JSAPI.postMessage('flashls.hlsNew');
        }

        public static function HLSdispose(hls:HLS):void{
            JSAPI.postMessage('flashls.hlsDispose');
            _duration = 0;
            _bandwidth = -1;
            _url = null;
            _state = HLSPlayStates.IDLE;
            _hls = null;
        }

        public static function get bandwidth():Number{
            return HSettings.gets('mode')=='adaptive' ? _bandwidth : -1;
        }

        private static function on_manifest_loaded(e:HLSEvent):void{
            _duration = e.levels[_hls.startLevel].duration;
        }

        private static function on_playlist_duration_updated(e:HLSEvent):void{
            _duration = e.duration;
        }

        private static function on_manifest_loading(e:HLSEvent):void{
            _url = e.url;
            _state = "LOADING";
            on_event(new HLSEvent(HLSEvent.PLAYBACK_STATE, _state));
        }

        private static function on_playback_state(e:HLSEvent):void{
            _state = e.state;
        }

	private static function on_level_loaded(e: HLSEvent): void
	{
            JSAPI.postMessage('flashls.'+e.type, {level: level_to_object(_hls.levels[e.loadMetrics.level])});
	}

	private static function on_seek_state(e: HLSEvent): void
	{
            JSAPI.postMessage('flashls.'+e.type, {state: e.state, seek_pos: _hls.position});
	}

        private static function on_event(e:HLSEvent):void{
	    if (_silence)
	        return;
            JSAPI.postMessage('flashls.'+e.type, {url: e.url, level: e.level,
		duration: e.duration, levels: e.levels, error: e.error,
		loadMetrics: e.loadMetrics, playMetrics: e.playMetrics,
		mediatime: e.mediatime, state: e.state,
		audioTrack: e.audioTrack, streamType: e.streamType});
        }

        private static function hola_version():Object{
            return {
                flashls_version: '0.4.4.20',
                patch_version: '2.0.13'
            };
        }

        private static function hola_hls_get_video_url():String{
            return _url;
        }

        private static function hola_hls_get_position():Number{
            return _hls.position;
        }

        private static function hola_hls_get_duration():Number{
            return _duration;
        }

        private static function hola_hls_get_decoded_frames(): Number
	{
            return _hls.stream.decodedFrames;
        }

        private static function hola_hls_get_buffer_sec():Number{
            return _hls.stream.bufferLength;
        }

        private static function hola_hls_get_state():String{
            return _state;
        }

        private static function hola_hls_get_type():String{
            return _hls.type;
        }

        private static function hola_hls_load_fragment(level: Number, frag: Number, url: String): Object
	{
	    if (HSettings.gets('mode')!='hola_adaptive')
	        return 0;
	    return _hls.loadFragment(level, frag, url);
        }

	private static function hola_hls_flush_stream(): void
	{
	    _silence = true;
	    _hls.stream.close();
	    _hls.stream.play();
            _hls.stream.pause();
	    _silence = false;
	}

        private static function hola_hls_abort_fragment(ldr_id: String): void
	{
	    if (HSettings.gets('mode')!='hola_adaptive')
	        return;
	    _hls.abortFragment(ldr_id);
        }

	private static function hola_hls_load_level(level: Number): void
	{
	    if (HSettings.gets('mode')!='hola_adaptive')
	        return;
	    _hls.dispatchEvent(new HLSEvent(HLSEvent.LEVEL_SWITCH, level));
        }

        private static function level_to_object(l: Level): Object
	{
            var fragments: Array = [];
	    for (var i: int = 0; i<l.fragments.length; i++)
	    {
	        var fragment: Fragment = l.fragments[i];
	        fragments.push({url: fragment.url,
		    duration: fragment.duration, seqnum: fragment.seqnum});
	    }
	    return {url: l.url, bitrate: l.bitrate, fragments: fragments,
	        index: l.index, width: l.width, height: l.height, audio: l.audio};
	}

        private static function hola_hls_get_levels():Object{
            var levels:Vector.<Object> =
                new Vector.<Object>(_hls.levels.length);
            for (var i:int = 0; i<_hls.levels.length; i++)
            {
                var l:Level = _hls.levels[i];
                // no fragments returned, use get_segment_info for fragm.info
                levels[i] = Object({url: l.url, bitrate: l.bitrate,
                    index: l.index, fragments: []});
            }
            return levels;
        }

        private static function hola_hls_get_levels_async(): void
	{
	    setTimeout(function(): void
	    {
                var levels: Array = [];
                for (var i: int = 0; i<_hls.levels.length; i++)
                    levels.push(level_to_object(_hls.levels[i]));
		JSAPI.postMessage('flashls.hlsAsyncMessage', {type: 'get_levels', msg: levels});
	    }, 0);
        }

        private static function hola_hls_get_segment_info(url:String):Object{
            for (var i:int = 0; i<_hls.levels.length; i++)
            {
                var l:Level = _hls.levels[i];
                for (var j:int = 0; j<l.fragments.length; j++)
                {
                    if (url==l.fragments[j].url)
                    {
                        return Object({fragment: l.fragments[j],
                            level: Object({url: l.url, bitrate: l.bitrate,
                            index: l.index})});
                    }
                }
            }
            return undefined;
        }

        private static function hola_hls_get_bitrate(): Number
	{
   	    return _hls.loadLevel<_hls.levels.length ? _hls.levels[_hls.loadLevel].bitrate : 0;
	}

        private static function hola_hls_get_level(): String
	{
            return _hls.loadLevel<_hls.levels.length ? _hls.levels[_hls.loadLevel].url : undefined;
        }

        private static function hola_setBandwidth(bandwidth:Number):void{
            _bandwidth = bandwidth;
        }
    }
}

add info about seeking_position to SEEK_STATE event


package aerys.minko.scene.controller.mesh.skinning
{
	import aerys.minko.Minko;
	import aerys.minko.ns.minko_math;
	import aerys.minko.render.Viewport;
	import aerys.minko.scene.controller.AbstractController;
	import aerys.minko.scene.controller.EnterFrameController;
	import aerys.minko.scene.controller.IRebindableController;
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Mesh;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.animation.SkinningMethod;
	import aerys.minko.type.binding.DataBindings;
	import aerys.minko.type.log.DebugLevel;
	import aerys.minko.type.math.Matrix4x4;

	import flash.display.BitmapData;
	import flash.geom.Matrix3D;
	import flash.utils.Dictionary;

	public final class SkinningController extends EnterFrameController implements IRebindableController
	{
		public static const MAX_NUM_INFLUENCES	: uint	= 8;
		public static const MAX_NUM_JOINTS		: uint	= 51;

		private var _skinningHelper		: AbstractSkinningHelper;
		private var _isDirty			: Boolean;

		private var _method				: uint;
		private var _bindShapeMatrix	: Matrix3D;
		private var _skeletonRoot		: Group;
		private var _joints				: Vector.<Group>;
		private var _invBindMatrices	: Vector.<Matrix3D>;

		private var _numVisibleTargets	: uint;

		public function get skinningMethod() : uint
		{
			return _method;
		}

		public function get bindShape() : Matrix4x4
		{
			var bindShape : Matrix4x4 = new Matrix4x4();
			bindShape.minko_math::_matrix = _bindShapeMatrix;

			return bindShape;
		}

		public function get skeletonRoot() : Group
		{
			return _skeletonRoot;
		}

		public function get joints() : Vector.<Group>
		{
			return _joints;
		}

		public function get invBindMatrices() : Vector.<Matrix4x4>
		{
			var numMatrices		: uint					= _invBindMatrices.length;
			var invBindMatrices : Vector.<Matrix4x4>	= new Vector.<Matrix4x4>(numMatrices);

			for (var matrixId : uint = 0; matrixId < numMatrices; ++matrixId)
			{
				invBindMatrices[matrixId] = new Matrix4x4();
				invBindMatrices[matrixId].minko_math::_matrix = _invBindMatrices[matrixId];
			}

			return invBindMatrices;
		}

		public function SkinningController(method			: uint,
										   skeletonRoot		: Group,
										   joints			: Vector.<Group>,
										   bindShape		: Matrix4x4,
										   invBindMatrices	: Vector.<Matrix4x4>)
		{
			super(Mesh);

			_method				= method;
			_skeletonRoot		= skeletonRoot;
			_bindShapeMatrix	= bindShape.minko_math::_matrix;
			_isDirty			= false;

			initialize(joints, invBindMatrices);
		}

		private function initialize(joints			: Vector.<Group>,
									invBindMatrices	: Vector.<Matrix4x4>) : void
		{
			var numJoints : uint = joints.length;

			_joints	= joints.slice();

			_invBindMatrices	= new Vector.<Matrix3D>(numJoints, true);
			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				_invBindMatrices[jointId] = invBindMatrices[jointId].minko_math::_matrix;
		}

		override protected function targetAddedToSceneHandler(target	: ISceneNode,
															  scene		: Scene) : void
		{
			super.targetAddedToSceneHandler(target, scene);

			if (numTargetsInScene == 1)
				subscribeToJoints();

			var mesh : Mesh = target as Mesh;

			mesh.bindings.addCallback('inFrustum', meshVisibilityChangedHandler);

			if (!_skinningHelper)
			{
				var numInfluences 	: uint = AbstractSkinningHelper.getNumInfluences(
                    mesh.geometry.format
                );

				if (_joints.length > MAX_NUM_JOINTS || numInfluences > MAX_NUM_INFLUENCES)
				{
					_method = SkinningMethod.SOFTWARE_MATRIX;
					Minko.log(
						DebugLevel.SKINNING,
						'Too many influences/joints: switching to SkinningMethod.SOFTWARE.'
					);
				}

				if (skinningMethod != SkinningMethod.SOFTWARE_MATRIX)
                {
                    try
                    {
    					_skinningHelper = new HardwareSkinningHelper(
    						_method, _bindShapeMatrix, _invBindMatrices
    					);
                    }
                    catch (e : Error)
                    {
                        Minko.log(
                            DebugLevel.SKINNING,
                            'Falling back to software skinning: ' + e.message,
                            this
                        );

                        _method = SkinningMethod.SOFTWARE_MATRIX;
                    }
                }

                _skinningHelper ||= new SoftwareSkinningHelper(
                    _method, _bindShapeMatrix, _invBindMatrices
                );
			}

			_skinningHelper.addMesh(mesh);

			_isDirty = true;
		}

		override protected function targetRemovedFromSceneHandler(target	: ISceneNode,
																  scene		: Scene) : void
		{
			super.targetRemovedFromSceneHandler(target, scene);

			if (numTargets == 0)
				unsubscribeFromJoints();

			var mesh : Mesh = target as Mesh;

			mesh.bindings.removeCallback('inFrustum', meshVisibilityChangedHandler);
			_skinningHelper.removeMesh(mesh);
		}

		private function jointLocalToWorldChangedHandler(emitter : Matrix4x4) : void
		{
			_isDirty = true;
		}

		public function rebindDependencies(nodeMap			: Dictionary,
										   controllerMap	: Dictionary) : void
		{
			var numJoints	: uint = _joints.length;

			if (numTargets != 0)
				unsubscribeFromJoints();

			if (_joints.indexOf(_skeletonRoot) == -1 && nodeMap[_skeletonRoot])
				_skeletonRoot = nodeMap[_skeletonRoot];

			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				if (nodeMap[_joints[jointId]])
					_joints[jointId] = nodeMap[_joints[jointId]];

			if (numTargets != 0)
				subscribeToJoints();

			_isDirty = true;
		}

		private function subscribeToJoints() : void
		{
			var numJoints	: uint = _joints.length;

			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				_joints[jointId].localToWorld.changed.add(jointLocalToWorldChangedHandler);

			if (_joints.indexOf(_skeletonRoot) == -1)
				_skeletonRoot.localToWorld.changed.add(jointLocalToWorldChangedHandler);
		}

		private function unsubscribeFromJoints() : void
		{
			var numJoints	: uint = _joints.length;

			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				_joints[jointId].localToWorld.changed.remove(jointLocalToWorldChangedHandler);

			if (_joints.indexOf(_skeletonRoot) == -1)
				_skeletonRoot.localToWorld.changed.remove(jointLocalToWorldChangedHandler);
		}

		override protected function sceneEnterFrameHandler(scene		: Scene,
														   viewport		: Viewport,
														   destination	: BitmapData,
														   time			: Number) : void
		{
			if (_isDirty && _skinningHelper.numMeshes != 0)
			{
				_skinningHelper.update(_skeletonRoot, _joints);
				_isDirty = false;
			}
		}

		override public function clone() : AbstractController
		{
			return new SkinningController(_method, _skeletonRoot, _joints, bindShape, invBindMatrices);
		}

		private function meshVisibilityChangedHandler(bindings 	: DataBindings,
												  property	: String,
												  oldValue	: Boolean,
												  newValue	: Boolean) : void
		{
			if (newValue)
				_skinningHelper.addMesh(bindings.owner as Mesh);
			else
				_skinningHelper.removeMesh(bindings.owner as Mesh);
		}
	}
}

package aerys.minko.scene.controller.mesh.skinning
{
	import aerys.minko.Minko;
	import aerys.minko.ns.minko_math;
	import aerys.minko.render.Viewport;
	import aerys.minko.scene.controller.AbstractController;
	import aerys.minko.scene.controller.EnterFrameController;
	import aerys.minko.scene.controller.IRebindableController;
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Mesh;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.animation.SkinningMethod;
	import aerys.minko.type.binding.DataBindings;
	import aerys.minko.type.log.DebugLevel;
	import aerys.minko.type.math.Matrix4x4;

	import flash.display.BitmapData;
	import flash.geom.Matrix3D;
	import flash.utils.Dictionary;

	public final class SkinningController extends EnterFrameController implements IRebindableController
	{
		public static const MAX_NUM_INFLUENCES	: uint	= 8;
		public static const MAX_NUM_JOINTS		: uint	= 51;

		private var _skinningHelper		: AbstractSkinningHelper;
		private var _isDirty			: Boolean;

		private var _method				: uint;
		private var _bindShapeMatrix	: Matrix3D;
		private var _skeletonRoot		: Group;
		private var _joints				: Vector.<Group>;
		private var _invBindMatrices	: Vector.<Matrix3D>;

		private var _numVisibleTargets	: uint;

		public function get skinningMethod() : uint
		{
			return _method;
		}

		public function get bindShape() : Matrix4x4
		{
			var bindShape : Matrix4x4 = new Matrix4x4();
			bindShape.minko_math::_matrix = _bindShapeMatrix;

			return bindShape;
		}

		public function get skeletonRoot() : Group
		{
			return _skeletonRoot;
		}

		public function get joints() : Vector.<Group>
		{
			return _joints;
		}

		public function get invBindMatrices() : Vector.<Matrix4x4>
		{
			var numMatrices		: uint					= _invBindMatrices.length;
			var invBindMatrices : Vector.<Matrix4x4>	= new Vector.<Matrix4x4>(numMatrices);

			for (var matrixId : uint = 0; matrixId < numMatrices; ++matrixId)
			{
				invBindMatrices[matrixId] = new Matrix4x4();
				invBindMatrices[matrixId].minko_math::_matrix = _invBindMatrices[matrixId];
			}

			return invBindMatrices;
		}

		public function SkinningController(method			: uint,
										   skeletonRoot		: Group,
										   joints			: Vector.<Group>,
										   bindShape		: Matrix4x4,
										   invBindMatrices	: Vector.<Matrix4x4>)
		{
			super(Mesh);

            if (!skeletonRoot)
                throw new Error('skeletonRoot cannot be null');

			_method				= method;
			_skeletonRoot		= skeletonRoot;
			_bindShapeMatrix	= bindShape.minko_math::_matrix;
			_isDirty			= false;

			initialize(joints, invBindMatrices);
		}

		private function initialize(joints			: Vector.<Group>,
									invBindMatrices	: Vector.<Matrix4x4>) : void
		{
			var numJoints : uint = joints.length;

			_joints	= joints.slice();

			_invBindMatrices	= new Vector.<Matrix3D>(numJoints, true);
			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				_invBindMatrices[jointId] = invBindMatrices[jointId].minko_math::_matrix;
		}

		override protected function targetAddedToSceneHandler(target	: ISceneNode,
															  scene		: Scene) : void
		{
			super.targetAddedToSceneHandler(target, scene);

			if (numTargetsInScene == 1)
				subscribeToJoints();

			var mesh : Mesh = target as Mesh;

			mesh.bindings.addCallback('inFrustum', meshVisibilityChangedHandler);

			if (!_skinningHelper)
			{
				var numInfluences 	: uint = AbstractSkinningHelper.getNumInfluences(
                    mesh.geometry.format
                );

				if (_joints.length > MAX_NUM_JOINTS || numInfluences > MAX_NUM_INFLUENCES)
				{
					_method = SkinningMethod.SOFTWARE_MATRIX;
					Minko.log(
						DebugLevel.SKINNING,
						'Too many influences/joints: switching to SkinningMethod.SOFTWARE.'
					);
				}

				if (skinningMethod != SkinningMethod.SOFTWARE_MATRIX)
                {
                    try
                    {
    					_skinningHelper = new HardwareSkinningHelper(
    						_method, _bindShapeMatrix, _invBindMatrices
    					);
                    }
                    catch (e : Error)
                    {
                        Minko.log(
                            DebugLevel.SKINNING,
                            'Falling back to software skinning: ' + e.message,
                            this
                        );

                        _method = SkinningMethod.SOFTWARE_MATRIX;
                    }
                }

                _skinningHelper ||= new SoftwareSkinningHelper(
                    _method, _bindShapeMatrix, _invBindMatrices
                );
			}

			_skinningHelper.addMesh(mesh);

			_isDirty = true;
		}

		override protected function targetRemovedFromSceneHandler(target	: ISceneNode,
																  scene		: Scene) : void
		{
			super.targetRemovedFromSceneHandler(target, scene);

			if (numTargets == 0)
				unsubscribeFromJoints();

			var mesh : Mesh = target as Mesh;

			mesh.bindings.removeCallback('inFrustum', meshVisibilityChangedHandler);
			_skinningHelper.removeMesh(mesh);
		}

		private function jointLocalToWorldChangedHandler(emitter : Matrix4x4) : void
		{
			_isDirty = true;
		}

		public function rebindDependencies(nodeMap			: Dictionary,
										   controllerMap	: Dictionary) : void
		{
			var numJoints	: uint = _joints.length;

			if (numTargets != 0)
				unsubscribeFromJoints();

			if (_joints.indexOf(_skeletonRoot) == -1 && nodeMap[_skeletonRoot])
				_skeletonRoot = nodeMap[_skeletonRoot];

			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				if (nodeMap[_joints[jointId]])
					_joints[jointId] = nodeMap[_joints[jointId]];

			if (numTargets != 0)
				subscribeToJoints();

			_isDirty = true;
		}

		private function subscribeToJoints() : void
		{
			var numJoints	: uint = _joints.length;

			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				_joints[jointId].localToWorld.changed.add(jointLocalToWorldChangedHandler);

			if (_joints.indexOf(_skeletonRoot) == -1)
				_skeletonRoot.localToWorld.changed.add(jointLocalToWorldChangedHandler);
		}

		private function unsubscribeFromJoints() : void
		{
			var numJoints	: uint = _joints.length;

			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
				_joints[jointId].localToWorld.changed.remove(jointLocalToWorldChangedHandler);

			if (_joints.indexOf(_skeletonRoot) == -1)
				_skeletonRoot.localToWorld.changed.remove(jointLocalToWorldChangedHandler);
		}

		override protected function sceneEnterFrameHandler(scene		: Scene,
														   viewport		: Viewport,
														   destination	: BitmapData,
														   time			: Number) : void
		{
			if (_isDirty && _skinningHelper.numMeshes != 0)
			{
				_skinningHelper.update(_skeletonRoot, _joints);
				_isDirty = false;
			}
		}

		override public function clone() : AbstractController
		{
			return new SkinningController(_method, _skeletonRoot, _joints, bindShape, invBindMatrices);
		}

		private function meshVisibilityChangedHandler(bindings 	: DataBindings,
												  property	: String,
												  oldValue	: Boolean,
												  newValue	: Boolean) : void
		{
			if (newValue)
				_skinningHelper.addMesh(bindings.owner as Mesh);
			else
				_skinningHelper.removeMesh(bindings.owner as Mesh);
		}
	}
}

throw an error when the skeletonRoot passed to SkinningController constructor is null


package aerys.minko.render.material.phong
{
	import aerys.minko.render.DataBindingsProxy;
	import aerys.minko.render.Effect;
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.resource.texture.CubeTextureResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.scene.data.LightDataProvider;
	import aerys.minko.scene.node.light.AmbientLight;
	import aerys.minko.scene.node.light.DirectionalLight;
	import aerys.minko.scene.node.light.PointLight;
	import aerys.minko.type.enum.ShadowMappingQuality;
	import aerys.minko.type.enum.ShadowMappingType;

	public class PhongEffect extends Effect
	{
        private var _singlePassShader   : Shader;
        private var _baseShader         : Shader;

		public function PhongEffect(singlePassShader    : Shader    = null,
                                    baseShader          : Shader    = null)
		{
            super();

            _singlePassShader = singlePassShader || new PhongSinglePassShader(null, 0);
            _baseShader = baseShader || new PhongBaseShader(null, .5);
		}

        override protected function initializePasses(sceneBindings	: DataBindingsProxy,
                                                     meshBindings	: DataBindingsProxy) : Vector.<Shader>
        {
            var passes : Vector.<Shader>    = super.initializePasses(sceneBindings, meshBindings);

            for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
            {
                if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
                {
                    var lightType			: uint	= getLightProperty(sceneBindings, lightId, 'type');
                    var shadowMappingType 	: uint	= getLightProperty(
                        sceneBindings, lightId, 'shadowCastingType'
                    );

                    switch (shadowMappingType)
                    {
                        case ShadowMappingType.PCF:
                            if (lightType == PointLight.LIGHT_TYPE)
                                pushCubeShadowMappingPass(sceneBindings, lightId, passes);
                            else
                                pushPCFShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.DUAL_PARABOLOID:
                            pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.VARIANCE:
                            pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.EXPONENTIAL:
                            pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                    }
                }
            }

            passes.push(_singlePassShader);

            return passes;
        }

        override protected function initializeFallbackPasses(sceneBindings  : DataBindingsProxy,
                                                             meshBindings   : DataBindingsProxy) : Vector.<Shader>
        {
            var passes              : Vector.<Shader>   = super.initializeFallbackPasses(sceneBindings, meshBindings);
            var discardDirectional  : Boolean           = true;

			for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
			{
                var lightType   : uint	= getLightProperty(sceneBindings, lightId, 'type');

                if (lightType != AmbientLight.LIGHT_TYPE
                    && getLightProperty(sceneBindings, lightId, 'enabled'))
                {
                    if (lightType == DirectionalLight.LIGHT_TYPE && discardDirectional)
                        discardDirectional = false;
                    else
                        passes.push(new PhongAdditionalShader(null, 0, lightId));
                }

				if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
				{
					var shadowMappingType 	: uint	= getLightProperty(
						sceneBindings, lightId, 'shadowCastingType'
					);

					switch (shadowMappingType)
					{
						case ShadowMappingType.PCF:
							if (lightType == PointLight.LIGHT_TYPE)
								pushCubeShadowMappingPass(sceneBindings, lightId, passes);
							else
								pushPCFShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.DUAL_PARABOLOID:
							pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.VARIANCE:
							pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.EXPONENTIAL:
							pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
							break ;
					}
				}
			}

            passes.push(_baseShader);

            return passes;
		}

		private function pushPCFShadowMappingPass(sceneBindings	: DataBindingsProxy,
													 lightId 		: uint,
													 passes 		: Vector.<Shader>) : void
		{
			var textureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var renderTarget	: RenderTarget		= new RenderTarget(
				textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
			);

			passes.push(new PCFShadowMapShader(lightId, lightId + 1, renderTarget));
		}

		private function pushDualParaboloidShadowMappingPass(sceneBindings	: DataBindingsProxy,
															 lightId 		: uint,
															 passes 		: Vector.<Shader>) : void
		{
			var frontTextureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapFront'
			);
			var backTextureResource	 : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapBack'
			);
			var size				 : uint				= frontTextureResource.width;
			var frontRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, frontTextureResource, 0, 0xffffffff
			);
			var backRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, backTextureResource, 0, 0xffffffff
			);

			passes.push(
				new ParaboloidShadowMapShader(lightId, true, lightId + 0.5, frontRenderTarget),
				new ParaboloidShadowMapShader(lightId, false, lightId + 1, backRenderTarget)
			);
		}

		private function pushCubeShadowMappingPass(sceneBindings	: DataBindingsProxy,
												   lightId 			: uint,
												   passes 			: Vector.<Shader>) : void
		{
			var cubeTexture	: CubeTextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var textureSize	: uint					= cubeTexture.size;

			for (var i : uint = 0; i < 6; ++i)
				passes.push(new PCFShadowMapShader(
					lightId,
					lightId + .1 * i,
					new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff),
					i
				));
		}

		private function pushVarianceShadowMappingPass(sceneBindings	: DataBindingsProxy,
													   lightId 			: uint,
													   passes 			: Vector.<Shader>) : void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget		= new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new VarianceShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new VarianceShadowMapShader(
                        lightId,
                        i,
                        lightId + .1 * i,
                        new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function pushExponentialShadowMappingPass(sceneBindings	: DataBindingsProxy,
														  lightId 		: uint,
														  passes 		: Vector.<Shader>):void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget = new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new ExponentialShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new ExponentialShadowMapShader(
						lightId,
						i,
						lightId + .1 * i,
						new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function hasShadowBlurPass(sceneBindings	: DataBindingsProxy,
							    		   lightId 			: uint) : Boolean
		{
			var quality	: uint	= getLightProperty(sceneBindings, lightId, 'shadowQuality');

			return quality > ShadowMappingQuality.HARD;
		}

		private function lightPropertyExists(sceneBindings 	: DataBindingsProxy,
											 lightId 		: uint,
											 propertyName 	: String) : Boolean
		{
			return sceneBindings.propertyExists(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}

		private function getLightProperty(sceneBindings : DataBindingsProxy,
										  lightId 		: uint,
										  propertyName 	: String) : *
		{
			return sceneBindings.getProperty(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}
	}
}

package aerys.minko.render.material.phong
{
	import aerys.minko.render.DataBindingsProxy;
	import aerys.minko.render.Effect;
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.resource.texture.CubeTextureResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.scene.data.LightDataProvider;
	import aerys.minko.scene.node.light.AmbientLight;
	import aerys.minko.scene.node.light.DirectionalLight;
	import aerys.minko.scene.node.light.PointLight;
	import aerys.minko.type.enum.ShadowMappingQuality;
	import aerys.minko.type.enum.ShadowMappingType;

    /**
     *
The PhongEffect using the Phong lighting model to render the geometry according to
     * the lighting setup of the scene. It supports an infinite number of lights/projected
     * shadows and will automatically switch between singlepass and multipass rendering
     * in order to give the best performances whenever possible.

     *
     *
Because of the Stage3D restrictions regarding the number of shader operations or
     * the number of available registers, the number of lights might be to big to allow them
     * to be rendered in a single pass. In this situation, the PhongEffect will automatically
     * fallback and use multipass rendering.

     *
     *
Multipass rendering is done as follow:

     *

     *
The "base" pass renders objects with one per-pixel directional lights with shadows,
     * the lightmap and the ambient/emissive lighting.

     *
Each "additional" pass (one per light) will render a single light with shadows and
     * blend it using additive blending.

     *

     *
     * The singlepass rendering will mimic this behavior in order to get preserve consistency.
     *
     * @author Jean-Marc Le Roux
     *
     */
	public class PhongEffect extends Effect
	{
        private var _singlePassShader   : Shader;
        private var _baseShader         : Shader;

		public function PhongEffect(singlePassShader    : Shader    = null,
                                    baseShader          : Shader    = null)
		{
            super();

            _singlePassShader = singlePassShader || new PhongSinglePassShader(null, 0);
            _baseShader = baseShader || new PhongBaseShader(null, .5);
		}

        override protected function initializePasses(sceneBindings	: DataBindingsProxy,
                                                     meshBindings	: DataBindingsProxy) : Vector.<Shader>
        {
            var passes : Vector.<Shader>    = super.initializePasses(sceneBindings, meshBindings);

            for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
            {
                if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
                {
                    var lightType			: uint	= getLightProperty(sceneBindings, lightId, 'type');
                    var shadowMappingType 	: uint	= getLightProperty(
                        sceneBindings, lightId, 'shadowCastingType'
                    );

                    switch (shadowMappingType)
                    {
                        case ShadowMappingType.PCF:
                            if (lightType == PointLight.LIGHT_TYPE)
                                pushCubeShadowMappingPass(sceneBindings, lightId, passes);
                            else
                                pushPCFShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.DUAL_PARABOLOID:
                            pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.VARIANCE:
                            pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.EXPONENTIAL:
                            pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                    }
                }
            }

            passes.push(_singlePassShader);

            return passes;
        }

        override protected function initializeFallbackPasses(sceneBindings  : DataBindingsProxy,
                                                             meshBindings   : DataBindingsProxy) : Vector.<Shader>
        {
            var passes              : Vector.<Shader>   = super.initializeFallbackPasses(sceneBindings, meshBindings);
            var discardDirectional  : Boolean           = true;

			for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
			{
                var lightType   : uint	= getLightProperty(sceneBindings, lightId, 'type');

                if (lightType != AmbientLight.LIGHT_TYPE
                    && getLightProperty(sceneBindings, lightId, 'enabled'))
                {
                    if (lightType == DirectionalLight.LIGHT_TYPE && discardDirectional)
                        discardDirectional = false;
                    else
                        passes.push(new PhongAdditionalShader(null, 0, lightId));
                }

				if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
				{
					var shadowMappingType 	: uint	= getLightProperty(
						sceneBindings, lightId, 'shadowCastingType'
					);

					switch (shadowMappingType)
					{
						case ShadowMappingType.PCF:
							if (lightType == PointLight.LIGHT_TYPE)
								pushCubeShadowMappingPass(sceneBindings, lightId, passes);
							else
								pushPCFShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.DUAL_PARABOLOID:
							pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.VARIANCE:
							pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.EXPONENTIAL:
							pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
							break ;
					}
				}
			}

            passes.push(_baseShader);

            return passes;
		}

		private function pushPCFShadowMappingPass(sceneBindings	: DataBindingsProxy,
													 lightId 		: uint,
													 passes 		: Vector.<Shader>) : void
		{
			var textureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var renderTarget	: RenderTarget		= new RenderTarget(
				textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
			);

			passes.push(new PCFShadowMapShader(lightId, lightId + 1, renderTarget));
		}

		private function pushDualParaboloidShadowMappingPass(sceneBindings	: DataBindingsProxy,
															 lightId 		: uint,
															 passes 		: Vector.<Shader>) : void
		{
			var frontTextureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapFront'
			);
			var backTextureResource	 : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapBack'
			);
			var size				 : uint				= frontTextureResource.width;
			var frontRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, frontTextureResource, 0, 0xffffffff
			);
			var backRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, backTextureResource, 0, 0xffffffff
			);

			passes.push(
				new ParaboloidShadowMapShader(lightId, true, lightId + 0.5, frontRenderTarget),
				new ParaboloidShadowMapShader(lightId, false, lightId + 1, backRenderTarget)
			);
		}

		private function pushCubeShadowMappingPass(sceneBindings	: DataBindingsProxy,
												   lightId 			: uint,
												   passes 			: Vector.<Shader>) : void
		{
			var cubeTexture	: CubeTextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var textureSize	: uint					= cubeTexture.size;

			for (var i : uint = 0; i < 6; ++i)
				passes.push(new PCFShadowMapShader(
					lightId,
					lightId + .1 * i,
					new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff),
					i
				));
		}

		private function pushVarianceShadowMappingPass(sceneBindings	: DataBindingsProxy,
													   lightId 			: uint,
													   passes 			: Vector.<Shader>) : void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget		= new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new VarianceShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new VarianceShadowMapShader(
                        lightId,
                        i,
                        lightId + .1 * i,
                        new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function pushExponentialShadowMappingPass(sceneBindings	: DataBindingsProxy,
														  lightId 		: uint,
														  passes 		: Vector.<Shader>):void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget = new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new ExponentialShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new ExponentialShadowMapShader(
						lightId,
						i,
						lightId + .1 * i,
						new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function hasShadowBlurPass(sceneBindings	: DataBindingsProxy,
							    		   lightId 			: uint) : Boolean
		{
			var quality	: uint	= getLightProperty(sceneBindings, lightId, 'shadowQuality');

			return quality > ShadowMappingQuality.HARD;
		}

		private function lightPropertyExists(sceneBindings 	: DataBindingsProxy,
											 lightId 		: uint,
											 propertyName 	: String) : Boolean
		{
			return sceneBindings.propertyExists(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}

		private function getLightProperty(sceneBindings : DataBindingsProxy,
										  lightId 		: uint,
										  propertyName 	: String) : *
		{
			return sceneBindings.getProperty(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}
	}
}

add ASDoc to explain the behavior of PhongEffect


////////////////////////////////////////////////////////////////////////////////
//
//  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
{
	import org.apache.flex.core.IPanelModel;

	[Event(name="close", type="org.apache.flex.events.Event")]

	/**
	 *  The Panel class is a Container component capable of parenting other
	 *  components. The Panel has a TitleBar.  If you want to a Panel with
     *  a ControlBar, use PanelWithControlBar which
     *  will instantiate, by default, an ControlBar.
	 *  The Panel uses the following bead types:
	 *
	 *  org.apache.flex.core.IBeadModel: the data model for the Panel that includes the title and whether
	 *  or not to display the close button.
	 *  org.apache.flex.core.IBeadView: creates the parts of the Panel.
	 *  org.apache.flex.core.IBorderBead: if present, draws a border around the Panel.
	 *  org.apache.flex.core.IBackgroundBead: if present, provides a colored background for the Panel.
	 *
	 *  @see PanelWithControlBar
	 *  @see ControlBar
	 *  @see TitleBar
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class Panel extends Container
	{
		/**
		 *  constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function Panel()
		{
			super();
		}

		/**
		 *  The string to display in the org.apache.flex.html.TitleBar.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get title():String
		{
			return IPanelModel(model).title;
		}
		public function set title(value:String):void
		{
			IPanelModel(model).title = value;
		}

		/**
		 *  The HTML string to display in the org.apache.flex.html.TitleBar.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get htmlTitle():String
		{
			return IPanelModel(model).htmlTitle;
		}
		public function set htmlTitle(value:String):void
		{
			IPanelModel(model).htmlTitle = value;
		}

		/**
		 * Whether or not to show a Close button in the org.apache.flex.html.TitleBar.
		 */
		public function get showCloseButton():Boolean
		{
			return IPanelModel(model).showCloseButton;
		}
		public function set showCloseButton(value:Boolean):void
		{
			IPanelModel(model).showCloseButton = 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
{
	import org.apache.flex.core.IPanelModel;

    COMPILE::JS
    {
        import org.apache.flex.core.WrappedHTMLElement;
    }

	[Event(name="close", type="org.apache.flex.events.Event")]

	/**
	 *  The Panel class is a Container component capable of parenting other
	 *  components. The Panel has a TitleBar.  If you want to a Panel with
     *  a ControlBar, use PanelWithControlBar which
     *  will instantiate, by default, an ControlBar.
	 *  The Panel uses the following bead types:
	 *
	 *  org.apache.flex.core.IBeadModel: the data model for the Panel that includes the title and whether
	 *  or not to display the close button.
	 *  org.apache.flex.core.IBeadView: creates the parts of the Panel.
	 *  org.apache.flex.core.IBorderBead: if present, draws a border around the Panel.
	 *  org.apache.flex.core.IBackgroundBead: if present, provides a colored background for the Panel.
	 *
	 *  @see PanelWithControlBar
	 *  @see ControlBar
	 *  @see TitleBar
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class Panel extends Container
	{
		/**
		 *  constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function Panel()
		{
			super();
		}

		/**
		 *  The string to display in the org.apache.flex.html.TitleBar.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get title():String
		{
			return IPanelModel(model).title;
		}
		public function set title(value:String):void
		{
			IPanelModel(model).title = value;
		}

		/**
		 *  The HTML string to display in the org.apache.flex.html.TitleBar.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get htmlTitle():String
		{
			return IPanelModel(model).htmlTitle;
		}
		public function set htmlTitle(value:String):void
		{
			IPanelModel(model).htmlTitle = value;
		}

		/**
		 * Whether or not to show a Close button in the org.apache.flex.html.TitleBar.
		 */
		public function get showCloseButton():Boolean
		{
			return IPanelModel(model).showCloseButton;
		}
		public function set showCloseButton(value:Boolean):void
		{
			IPanelModel(model).showCloseButton = value;
		}

        COMPILE::JS
        override protected function createElement():WrappedHTMLElement
        {
            super.createElement();
            element.className = "Panel";
            typeNames = "Panel";
            return element;
        }
	}
}

fix panel background styling

fix panel background styling