public Scene this[string name, double start, double end]
        {
            get
            {
                var s = new Scene
                {
                    start = start,
                    end = end,
                    name = name,

                    Owner = this
                };

                ReferencedScenes.Add(s);

                return s;
            }
        }
        public YouTubePlayer(
            string TargetContent = "http://www.youtube.com/apiplayer?version=3",
            int DefaultWidth = 1280,
            int DefaultHeight = 720,
            string DefaultVideo = "Z__-3BbPq6g",

            string suggestedQuality = "hd720",


            Action yield_init = null
            )
        {
            var ldr = new Loader();
            this.Loader = ldr;
            var urlReq = new URLRequest(TargetContent);

            var ctx_app = ApplicationDomain.currentDomain;
            var ctx_sec = SecurityDomain.currentDomain;

            // http://www.youtube.com/crossdomain.xml
            ctx_app = null;
            ctx_sec = null;

            // http://www.zedia.net/2010/using-the-actionscript-3-youtube-api/

            bool once = false;

            #region onReady
            Action<Event> onReady = e =>
            {
                if (once)
                    return;

                once = true;


#if JSC_FEATURE_dynamic
                        dynamic player = ldr.content;

                        player.setSize(160, 120);
#endif
                ldr.content.setSize(DefaultWidth, DefaultHeight);

                pauseVideo = delegate
                {
                    ldr.content.pauseVideo();
                };

                loadVideoById = x =>
                {
                    CurrentVideoId = x;

                    ldr.content.loadVideoById(x, suggestedQuality: suggestedQuality);
                };

                loadVideoById(DefaultVideo);

                if (yield_init != null)
                {
                    yield_init();
                    yield_init = null;
                }


            };
            #endregion


            var PreviousCurrentState = YouTubePlayerState.unknown;
            var CurrentState = YouTubePlayerState.unknown;

            DefaultScene = this["default", 0, 1000];
            var CurrentScene = DefaultScene;
            Action CurrentSceneDone = delegate { };

            #region onStateChange
            Action<Event> onStateChange = e =>
            {
                PreviousCurrentState = CurrentState;
                CurrentState = e.get_data_as_YouTubePlayerState();

                if (PreviousCurrentState != CurrentState)
                {
                    if (CurrentState == YouTubePlayerState.playing)
                    {
                        // notify other scenes of delinking?

                        if (this.Playing != null)
                            this.Playing(SceneTranslate(CurrentScene));

                        this.ReferencedScenes.WithEach(
                            k =>
                            {
                                k.RaiseLinkDenotification();
                            }
                        );
                    }
                    else
                    {
                        if (this.NotPlaying != null)
                            this.NotPlaying(SceneTranslate(CurrentScene));
                    }

                    if (CurrentState == YouTubePlayerState.paused)
                    {
                        if (this.Paused != null)
                            this.Paused(SceneTranslate(CurrentScene));

                    }
                }
            };
            #endregion


            var TimeToPause = 0.4;

            var t = new Timer(1000 / 100);

            var PlaySceneCounter = 0;

            t.timer +=
                delegate
                {
                    if (ldr.content == null)
                        return;

                    if (CurrentState == YouTubePlayerState.playing)
                    {
                        var time = ldr.content.getCurrentTime();

                        var time_index = (int)time;

                        var duration = ldr.content.getDuration();

                        var playall = CurrentScene.end > duration;

                        // flag4 = ((double0 < (double2 - 500)) == 0);
                        // 1 second is 1.0!! :)
                        var notending = time < (duration - 0.500);
                        //var xending = time >= (duration - 500);
                        var ending = !notending;

                        // ReferenceError: Error #1069: Property getDuration not found on flash.display.Loader and there is no default value.
                        var m = new { PlaySceneCounter, time, time_index, CurrentScene.end, duration, playall, ending }.ToString();

                        if (StatusToClients != null)
                            StatusToClients(m);

                        // phone activated

                        if (playall)
                        {
                            if (ending)
                            {
                                ldr.content.pauseVideo();
                                CurrentSceneDone();
                            }
                        }
                        else if (time >= (TimeToPause))
                        {
                            ldr.content.pauseVideo();
                            CurrentSceneDone();
                        }
                    }
                };

            t.start();

            #region PlayScene
            this.PlayScene =
                (e, Done) =>
                {
                    PlaySceneCounter++;

                    //if (e.end == 0)
                    //    e.end = ldr.content.getDuration() - 1000;

                    CurrentScene = e;
                    CurrentSceneDone = Done;

                    TimeToPause = e.end;

                    ldr.content.seekTo(e.start);
                    ldr.content.playVideo();
                };
            #endregion



            ldr.contentLoaderInfo.ioError +=
                delegate
                {

                };

            ldr.contentLoaderInfo.init +=
                delegate
                {
                    ldr.content.addEventListener("onReady", onReady.ToFunction(), false, 0, false);
                    ldr.content.addEventListener("onStateChange", onStateChange.ToFunction(), false, 0, false);

                };

            var ctx = new LoaderContext(true, ctx_app, ctx_sec);
            ldr.load(urlReq, ctx);


            this.Scenes = new SceneSequenzer { Owner = this };
        }