/// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IDefault page)
        {
            // http://blog.teamtreehouse.com/accessing-the-device-camera-with-getusermedia
            // http://stackoverflow.com/questions/11539689/why-localstreams-contains-localmediastream-and-remotestreams-contains-mediastrea
            // https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getUserMedia
            // http://neave.github.io/face-detection/


            var navigator = (NavigatorUserMedia)(object)Native.window.navigator;

            var successCallback =
                new Action<LocalMediaStream>(
                    localMediaStream =>
                    {
                        Console.WriteLine("got video");

                        //var src = (string)new IFunction("return window.URL.createObjectURL(this);").apply(localMediaStream);

                        var v = new IHTMLVideo { src = localMediaStream.ToObjectURL() }.AttachToDocument();

                        v.play();
                    }
                );

            var errorCallback =
                new Action<NavigatorUserMediaError>(
                    e =>
                    {
                        // restart on error? :P
                        Native.window.alert("no video: " + new { e.code });
                    }
                );

            //var a = 1;

            //var c = new MediaStreamConstraints { video = a == 1, audio = a == 0 };

            //var o = new IFunction("return {video: true};").apply(null);


            navigator.webkitGetUserMedia(
                new { video = true, audio = false },
                successCallback: IFunction.OfDelegate(
                    successCallback
                ),
                errorCallback: IFunction.OfDelegate(
                    errorCallback
                )
            );

            @"Hello world".ToDocumentTitle();
            // Send data from JavaScript to the server tier
            service.WebMethod2(
                @"A string from JavaScript.",
                value => value.ToDocumentTitle()
            );
        }
 public void drawImage(IHTMLVideo image, float dx, float dy, float dw, float dh)
 {
 }
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            Native.document.body.Clear();
            Native.document.body.style.margin = "0px";
            Native.document.body.style.padding = "0px";

            // http://stackoverflow.com/questions/11294836/streaming-mp4-with-vlc-to-html-browser

            // In XHTML, attribute minimization is forbidden, and the controls attribute must be defined as <video controls="controls">.

            // ogg wont show up on gearvr?

            //var v = new IHTMLVideo { src = "http://192.168.1.12:8080/x.ogg", controls = true }.AttachToDocument();

            // chrome displays 1 still and crashes on webm play. vlc shows black.
            // gearvr stays white.
            //var v = new IHTMLVideo { src = "http://192.168.1.12:8080/x.webm", controls = true }.AttachToDocument();

            // chrome stays black.
            var v = new IHTMLVideo { src = "http://192.168.1.12:8080/x.mp4", controls = true }.AttachToDocument();

            // this works in gearvr!
            //var v = new IHTMLVideo { src = "https://broken-links.com/tests/media/BigBuck.webm", controls = true }.AttachToDocument();
            //var v = new IHTMLVideo { src = "https://broken-links.com/tests/media/BigBuck.theora.ogv", controls = true }.AttachToDocument();

            // run in console session?
            // vlc goes crazy!
            // "C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"  –no-sse2 –no-sse41 -vvv "X:\media\Abraham Hicks - Is There Value In Being Vulnerable Or Open (2014).mp4" --sout '#transcode{vcodec=VP80,vb=800,scale=1,acodec=vorbis,ab=128,channels=2}:standard{access=http,mux="ffmpeg{mux=webm}",dst=192.168.1.12:8080/x.webm}' 
            // "X:\util\vlc-2.2.1-win32\vlc-2.2.1\vlc.exe" --intf dummy --verbose  -vvv "X:\media\Abraham Hicks - Is There Value In Being Vulnerable Or Open (2014).mp4" vlc://quit --sout '#transcode{vcodec=VP80,vb=800,scale=1,acodec=vorbis,ab=128,channels=2}:standard{access=http,mux="ffmpeg{mux=webm}",dst=192.168.1.12:8080/x.webm}' 
            // "X:\util\vlc-2.2.1-win32\vlc-2.2.1\vlc.exe" --no-loop --intf dummy --verbose  -vvv "X:\media\Abraham Hicks - Is There Value In Being Vulnerable Or Open (2014).mp4" --sout '#transcode{vcodec=VP80,vb=800,scale=1,acodec=vorbis,ab=128,channels=2}:standard{access=http,mux="ffmpeg{mux=webm}",dst=192.168.1.12:8080/x.webm}' 



            // http://stackoverflow.com/questions/5087687/howto-encode-webm-using-command-line-vlc

            // [0276ac3c] core input error: cannot start stream output instance, aborting
            //[006a75f4] stream_out_standard stream out error: no mux specified or found by extension

            // cvlc my_first_video.avi  –sout “#transcode{vcodec=VP80,vb=800,scale=1,acodec=vorbis,ab=128,channels=2}:std{access=file,mux=”ffmpeg{mux=webm}”,dst=my_first_video.webm}”
            //(note:


            //[02130d24] dummy interface: VLC media player - 2.2.1 Terry Pratchett (Weatherwax)
            //[02130d24] dummy interface: Copyright © 1996-2015 the VideoLAN team
            //[02130d24] dummy interface:
            //Warning: if you cannot access the GUI anymore, open a command-line window, go to the directory where you installed VLC and run "vlc -I qt"

            //[02130d24] dummy interface: using the dummy interface module...
            //[0218d6a4] stream_out_standard stream out error: no mux specified or found by extension
            //[0218d60c] core stream output error: stream chain failed for `standard{mux="",access="'#transcode{vcodec=VP80,vb=800,scale=1,acodec=vorbis,ab=128,channels=2}",dst="standard{access=http,mux=ffmpeg{mux=webm},dst=192.168.1.12:8080/x.webm}'"}'
            //[0213cc3c] core input error: cannot start stream output instance, aborting



            // https://www.maketecheasier.com/mastering-vlc-via-the-command-line-linux/
            // http://alien.slackbook.org/blog/vlc-and-creating-webm-video/

            //What the VLC graphical interface can not yet do, is allow you to encode WebM video. Lucky for us, VLC has a command-line interface as well, with a humongous amount of options whose learning curve is even steeper than that of vi 😉

            //The VLC command-line allows to encode/transcode WebM video! Want to try it out?


            // view-source:https://broken-links.com/tests/video/
            //            <video id="video" autobuffer height="240" poster="../images/bbb_poster-360x240.jpg" width="360">
            //        <source src="../media/BigBuck.m4v">
            //        <source src="../media/BigBuck.webm" type="video/webm">
            //        <source src="../media/BigBuck.theora.ogv" type="video/ogg">
            //</video>



            //            Streaming / Transcoding failed:
            //VLC could not open the mp4a audio encoder.
            // https://www.broken-links.com/2010/07/30/encoding-video-for-android/


            // https://broken-links.com/tests/video/comparison.html


            //new IStyle(v)
            //{
            //    position = IStyle.PositionEnum.@fixed,
            //    left = "0px",
            //    top = "0px",
            //    right = "0px",
            //    bottom = "0px",
            //};

            new IStyle(v)
            {
                position = IStyle.PositionEnum.absolute,
                left = "0px",
                top = "0px",
                width = "100%",
                height = "100%",
            };


            // would jsc be able to be the overlay buffer?
        }
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            // http://www.brucelawson.co.uk/2012/specifying-which-camera-in-getusermedia/
            // https://groups.google.com/forum/#!topic/discuss-webrtc/xLBdsLz_Mbw
            // http://stackoverflow.com/questions/15322622/using-multiple-usb-cameras-with-web-rtc

            // dont we have async available?
            Native.window.navigator.getUserMedia(
                stream =>
                {
                    // getUserMedia error { code = , message = , name = DevicesNotFoundError }


                    var v = new IHTMLVideo { src = stream.ToObjectURL() };

                    v.AttachToDocument();

                    v.play();

                    new IHTMLButton { innerText = "record frame" }.AttachToDocument().onclick +=
                        delegate
                        {
                            // Uncaught IndexSizeError: Index or size was negative, or greater than the allowed value. 
                            var c = new CanvasRenderingContext2D(v.clientWidth, v.clientHeight);

                            c.drawImage(
                                v, 0, 0, c.canvas.width, c.canvas.height
                            );

                            var bytes = c.bytes;

                            c.canvas.AttachToDocument();
                        };

                    new IHTMLButton { innerText = "record gif" }.AttachToDocument().WhenClicked(

                       async btn =>
                       {
                           btn.disabled = true;


                           var frames = new List<byte[]>();
                           var x = v.clientWidth;
                           var y = v.clientHeight;

                           //new Timer(
                           //    async tt =>
                           //    {


                           btn.innerText = "rec " + new { frames.Count }.ToString();
                           //while (frames.Count < 60)

                           //while (frames.Count < 20)
                           while (frames.Count < 2)

                               // works with two frames.
                               // are we logging too much data?

                               // cant we hop to another thread in bytes instead yet?
                           // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108
                               // are we encoding grame bytes as base64?

                           {
                               await Task.Delay(1000 / 5);

                               btn.innerText = new { frames.Count }.ToString();

                               var bytes = v.bytes;

                               Console.WriteLine(new { bytes.Length });

                               // script: error JSC1000: No implementation found for this native method, please implement
                               // [System.Threading.Tasks.TaskFactory`1.
                               // StartNew(, System.Object, System.Threading.CancellationToken, System.Threading.Tasks.TaskCreationOptions, System.Threading.Tasks.TaskScheduler)]

                               frames.Add(bytes);

                           }


                           Console.WriteLine("encoding!");

                           var e = new Stopwatch();
                           e.Start();


                           // crashes the browser why???
                           var src = await new GIFEncoderWorker(
                               x,
                               y,
                                   delay: 1000 / 10,
                               frames: frames,
                               AtFrame:
                                async index =>
                                {
                                    btn.innerText = new { index, frames.Count }.ToString();

                                    if (index == frames.Count - 1)
                                    {
                                        btn.style.color = "blue";
                                        await Task.Delay(800);
                                        btn.style.color = "";

                                        btn.innerText = "record gif";

                                    }
                                }


                           );


                           Console.WriteLine("done! " + new { e.Elapsed });

                           new IHTMLImage { src = src }.AttachToDocument();


                           btn.disabled = false;


                           btn.title = new { e.Elapsed, src.Length }.ToString();

                       }
                       );
                }
            );

        }
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {

            // X:\jsc.svn\examples\javascript\WebCamToGIFAnimation\WebCamToGIFAnimation\Application.cs

            control.nfc.onnfc +=
                nfcid =>
                {
                    page.nfcid.innerText = new { nfcid }.ToString();
                };

            Native.window.navigator.getUserMedia(
               stream =>
               {

                   var v = new IHTMLVideo { src = stream.ToObjectURL() };

                   v.AttachToDocument();

                   v.play();



                   control.nfc.onnfc +=
                        nfcid =>
                        {
                            var c = new CanvasRenderingContext2D(v.clientWidth, v.clientHeight);

                            c.drawImage(
                                v, 0, 0, c.canvas.width, c.canvas.height
                            );

                            c.fillText(
                                new { nfcid }.ToString()
                                , 4, 32, 400
                            );

                            var bytes = c.bytes;

                            c.canvas.AttachToDocument();
                        };

                   new IHTMLButton { innerText = "record frame" }.AttachToDocument().onclick +=
                       delegate
                       {
                           var c = new CanvasRenderingContext2D(v.clientWidth, v.clientHeight);

                           c.drawImage(
                               v, 0, 0, c.canvas.width, c.canvas.height
                           );

                           c.fillText(
                              new { xnfcid = "?", page.nfcid }.ToString()
                              , 4, 32, 400
                          );

                           var bytes = c.bytes;

                           c.canvas.AttachToDocument();
                       };
               }
           );

        }
 public void drawImage(IHTMLVideo image, float dx, float dy, float dw, float dh)
 {
 }