// new three broke it?
        // http://www.clicktorelease.com/code/perlin/explosion.html
        // http://www.webgl.com/2013/01/webgl-tutorial-vertex-displacement-with-a-noise-function-aka-fiery-explosion/


        /// <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 = null)
        {
            // http://inear.se/fireshader/




            // http://stackoverflow.com/questions/16765120/ashima-perlin-noise-shader-not-working-with-recent-versions-of-three-js

            //var container, renderer,  camera, mesh;
            var start = IDate.Now;
            var fov = 30;


            #region container
            Native.document.body.style.overflow = IStyle.OverflowEnum.hidden;
            var container = new IHTMLDiv();

            container.AttachToDocument();
            container.style.backgroundColor = "#000000";
            container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);
            #endregion


            var scene = new THREE.Scene();
            var bkgScene = new THREE.Scene();

            var camera = new THREE.PerspectiveCamera(fov, Native.window.aspect, 1, 10000);
            camera.position.z = 100;
            //camera.target = new THREE.Vector3(0, 0, 0);

            scene.add(camera);

            var bkgCamera = new THREE.OrthographicCamera(
                Native.window.Width / -2,
                Native.window.Width / 2,
                Native.window.Height / 2,
                Native.window.Height / -2,
                -10000,
                10000
            );

            bkgScene.add(bkgCamera);

            var bkgShader = new THREE.ShaderMaterial(
                new 
                {
                    uniforms = new 
                    {
                        tDiffuse = new 
                        {
                            type = "t",
                            value = THREE.ImageUtils.loadTexture(
                                new HTML.Images.FromAssets.bkg().src
                            )
                        },

                        resolution = new  { type = "v2", value = new THREE.Vector2(Native.window.Width, Native.window.Height) }
                    },

                    vertexShader = new Shaders.ExplosionVertexShader().ToString(),
                    //        fragmentShader: document.getElementById( 'fs_Gradient' ).textContent,
                    //fragmentShader = new Shaders.GradientFragmentShader().ToString(),
                    fragmentShader = new Shaders.ExplosionFragmentShader().ToString(),

                    depthWrite = false,
                    depthTest = false,
                    transparent = true
                }
            );

            var quad = new THREE.Mesh(new THREE.PlaneGeometry(Native.window.Width, Native.window.Height), bkgShader);
            quad.position.z = -100;
            quad.rotation.x = (float)Math.PI / 2;
            bkgScene.add(quad);


            var material = new THREE.ShaderMaterial(

                new 
                {
                    uniforms = new // material_uniforms
                    {
                        tExplosion = new  //uniforms_item
                        {
                            type = "t",
                            value =  THREE.ImageUtils.loadTexture(
                                new HTML.Images.FromAssets.explosion().src
                            )
                        },
                        time = new { type = "f", value = 0.0 },
                        weight = new { type = "f", value = 8.0 },
                    },

                    vertexShader = new Shaders.ExplosionVertexShader().ToString(),
                    fragmentShader = new Shaders.ExplosionFragmentShader().ToString(),
                    depthWrite = false,
                    depthTest = false,
                    transparent = true
                }
            );


            var mesh = new THREE.Mesh(new THREE.SphereGeometry(20, 200, 200), material);
            scene.add(mesh);

            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(Native.window.Width, Native.window.Height);
            renderer.autoClear = false;

            container.appendChild(renderer.domElement);

          
            var lon = 0.0;
            var phi = 0.0;
            var theta = 0.0;
            var lat = 15.0;
            var isUserInteracting = false;


            var scale = 0.0;

            #region render

            Native.window.onframe += delegate
            {

                ((material_uniforms)material.uniforms).time.value = .00025 * (IDate.Now - start);

                scale += .005;
                scale %= 2;

                lat = Math.Max(-85, Math.Min(85, lat));
                phi = (90 - lat) * Math.PI / 180;
                theta = lon * Math.PI / 180;

                camera.position.x = (float)(100 * Math.Sin(phi) * Math.Cos(theta));
                camera.position.y = (float)(100 * Math.Cos(phi));
                camera.position.z = (float)(100 * Math.Sin(phi) * Math.Sin(theta));

                //mesh.rotation.x += .012;
                //mesh.rotation.y += .01;
                camera.lookAt(scene.position);

                //    //renderer.render( bkgScene, bkgCamera );
                renderer.render(scene, camera);

                //    stats.update();

            };


            #endregion



            #region IsDisposed

            Dispose = delegate
            {
                if (IsDisposed)
                    return;

                IsDisposed = true;


                container.Orphanize();
            };
            #endregion






            #region AtResize
            Action AtResize = delegate
            {
                container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);


                renderer.setSize(Native.window.Width, Native.window.Height);

                camera.projectionMatrix.makePerspective(fov, Native.window.aspect, 1, 1100);

                //camera.aspect = Native.Window.Width / Native.Window.Height;
                //camera.updateProjectionMatrix();
            };

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

            AtResize();
            #endregion



            var ze = new ZeProperties();

            ze.Show();
            ze.treeView1.Nodes.Clear();

            ze.Add(() => renderer);
            //ze.Add(() => controls);
            ze.Add(() => scene);
            ze.Left = 0;



        }
示例#2
0
        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108

        // X:\jsc.svn\examples\javascript\android\com.abstractatech.appmanager\com.abstractatech.appmanager\Application.cs

        // tested by
        // X:\jsc.svn\examples\javascript\android\com.abstractatech.adminshell\com.abstractatech.adminshell\Application.cs

        //02000066 ScriptCoreLib.JavaScript.Experimental.X+<>c__DisplayClassc+<<GetAwaiter>b__7>d__11
        //script: error JSC1000: if block not detected correctly, opcode was { Branch = [0x0020] beq        +0 -2{[0x0019] ldfld      +1 -1{[0x0018] ldarg.0    +1 -0} } {[0x001e] ldc.i4.s   +1 -0} , Location =
        // assembly: T:\com.abstractatech.adminshell.Application.exe
        // type: ScriptCoreLib.JavaScript.Experimental.X+<>c__DisplayClassc+<<GetAwaiter>b__7>d__11, com.abstractatech.adminshell.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
        // offset: 0x0020
        //  method:Int32 <>02000019<>06000044<>MoveNext<0000>.try(<>02000019<>06000044<>MoveNext, <<GetAwaiter>b__7>d__11 ByRef, System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]] ByRef, System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]] ByRef) }

        //public static object 


        // .NET 4.5!!!
        public static TaskAwaiter<InternalScriptApplicationSource> GetAwaiter(this Type __e)
        {
            Console.WriteLine("enter ScriptCoreLib.JavaScript.Experimental " + new { __e.Name });

            // http://stackoverflow.com/questions/9713058/sending-post-data-with-a-xmlhttprequest

            var y = new TaskCompletionSource<InternalScriptApplicationSource>();

            //var ysource = Native.window.sessionStorage[__e.Name];
            //if (ysource != null)
            //{
            //    y.SetResult(ysource);

            //    return y.Task.GetAwaiter();
            //}

            //return 

            //InternalInitializeInlineWorker Report: { __IProgress_Report = { value = [object Object] } }
            // view-source:27346
            //{ Name = a, loaded = 4538818, total = 4538818 } view-source:27346

            // view-source:27346
            //loading secondary app in a moment... { responseType = arraybuffer, ManagedThreadId = 10 }
            // view-source:27346
            //loading secondary app in a moment... { Length = 4538818 } decrypting...
            // view-source:27346
            //loading secondary app in a moment... { Length = 2269409 } done!

            var bar = new IHTMLDiv { }.AttachToDocument();

            bar.style.SetLocation(0, -2);
            bar.style.position = IStyle.PositionEnum.@fixed;
            bar.style.height = "3px";
            bar.style.backgroundColor = "red";
            //bar.style.borderBottom = "1px solid darkred";

            // http://stackoverflow.com/questions/9670075/css-transition-shorthand-with-multiple-properties

            (bar.style as dynamic).webkitTransition = "top 0.5s linear";
            //(bar.style as dynamic).webkitTransitionProperty = "top, width, background-color";
            (bar.style as dynamic).webkitTransitionProperty = "top, width";




            var state = new
                {
                    __e.Name,

                    backgroundColor = "red",

                    loaded = default(long),
                    total = default(long),
                    source = default(string),

                    Native.document.location.href,


                    references = new InternalScriptApplicationReference[0]
                };

            Console.WriteLine("call Task.Factory.StartNewWithProgress");

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108

            Task.Factory.StartNewWithProgress(
                state,

                progress: x =>
                {
                    bar.style.top = "0px";


                    #region bar
                    if (x.loaded > 0)
                        if (x.total > 0)
                        {
                            //if (x.loaded == x.total)
                            //{
                            //}
                            //else
                            //{
                            //    bar.style.SetLocation(0, 0);
                            //}

                            var xx = (int)(100 * x.loaded / x.total);

                            ;
                            // 
                            // 3% is the minimum we want to show
                            var per = Math.Max(3, xx) + "%";

                            //Console.WriteLine(new { per, x.loaded, x.total, x.backgroundColor });

                            bar.style.backgroundColor = x.backgroundColor;
                            bar.style.width = per;

                        }
                    #endregion



                    //Console.WriteLine(
                    //    new { x.Name, x.loaded, x.total }
                    //);

                    #region SetResult
                    x.source.With(
                        async source =>
                        {
                            //        // should we analyze? IFunction

                            //Console.WriteLine("wall save source to localStorage " + new { __e.Name, source.Length });

                            // sessionStorage out of memory?
                            //Native.window.sessionStorage[__e.Name] = source;

                            //Native.window.eval(
                            //    //x.responseText
                            //    source
                            //);


                            bar.style.backgroundColor = "yellow";
                            await Task.Delay(300);
                            bar.style.backgroundColor = "red";
                            await Task.Delay(300);
                            bar.style.backgroundColor = "yellow";
                            await Task.Delay(300);
                            bar.style.backgroundColor = "red";
                            await Task.Delay(300);
                            bar.Orphanize();

                            //                            { index = 0, name =  ScriptCoreLib.dll.js, size = 1330538 } view-source:27530

                            // view-source:27530
                            //{ index = 1, name =  WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js, size = 507500 } view-source:2753


                            y.SetResult(
                                new InternalScriptApplicationSource
                                {
                                    source = source,
                                    references = x.references
                                }

                            );
                        }
                    );
                    #endregion


                },


                function:
                    tuple =>
                    {
                        var progress = tuple.Item1;
                        var scope = tuple.Item2;

                        // http://stackoverflow.com/questions/13870853/how-to-upload-files-in-web-workers-when-formdata-is-not-defined
                        // FormData is not defined
                        //var f = new FormData();

                        //f.append("Application", scope.Name);


                        // can we use WebClient instead now?
                        var x = new IXMLHttpRequest();

                        // { src = /more-source } 

                        // { src = blob:http%3A//192.168.43.252%3A5485/fdec11d3-735f-4165-937a-43f25ef8d8d3#worker/more-source } 
                        // worker location might not help us talk to our server!

                        //var src = Native.worker.location.href + "/more-source";
                        //POST http://public:[email protected]:14356//more-source 400 (Bad Request) 
                        var src = scope.href;

                        Console.WriteLine(new { src });

                        x.open(ScriptCoreLib.Shared.HTTPMethodEnum.POST, src,
                            async: true,
                            user: "******",
                            password: "******"
                        );

                        // Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
                        x.setRequestHeader(
                            "X-Application", scope.Name
                        );

                        // what about progress?


                        // http://stackoverflow.com/questions/10956574/why-might-xmlhttprequest-progressevent-lengthcomputable-be-false

                        var xprogress = new { scope.loaded, scope.total };

                        // AppEngine will not report progress

                        #region onprogress
                        x.onprogress +=
                            e =>
                            {
                                // make room for decrypt progress
                                var loaded = e.loaded / 2;

                                xprogress = new { loaded, e.total };

                                //Console.WriteLine();

                                progress.Report(
                                    new
                                    {
                                        scope.Name,
                                        scope.backgroundColor,
                                        xprogress.loaded,
                                        xprogress.total,
                                        scope.source,
                                        scope.href,
                                        scope.references
                                    }
                                );

                            };
                        #endregion


                        #region decrypt
                        Action<byte[]> decrypt = response =>
                        {
                            var AllResponseHeaders = x.getAllResponseHeaders();

                            //AllResponseHeaders = Date: Wed, 11 Sep 2013 14:31:43 GMT
                            //X-Reference-0: ScriptCoreLib.dll.js 1330538
                            //Server: ASP.NET Development Server/11.0.0.0
                            //X-AspNet-Version: 4.0.30319
                            //X-Reference-1: WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js 487668
                            //X-DiagnosticsMakeItSlowAndAddSalt: ok
                            //Content-Type: application/octet-stream
                            //Cache-Control: public
                            //Connection: Close
                            //Content-Length: 3636412
                            //Expires: Wed, 11 Sep 2013 14:46:43 GMT

                            var prefix = "X-Reference-";

                            var references = AllResponseHeaders.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Where(k => k.StartsWith(prefix)).Select(
                                k =>
                                {
                                    var text = k.Substring(prefix.Length);

                                    var index = int.Parse(text.TakeUntilIfAny(":"));
                                    var name = text.SkipUntilIfAny(":").TakeUntilLastIfAny(" ");
                                    var size = int.Parse(text.SkipUntilIfAny(":").SkipUntilLastIfAny(" "));

                                    return new InternalScriptApplicationReference
                                    {
                                        index = index,
                                        name = name,
                                        size = size
                                    };
                                }
                            ).ToArray();


                            Console.WriteLine(
                                "loading secondary app in a moment... "
                                + new
                                {
                                    response.Length,
                                    Thread.CurrentThread.ManagedThreadId
                                } + " decrypting...");

                            // loading secondary app in a moment... { Length = 6265416, ManagedThreadId = 10 } decrypting...


                            //                            X-Reference-0:ScriptCoreLib.dll.js 1330538
                            //X-Reference-1:WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js 485234
                            // "X:\jsc.svn\examples\javascript\WorkerInsideSecondaryApplication\WorkerInsideSecondaryApplication.sln"

                            //y.SetResult(new { x.responseText.Length }.ToString());
                            // X:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\WebService\InternalGlobalExtensions.cs

                            var mstopwatch = Stopwatch.StartNew();
                            var m = new MemoryStream();

                            var lo = default(byte);
                            var lo_set = false;

                            foreach (var item in response)
                            {
                                if (lo_set)
                                {
                                    lo_set = false;

                                    var hi = (byte)(item << 4);

                                    m.WriteByte(
                                        (byte)(lo | hi)
                                    );

                                    if ((m.Length % 1024 * 8) == 0)
                                    {
                                        var loaded = xprogress.total / 2 + m.Length;

                                        xprogress = new { loaded, xprogress.total };

                                        //Console.WriteLine(new
                                        //{
                                        //    Thread.CurrentThread.ManagedThreadId,

                                        //    mstopwatch.ElapsedMilliseconds,
                                        //    xprogress
                                        //});

                                        progress.Report(
                                            new
                                            {
                                                scope.Name,
                                                backgroundColor = "cyan",
                                                xprogress.loaded,
                                                xprogress.total,
                                                scope.source,
                                                scope.href,
                                                scope.references
                                            }
                                        );
                                    }
                                }
                                else
                                {
                                    lo = item;
                                    lo_set = true;
                                }
                            }

                            // decrypted
                            Console.WriteLine("UTF8.GetString " + new { m.Length });

                            var source = Encoding.UTF8.GetString(m.ToArray());


                            Console.WriteLine("loading secondary app in a moment... " + new { source.Length } + " done!");

                            //return new { response.Length, responseText = source };

                            progress.Report(
                                new
                                {
                                    scope.Name,
                                    backgroundColor = "green",
                                    xprogress.loaded,
                                    xprogress.total,
                                    source,
                                    scope.href,
                                    references
                                }
                            );

                        };
                        #endregion


                        Action send = async delegate
                        {


                            var response = await x.bytes;


                            decrypt(response);

                        };


                        send();

                        // no changes yet
                        return scope;
                    }


            );


            return y.Task.GetAwaiter();


        }
        public void DrawRectangleToCanvas(CanvasRectangle c)
        {
            var x = new IHTMLDiv();

            x.style.overflow = IStyle.OverflowEnum.hidden;

            c._Dispose =
                delegate(CanvasRectangle u)
                {
                    if (x == null)
                        return;
                    x.Orphanize();
                    x = null;
                };

            c._Update =
                delegate(CanvasRectangle u)
                {
                    if (x == null)
                        return;

                    var r = u.Location;

                    x.style.SetLocation(r.Left, r.Top, r.Width, r.Height);
                    x.style.backgroundColor = u.BackgroundColor;
                };

            c.Update();

            this.Layers.Canvas.appendChild(x);

        }
        //Revision: 3636
        //Author: zproxy
        //Date: 22. aprill 2012. a. 11:16:53
        //Message:

        //----
        //Added : /examples/java/OutRun4KTemplate
        //Added : /examples/java/OutRun4KTemplate/OutRun4KTemplate




        // http://www.digitalinsane.com/archives/2007/01/21/space_invaders/
        public SpaceInvaders()
        {

            ImageResources gfx = "http://server/";

            var overlay = new Overlay();

            overlay.BackgroundColor = Color.Black;
            overlay.MaximumOpacity = 1;
            overlay.ControlInBack.style.zIndex = 100000;
            overlay.ControlInFront.style.zIndex = 100001;


            var view = overlay.ControlInFront;

            view.style.textAlign = IStyle.TextAlignEnum.center;
            view.style.SetSize(480, 480);
            view.style.backgroundColor = Color.Green;
            view.style.color = Color.White;
            view.style.fontFamily = IStyle.FontFamilyEnum.Fixedsys;




            //Native.Document.body.appendChild(
            //    new IHTMLElement(IHTMLElement.HTMLElementEnum.center,
            //    view)
            //    );



            //Native.Document.body.style.backgroundColor = Color.Black;
            // Native.Document.body.style.overflow = IStyle.OverflowEnum.hidden;

            System.Func<IHTMLDiv> CreateCanvas =
                delegate
                {
                    var c = new IHTMLDiv();

                    c.style.overflow = IStyle.OverflowEnum.hidden;
                    c.style.SetLocation(1, 1, 478, 478);

                    return c;
                };

            view.style.position = IStyle.PositionEnum.relative;

            var canvas = CreateCanvas();
            var menu = CreateCanvas();

            canvas.style.backgroundColor = Color.Black;


            view.appendChild(canvas, menu);

            var msg_loading = new IHTMLDiv("loading...");

            msg_loading.style.color = Color.Green;

            menu.appendChild(msg_loading);

            // at this point we want our images

            overlay.Visible = true;

            ScriptCoreLib.JavaScript.Runtime.Timer.DoAsync(overlay.UpdateLocation);

            // now wait while all images are loaded/complete

            ((fbool)(() => !gfx.IsComplete)).Trigger(
            delegate
            {
                // loading images is done now.



                // build the scoreboard
                var MyEnemyDirectory = new EnemyDirectory(gfx);

                var board = new ScoreBoard(gfx);

                board.Control.style.SetLocation(8, 8, 464, 64);

                canvas.appendChild(board.Control);

                board.Lives = 2;
                board.Score = 450;

                // now we can see lives and score.
                // ie does not issue keypress for control keys.
                // scriptcorelib should filter firefox events...

                // lets show main menu

                var mmenu = new MainMenu(MyEnemyDirectory, gfx);
                var gameovermenu = new GameOverMenu();

                menu.appendChild(mmenu.Control, gameovermenu.Control);

                gameovermenu.Visible = false;
                gameovermenu.Control.style.SetLocation(0, 100, 468, 468 - 100);

                mmenu.Control.style.SetLocation(0, 64, 468, 468 - 64);
                mmenu.Visible = true;

                var Enemy_Ammo = new AmmoInfo
                                 {
                                     Color = Color.White,
                                     Speed = 8
                                 };

                var Player = (IHTMLImage)gfx.biggun.Clone();
                var Player_Ammo = new AmmoInfo
                                  {
                                      Color = Color.Green,
                                      Speed = -8
                                  };

                var Map_Top = 64;
                var Map_Left = 20;
                var Map_Right = 450;
                var Map_Bottom = 470;

                var Map_Rect = new Rectangle();

                Map_Rect.Top = Map_Top;
                Map_Rect.Left = Map_Left;
                Map_Rect.Right = Map_Right;
                Map_Rect.Bottom = Map_Bottom;

                var Player_Y = 460;
                var Player_X = 200;

                var Player_X_step = 8;

                Action<int> UpdatePlayer =
                    delegate(int v)
                    {
                        Player_X += v;

                        if (Player_X < Map_Left)
                            Player_X = Map_Left;

                        if (Player_X > Map_Right)
                            Player_X = Map_Right;


                        Player.SetCenteredLocation(Player_X, Player_Y);
                        Player.style.position = IStyle.PositionEnum.absolute;
                    };

                Player.Hide();

                canvas.appendChild(Player, Player_Ammo.Control, Enemy_Ammo.Control);

                AmmoInfo[] KnownAmmo = new[] { Player_Ammo, Enemy_Ammo };

                var KnownConcrete = new List<Concrete>();
                var ConcreteTop = 432;

                KnownConcrete.AddRange(Concrete.BuildAt(new Point(62 + 120 * 0, ConcreteTop)));
                KnownConcrete.AddRange(Concrete.BuildAt(new Point(62 + 120 * 1, ConcreteTop)));
                KnownConcrete.AddRange(Concrete.BuildAt(new Point(62 + 120 * 2, ConcreteTop)));
                KnownConcrete.AddRange(Concrete.BuildAt(new Point(62 + 120 * 3, ConcreteTop)));

                foreach (Concrete v in KnownConcrete.ToArray())
                {
                    canvas.appendChild(v.Control);
                }


                var UFO = new EnemyUnit(MyEnemyDirectory.UFO);
                var UFO_Direction = 1;

                UFO.Visible = false;

                canvas.appendChild(UFO.Control);


                var EnemyTop = 128;
                var EnemySpacing = 32;
                var EnemyCount = 9;

                var KnownEnemies = new List<EnemyUnit>();

                KnownEnemies.AddRange(EnemyUnit.Build(MyEnemyDirectory.A, 20, EnemyTop + 0 * EnemySpacing, EnemyCount, EnemySpacing));
                KnownEnemies.AddRange(EnemyUnit.Build(MyEnemyDirectory.B, 20, EnemyTop + 1 * EnemySpacing, EnemyCount, EnemySpacing));
                KnownEnemies.AddRange(EnemyUnit.Build(MyEnemyDirectory.B, 20, EnemyTop + 2 * EnemySpacing, EnemyCount, EnemySpacing));
                KnownEnemies.AddRange(EnemyUnit.Build(MyEnemyDirectory.C, 20, EnemyTop + 3 * EnemySpacing, EnemyCount, EnemySpacing));
                KnownEnemies.AddRange(EnemyUnit.Build(MyEnemyDirectory.C, 20, EnemyTop + 4 * EnemySpacing, EnemyCount, EnemySpacing));

                foreach (EnemyUnit v in KnownEnemies.ToArray())
                {
                    canvas.appendChild(v.Control);
                }

                var HitDamage = 40;

                var GameTimer = new ScriptCoreLib.JavaScript.Runtime.Timer();

                int GangDirection = 1;

                Action<string> EndGame =
                    delegate
                    {
                        gameovermenu.Visible = true;

                        GameTimer.Stop();
                    };

                #region DoAmmoDamage
                Func<AmmoInfo, bool> DoAmmoDamage =
                    delegate(AmmoInfo a)
                    {
                        bool hit = false;

                        #region did we hit ufo?
                        if (UFO.Visible)
                        {
                            if (UFO.Bounds.Contains(a.Location))
                            {
                                board.Score += UFO.Info.Points;

                                UFO.Visible = false;

                                hit = true;
                            }
                        }
                        #endregion

                        #region did we hit player
                        if (Player.Bounds.Contains(a.Location))
                        {
                            board.Lives--;

                            hit = true;

                            if (board.Lives < 1)
                            {
                                EndGame("Ship destroied");

                            }
                        }
                        #endregion


                        foreach (Concrete v in KnownConcrete.ToArray())
                        {
                            if (v.Visible)
                            {
                                if (v.Bounds.Contains(a.Location))
                                {
                                    v.Health -= HitDamage;

                                    if (v.Health > 0)
                                    {
                                        hit = true;
                                    }
                                    else
                                    {
                                        v.Visible = false;
                                    }
                                }
                            }
                        }

                        foreach (EnemyUnit v in KnownEnemies.ToArray())
                        {
                            if (v.Visible)
                            {
                                if (v.Bounds.Contains(a.Location))
                                {
                                    v.Visible = false;

                                    hit = true;
                                    new SpaceInvadersTemplate.HTML.Audio.FromAssets.invaderexplode().play();

                                    board.Score += v.Info.Points;
                                }
                            }
                        }



                        return hit;
                    };
                #endregion


                var MyRandom = new System.Random();

                var mothershiploop = new SpaceInvadersTemplate.HTML.Audio.FromAssets.mothershiploopx
                {

                    loop = true
                };


                var duh = new IHTMLAudio[] { 
                    new SpaceInvadersTemplate.HTML.Audio.FromAssets.duh0(),
                    new SpaceInvadersTemplate.HTML.Audio.FromAssets.duh1(),
                    new SpaceInvadersTemplate.HTML.Audio.FromAssets.duh2(),
                    new SpaceInvadersTemplate.HTML.Audio.FromAssets.duh3(),
                };

                var duh_cycle = duh.ToCyclicAction(a => a.play());


                #region EnemyAction
                Action EnemyAction =
                    delegate
                    {
                        #region create ufo

                        if (!UFO.Visible)
                        {
                            if (MyRandom.NextDouble() < 0.1)
                            {
                                Console.WriteLine("UFO!");
                                mothershiploop.play();

                                if (MyRandom.NextDouble() > 0.5)
                                {
                                    UFO_Direction = 1;
                                    UFO.MoveTo(0, EnemyTop - UFO.Control.height * 2);
                                }
                                else
                                {
                                    UFO_Direction = -1;
                                    UFO.MoveTo(478, EnemyTop - UFO.Control.height * 2);
                                }

                                UFO.Visible = true;
                            }
                        }
                        #endregion

                        var ev = Enumerable.Where(KnownEnemies.ToArray(), i => i.Visible);

                        if (!Enemy_Ammo.Visible)
                        {
                            var ei = (int)System.Math.Round(MyRandom.NextDouble() * Enumerable.Count(ev));

                            EnemyUnit et = Enumerable.ElementAt(ev, ei);

                            if (et == null)
                                System.Console.WriteLine("element at " + ei + " not found");
                            else
                            {
                                int ey = Enumerable.Max(
                                    from i in ev where i.X == et.X select i.Y
                                    //    Enumerable.Select(Enumerable.Where(ev, i => i.X == et.X), i => i.Y)
                                );

                                Enemy_Ammo.MoveTo(et.X, ey + 20);
                                Enemy_Ammo.Visible = true;
                            }
                        }


                        #region MoveAll
                        Action<Point> MoveAll =
                            delegate(Point to)
                            {
                                var ConcreteReached = false;

                                foreach (EnemyUnit v in ev)
                                {
                                    var vy = v.Y + to.Y;

                                    if (vy > ConcreteTop)
                                    {
                                        ConcreteReached = true;
                                    }

                                    v.MoveTo(v.X + to.X, vy);
                                }

                                if (ConcreteReached)
                                {
                                    EndGame("The walls have been breached.");
                                }
                            };
                        #endregion

                        Action MoveAllDown =
                            delegate
                            {
                                MoveAll(new Point(0, 8));
                            };

                        duh_cycle();

                        #region move the gang
                        if (GangDirection > 0)
                        {
                            int ex_max = Enumerable.Max(Enumerable.Select(ev, i => i.X));

                            // gang goes right

                            if (ex_max >= Map_Rect.Right)
                            {
                                GangDirection = -1;
                                MoveAllDown();
                            }
                            else
                            {
                                MoveAll(new Point(4, 0));
                            }
                        }
                        else
                        {
                            int ex_min = Enumerable.Min(Enumerable.Select(ev, i => i.X));

                            // gang goes left

                            if (ex_min <= Map_Rect.Left)
                            {
                                GangDirection = 1;
                                MoveAllDown();
                            }
                            else
                            {
                                MoveAll(new Point(-4, 0));
                            }
                        }
                        #endregion

                    };
                #endregion

                bool GamePaused = false;




                GameTimer.Tick +=
                    delegate
                    {

                        #region only blink while paused
                        if (GamePaused)
                        {
                            if (GameTimer.Counter % 15 == 0)
                            {
                                Player.ToggleVisible();
                            }

                            return;
                        }
                        #endregion



                        Player.Show();

                        #region move ufo

                        if (UFO.Visible)
                        {
                            if (UFO_Direction > 0)
                            {
                                UFO.MoveTo(UFO.X + 4, UFO.Y);

                                if (UFO.X > 478 + UFO.Control.width)
                                {
                                    UFO.Visible = false;
                                    mothershiploop.pause();
                                }
                            }
                            else
                            {
                                UFO.MoveTo(UFO.X - 4, UFO.Y);

                                if (UFO.X < -UFO.Control.width)
                                {
                                    UFO.Visible = false;
                                    mothershiploop.pause();
                                }
                            }
                        }
                        #endregion


                        #region do ammo stuff
                        foreach (AmmoInfo v in KnownAmmo)
                        {
                            if (v.Visible)
                            {
                                var y = v.Y + v.Speed;

                                if (Map_Rect.Contains(new Point(v.X, y)))
                                {
                                    // did we hit?
                                    if (DoAmmoDamage(v))
                                    {

                                        v.Visible = false;
                                    }
                                    else
                                    {
                                        v.MoveTo(v.X, y);
                                    }
                                }
                                else
                                {
                                    v.Visible = false;
                                }
                            }
                        }
                        #endregion



                        var AliveEnemies = Enumerable.Where(KnownEnemies.ToArray(), i => i.Visible);
                        var AliveCount = Enumerable.Count(AliveEnemies);

                        if (AliveCount == 0)
                        {
                            EndGame("Aliens destoried");

                            return;
                        }

                        if (GameTimer.Counter % (AliveCount / 2) == 0)
                        {
                            EnemyAction();
                        }

                    };


                #region ResetGame
                Action ResetGame =
                    delegate
                    {
                        mmenu.Visible = false;

                        Player_X = 220;
                        board.Score = 0;
                        board.Lives = 3;

                        Player.Show();

                        foreach (Concrete v in KnownConcrete.ToArray())
                        {
                            v.Health = 255;
                            v.Visible = true;
                        }


                        foreach (EnemyUnit v in KnownEnemies.ToArray())
                        {
                            v.ResetPosition();
                            v.Visible = true;
                        }

                        EnemyAction();

                        GameTimer.StartInterval(50);

                        UpdatePlayer(0);
                    };
                #endregion

                Action EgoShoot =
                    delegate
                    {
                        if (!Player_Ammo.Visible)
                        {
                            Player_Ammo.MoveTo(Player_X, Player_Y - 20);

                            new SpaceInvadersTemplate.HTML.Audio.FromAssets.firemissile().play();

                            Player_Ammo.Visible = true;

                        }
                    };

                overlay.ControlInBack.onclick +=
                    delegate
                    {
                        if (mmenu.Visible)
                            ResetGame();
                        else
                            EgoShoot();
                    };


                double gamma = 0;

                //Native.window.ondeviceorientation +=
                //    eventData =>
                //    {
                //        if (eventData.gamma < -50)
                //            gamma = eventData.beta;
                //        else
                //            gamma = eventData.gamma;


                //    };

                new ScriptCoreLib.JavaScript.Runtime.Timer(
                    t =>
                    {
                        // gamma is the left-to-right tilt in degrees, where right is positive
                        if (gamma < -15)
                        {
                            if (mmenu.Visible)
                                ResetGame();
                            else
                                UpdatePlayer(-Player_X_step);
                        }

                        if (gamma > 15)
                        {
                            if (mmenu.Visible)
                                ResetGame();
                            else
                                UpdatePlayer(Player_X_step);
                        }
                    }
                ).StartInterval(100);

                Native.Document.onkeydown += delegate(IEvent ev)
                {
                    Console.WriteLine(new { ev.KeyCode }.ToString());

                    if (mmenu.Visible)
                    {
                        if (ev.IsReturn)
                        {

                            ResetGame();

                        }

                        return;
                    }
                    else
                    {
                        if (ev.IsEscape)
                        {
                            GameTimer.Stop();

                            Player.Hide();

                            mmenu.Visible = true;

                            foreach (AmmoInfo v in KnownAmmo)
                            {
                                v.Visible = false;
                            }

                            foreach (Concrete v in KnownConcrete.ToArray())
                            {
                                v.Visible = false;
                            }

                            foreach (EnemyUnit v in KnownEnemies.ToArray())
                            {
                                v.Visible = false;
                            }

                            UFO.Visible = false;

                            gameovermenu.Visible = false;

                            // the animated gifs would stop after escape key
                            ev.preventDefault();

                            GamePaused = false;
                        }
                    }

                    int key_p = 80;


                    if (ev.KeyCode == key_p)
                    {
                        GamePaused = !GamePaused;
                    }

                    // player shouldn't really move while game is paused
                    // its cheating:)
                    if (GamePaused)
                        return;

                    int key_right = 39;
                    int key_left = 37;

                    if (ev.KeyCode == key_left)
                    {
                        UpdatePlayer(-Player_X_step);
                    }
                    else if (ev.KeyCode == key_right)
                    {
                        UpdatePlayer(Player_X_step);
                    }
                    else if (ev.IsSpaceOrEnterKey())
                    {
                        // the animated gifs would stop after escape key
                        ev.preventDefault();

                        EgoShoot();
                    }
                    else
                    {
                        Console.WriteLine(new { UnknownKeyCode = ev.KeyCode }.ToString());
                    }
                };

                msg_loading.Orphanize();
            }
            , 50);


        }
        void InitializeContent()
        {

            #region make sure we atleast have our invisible DOM
            var page_song = new nyanlooped { loop = true };
            var page_song2 = new nyanslow { loop = true };


            #endregion

            #region container
            Native.document.body.style.overflow = IStyle.OverflowEnum.hidden;
            var container = new IHTMLDiv();

            container.AttachToDocument();
            container.style.backgroundColor = "#003366";
            container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);
            #endregion

            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(Native.window.Width, Native.window.Height);
            renderer.domElement.AttachTo(container);

            var numStars = 10;
            var numRainChunks = 30;
            var mouseX = 0;
            var mouseY = 0;

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

            var deltaSum = 0f;
            //tick=0, 
            var frame = 0;

            var running = true;


            #region onmousemove
            Native.document.onmousemove +=
                e =>
                {
                    if (IsDisposed)
                        return;

                    var windowHalfX = Native.window.Width / 2;
                    var windowHalfY = Native.window.Height / 2;

                    mouseX = (e.CursorX - windowHalfX);
                    mouseY = (e.CursorY - windowHalfY);
                };

            #endregion

            Action PlaySomething =
                delegate
                {
                    if (running)
                    {
                        page_song.play();
                        page_song2.pause();
                    }
                    else
                    {
                        page_song.pause();
                        page_song2.play();
                    }
                };
            #region onmousedown
            Native.document.onmousedown +=
                e =>
                {
                    if (IsDisposed)
                        return;


                    running = !running;
                    PlaySomething();
                };
            #endregion

            #region HasFocus
            var HasFocus = false;

            Native.window.onblur +=
               delegate
               {
                   HasFocus = false;

                   page_song.pause();
                   page_song2.pause();
               };

            Native.window.onfocus +=
                delegate
                {
                    HasFocus = true;
                    PlaySomething();
                };
            Native.Document.onmousemove +=
          delegate
          {
              if (HasFocus)
                  return;
              PlaySomething();
          };

            Native.Document.onmouseout +=
              delegate
              {
                  if (HasFocus)
                      return;

                  page_song.pause();
                  page_song2.pause();
              };
            #endregion


            #region helper
            Action<THREE.Object3D, f, f, f, f, f, f, int> helper =
                (o, x, y, z, w, h, d, c) =>
                {
                    //            function helper(o, x, y, z, w, h, d, c){
                    var material = new THREE.MeshLambertMaterial(new { color = c });
                    var geometry = new THREE.CubeGeometry(w, h, d, 1, 1, 1);
                    var mesh = new THREE.Mesh(geometry, material);
                    mesh.position.x = x + (w / 2);
                    mesh.position.y = y - (h / 2);
                    mesh.position.z = z + (d / 2);
                    o.add(mesh);
                };
            #endregion

            #region buildStar
            Action<THREE.Object3D, int> buildStar =
                (star, state) =>
                {
                    #region  dear JSC, please start supporting switch!
                    if (state == 0)
                    {
                        helper(star, 0, 0, 0, 1, 1, 1, 0xffffff);
                    }
                    else if (state == 1)
                    {
                        helper(star, 1, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, -1, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, 0, 1, 0, 1, 1, 1, 0xffffff);
                        helper(star, 0, -1, 0, 1, 1, 1, 0xffffff);
                    }
                    else if (state == 2)
                    {
                        helper(star, 1, 0, 0, 2, 1, 1, 0xffffff);
                        helper(star, -2, 0, 0, 2, 1, 1, 0xffffff);
                        helper(star, 0, 2, 0, 1, 2, 1, 0xffffff);
                        helper(star, 0, -1, 0, 1, 2, 1, 0xffffff);
                    }
                    else if (state == 3)
                    {
                        helper(star, 0, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, 2, 0, 0, 2, 1, 1, 0xffffff);
                        helper(star, -3, 0, 0, 2, 1, 1, 0xffffff);
                        helper(star, 0, 3, 0, 1, 2, 1, 0xffffff);
                        helper(star, 0, -2, 0, 1, 2, 1, 0xffffff);
                    }
                    else if (state == 4)
                    {
                        helper(star, 0, 3, 0, 1, 1, 1, 0xffffff);
                        helper(star, 2, 2, 0, 1, 1, 1, 0xffffff);
                        helper(star, 3, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, 2, -2, 0, 1, 1, 1, 0xffffff);
                        helper(star, 0, -3, 0, 1, 1, 1, 0xffffff);
                        helper(star, -2, -2, 0, 1, 1, 1, 0xffffff);
                        helper(star, -3, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, -2, 2, 0, 1, 1, 1, 0xffffff);
                    }
                    else if (state == 4)
                    {
                        helper(star, 2, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, -2, 0, 0, 1, 1, 1, 0xffffff);
                        helper(star, 0, 2, 0, 1, 1, 1, 0xffffff);
                        helper(star, 0, -2, 0, 1, 1, 1, 0xffffff);
                    }
                    #endregion
                };
            #endregion

            var r = new Random();
            Func<f> Math_random = () => r.NextFloat();

            var stars = new List<List<THREE.Object3D>>();


            #region  init
            var camera = new THREE.PerspectiveCamera(45,
            Native.window.Width / Native.window.Height, .1f, 10000);

            camera.position.z = 30;
            camera.position.x = 0;
            camera.position.y = 0;

            var scene = new THREE.Scene();
            scene.fog = new THREE.FogExp2(0x003366, 0.0095f);

            #region POPTART
            var poptart = new THREE.Object3D();

            //		object	   x    y    z    w    h    d	  color
            helper(poptart, 0, -2, -1, 21, 14, 3, 0x222222);
            helper(poptart, 1, -1, -1, 19, 16, 3, 0x222222);
            helper(poptart, 2, 0, -1, 17, 18, 3, 0x222222);

            helper(poptart, 1, -2, -1.5f, 19, 14, 4, 0xffcc99);
            helper(poptart, 2, -1, -1.5f, 17, 16, 4, 0xffcc99);

            helper(poptart, 2, -4, 2, 17, 10, .6f, 0xff99ff);
            helper(poptart, 3, -3, 2, 15, 12, .6f, 0xff99ff);
            helper(poptart, 4, -2, 2, 13, 14, .6f, 0xff99ff);

            helper(poptart, 4, -4, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 9, -3, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 12, -3, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 16, -5, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 8, -7, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 5, -9, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 9, -10, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 3, -11, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 7, -13, 2, 1, 1, .7f, 0xff3399);
            helper(poptart, 4, -14, 2, 1, 1, .7f, 0xff3399);

            poptart.position.x = -10.5f;
            poptart.position.y = 9;
            scene.add(poptart);
            #endregion

            #region FEET
            var feet = new THREE.Object3D();
            helper(feet, 0, -2, .49f, 3, 3, 1, 0x222222);
            helper(feet, 1, -1, .49f, 3, 3, 1, 0x222222);
            helper(feet, 1, -2, -.01f, 2, 2, 2, 0x999999);
            helper(feet, 2, -1, -.01f, 2, 2, 2, 0x999999);

            helper(feet, 6, -2, -.5f, 3, 3, 1, 0x222222);
            helper(feet, 6, -2, -.5f, 4, 2, 1, 0x222222);
            helper(feet, 7, -2, -.99f, 2, 2, 2, 0x999999);

            helper(feet, 16, -3, .49f, 3, 2, 1, 0x222222);
            helper(feet, 15, -2, .49f, 3, 2, 1, 0x222222);
            helper(feet, 15, -2, -.01f, 2, 1, 2, 0x999999);
            helper(feet, 16, -3, -.01f, 2, 1, 2, 0x999999);

            helper(feet, 21, -3, -.5f, 3, 2, 1, 0x222222);
            helper(feet, 20, -2, -.5f, 3, 2, 1, 0x222222);
            helper(feet, 20, -2, -.99f, 2, 1, 2, 0x999999);
            helper(feet, 21, -3, -.99f, 2, 1, 2, 0x999999);

            feet.position.x = -12.5f;
            feet.position.y = -6;
            scene.add(feet);
            #endregion


            #region TAIL
            var tail = new THREE.Object3D();
            helper(tail, 0, 0, -.25f, 4, 3, 1.5f, 0x222222);
            helper(tail, 1, -1, -.25f, 4, 3, 1.5f, 0x222222);
            helper(tail, 2, -2, -.25f, 4, 3, 1.5f, 0x222222);
            helper(tail, 3, -3, -.25f, 4, 3, 1.5f, 0x222222);
            helper(tail, 1, -1, -.5f, 2, 1, 2, 0x999999);
            helper(tail, 2, -2, -.5f, 2, 1, 2, 0x999999);
            helper(tail, 3, -3, -.5f, 2, 1, 2, 0x999999);
            helper(tail, 4, -4, -.5f, 2, 1, 2, 0x999999);

            tail.position.x = -16.5f;
            tail.position.y = 2;
            scene.add(tail);
            #endregion


            #region FACE
            var face = new THREE.Object3D();
            helper(face, 2, -3, -3, 12, 9, 4, 0x222222);
            helper(face, 0, -5, 0, 16, 5, 1, 0x222222);
            helper(face, 1, -1, 0, 4, 10, 1, 0x222222);
            helper(face, 11, -1, 0, 4, 10, 1, 0x222222);
            helper(face, 3, -11, 0, 10, 2, 1, 0x222222);
            helper(face, 2, 0, 0, 2, 2, 1, 0x222222);
            helper(face, 4, -2, 0, 2, 2, 1, 0x222222);
            helper(face, 12, 0, 0, 2, 2, 1, 0x222222);
            helper(face, 10, -2, 0, 2, 2, 1, 0x222222);

            helper(face, 1, -5, .5f, 14, 5, 1, 0x999999);
            helper(face, 3, -4, .5f, 10, 8, 1, 0x999999);
            helper(face, 2, -1, .5f, 2, 10, 1, 0x999999);
            helper(face, 12, -1, .5f, 2, 10, 1, 0x999999);
            helper(face, 4, -2, .5f, 1, 2, 1, 0x999999);
            helper(face, 5, -3, .5f, 1, 1, 1, 0x999999);
            helper(face, 11, -2, .5f, 1, 2, 1, 0x999999);
            helper(face, 10, -3, .5f, 1, 1, 1, 0x999999);
            //Eyes
            helper(face, 4, -6, .6f, 2, 2, 1, 0x222222);
            helper(face, 11, -6, .6f, 2, 2, 1, 0x222222);
            helper(face, 3.99f, -5.99f, .6f, 1.01f, 1.01f, 1.01f, 0xffffff);
            helper(face, 10.99f, -5.99f, .6f, 1.01f, 1.01f, 1.01f, 0xffffff);
            //MOUTH
            helper(face, 5, -10, .6f, 7, 1, 1, 0x222222);
            helper(face, 5, -9, .6f, 1, 2, 1, 0x222222);
            helper(face, 8, -9, .6f, 1, 2, 1, 0x222222);
            helper(face, 11, -9, .6f, 1, 2, 1, 0x222222);
            //CHEEKS
            helper(face, 2, -8, .6f, 2, 2, .91f, 0xff9999);
            helper(face, 13, -8, .6f, 2, 2, .91f, 0xff9999);

            face.position.x = -.5f;
            face.position.y = 4;
            face.position.z = 4;
            scene.add(face);
            #endregion

            #region RAINBOW
            var rainbow = new THREE.Object3D();
            for (var c = 0; c < numRainChunks - 1; c++)
            {
                var yOffset = 8;
                if (c % 2 == 1) yOffset = 7;
                var xOffset = (-c * 8) - 16.5f;
                helper(rainbow, xOffset, yOffset, 0, 8, 3, 1, 0xff0000);
                helper(rainbow, xOffset, yOffset - 3, 0, 8, 3, 1, 0xff9900);
                helper(rainbow, xOffset, yOffset - 6, 0, 8, 3, 1, 0xffff00);
                helper(rainbow, xOffset, yOffset - 9, 0, 8, 3, 1, 0x33ff00);
                helper(rainbow, xOffset, yOffset - 12, 0, 8, 3, 1, 0x0099ff);
                helper(rainbow, xOffset, yOffset - 15, 0, 8, 3, 1, 0x6633ff);
            }
            scene.add(rainbow);
            #endregion


            #region rainChunk
            var rainChunk = new THREE.Object3D();
            helper(rainChunk, -16.5f, 7, 0, 8, 3, 1, 0xff0000);
            helper(rainChunk, -16.5f, 4, 0, 8, 3, 1, 0xff9900);
            helper(rainChunk, -16.5f, 1, 0, 8, 3, 1, 0xffff00);
            helper(rainChunk, -16.5f, -2, 0, 8, 3, 1, 0x33ff00);
            helper(rainChunk, -16.5f, -5, 0, 8, 3, 1, 0x0099ff);
            helper(rainChunk, -16.5f, -8, 0, 8, 3, 1, 0x6633ff);
            rainChunk.position.x -= (8 * (numRainChunks - 1));
            scene.add(rainChunk);
            #endregion

            #region stars



            for (var state = 0; state < 6; state++)
            {

                stars.Add(new List<THREE.Object3D>());

                for (var c = 0; c < numStars; c++)
                {
                    var star = new THREE.Object3D();
                    star.position.x = Math_random() * 200 - 100;
                    star.position.y = Math_random() * 200 - 100;
                    star.position.z = Math_random() * 200 - 100;
                    buildStar(star, state);
                    scene.add(star);
                    stars[state].Add(star);
                }
            }
            #endregion


            var pointLight = new THREE.PointLight(0xFFFFFF);
            pointLight.position.z = 1000;
            scene.add(pointLight);



            #endregion




            #region IsDisposed

            Dispose = delegate
            {
                if (IsDisposed)
                    return;

                IsDisposed = true;

                page_song.pause();
                page_song2.pause();

                container.Orphanize();
            };
            #endregion




            Native.window.onframe +=
                delegate
                {
                    f delta = clock.ElapsedMilliseconds * 0.001f;
                    clock.Restart();

                    if (running) deltaSum += delta;

                    if (deltaSum > .07)
                    {
                        deltaSum = deltaSum % .07f;
                        frame = (frame + 1) % 12;
                        for (var c = 0; c < numStars; c++)
                        {
                            var tempX = stars[5][c].position.x;
                            var tempY = stars[5][c].position.y;
                            var tempZ = stars[5][c].position.z;
                            for (var state = 5; state > 0; state--)
                            {
                                var star = stars[state][c];
                                var star2 = stars[state - 1][c];
                                star.position.x = star2.position.x - 8;
                                star.position.y = star2.position.y;
                                star.position.z = star2.position.z;

                                if (star.position.x < -100)
                                {
                                    star.position.x += 200;
                                    star.position.y = Math_random() * 200 - 100;
                                    star.position.z = Math_random() * 200 - 100;
                                }
                            }
                            stars[0][c].position.x = tempX;
                            stars[0][c].position.y = tempY;
                            stars[0][c].position.z = tempZ;
                        }

                        #region  dear JSC, please start supporting switch!

                        if (frame == 0)
                        {
                            face.position.x++;
                            feet.position.x++;
                        }
                        else if (frame == 1)
                        {
                            face.position.y--;
                            feet.position.x++;
                            feet.position.y--;
                            poptart.position.y--;
                            rainbow.position.x -= 9;
                            rainChunk.position.x += (8 * (numRainChunks - 1)) - 1;
                        }
                        else if (frame == 2)
                        {
                            feet.position.x--;
                        }
                        else if (frame == 3)
                        {
                            face.position.x--;
                            feet.position.x--;
                            rainbow.position.x += 9;
                            rainChunk.position.x -= (8 * (numRainChunks - 1)) - 1;

                        }
                        else if (frame == 4)
                        {
                            face.position.y++;
                        }
                        else if (frame == 5)
                        {
                            poptart.position.y++;
                            feet.position.y++;
                            rainbow.position.x -= 9;
                            rainChunk.position.x += (8 * (numRainChunks - 1)) - 1;
                        }
                        else if (frame == 6)
                        {

                            face.position.x++;
                            feet.position.x++;
                        }
                        else if (frame == 7)
                        {
                            poptart.position.y--;
                            face.position.y--;
                            feet.position.x++;
                            feet.position.y--;
                            rainbow.position.x += 9;
                            rainChunk.position.x -= (8 * (numRainChunks - 1)) - 1;
                        }
                        else if (frame == 8)
                        {
                            feet.position.x--;
                        }
                        else if (frame == 9)
                        {
                            face.position.x--;
                            feet.position.x--;
                            rainbow.position.x -= 9;
                            rainChunk.position.x += (8 * (numRainChunks - 1)) - 1;
                        }
                        else if (frame == 10)
                        {
                            face.position.y++;
                        }
                        else if (frame == 11)
                        {
                            poptart.position.y++;
                            feet.position.y++;
                            rainbow.position.x += 9;
                            rainChunk.position.x -= (8 * (numRainChunks - 1)) - 1;
                        }
                        #endregion

                    }
                    camera.position.x += (mouseX - camera.position.x) * .005f;
                    camera.position.y += (-mouseY - camera.position.y) * .005f;
                    camera.lookAt(scene.position);
                    renderer.render(scene, camera);
                };





            #region AtResize
            Action AtResize = delegate
            {
                container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);

                camera.aspect = Native.window.aspect;
                camera.updateProjectionMatrix();

                renderer.setSize(Native.window.Width, Native.window.Height);
            };

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

            AtResize();
            #endregion

            #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


        }
        void InitializeContent(IDefault page = null)
        {
            #region make sure we atleast have our invisible DOM
            if (page == null)
                page = new HTML.Pages.Default();
            #endregion

            #region container
            Native.document.body.style.overflow = IStyle.OverflowEnum.hidden;
            var container = new IHTMLDiv();

            container.AttachToDocument();
            container.style.backgroundColor = "#000000";
            container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);
            #endregion



            #region code port

            double SCREEN_WIDTH = Native.window.Width ;
            double  SCREEN_HEIGHT = Native.window.Height;

            var animDelta = 0;
            var animDeltaDir = -1;
            var lightVal = 0;
            var lightDir = 1;
            var soundVal = 0;
            var oldSoundVal = 0;
            var soundDir = 1;

            #region animate it
            animDeltaDir *= -1;
            #endregion


            var clock = new THREE.Clock();

            var morphs = new List<THREE.MorphAnimMesh>();

            var updateNoise = true;


            var mlib = new Dictionary<string, THREE.ShaderMaterial>();

            var soundtrack = new Five_Armies { loop = true, volume = 0.9 };


            #region HasFocus
            var HasFocus = false;

            Native.window.onblur +=
               delegate
               {
                   HasFocus = false;

                   soundtrack.volume = 0.1;
               };

            Native.window.onfocus +=
                delegate
                {
                    HasFocus = true;
                    soundtrack.volume = 0.9;
                };
            //  Native.Document.onmousemove +=
            //delegate
            //{
            //    if (HasFocus)
            //        return;
            //    soundtrack.play();
            //};

            //  Native.Document.onmouseout +=
            //    delegate
            //    {
            //        if (HasFocus)
            //            return;

            //        soundtrack.pause();
            //    };
            #endregion


            var THREE_RepeatWrapping = 0;
            var THREE_FaceColors = 1;
            var THREE_LinearFilter = 6;
            var THREE_RGBFormat = 17;
            var THREE_LinearMipMapLinearFilter = 8;


            #region SCENE (RENDER TARGET)

            var sceneRenderTarget = new THREE.Scene();

            var cameraOrtho = new THREE.OrthographicCamera(
                (int)SCREEN_WIDTH / -2,
                (int)SCREEN_WIDTH / 2,
                (int)SCREEN_HEIGHT / 2,
                (int)SCREEN_HEIGHT / -2,
                -10000,
                10000
            );

            cameraOrtho.position.z = 100;

            sceneRenderTarget.add(cameraOrtho);
            #endregion

            #region SCENE (FINAL)

            var scene = new THREE.Scene();

            scene.fog = new THREE.Fog(0x050505, 2000, 4000);
            scene.fog.color.setHSV(0.102, 0.9, 0.825);

            var camera = new THREE.PerspectiveCamera(40, (int)Native.window.aspect, 2, 4000);
            camera.position.set(-1200, 800, 1200);

            scene.add(camera);

            var controls = new THREE.TrackballControls(camera);
            controls.target.set(0, 0, 0);

            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;
            controls.panSpeed = 0.8;

            controls.noZoom = false;
            controls.noPan = false;

            controls.staticMoving = false;
            controls.dynamicDampingFactor = 0.15;

            controls.keys = new[] { 65, 83, 68 };
            #endregion

            #region LIGHTS

            scene.add(new THREE.AmbientLight(0x111111));

            var spotLight = new THREE.SpotLight(0xffffff, 1.15);
            spotLight.position.set(500, 2000, 0);
            spotLight.castShadow = true;
            scene.add(spotLight);

            var pointLight = new THREE.PointLight(0xff4400, 1.5);
            pointLight.position.set(0, 0, 0);
            scene.add(pointLight);

            #endregion



            #region HEIGHT + NORMAL MAPS

            var normalShader = __THREE.ShaderExtras.normalmap;

            var rx = 256;
            var ry = 256;

            var pars = new THREE.WebGLRenderTargetArguments
            {
                minFilter = THREE_LinearMipMapLinearFilter,
                magFilter = THREE_LinearFilter,
                format = THREE_RGBFormat
            };

            var heightMap = new THREE.WebGLRenderTarget(rx, ry, pars);
            var normalMap = new THREE.WebGLRenderTarget(rx, ry, pars);

            var uniformsNoise = new MyUniformsNoise
            {
                time = new THREE.ShaderExtrasModuleItem_uniforms_item { type = "f", value = 1.0 },
                scale = new THREE.ShaderExtrasModuleItem_uniforms_item { type = "v2", value = new THREE.Vector2(1.5, 1.5) },
                offset = new THREE.ShaderExtrasModuleItem_uniforms_item { type = "v2", value = new THREE.Vector2(0, 0) }
            };

            var uniformsNormal = __THREE.UniformsUtils.clone(normalShader.uniforms);

            uniformsNormal.height.value = 0.05;
            ((THREE.Vector2)uniformsNormal.resolution.value).set(rx, ry);
            uniformsNormal.heightMap.texture = heightMap;

            var vertexShader = new Shaders.NoiseVertexShader().ToString();
            #endregion


            #region before TEXTURES
            var textureCounter = 0;


            #region RENDERER

            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(Native.window.Width, Native.window.Height);
            renderer.setClearColor(scene.fog.color, 1);

            renderer.domElement.style.position = IStyle.PositionEnum.absolute;
            renderer.domElement.style.top = "0px";
            renderer.domElement.style.left = "0px";

            container.appendChild(renderer.domElement);

            //    //

            renderer.gammaInput = true;
            renderer.gammaOutput = true;
            #endregion

            #region applyShader
            Action<THREE.ShaderExtrasModuleItem, object, object> applyShader = (shader, texture, target) =>
            {

                var shaderMaterial = new THREE.ShaderMaterial(
                    new THREE.ShaderMaterialArguments
                    {

                        fragmentShader = shader.fragmentShader,
                        vertexShader = shader.vertexShader,
                        uniforms = __THREE.UniformsUtils.clone(shader.uniforms)

                    }
                );

                shaderMaterial.uniforms.tDiffuse.texture = texture;

                var sceneTmp = new THREE.Scene();

                var meshTmp = new THREE.Mesh(new THREE.PlaneGeometry(Native.window.Width, Native.window.Height), shaderMaterial);
                meshTmp.position.z = -500;
                sceneTmp.add(meshTmp);

                renderer.render(sceneTmp, cameraOrtho, target, true);
            };
            #endregion


            var terrain = default(THREE.Mesh);

            #region loadTextures
            Action loadTextures = () =>
            {

                textureCounter += 1;

                if (textureCounter == 3)
                {

                    terrain.visible = true;

                    //document.getElementById("loading").style.display = "none";

                }

            };

            ////
            #endregion

            #endregion

            #region TEXTURES

            var specularMap = new THREE.WebGLRenderTarget(2048, 2048, pars);


            var diffuseTexture1 = default(THREE.WebGLRenderTarget);

            diffuseTexture1 = __THREE.ImageUtils.loadTexture(
                new global::WebGLDynamicTerrainTemplate.HTML.Images.FromAssets.grasslight_big().src,
                null,
                IFunction.Of(
                    delegate ()
                    {
                        loadTextures();
                        applyShader(__THREE.ShaderExtras.luminosity, diffuseTexture1, specularMap);
                    }
                )
            );

            var diffuseTexture2 = __THREE.ImageUtils.loadTexture(
                   new global::WebGLDynamicTerrainTemplate.HTML.Images.FromAssets.backgrounddetailed6().src,
                   null,
                   IFunction.Of(
                       delegate ()
                       {
                           loadTextures();
                       }
                   )
               );

            var detailTexture = __THREE.ImageUtils.loadTexture(
              new global::WebGLDynamicTerrainTemplate.HTML.Images.FromAssets.grasslight_big_nm().src,
              null,
              IFunction.Of(
                  delegate ()
                  {
                      loadTextures();
                  }
              )
          );

            diffuseTexture1.wrapS = THREE_RepeatWrapping;
            diffuseTexture1.wrapT = THREE_RepeatWrapping;


            diffuseTexture2.wrapS = THREE_RepeatWrapping;
            diffuseTexture2.wrapT = THREE_RepeatWrapping;

            detailTexture.wrapS = THREE_RepeatWrapping;
            detailTexture.wrapT = THREE_RepeatWrapping;

            specularMap.wrapS = THREE_RepeatWrapping;
            specularMap.wrapT = THREE_RepeatWrapping;
            #endregion

            #region TERRAIN SHADER

            var terrainShader = __THREE.ShaderTerrain.terrain;

            var uniformsTerrain = __THREE.UniformsUtils.clone(terrainShader.uniforms);

            uniformsTerrain.tNormal.texture = normalMap;
            uniformsTerrain.uNormalScale.value = 3.5;

            uniformsTerrain.tDisplacement.texture = heightMap;

            uniformsTerrain.tDiffuse1.texture = diffuseTexture1;
            uniformsTerrain.tDiffuse2.texture = diffuseTexture2;
            uniformsTerrain.tSpecular.texture = specularMap;
            uniformsTerrain.tDetail.texture = detailTexture;

            uniformsTerrain.enableDiffuse1.value = true;
            uniformsTerrain.enableDiffuse2.value = true;
            uniformsTerrain.enableSpecular.value = true;

            ((THREE.Color)uniformsTerrain.uDiffuseColor.value).setHex(0xffffff);
            ((THREE.Color)uniformsTerrain.uSpecularColor.value).setHex(0xffffff);
            ((THREE.Color)uniformsTerrain.uAmbientColor.value).setHex(0x111111);

            uniformsTerrain.uShininess.value = 30;
            uniformsTerrain.uDisplacementScale.value = 375;

            ((THREE.Vector2)uniformsTerrain.uRepeatOverlay.value).set(6, 6);


            var _params = new[] {
                new { id= "heightmap", fragmentShader= new Shaders.NoiseFragmentShader().ToString(), vertexShader=  vertexShader, uniforms= (object)uniformsNoise, lights = false },
                new { id="normal", fragmentShader=  normalShader.fragmentShader,  vertexShader=normalShader.vertexShader, uniforms=(object)uniformsNormal, lights = false },
                new { id="terrain", fragmentShader= terrainShader.fragmentShader, vertexShader=terrainShader.vertexShader, uniforms=(object)uniformsTerrain, lights = true }
            };

            for (var i = 0; i < _params.Length; i++)
            {

                var material = new THREE.ShaderMaterial(
                    new THREE.ShaderMaterialArguments
                    {

                        uniforms = (THREE.ShaderExtrasModuleItem_uniforms)_params[i].uniforms,
                        vertexShader = _params[i].vertexShader,
                        fragmentShader = _params[i].fragmentShader,
                        lights = _params[i].lights,
                        fog = true
                    }
                );

                mlib[(string)_params[i].id] = material;

            }


            var plane = new THREE.PlaneGeometry(Native.window.Width, Native.window.Height);

            var quadTarget = new THREE.Mesh(
                plane,
                new THREE.MeshBasicMaterial(
                    new THREE.MeshBasicMaterialArguments { color = 0xff0000 }
                    )
                    );

            quadTarget.position.z = -500;
            sceneRenderTarget.addObject(quadTarget);
            #endregion

            #region TERRAIN MESH

            var geometryTerrain = new THREE.PlaneGeometry(6000, 6000, 256, 256);
            geometryTerrain.computeFaceNormals();
            geometryTerrain.computeVertexNormals();
            geometryTerrain.computeTangents();

            terrain = new THREE.Mesh(geometryTerrain, mlib["terrain"]);
            terrain.rotation.set(-Math.PI / 2.0, 0, 0);
            terrain.position.set(0, -125, 0);
            terrain.visible = false;
            scene.add(terrain);
            #endregion






            #region COMPOSER

            renderer.autoClear = false;



            var renderTargetParameters = new THREE.WebGLRenderTargetArguments
            {
                minFilter = THREE_LinearFilter,
                magFilter = THREE_LinearFilter,
                format = THREE_RGBFormat,
                stencilBufer = false
            };

            var renderTarget = new THREE.WebGLRenderTarget((int)SCREEN_WIDTH, (int)SCREEN_HEIGHT, renderTargetParameters);

            var effectBloom = new THREE.BloomPass(0.6);
            var effectBleach = new THREE.ShaderPass(__THREE.ShaderExtras.bleachbypass);

            var hblur = new THREE.ShaderPass(__THREE.ShaderExtras.horizontalTiltShift);
            var vblur = new THREE.ShaderPass(__THREE.ShaderExtras.verticalTiltShift);

            var bluriness = 6;

            hblur.uniforms.h.value = bluriness / SCREEN_WIDTH;
            vblur.uniforms.v.value = bluriness / SCREEN_HEIGHT;

            hblur.uniforms.r.value = 0.5;
            vblur.uniforms.r.value = 0.5;

            effectBleach.uniforms.opacity.value = 0.65;

            var composer0 = new THREE.EffectComposer(renderer, renderTarget);

            var renderModel = new THREE.RenderPass(scene, camera);

            vblur.renderToScreen = true;

            var composer = new THREE.EffectComposer(renderer, renderTarget);

            composer.addPass(renderModel);

            composer.addPass(effectBloom);
            //composer.addPass( effectBleach );

            composer.addPass(hblur);
            composer.addPass(vblur);
            #endregion

            var r = new Random();

            Func<f> Math_random = () => (f)r.NextDouble();



            #region addMorph

            Action<MyModelGeometry, f, f, f, f, f> addMorph = (geometry, speed, duration, x, y, z) =>
            {

                var material = new THREE.MeshLambertMaterial(
                    new THREE.MeshLambertMaterialArguments
                    {
                        color = 0xffaa55,
                        morphTargets = true,
                        vertexColors = THREE_FaceColors
                    }
                );


                var meshAnim = new THREE.MorphAnimMesh(geometry, material);

                meshAnim.speed = speed;
                meshAnim.duration = duration;
                meshAnim.time = 600.0 * Math_random();

                meshAnim.position.set(x, y, z);
                meshAnim.rotation.y = (f)(Math.PI / 2f);

                meshAnim.castShadow = true;
                meshAnim.receiveShadow = false;

                scene.add(meshAnim);

                morphs.Add(meshAnim);

                renderer.initWebGLObjects(scene);

            };
            #endregion

            #region morphColorsToFaceColors

            Action<MyModelGeometry> morphColorsToFaceColors = (geometry) =>
            {

                if (geometry.morphColors != null)
                    if (geometry.morphColors.Length > 0)
                    {

                        var colorMap = geometry.morphColors[0];

                        for (var i = 0; i < colorMap.colors.Length; i++)
                        {

                            geometry.faces[i].color = colorMap.colors[i];

                        }

                    }

            };
            #endregion

            #region Models
            var loader = new THREE.JSONLoader();

            var startX = -3000;


            loader.load(
                new Models.parrot().Content.src,

                IFunction.OfDelegate(
                    new Action<MyModelGeometry>(
                        geometry =>
                        {
                            morphColorsToFaceColors(geometry);

                            addMorph(geometry, 250, 500, startX - 500, 500, 700);
                            addMorph(geometry, 250, 500, startX - Math_random() * 500, 500, -200);
                            addMorph(geometry, 250, 500, startX - Math_random() * 500, 500, 200);
                            addMorph(geometry, 250, 500, startX - Math_random() * 500, 500, 1000);
                        }
                    )
                )
            );

            loader.load(
                new Models.flamingo().Content.src,
                IFunction.OfDelegate(
                    new Action<MyModelGeometry>(
                        geometry =>
                        {
                            morphColorsToFaceColors(geometry);
                            addMorph(geometry, 500, 1000, startX - Math_random() * 500, 350, 40);
                        }
                    )
                )
            );


            loader.load(
                new Models.stork().Content.src,
                IFunction.OfDelegate(
                        new Action<MyModelGeometry>(
                            geometry =>
                            {
                                morphColorsToFaceColors(geometry);
                                addMorph(geometry, 350, 1000, startX - Math_random() * 500, 350, 340);
                            }
                        )
                    )
            );
            #endregion



            #region PRE-INIT

            renderer.initWebGLObjects(scene);
            #endregion


            #region onkeydown
            Native.document.body.onkeydown +=
                 (e) =>
                 {

                     if (e.KeyCode == 78) lightDir *= -1;
                     if (e.KeyCode == 77) animDeltaDir *= -1;
                     if (e.KeyCode == 66) soundDir *= -1;

                 };
            #endregion



            Action __loaded = null;

            #region event Action loaded;

            Native.window.parent.With(
                parent =>
                {
                    __loaded = delegate
                    {
                        __loaded = null;
                        parent.postMessage("WebGLDynamicTerrainTemplate.loaded");
                    };
                }
            );
            #endregion


            #region render
            Action render = () =>
            {

                var delta = clock.getDelta();

                soundVal = __THREE.Math.clamp(soundVal + delta * soundDir, 0, 1);

                if (soundVal != oldSoundVal)
                {

                    if (soundtrack != null)
                    {

                        soundtrack.volume = soundVal;
                        oldSoundVal = soundVal;

                    }

                }

                //Native.Document.title = "textureCounter " + textureCounter;


                if (terrain.visible)
                {

                    controls.update();

                    var Date_now = new IDate().getTime();
                    var time = Date_now * 0.001;

                    var fLow = 0.4;
                    var fHigh = 0.825;

                    lightVal = __THREE.Math.clamp(lightVal + 0.5 * delta * lightDir, fLow, fHigh);

                    var valNorm = (lightVal - fLow) / (fHigh - fLow);

                    var sat = __THREE.Math.mapLinear(valNorm, 0, 1, 0.95, 0.25);
                    scene.fog.color.setHSV(0.1, sat, lightVal);

                    renderer.setClearColor(scene.fog.color, 1);

                    spotLight.intensity = __THREE.Math.mapLinear(valNorm, 0, 1, 0.1, 1.15);
                    pointLight.intensity = __THREE.Math.mapLinear(valNorm, 0, 1, 0.9, 1.5);

                    uniformsTerrain.uNormalScale.value = __THREE.Math.mapLinear(valNorm, 0, 1, 0.6, 3.5);

                    if (updateNoise)
                    {

                        animDelta = __THREE.Math.clamp(animDelta + 0.00075 * animDeltaDir, 0, 0.05);
                        uniformsNoise.time.value = ((f)uniformsNoise.time.value) + delta * animDelta;

                        var uniformsNoise_offset_value = (THREE.Vector3)uniformsNoise.offset.value;
                        uniformsNoise_offset_value.x += delta * 0.05f;

                        var uniformsTerrain_uOffset_value = (THREE.Vector3)uniformsTerrain.uOffset.value;
                        uniformsTerrain_uOffset_value.x = 4.0f * uniformsNoise_offset_value.x;

                        quadTarget.material = mlib["heightmap"];
                        renderer.render(sceneRenderTarget, cameraOrtho, heightMap, true);

                        quadTarget.material = mlib["normal"];
                        renderer.render(sceneRenderTarget, cameraOrtho, normalMap, true);

                        //updateNoise = false;

                    }


                    for (var i = 0; i < morphs.Count; i++)
                    {

                        var morph = morphs[i];

                        morph.updateAnimation(1000 * delta);

                        morph.position.x += morph.speed * delta;

                        if (morph.position.x > 2000)
                        {

                            morph.position.x = -1500 - Math_random() * 500;

                        }


                    }

                    //renderer.render( scene, camera );
                    composer.render(0.1);


                    if (__loaded != null)
                        __loaded();
                }
                else
                {
                }

            };
            #endregion





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


                    render();


                };




            #endregion



            #region IsDisposed

            Dispose = delegate
            {
                if (IsDisposed)
                    return;

                IsDisposed = true;

                //page.song.pause();
                soundtrack.pause();

                container.Orphanize();
            };
            #endregion






            #region AtResize
            Action AtResize = delegate
            {
                container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);

                renderer.setSize(Native.window.Width, Native.window.Height);

                camera.aspect = Native.window.Width / Native.window.Height;
                camera.updateProjectionMatrix();
            };

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

            AtResize();
            #endregion


            Native.document.body.onmousedown +=
                e =>
                {
                    if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
                    {
                        Native.document.body.requestFullscreen();
                    }
                };

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

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

                    Native.document.body.requestFullscreen();

                    //AtResize();
                };
            #endregion


        }
        /// <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)
        {
           

            // test it
            //base.Insert(
            //    new Abstractatech.JavaScript.Avatar.Design.WebCamAvatarsSheet1Row()
            //    );

            page.Reset.WhenClicked(
                delegate
            {
                this.Reset();
            }
            );

            page.NewImage.WhenClicked(
                //async 
                button =>
                {
                    var overlay = new IHTMLDiv { }.AttachTo(Native.document.documentElement);
                    overlay.style.position = IStyle.PositionEnum.@fixed;
                    overlay.style.left = "0";
                    overlay.style.top = "0";
                    overlay.style.right = "0";
                    overlay.style.bottom = "0";
                    overlay.style.backgroundColor = "black";

                    var div = new IHTMLDiv { }.AttachTo(overlay);

                    var css = Native.document.body.css.children;

                    css.style.display = IStyle.DisplayEnum.none;

                    Abstractatech.JavaScript.Avatar.ApplicationImplementation.MakeCamGrabber(
                        div,
                        sizeToWindow: true,
                        yield:
                        y =>
                        {
                            overlay.Orphanize();
                            css.style.display = IStyle.DisplayEnum.empty;

                            // napta ocr?
                            // http://projectnaptha.com/

                            new IHTMLImage { y.Avatar640x480 }.AttachToDocument();



                            new IHTMLImage { y.Avatar96gif }.AttachToDocument();

                            //  method:Void <.ctor>b__3(Abstractatech.JavaScript.Avatar.Design.WebCamAvatarsSheet1Row), ex = System.InvalidOperationException: Unable to change after type has been created.
                            //base.Insert(y.Avatar96gif);
                            base.Insert(y);
                        }

                   );
                }
            );

        }
        /// <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)
        {
            WebCamAvatarsSheet1Row lastPicture = null;

            new IStyle(page.ImgContainer.css + IHTMLElement.HTMLElementEnum.img)
            {
                transition = "left linear 2000ms",
                position = IStyle.PositionEnum.absolute,
                Opacity = 1
            };

            //new IStyle(Native.css[typeof(IHTMLImage)].hover)
            //{
            //    width = "100px",
            //};

           

            Action getNewPicture = async delegate
            {
                while (true)
                {
                    var pic = await this.GetLastUserImage();

                    if (lastPicture != null)
                    {
                        if (pic != null)
                        {
                            Console.WriteLine(pic.Key.ToString());
                            Console.WriteLine(lastPicture.Key.ToString());
                            if (pic.Key == lastPicture.Key)
                            {
                                page.ImgContainer.Clear();
                            }
                            else
                            {
                                IHTMLImage img = new IHTMLImage();
                                img.AttachTo(page.ImgContainer);
                                img.src = pic.Avatar96frame1;
                                img.style.left = "-150px";
                                lastPicture = pic;

                                await 500;

                                Native.window.requestAnimationFrame += delegate
                                {
                                    img.style.left = "50px";

                                };

                                await 10000;

                                Native.window.requestAnimationFrame += delegate
                                {
                                    img.style.left = "-150px";

                                };
                            }
                        }
                        else
                        {
                            page.ImgContainer.Clear();
                        }
                    }
                    else
                    {
                        IHTMLImage img = new IHTMLImage();
                        img.AttachTo(page.ImgContainer);
                        lastPicture = pic;
                        img.src = pic.Avatar96frame1;
                        img.style.left = "-150px";
                        
                        await 500;

                        Native.window.requestAnimationFrame += delegate
                        {
                            img.style.left = "50px";

                        };

                        await 10000;

                        Native.window.requestAnimationFrame += delegate
                        {
                            img.style.left = "-150px";

                        };
                    }
                    await 4000;
                }
            };
            Console.WriteLine("Start");
            //getNewPicture();

           // new IHTMLDiv { }.AttachToDocument().With(x => ApplicationImplementation.MakeCamGrabber(x, sizeToWindow: true));
           // var service = new AvatarNotificationService();
            page.ImgContainer.With(x => ApplicationImplementation.MakeimageNotification(page.ImgContainer, this));

            var button = new IHTMLButton { innerHTML = "SubmitButton" }.AttachToDocument();

            button.onclick += delegate
            {
                var overlay = new IHTMLDiv { }.AttachTo(Native.document.documentElement);
                overlay.style.position = IStyle.PositionEnum.@fixed;
                overlay.style.left = "0";
                overlay.style.top = "0";
                overlay.style.right = "0";
                overlay.style.bottom = "0";
                overlay.style.backgroundColor = "black";

                var div = new IHTMLDiv { }.AttachTo(overlay);

                var xcss = Native.document.body.css.children;

                xcss.style.display = IStyle.DisplayEnum.none;

                Abstractatech.JavaScript.Avatar.ApplicationImplementation.MakeCamGrabber(
                    div,
                    sizeToWindow: true,
                    yield:
                    y =>
                    {
                        overlay.Orphanize();
                        xcss.style.display = IStyle.DisplayEnum.empty;

                        Console.WriteLine("InsertNewPicture");

                        if (y.Avatar640x480.Length >= (1024 * 64))
                        {
                            //MessageBox.Show("Picture size too big for now");
                            return;
                        }

                        this.DiagnosticInsertNewPicture(y);

                        //var z = (__PictureBox)(object)f.pictureBox1;

                        // dow we like gif of jpg?
                        //z.InternalElement.src = y.Avatar96gif;
                        //z.InternalElement.src = y.Avatar96frame1;
                    }
                );
            };
        }