// http://stackoverflow.com/questions/14111052/adding-multi-window-support-to-android-application

        protected override void onCreate(Bundle savedInstanceState)
        {
            base.onCreate(savedInstanceState);

            //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

            //this.ToFullscreen();

            var v = new RenderingContextView(this);
            var s = new SpiralSurface(v);

            this.setContentView(v);

            //this.TryHideActionbar(v);

            this.ShowToast("http://my.jsc-solutions.net");
        }
            public __WebGLSpiralElement(WebGLSpiralElement e)
            {
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/20140705/20140718-shadowdom
                // can we become the first shadow DOM webgl example?



                //          public bool alpha = false;
                //public bool preserveDrawingBuffer = true;

                var gl = new WebGLRenderingContext(alpha: false, preserveDrawingBuffer: true);

                var canvas = gl.canvas.AttachTo(e.shadow);

                //canvas.style.SetLocation(0, 0);



                //#region Dispose
                var IsDisposed = false;

                //Dispose = delegate
                //{
                //    if (IsDisposed)
                //        return;

                //    IsDisposed = true;

                //    canvas.Orphanize();
                //};
                //#endregion


                var s = new SpiralSurface(this);

                this.onsurface(gl);

                #region AtResize
                Action AtResize = delegate
                {
                    if (IsDisposed)
                    {
                        return;
                    }

                    canvas.width = 256;
                    canvas.height = 256;

                    this.onresize(256, 256);
                };

                AtResize();

                //Native.window.onresize += delegate
                //{
                //    AtResize();
                //};
                #endregion



                Native.window.onframe += delegate
                {
                    if (IsDisposed)
                        return;

                    s.ucolor_1 = float.Parse(e.cursorx) / (float)256;

                    this.onframe();


                };


                //#region requestFullscreen
                //Native.Document.body.ondblclick +=
                //    delegate
                //    {
                //        if (IsDisposed)
                //            return;

                //        // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/

                //        Native.Document.body.requestFullscreen();
                //    };
                //#endregion

                //#region newicon
                //Func<string> newicon = delegate
                //{
                //    var icon = canvas.toDataURL("image/png");

                //    Native.Document.getElementsByTagName("link").AsEnumerable().ToList().WithEach(
                //        e =>
                //        {
                //            var link = (IHTMLLink)e;

                //            if (link.rel == "icon")
                //            {
                //                if (link.type == "image/png")
                //                {

                //                    link.href = icon;
                //                }
                //                else
                //                {
                //                    link.Orphanize();
                //                }
                //            }
                //        }
                //    );

                //    return icon;
                //};
                //#endregion


                e.onmousemove +=
                    ee =>
                    {
                        e.cursorx = "" + ee.CursorX;
                        //s.ucolor_1 = ee.CursorX / (float)256;
                        s.ucolor_2 = ee.CursorY / (float)256;
                    };

                Action speed_AtResize = delegate
                {
                    //s.speed = Native.Screen.width - Native.Screen.width;
                };

                Native.window.onresize +=
                    delegate
                    {
                        speed_AtResize();
                    };

                speed_AtResize();

                //Native.document.body.onclick +=
                //    delegate
                //    {
                //        if (IsDisposed)
                //            return;

                //        newicon();
                //    };

                //@"Spiral".ToDocumentTitle();

                //new IHTMLAnchor { "drag me" }.AttachToDocument().With(
                //    dragme =>
                //    {
                //        dragme.style.position = IStyle.PositionEnum.@fixed;
                //        dragme.style.left = "1em";
                //        dragme.style.bottom = "1em";

                //        // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201405/20140504
                //        // look up the doc.
                //        // build server needs to build that component first.
                //        // where is it?
                //        //#region Assembly TestPackageAsApplication.dll, v1.0.0.0
                //        //// X:\jsc.svn\examples\javascript\WebGL\WebGLSpiral\packages\TestPackageAsApplication.1.0.0.0\lib\TestPackageAsApplication.dll
                //        //#endregion
                //        // "X:\jsc.svn\examples\javascript\Test\TestPackageAsApplication\TestPackageAsApplication\TestPackageAsApplication.csproj"

                //        dragme.AllowToDragAsApplicationPackage();
                //    }
                //);
            }
        /// <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)
        {
            "Spiral".ToDocumentTitle();

            var canvas = new IHTMLCanvas().AttachToDocument();

            Native.Document.body.style.overflow = IStyle.OverflowEnum.hidden;
            canvas.style.SetLocation(0, 0);

            #region gl

            var gl = default(WebGLRenderingContext);

            try
            {

                gl = (WebGLRenderingContext)canvas.getContext("experimental-webgl");

            }
            catch { }

            if (gl == null)
            {
                //Native.Window.alert("WebGL not supported");
                //throw new InvalidOperationException("cannot create webgl context");
                return;
            }
            #endregion

            #region Dispose
            var IsDisposed = false;

            //Dispose = delegate
            //{
            //    if (IsDisposed)
            //        return;

            //    IsDisposed = true;

            //    canvas.Orphanize();
            //};
            #endregion


            var s = new SpiralSurface(this);

            this.onsurface(gl);

            #region AtResize
            Action AtResize = delegate
            {
                if (IsDisposed)
                {
                    return;
                }

                canvas.width = Native.window.Width;
                canvas.height = Native.window.Height;

                this.onresize(Native.window.Width, Native.window.Height);
            };

            AtResize();

            Native.window.onresize += delegate
            {
                AtResize();
            };
            #endregion


          

            Native.window.onframe += delegate { this.onframe(); };


            #region requestFullscreen
            Native.Document.body.ondblclick +=
                delegate
                {
                    if (IsDisposed)
                        return;

                    // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/

                    Native.Document.body.requestFullscreen();
                };
            #endregion




            Native.Document.onmousemove +=
                e =>
                {
                    s.ucolor_1 = e.CursorX / Native.window.Width;
                    s.ucolor_2 = e.CursorY / Native.window.Height;
                };

        }
        /// <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)
        {
            //#region ChromeTCPServer
            //dynamic self = Native.self;
            //dynamic self_chrome = self.chrome;
            //object self_chrome_socket = self_chrome.socket;

            //if (self_chrome_socket != null)
            //{
            //    //chrome.Notification.DefaultIconUrl = new HTML.Images.FromAssets.Preview().src;
            //    chrome.Notification.DefaultTitle = "WebGLToAnimatedGIFExperiment";


            //    ChromeTCPServer.TheServerWithStyledForm.Invoke(
            //        AppSource.Text
            //    );

            //    return;
            //}
            //#endregion




            var ani6 = new WebGLEarthByBjorn.Application(null);

            ani6.canvas.AttachTo(page.e1);
            ani6.canvas.style.SetSize(96, 96);
            ani6.canvas.style.position = IStyle.PositionEnum.relative;



            var ani5 = new WebGLSVGAnonymous.Application(null);

            ani5.canvas.AttachTo(page.e1);

            // gif needs a bg?
            //ani4.canvas.style.backgroundColor = "yellow";

            ani5.canvas.style.SetSize(96, 96);
            ani5.canvas.style.position = IStyle.PositionEnum.relative;

            var ani4 = new WebGLColladaExperiment.Application(null);

            ani4.canvas.AttachTo(page.e1);

            // gif needs a bg?
            //ani4.canvas.style.backgroundColor = "yellow";

            ani4.canvas.style.SetSize(96, 96);
            ani4.canvas.style.position = IStyle.PositionEnum.relative;


            var ani3 = new WebGLTetrahedron.Application();

            ani3.gl.canvas.AttachTo(page.e1);

            // : ScriptComponent
            var ani2 = new WebGLEscherDrosteEffect.Application();

            ani2.gl.canvas.AttachTo(page.e1);





            var gl = new WebGLRenderingContext(alpha: false, preserveDrawingBuffer: true);

            // replace placeholder
            gl.canvas.id = page.canvas.id;
            page.canvas = gl.canvas;

            page.canvas.width = 96;
            page.canvas.height = 96;

            var s = new SpiralSurface(this);

            this.onsurface(gl);



            this.onresize(page.canvas.width, page.canvas.height);

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

            Native.window.onframe += delegate
            {
                s.ucolor_1 = (float)Math.Sin(st.ElapsedMilliseconds * 0.001) * 0.5f + 0.5f;

                this.onframe();
            };






            // jsc should link that js file once we reference it. for now its manual


            #region activate
            Action<IHTMLCanvas> activate =
                xcanvas =>
                {
                    var context = new { canvas = xcanvas };

                    context.canvas.style.border = "2px solid yellow";
                    context.canvas.style.cursor = IStyle.CursorEnum.pointer;

                    context.canvas.onclick +=
                         delegate
                         {
                             var c0 = new CanvasRenderingContext2D(96, 96);
                             c0.canvas.AttachToDocument();

                             var frames = new List<byte[]>();

                             // view-source:36524
                             //{ ToBase64String_while_timeout = 00:00:00.504, i = 911952, length = 1454096 } view-source:36524


                             //var framecount = 240;
                             //var delay = 1000 / 60;

                             var framecount = 16;
                             var delay = 1000 / 15;

                             new ScriptCoreLib.JavaScript.Runtime.Timer(
                                 async t =>
                                 {
                                     if (t.Counter == framecount)
                                     {
                                         Console.WriteLine("GIFEncoderWorker!");


                                         var src = await new GIFEncoderWorker(
                                                 96,
                                                 96,
                                                  delay: delay,
                                                 frames: frames
                                         );

                                         Console.WriteLine("done!");

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

                                         return;
                                     }

                                     if (t.Counter >= framecount)
                                     {
                                         c0.bytes = frames[t.Counter % frames.Count];

                                         return;
                                     }

                                     #region force redraw all
                                     s.ucolor_2 = t.Counter / 32.0f;

                                     // force redraw
                                     this.onframe();
                                     #endregion


                                     if (!t.IsAlive)
                                         return;

                                     c0.drawImage(context.canvas, 0, 0, 96, 96);

                                     frames.Add(c0.getImageData().data);



                                 }
                              ).StartInterval(1000 / 60);

                         };
                };
            #endregion


            activate(gl.canvas);
            activate(ani2.gl.canvas);
            activate(ani3.gl.canvas);
            activate(ani4.canvas);
            activate(ani5.canvas);
            activate(ani6.canvas);





        }
        public __InitializeAndroidActivity()
        {
            var isActivity = ScriptCoreLib.Android.ThreadLocalContextReference.CurrentContext is Activity;
            var isService = ScriptCoreLib.Android.ThreadLocalContextReference.CurrentContext is Service;


            var t = ScriptCoreLib.Android.ThreadLocalContextReference.CurrentContext.GetType();

            Console.WriteLine("StaticInvoke " + new { isActivity, isService, t });

            //  Exception Ljava/lang/RuntimeException; thrown while initializing LTryHideActionbarExperiment/StaticInvoke;
            try
            {


                // https://groups.google.com/forum/?fromgroups=#!topic/android-developers/suLMCWiG0D8


                // StaticInvoke { isActivity = false, t = com.abstractatech.spiral.ApplicationWebServiceXWidgetsWindow }

                //(ScriptCoreLib.Android.ThreadLocalContextReference.CurrentContext as Service).With(

                //                public virtual View getChildAt(int value);
                //public virtual int getChildCount();

                // 
                //         Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                //at android.view.ViewRoot.checkThread(ViewRoot.java:3020)
                //at android.view.ViewRoot.clearChildFocus(ViewRoot.java:1699)




                (ScriptCoreLib.Android.ThreadLocalContextReference.CurrentContext as Activity).runOnUiThread(
                    a =>
                    {
                        // http://stackoverflow.com/questions/4451641/change-android-layout-programatically
                        var v = new RenderingContextView(a);
                        var s = new SpiralSurface(v);

                        v.onsurface +=
                            gl =>
                            {

                                #region onaccelerometer
                                v.onaccelerometer +=
                                    (x, y, z) =>
                                    {
                                        s.speed = 10 + 200 * x / 10f + 200 * y / 10f;

                                        var ay = y;
                                        if (y < 0)
                                            ay = -y;

                                        s.ucolor_1 = (10f - ay) / 10f;

                                        if (s.ucolor_1 < 0)
                                            s.ucolor_1 = 0;

                                        if (s.ucolor_1 > 10)
                                            s.ucolor_1 = 10;

                                        var ax = x;
                                        if (x < 0)
                                            ax = -x;

                                        s.ucolor_2 = (10f - ax) / 10f;

                                        if (s.ucolor_2 < 0)
                                            s.ucolor_2 = 0;

                                        if (s.ucolor_2 > 10)
                                            s.ucolor_2 = 10;
                                    };
                                #endregion



                                //Log.wtf("com.abstractatech.spiral", "onsurface done");

                            };


                        a.setContentView(v);
                    }
                );
            }
            catch (Exception ex)
            {
                Console.WriteLine("error: " + new { ex.Message, ex.StackTrace });
            }
        }