package net.eidiot.player
{
    import fl.controls.*;
    import fl.events.SliderEvent;

    import flash.display.*;
    import flash.events.*;
    import flash.geom.Rectangle;
    import flash.net.URLRequest;

    /**
     * SWF播放器
     *
     * @author    eidiot (http://eidiot.net)
     * @date    070613
     * @version    0.1.070616
     */
    public class SWFPlayer extends Sprite
    {
        /* 载入MC的显示区域 */
        private static const SHOW_X : Number = 20;
        private static const SHOW_Y : Number = 20;
        private static const SHOW_W : Number = 200;
        private static const SHOW_H : Number = 200;
        /* ui */
        public var btn1 : Button;
        public var btn2 : Button;
        public var fms : TextInput;
        public var sdr : Slider;
        /* 加载 */
        private var m_urlList : Array = ["mc1.swf", "mc2.swf"];
        private var m_request : URLRequest;
        private var m_loader : Loader;
        private var m_loading : SWFLoading;
        private var m_mc : MovieClip;
        /* 状态变量 */
        private var m_isPressSdr : Boolean = false;

        /**
         * 构造函数
         */
        public function SWFPlayer()
        {
            this.init();
        }
        /**
         * @private
         * 初始化
         */
        private function init() : void
        {
            /* init ui */
            this.btn1.addEventListener(MouseEvent.CLICK, this.onClickBtn1);
            this.btn2.addEventListener(MouseEvent.CLICK, this.onClickBtn2);
            this.sdr.liveDragging = true;
            this.sdr.addEventListener(SliderEvent.CHANGE, this.onChangeSdr);
            this.sdr.addEventListener(SliderEvent.THUMB_PRESS, this.onPressSdr);
            this.sdr.addEventListener(SliderEvent.THUMB_RELEASE, this.onReleaseSdr);
            this.sdr.enabled = this.fms.enabled = false;
            /* init load */
            this.m_request = new URLRequest();
            this.m_loading = new SWFLoading(SHOW_W, SHOW_H, SHOW_X, SHOW_Y);
        }
        /**
         * @private
         * 加载MC
         *
         * @param p_index    MC(地址在m_urlList中的)索引
         */
        private function loadMc(p_index : int) : void
        {
            /* reset ui */
            this.sdr.value = 0;
            this.sdr.enabled = this.btn1.enabled = this.btn2.enabled = false;
            /* 移除已经加载的mc */
            if (this.m_mc != null)
            {
                this.removeEventListener(Event.ENTER_FRAME, this.onEnterFrame);
                this.removeChild(this.m_mc);
                this.m_mc = null;
            }
            /* 加载新的MC */
            this.m_request.url = this.m_urlList[p_index];
            this.m_loader = new Loader();
            this.initLoaderEvent();
            this.m_loader.load(this.m_request);
            this.m_loading.show(this);
        }
        /**
         * @private
         * 显示加载的MC
         */
        private function showSWF() : void
        {
            // 隐藏loading
            this.m_loading.hide();
            // loaderInfo
            var t_info : LoaderInfo = this.m_loader.contentLoaderInfo;
            // 载入的MC
            this.m_mc = t_info.content as MovieClip;
            // 载入MC的舞台宽度
            var t_stageW : Number = t_info.width;
            // 载入MC的舞台高度
            var t_stageH : Number = t_info.height;
            // 载入MC的实际宽度
            var t_mcW : Number = this.m_mc.width;
            // 载入MC的实际高度
            var t_mcH : Number = this.m_mc.height;
            // 是否缩放MC适应显示宽度(载入MC舞台的宽高比是否大于显示区域宽高比)
            var t_scaleWidth : Boolean = t_stageW / t_stageH > SHOW_W / SHOW_H;
            // 缩放比率
            var t_scaleRate : Number = t_scaleWidth ? SHOW_W / t_stageW : SHOW_H / t_stageH;
            // 缩放MC
            this.m_mc.scaleX = this.m_mc.scaleY = t_scaleRate;
            // 显示载入MC的显示范围
            this.m_mc.scrollRect = new Rectangle(0, 0, t_stageW, t_stageH);
            // 显示载入MC
            this.addChild(this.m_mc);
            // 调整显示位置
            this.m_mc.x = SHOW_X;
            this.m_mc.y = SHOW_Y;
            if (t_scaleWidth) this.m_mc.y += (SHOW_H - t_stageH * t_scaleRate) / 2;
            else this.m_mc.x += (SHOW_W - t_stageW * t_scaleRate) / 2;
            // 修改帧频
            this.stage.frameRate = t_info.frameRate;
            this.fms.text = String(this.stage.frameRate);
            // 设置组件
            this.sdr.enabled = this.btn1.enabled = this.btn2.enabled = true;
            this.sdr.maximum = this.m_mc.totalFrames;
            // 监听MC事件
            this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
        }
        /**
         * @private
         * 初始化加载事件
         */
        private function initLoaderEvent() : void
        {
            var t_info : LoaderInfo = this.m_loader.contentLoaderInfo;
            t_info.addEventListener(Event.COMPLETE, this.onLoadDone);
            t_info.addEventListener(IOErrorEvent.IO_ERROR, this.onLoadError);
            t_info.addEventListener(ProgressEvent.PROGRESS, this.onLoadProgress);
        }
        /**
         * @private
         * 移除加载事件
         */
        private function killLoaderEvent() : void
        {
            var t_info : LoaderInfo = this.m_loader.contentLoaderInfo;
            t_info.removeEventListener(Event.COMPLETE, this.onLoadDone);
            t_info.removeEventListener(IOErrorEvent.IO_ERROR, this.onLoadError);
            t_info.removeEventListener(ProgressEvent.PROGRESS, this.onLoadProgress);
        }
        /* onEnterFrame事件 */
        private function onEnterFrame(p_e : Event) : void
        {
            this.sdr.value = this.m_mc.currentFrame;
        }
        /* ui 事件 */
        private function onClickBtn1(p_e : MouseEvent) : void
        {
            this.loadMc(0);
        }
        private function onClickBtn2(p_e : MouseEvent) : void
        {
            this.loadMc(1);
        }
        private function onChangeSdr(p_e : SliderEvent) : void
        {
            if (this.m_isPressSdr) this.m_mc.gotoAndStop(p_e.value);
        }
        private function onPressSdr(p_e : SliderEvent) : void
        {
            this.m_isPressSdr = true;
            this.m_mc.stop();
        }
        private function onReleaseSdr(p_e : SliderEvent) : void
        {
            this.m_isPressSdr = false;
            this.m_mc.play();
        }
        /* 加载事件 */
        private function onLoadDone(p_e : Event) : void
        {
            this.killLoaderEvent();
            this.m_loading.hide();
            this.showSWF();
        }
        private function onLoadError(p_e : Event) : void
        {
            this.killLoaderEvent();
            this.m_loading.showError();
        }
        private function onLoadProgress(p_e : ProgressEvent) : void
        {
            this.m_loading.progress(p_e.bytesLoaded, p_e.bytesTotal);
        }
    }
}
    import flash.text.TextField;
    import flash.display.DisplayObjectContainer;
    import flash.text.TextFieldAutoSize;

    /**
     * 加载进度显示
     */
    internal class SWFLoading extends TextField
    {
        /**
         * 构造函数
         *
         * @param p_w    显示宽度
         * @param p_h    显示高度
         * @param p_x    x坐标
         * @param p_y    y坐标
         */
        public function SWFLoading(p_w : Number, p_h : Number, p_x : Number = 0, p_y : Number = 0)
        {
            this.text = "正在加载SWF ... ";
            this.width = p_w;
            this.autoSize = TextFieldAutoSize.CENTER;
            this.selectable = false;
            this.x += p_x;
            this.y += p_y + (p_h - this.height) / 2;
        }
        /**
         * 显示
         *
         * @param p_parent 父容器
         */
        internal function show(p_parent : DisplayObjectContainer) : void
        {
            p_parent.addChild(this);
        }
        /**
         * 隐藏
         */
        internal function hide() : void
        {
            if (this.parent != null) this.parent.removeChild(this);
        }
        /**
         * 更新加载进度
         *
         * @param p_loaded    已加载字节
         * @param p_total    文件总字节
         */
        internal function progress(p_loaded : Number, p_total : Number) : void
        {
            this.text = "正在加载SWF ... " + int(p_loaded / p_total * 100) + "%";
        }
        /**
         * 显示信息
         *
         * @param p_info    文字信息
         */
        internal function showInfo(p_info : String) : void
        {
            this.text = p_info;
        }
        /**
         * 显示加载失败
         * @param p_info    错误信息
         */
        internal function showError(p_info : String = null) : void
        {
            this.text = p_info == null ? "SWF加载失败" : p_info;
        }
    }