// dynamic does not work in static yet?
            //static 
            void InitializeContent()
        {
            floorplan = new Floorplan();


            var c = new Controls.UserControl1();




            Action<string, double, double, double, double, double, double, double, double, double> buildCube =
                (colour, w, h, d, x, y, z, rx, ry, rz) =>
                {
                    new cube(colour, w, h, d, x, y, z, rx, ry, rz);

                    //world.addPlane(new Plane(colour, h, w, x, y, z, 0, 180, 90));
                    //world.addPlane(new Plane(colour, w, d, x, y, z, 90, 0, 0));
                    //world.addPlane(new Plane(colour, d, h, x, y, z, 0, 270, 0));
                    //world.addPlane(new Plane(colour, d, h, x + w, y, z + d, 0, 90, 0));
                    //world.addPlane(new Plane(colour, w, d, x + w, y + h, z, 90, 180, 0));
                    //world.addPlane(new Plane(colour, w, h, x, y, z + d, 0, 0, 0));
                };



            var zoom = 4;
            var zz = 60;

            #region CreateFromFloorplan
            Action CreateFromFloorplan = delegate
            {
                foreach (var item in floorplan.Controls)
                {
                    (item as DeskCube).With(
                        f =>
                        {


                            var cubeheight = Math.Max(300, f.CubeHeight);

                            new cube(
                                "url(assets/CSSTransform3DFPSBlueprint/desk.jpg)",

                                 //w, h, d, x, y, z, rx, ry, rz
                                f.Width * zoom,

                                f.Height * zoom,

                                cubeheight,
                                //0,

                                -f.Right * zoom,

                                f.Top * zoom,

                                -cubeheight + zz,
                                //-250, 

                                0, 0, 0
                            ).With(
                                cube =>
                                {
                                    if (!string.IsNullOrEmpty(f.LeftWallSource))
                                        new IHTMLDiv { }.AttachTo(cube.west.node).With(
                                            westContainer =>
                                            {
                                                //innerText = f.LeftWallSource
                                                //btn.className = "nolock";


                                                westContainer.style.transform = "rotateZ(90deg)";
                                                westContainer.style.transformOrigin = "0% 0%";

                                                westContainer.style.position = IStyle.PositionEnum.absolute;
                                                westContainer.style.width = cube.west.node.clientHeight + "px";
                                                westContainer.style.left = cube.west.node.clientWidth + "px";
                                                westContainer.style.height = cube.west.node.clientWidth + "px";

                                                Action LoadContent = delegate
                                                {

                                                    new IHTMLIFrame { allowFullScreen = true, src = f.LeftWallSource, frameBorder = "0" }.AttachTo(westContainer).With(
                                                        iframe =>
                                                        {
                                                            iframe.style.position = IStyle.PositionEnum.absolute;
                                                            iframe.style.left = "0px";
                                                            iframe.style.top = "0px";
                                                            iframe.style.width = "100%";
                                                            iframe.style.height = "100%";
                                                        }
                                                    );
                                                };

                                                if (f.LeftWallSourceAutoLoad)
                                                {
                                                    LoadContent();
                                                }
                                                else
                                                {
                                                    new IHTMLButton { innerText = "Click to see " + f.LeftWallSource, className = "nolock" }.AttachTo(westContainer).With(
                                                       btn =>
                                                       {
                                                           btn.style.position = IStyle.PositionEnum.absolute;
                                                           btn.style.left = "2em";
                                                           btn.style.top = "2em";
                                                           btn.style.right = "2em";
                                                           btn.style.bottom = "2em";

                                                           btn.onclick +=
                                                               delegate
                                                               {
                                                                   btn.Orphanize();

                                                                   LoadContent();
                                                               };

                                                           f.LeftWallSourceAutoLoadChanged +=
                                                               delegate
                                                               {
                                                                   if (btn == null)
                                                                       return;

                                                                   if (f.LeftWallSourceAutoLoad)
                                                                   {
                                                                       btn.Orphanize();
                                                                       btn = null;

                                                                       LoadContent();
                                                                   }
                                                               };
                                                       }
                                                        );
                                                }
                                            }
                                        );
                                }
                            );

                        }
                    );
                    (item as Floor).With(
                        f =>
                        {

                            buildCube("url(assets/CSSTransform3DFPSBlueprint/wood.jpg)",

                                 //w, h, d, x, y, z, rx, ry, rz
                                f.Width * zoom,

                                f.Height * zoom,

                                10,
                                //0,

                                -f.Right * zoom, f.Top * zoom,

                                0 - f.Z * zoom + zz,
                                //-250, 

                                0, 0, 0);

                        }
                    );
                }
            };

            CreateFromFloorplan();

            //zz += 300;

            //CreateFromFloorplan();
            #endregion


            //avoid out of memory - elements will go missing
            //zz += 300;

            //CreateFromFloorplan();


            c.GetHTMLTarget().className = "nolock";


            c.button1.Click +=
                delegate
                {
                    var cf = new Form1();

                    cf.Show();

                    cf.FormClosing +=
                        (ss, ee) =>
                        {
                            if (cf.WindowState == FormWindowState.Normal)
                            {
                                if (ee.CloseReason == CloseReason.UserClosing)
                                {
                                    ee.Cancel = true;
                                    cf.WindowState = FormWindowState.Minimized;
                                }
                            }
                        };

                    cf.GetHTMLTarget().className = "nolock";

                };
            c.button2.Click +=
                delegate
                {
                    var cf = new Form();

                    var cw = new WebBrowser { Dock = DockStyle.Fill };

                    cf.Controls.Add(cw);

                    cw.Navigate(
                "http://discover.xavalon.net"

                         //"/"

                        );

                    cf.FormClosing +=
                        (ss, ee) =>
                        {
                            if (cf.WindowState == FormWindowState.Normal)
                            {
                                if (ee.CloseReason == CloseReason.UserClosing)
                                {
                                    ee.Cancel = true;
                                    cf.WindowState = FormWindowState.Minimized;
                                }
                            }
                        };
                    cf.Show();

                    //Console.WriteLine("button2.Click");
                    cf.GetHTMLTarget().className = "nolock";

                    //cf.GetHTMLTarget().style.border = "2px solid red";

                };

            c.BackColor = Color.Transparent;

            var xx = c.GetHTMLTargetContainer();

            xx.style.transform = "scale(0.5)";
            xx.style.transformOrigin = "0% 0%";

            xx.style.SetSize(
                __osxPlane_node.clientWidth * 2,
                __osxPlane_node.clientHeight * 2
            );

            c.AttachControlTo(__osxPlane_node);


            #region onkeydown
            Native.Document.body.onkeydown += e =>
            {
                //Console.WriteLine(new { e.KeyCode });

                if (e.KeyCode == (int)Keys.W)
                    window.keyState.forward = true;
                if (e.KeyCode == (int)Keys.S)
                    window.keyState.backward = true;
                if (e.KeyCode == (int)Keys.A)
                    window.keyState.strafeleft = true;
                if (e.KeyCode == (int)Keys.D)
                    window.keyState.straferight = true;

                if (AfterKeystateChange != null)
                    AfterKeystateChange();
            };

            Native.Document.body.onkeyup += e =>
            {
                if (e.KeyCode == (int)Keys.W)
                    window.keyState.forward = false;
                if (e.KeyCode == (int)Keys.S)
                    window.keyState.backward = false;

                if (e.KeyCode == (int)Keys.A)
                    window.keyState.strafeleft = false;
                if (e.KeyCode == (int)Keys.D)
                    window.keyState.straferight = false;

                if (AfterKeystateChange != null)
                    AfterKeystateChange();
            };
            #endregion

            Func<INode, bool> isnolock =
                p =>
                {
                    var nolock = false;

                    while (p != Native.Document.body)
                    {
                        if (((IHTMLElement)p).className == "nolock")
                            nolock = true;

                        p = p.parentNode;
                    }

                    return nolock;
                };

            #region onmousemove
            Native.Document.body.tabIndex = 101;
            Native.Document.body.onmousedown +=
                e =>
                {
                    var nolock = isnolock(e.Element);
                    if (nolock)
                        return;

                    e.preventDefault();
                    Native.Document.body.focus();
                    Native.Document.body.requestPointerLock();
                };

            Native.Document.body.onmousemove +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        window.viewport.camera.rotation.x -= e.movementY / 2;
                        window.viewport.camera.rotation.z += e.movementX / 2;

                        if (AfterCameraRotationChange != null)
                            AfterCameraRotationChange();
                    }
                    else
                    {
                        var nolock = isnolock(e.Element);

                        if (nolock)
                            Native.Document.body.style.cursor = IStyle.CursorEnum.auto;
                        else
                            Native.Document.body.style.cursor = IStyle.CursorEnum.move;
                    }
                };


            Native.Document.body.onmouseup +=
                 e =>
                 {
                     if (Native.Document.pointerLockElement == Native.Document.body)
                     {
                         Native.Document.exitPointerLock();
                     }
                 };
            #endregion

            var touchx = 0;
            var touchy = 0;

            Native.Document.body.ontouchstart +=
             e =>
             {
                 touchx = e.touches[0].pageX;
                 touchy = e.touches[0].pageY;

                 e.preventDefault();
             };

            Native.Document.body.ontouchmove +=
              e =>
              {
                  e.preventDefault();

                  var ztouchx = e.touches[0].pageX;
                  var ztouchy = e.touches[0].pageY;

                  window.viewport.camera.rotation.x -= (ztouchy - touchy) / 2;
                  window.viewport.camera.rotation.z += (ztouchx - touchx) / 2;

                  touchx = ztouchx;
                  touchy = ztouchy;
              };
            //document.addEventListener("touchstart", function (ev) {
            //    pointer.x = ev.targetTouches[0].pageX;
            //    pointer.y = ev.targetTouches[0].pageY;
            //    ev.preventDefault();
            //}, false);

            //document.addEventListener("touchmove", function (ev) {
            //    viewport.camera.rotation.x -= (ev.targetTouches[0].pageY - pointer.y) / 2;
            //    viewport.camera.rotation.z += (ev.targetTouches[0].pageX - pointer.x) / 2;
            //    pointer.x = ev.targetTouches[0].pageX;
            //    pointer.y = ev.targetTouches[0].pageY;
            //    ev.preventDefault();
            //}, false);




            #region loop
            Action loop = delegate
            {
                // is external target working bot ways?
                //window.speed = window.speed;

                //Console.WriteLine(new { window.keyState.forward });

                #region speed
                if (window.keyState.backward)
                {
                    if (window.speed > -window.maxSpeed)
                        window.speed -= window.accel;
                }
                else if (window.keyState.forward)
                {
                    if (window.speed < window.maxSpeed)
                        window.speed += window.accel;
                }
                else if (window.speed > 0)
                {
                    window.speed = Math.Max(window.speed - window.accel, 0);
                }
                else if (window.speed < 0)
                {
                    window.speed = Math.Max(window.speed + window.accel, 0);
                }
                else
                {
                    window.speed = 0;
                }
                #endregion


                #region strafespeed
                if (window.keyState.straferight)
                {
                    if (window.strafespeed > -window.maxSpeed)
                        window.strafespeed -= window.accel;
                }
                else if (window.keyState.strafeleft)
                {
                    if (window.strafespeed < window.maxSpeed)
                        window.strafespeed += window.accel;
                }
                else if (window.strafespeed > 0)
                {
                    window.strafespeed = Math.Max(window.strafespeed - window.accel, 0);
                }
                else if (window.strafespeed < 0)
                {
                    window.strafespeed = Math.Max(window.strafespeed + window.accel, 0);
                }
                else
                {
                    window.strafespeed = 0;
                }
                #endregion


                // sideway
                {

                    var xo = Math.Sin(window.viewport.camera.rotation.z * 0.0174532925);
                    var yo = Math.Cos(window.viewport.camera.rotation.z * 0.0174532925);

                    window.viewport.camera.position.x -= xo * window.speed;
                    window.viewport.camera.position.y -= yo * window.speed;
                }

                {
                    var xo = Math.Sin(window.viewport.camera.rotation.z * 0.0174532925 - 3.14 / 2);
                    var yo = Math.Cos(window.viewport.camera.rotation.z * 0.0174532925 - 3.14 / 2);

                    window.viewport.camera.position.x -= xo * window.strafespeed;
                    window.viewport.camera.position.y -= yo * window.strafespeed;
                }

                window.viewport.camera.update();


            };


            loop.AtAnimationFrame();
            #endregion

        }
            // dynamic does not work in static yet?
            //static 
            void InitializeContent()
        {
            //        script: error JSC1000: Method: InitializeContent, Type: CSSTransform3DFPSExperimentByKeith.Application; emmiting failed : System.InvalidOperationException: unsupported flow detected, try to simplify.
            // Assembly V:\CSSTransform3DFPSExperimentByKeith.Application.exe
            // DeclaringType CSSTransform3DFPSExperimentByKeith.Application, CSSTransform3DFPSExperimentByKeith.Application, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null
            //         OwnerMethod InitializeContent
            //         Offset 00a0
            //         .Try ommiting the return, break or continue instruction.
            //          at jsc.Script.CompilerBase.BreakToDebugger(String e) in x:\jsc.internal.svn\compiler\jsc\Languages\CompilerBase.cs:line 266
            //   at jsc.ILBlock.PrestatementBlock.AddPrestatement(Prestatement p) in x:\jsc.internal.svn\compiler\jsc\CodeModel\ILBlock.cs:line 1654
            //   at jsc.ILBlock.PrestatementBlock.Populate(ILInstruction First, ILInstruction Last) in x:\jsc.internal.svn\compiler\jsc\CodeModel\ILBlock.cs:line 1606
            //   at jsc.ILBlock.PrestatementBlock.Populate() in x:\jsc.internal.svn\compiler\jsc\CodeModel\ILBlock.cs:line 1433
            //   at jsc.ILBlock.get_Prestatements() in x:\jsc.internal.svn\compiler\jsc\CodeModel\ILBlock.cs:line 1759
            //   at jsc.Languages.JavaScript.MethodBodyOptimizer.TryOptimize(IdentWriter w, ILBlock xb) in x:\jsc.internal.svn\compiler\jsc\Languages\JavaScript\MethodBodyOptimizer.cs:line 89
            //   at jsc.IL2Script.EmitBody(IdentWriter w, MethodBase SourceMethod, Boolean define_self) in x:\jsc.internal.svn\compiler\jsc\Languages\JavaScript\IL2Script.cs:line 576

            //Unhandled Exception: System.InvalidOperationException: Method: InitializeContent, Type: CSSTransform3DFPSExperimentByKeith.Application; emmiting failed : System.InvalidOperationException: unsupported flow detected, try to simplify.


            //dynamic window = Native.Window;

            //dynamic __osxPlane = window.__osxPlane;
            //IHTMLDiv __osxPlane_node = __osxPlane.node;

            var discover = new IHTMLIFrame
            {
                //border = "0",
                src = "http://discover.xavalon.net",
                allowFullScreen = true,
                frameBorder = "0"
            };


            //discover.style.transform = "scale(0.5)";
            //discover.style.transformOrigin = "0% 0%";

            //var scale = 1.25;
            var scale = 1;
            var zoom = 8;

            discover.style.transform = "scale(" + (1 / scale) + ")";
            discover.style.transformOrigin = "0% 0%";

            discover.style.SetSize(
                (int)(__wall_c.clientWidth * zoom * scale),
                 (int)(__wall_c.clientHeight * zoom * scale)
            );

            //dynamic ds = discover.style;

            //ds.zoom = (100.0 / zoom) + "%";

            discover.AttachTo(__wall_c);


            var c = new Controls.UserControl1();
            c.GetHTMLTarget().className = "nolock";


            #region button1
            c.button1.Click +=
                delegate
            {
                var cf = new Form1();

                cf.Show();

                cf.FormClosing +=
                    (ss, ee) =>
                        {
                            if (cf.WindowState == FormWindowState.Normal)
                            {
                                if (ee.CloseReason == CloseReason.UserClosing)
                                {
                                    ee.Cancel = true;
                                    cf.WindowState = FormWindowState.Minimized;
                                }
                            }
                        };

                cf.GetHTMLTarget().className = "nolock";

            };
            #endregion


            #region button2
            c.button2.Click +=
                delegate
            {
                var cf = new Form();

                var cw = new WebBrowser { Dock = DockStyle.Fill };

                cf.Controls.Add(cw);

                cw.Navigate(
            "http://discover.xavalon.net"

                        //"/"

                        );

                cf.FormClosing +=
                    (ss, ee) =>
                        {
                            if (cf.WindowState == FormWindowState.Normal)
                            {
                                if (ee.CloseReason == CloseReason.UserClosing)
                                {
                                    ee.Cancel = true;
                                    cf.WindowState = FormWindowState.Minimized;
                                }
                            }
                        };
                cf.Show();

                //Console.WriteLine("button2.Click");
                cf.GetHTMLTarget().className = "nolock";

                //cf.GetHTMLTarget().style.border = "2px solid red";

            };
            #endregion

            c.BackColor = Color.Transparent;

            var x = c.GetHTMLTargetContainer();

            x.style.transform = "scale(0.5)";
            x.style.transformOrigin = "0% 0%";

            x.style.SetSize(
                __osxPlane_node.clientWidth * 2,
                __osxPlane_node.clientHeight * 2
            );

            c.AttachControlTo(__osxPlane_node);




            #region onkeydown
            Native.Document.body.onkeydown += e =>
            {
                //Console.WriteLine(new { e.KeyCode });

                if (e.KeyCode == 87)
                    window.keyState.forward = true;
                if (e.KeyCode == 83)
                    window.keyState.backward = true;
                if (e.KeyCode == (int)Keys.A)
                    window.keyState.strafeleft = true;
                if (e.KeyCode == (int)Keys.D)
                    window.keyState.straferight = true;
            };

            Native.Document.body.onkeyup += e =>
            {
                if (e.KeyCode == 87)
                    window.keyState.forward = false;

                if (e.KeyCode == 83)
                    window.keyState.backward = false;

                if (e.KeyCode == (int)Keys.A)
                    window.keyState.strafeleft = false;
                if (e.KeyCode == (int)Keys.D)
                    window.keyState.straferight = false;

            };
            #endregion


            #region isnolock
            Func<INode, bool> isnolock =
                p =>
                {
                    var nolock = false;

                    while (p != Native.Document.body)
                    {
                        if (((IHTMLElement)p).className == "nolock")
                            nolock = true;

                        p = p.parentNode;
                    }

                    return nolock;
                };
            #endregion



            #region onmousemove
            Native.Document.body.tabIndex = 101;
            Native.Document.body.onmousedown +=
                e =>
                {
                    var nolock = isnolock(e.Element);
                    if (nolock)
                        return;

                    e.PreventDefault();
                    Native.Document.body.focus();
                    Native.Document.body.requestPointerLock();
                };

            Native.Document.body.onmousemove +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        window.viewport.camera.rotation.x -= e.movementY / 2;
                        window.viewport.camera.rotation.z += e.movementX / 2;
                    }
                    else
                    {
                        var nolock = isnolock(e.Element);

                        if (nolock)
                            Native.Document.body.style.cursor = IStyle.CursorEnum.auto;
                        else
                            Native.Document.body.style.cursor = IStyle.CursorEnum.move;
                    }
                };


            Native.Document.body.onmouseup +=
                 e =>
                 {
                     if (Native.Document.pointerLockElement == Native.Document.body)
                     {
                         Native.Document.exitPointerLock();
                     }
                 };
            #endregion





            #region onframe
            Native.window.onframe += delegate
            {
                // is external target working bot ways?
                //window.speed = window.speed;

                //Console.WriteLine(new { window.keyState.forward });

                #region speed
                if (window.keyState.backward)
                {
                    if (window.speed > -window.maxSpeed)
                        window.speed -= window.accel;
                }
                else if (window.keyState.forward)
                {
                    if (window.speed < window.maxSpeed)
                        window.speed += window.accel;
                }
                else if (window.speed > 0)
                {
                    window.speed = Math.Max(window.speed - window.accel, 0);
                }
                else if (window.speed < 0)
                {
                    window.speed = Math.Max(window.speed + window.accel, 0);
                }
                else
                {
                    window.speed = 0;
                }
                #endregion


                #region strafespeed
                if (window.keyState.straferight)
                {
                    if (window.strafespeed > -window.maxSpeed)
                        window.strafespeed -= window.accel;
                }
                else if (window.keyState.strafeleft)
                {
                    if (window.strafespeed < window.maxSpeed)
                        window.strafespeed += window.accel;
                }
                else if (window.strafespeed > 0)
                {
                    window.strafespeed = Math.Max(window.strafespeed - window.accel, 0);
                }
                else if (window.strafespeed < 0)
                {
                    window.strafespeed = Math.Max(window.strafespeed + window.accel, 0);
                }
                else
                {
                    window.strafespeed = 0;
                }
                #endregion


                // sideway
                {

                    var xo = Math.Sin(window.viewport.camera.rotation.z * 0.0174532925);
                    var yo = Math.Cos(window.viewport.camera.rotation.z * 0.0174532925);

                    window.viewport.camera.position.x -= xo * window.speed;
                    window.viewport.camera.position.y -= yo * window.speed;
                }

                {
                    var xo = Math.Sin(window.viewport.camera.rotation.z * 0.0174532925 - 3.14 / 2);
                    var yo = Math.Cos(window.viewport.camera.rotation.z * 0.0174532925 - 3.14 / 2);

                    window.viewport.camera.position.x -= xo * window.strafespeed;
                    window.viewport.camera.position.y -= yo * window.strafespeed;
                }

                window.viewport.camera.update();


            };
            #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)
        {
            // what about webrtc?

            content.BackColor = Color.Transparent;

            if (Native.window.opener != null)
            {
                content.button1.Enabled = false;
                content.button1.Text = "we are the secondary screen!";
                return;
            }

            var flocal = new Form1();

            flocal.Show();
            flocal.webBrowser1.Navigate("/jsc");

            content.button1.Click +=
                delegate
                {
                    content.button1.Enabled = false;

                    int c = -1;

                    Native.window.open("/", "_blank").With(
                        w =>
                        {
                            w.onload +=
                                delegate
                                {
                                    c++;

                                    if (c == 0)
                                    {

                                    }
                                    else if (c == 1)
                                    {
                                        // we need the secondary load?
                                        w.document.title = "secondary screen";


                                        w.document.body.style.backgroundColor = JSColor.Yellow;



                                        var fremote = new Form1 { Text = "(Remote)" };

                                        fremote.webBrowser1.Navigate("/jsc");

                                        fremote.Show();


                                        fremote.GetHTMLTarget().AttachTo(
                                            w.document.body
                                        );

                                        fremote.Opacity = 0.5;

                                        var shadow = new IHTMLDiv();

                                        shadow.style.SetLocation(
                                            32, 32, 200,
                                            200
                                        );

                                        shadow.style.backgroundColor = JSColor.Yellow;

                                        shadow.style.Opacity = 0.5;

                                        shadow.AttachToDocument();

                                        #region update
                                        Action update =
                                            delegate
                                            {
                                                dynamic xwlocal = Native.window;

                                                int xwlocal_left = xwlocal.screenLeft;
                                                int xwlocal_top = xwlocal.screenTop;

                                                int xwlocal_innerHeight = xwlocal.innerHeight;
                                                int xwlocal_outerHeight = xwlocal.outerHeight;
                                                int xwlocal_innerWidth = xwlocal.innerWidth;
                                                int xwlocal_outerWidth = xwlocal.outerWidth;

                                                dynamic xw = w;

                                                int xw_left = xw.screenLeft;
                                                int xw_top = xw.screenTop;

                                                int xw_innerHeight = xw.innerHeight;
                                                int xw_outerHeight = xw.outerHeight;
                                                int xw_innerWidth = xw.innerWidth;
                                                int xw_outerWidth = xw.outerWidth;

                                                Console.WriteLine(
                                                    new
                                                    {
                                                        flocal.Left,
                                                        xwlocal_left,
                                                        xw_left,
                                                        xwlocal_innerWidth,
                                                        xwlocal_outerWidth,
                                                        xw_innerWidth,
                                                        xw_outerWidth
                                                    }
                                                    );

                                                fremote.MoveTo(
                                                    flocal.Left + xwlocal_left + (xwlocal_outerWidth - xwlocal_innerWidth) - xw_left - (xw_outerWidth - xw_innerWidth),
                                                    flocal.Top + xwlocal_top + (xwlocal_outerHeight - xwlocal_innerHeight) - xw_top - (xw_outerHeight - xw_innerHeight)
                                                );

                                                fremote.SizeTo(
                                                    flocal.Width,
                                                    flocal.Height
                                                );

                                                shadow.style.SetLocation(
                                                   -xwlocal_left - (xwlocal_outerWidth - xwlocal_innerWidth) + xw_left + (xw_outerWidth - xw_innerWidth),
                                                   -xwlocal_top - (xwlocal_outerHeight - xwlocal_innerHeight) + xw_top + (xw_outerHeight - xw_innerHeight),

                                                   xw_innerWidth,
                                                   xw_innerHeight
                                               );

                                            };
                                        flocal.LocationChanged +=
                                            delegate
                                            {
                                                update();
                                            };

                                        flocal.SizeChanged +=
                                            delegate
                                            {
                                                update();
                                            };

                                        update();

                                        Action loop = null;
                                        loop = delegate
                                            {
                                                update();
                                                Native.window.requestAnimationFrame += loop;
                                            };
                                        loop();
                                        #endregion

                                        content.button1.Enabled = true;

                                    }

                                };
                        }
                    );

                    @"primary screen".ToDocumentTitle();
                };

            //content.AttachControlTo(page.Content);

            content.AttachControlToDocument();

            //content.AutoSizeControlTo(page.ContentSize);

        }
            // dynamic does not work in static yet?
            //static 
            void InitializeContent()
        {
            var c = new Controls.UserControl1();

            // artwork
            var __artworkPlane = new Plane(
                "url(assets/CSSTransform3DFPSExperiment/osx.jpg)", 424, 174, -398, -240, -300, 90, 90, 0);

            world.addPlane(__artworkPlane);

            world.addPlane(
                new Plane(
                    "url(assets/CSSTransform3DFPSExperiment/wood.jpg)", 800, 800, -400, 400, 53, 180, 0, 0
                )
            );



            new Plane("url(assets/CSSTransform3DFPSExperiment/wall.jpg?3)", 800, 500, -400, -400, -447, 270, 90, 180).With(
                __wall_a =>
                {
                    world.addPlane(__wall_a);
                }
            );

            var ix = 0;

            Action NextWallToTHeRight = delegate
                    {

                        ix++;

                        world.addPlane(
                          new Plane(
                              "url(assets/CSSTransform3DFPSExperiment/wood.jpg)", 800, 800, -400, 400 + 800 * ix, 53, 180, 0, 0
                          )
                      );

                        new Plane("url(assets/CSSTransform3DFPSExperiment/wall.jpg?3)", 800, 500, -400, -400 + 800 * ix, -447, 270, 90, 180).With(
                            __wall_a =>
                            {
                                world.addPlane(__wall_a);
                            }
                        );
                    }
                ;

            NextWallToTHeRight();
            c.button3.Click += delegate { NextWallToTHeRight(); };

            Action<string, double, double, double, double, double, double, double, double, double> buildCube0 =
            (colour, w, h, d, x, y, z, rx, ry, rz) =>
            {
                //world.addPlane(new Plane(colour, h, w, x, y, z, 0, 180, 90));
                //world.addPlane(new Plane(colour, w, d, x, y, z, 90, 0, 0));
                //world.addPlane(new Plane(colour, d, h, x, y, z, 0, 270, 0));

                new Plane(colour, d, h, x + w, y, z + d, 0, 90, 0).With(
                    p =>
                    {
                        world.addPlane(p);

                        //new ScriptCoreLib.JavaScript.Runtime.Timer(
                        //    delegate
                        //    {
                        //        p.rotation.z += 15;
                        //        p.update();
                        //    }
                        //).StartInterval(150);
                    }
                );

                //world.addPlane(new Plane(colour, w, d, x + w, y + h, z, 90, 180, 0));
                //world.addPlane(new Plane(colour, w, h, x, y, z + d, 0, 0, 0));
            };

            Action<string, double, double, double, double, double, double, double, double, double> buildCube =
                (colour, w, h, d, x, y, z, rx, ry, rz) =>
                {
                    world.addPlane(new Plane(colour, h, w, x, y, z, 0, 180, 90));
                    world.addPlane(new Plane(colour, w, d, x, y, z, 90, 0, 0));
                    world.addPlane(new Plane(colour, d, h, x, y, z, 0, 270, 0));
                    world.addPlane(new Plane(colour, d, h, x + w, y, z + d, 0, 90, 0));
                    world.addPlane(new Plane(colour, w, d, x + w, y + h, z, 90, 180, 0));
                    world.addPlane(new Plane(colour, w, h, x, y, z + d, 0, 0, 0));
                };

            buildCube0("url(assets/CSSTransform3DFPSExperiment/desk.jpg)", 10, 50, 300, -150 + 400, 345, -250, 0, 0, 0);

            for (int xi = 0; xi < 20; xi++)
            {
                buildCube("url(assets/CSSTransform3DFPSExperiment/desk.jpg)", 10, 50, 300, -150 + 400, 345 + 60 * xi, -250, 0, 0, 0);

            }


            new Plane(
                "url(assets/CSSTransform3DFPSExperiment/wood.jpg)", 800, 800, -400 + 800, 400, 53, 180, 0, 0
            ).With(
               pp =>
               {
                   world.addPlane(pp);


                   pp.position.x += 20;
                   //pp.rotation.z += 15;

                   pp.update();

               }
           );


            c.GetHTMLTarget().className = "nolock";


            c.button1.Click +=
                delegate
                {
                    var cf = new Form1();

                    cf.Show();

                    cf.FormClosing +=
                        (ss, ee) =>
                        {
                            if (cf.WindowState == FormWindowState.Normal)
                            {
                                if (ee.CloseReason == CloseReason.UserClosing)
                                {
                                    ee.Cancel = true;
                                    cf.WindowState = FormWindowState.Minimized;
                                }
                            }
                        };

                    cf.GetHTMLTarget().className = "nolock";

                };
            c.button2.Click +=
                delegate
                {
                    var cf = new Form();

                    var cw = new WebBrowser { Dock = DockStyle.Fill };

                    cf.Controls.Add(cw);

                    cw.Navigate(
                "http://discover.xavalon.net"

                         //"/"

                        );

                    cf.FormClosing +=
                        (ss, ee) =>
                        {
                            if (cf.WindowState == FormWindowState.Normal)
                            {
                                if (ee.CloseReason == CloseReason.UserClosing)
                                {
                                    ee.Cancel = true;
                                    cf.WindowState = FormWindowState.Minimized;
                                }
                            }
                        };
                    cf.Show();

                    //Console.WriteLine("button2.Click");
                    cf.GetHTMLTarget().className = "nolock";

                    //cf.GetHTMLTarget().style.border = "2px solid red";

                };

            c.BackColor = Color.Transparent;

            var xx = c.GetHTMLTargetContainer();

            xx.style.transform = "scale(0.5)";
            xx.style.transformOrigin = "0% 0%";

            xx.style.SetSize(
                __osxPlane_node.clientWidth * 2,
                __osxPlane_node.clientHeight * 2
            );

            c.AttachControlTo(__osxPlane_node);


            #region onkeydown
            Native.Document.body.onkeydown += e =>
            {
                //Console.WriteLine(new { e.KeyCode });

                if (e.KeyCode == 87)
                    window.keyState.forward = true;
                if (e.KeyCode == 83)
                    window.keyState.backward = true;
                if (e.KeyCode == (int)Keys.A)
                    window.keyState.strafeleft = true;
                if (e.KeyCode == (int)Keys.D)
                    window.keyState.straferight = true;
            };

            Native.Document.body.onkeyup += e =>
            {
                if (e.KeyCode == 87)
                    window.keyState.forward = false;

                if (e.KeyCode == 83)
                    window.keyState.backward = false;

                if (e.KeyCode == (int)Keys.A)
                    window.keyState.strafeleft = false;
                if (e.KeyCode == (int)Keys.D)
                    window.keyState.straferight = false;

            };
            #endregion

            Func<INode, bool> isnolock =
                p =>
                {
                    var nolock = false;

                    while (p != Native.Document.body)
                    {
                        if (((IHTMLElement)p).className == "nolock")
                            nolock = true;

                        p = p.parentNode;
                    }

                    return nolock;
                };

            #region onmousemove
            Native.Document.body.tabIndex = 101;
            Native.Document.body.onmousedown +=
                e =>
                {
                    var nolock = isnolock(e.Element);
                    if (nolock)
                        return;

                    e.PreventDefault();
                    Native.Document.body.focus();
                    Native.Document.body.requestPointerLock();
                };

            Native.Document.body.onmousemove +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        window.viewport.camera.rotation.x -= e.movementY / 2;
                        window.viewport.camera.rotation.z += e.movementX / 2;
                    }
                    else
                    {
                        var nolock = isnolock(e.Element);

                        if (nolock)
                            Native.Document.body.style.cursor = IStyle.CursorEnum.auto;
                        else
                            Native.Document.body.style.cursor = IStyle.CursorEnum.move;
                    }
                };


            Native.Document.body.onmouseup +=
                 e =>
                 {
                     if (Native.Document.pointerLockElement == Native.Document.body)
                     {
                         Native.Document.exitPointerLock();
                     }
                 };
            #endregion


            #region loop
            Native.window.onframe += delegate
            {
                // is external target working bot ways?
                //window.speed = window.speed;

                //Console.WriteLine(new { window.keyState.forward });

                #region speed
                if (window.keyState.backward)
                {
                    if (window.speed > -window.maxSpeed)
                        window.speed -= window.accel;
                }
                else if (window.keyState.forward)
                {
                    if (window.speed < window.maxSpeed)
                        window.speed += window.accel;
                }
                else if (window.speed > 0)
                {
                    window.speed = Math.Max(window.speed - window.accel, 0);
                }
                else if (window.speed < 0)
                {
                    window.speed = Math.Max(window.speed + window.accel, 0);
                }
                else
                {
                    window.speed = 0;
                }
                #endregion


                #region strafespeed
                if (window.keyState.straferight)
                {
                    if (window.strafespeed > -window.maxSpeed)
                        window.strafespeed -= window.accel;
                }
                else if (window.keyState.strafeleft)
                {
                    if (window.strafespeed < window.maxSpeed)
                        window.strafespeed += window.accel;
                }
                else if (window.strafespeed > 0)
                {
                    window.strafespeed = Math.Max(window.strafespeed - window.accel, 0);
                }
                else if (window.strafespeed < 0)
                {
                    window.strafespeed = Math.Max(window.strafespeed + window.accel, 0);
                }
                else
                {
                    window.strafespeed = 0;
                }
                #endregion


                // sideway
                {

                    var xo = Math.Sin(window.viewport.camera.rotation.z * 0.0174532925);
                    var yo = Math.Cos(window.viewport.camera.rotation.z * 0.0174532925);

                    window.viewport.camera.position.x -= xo * window.speed;
                    window.viewport.camera.position.y -= yo * window.speed;
                }

                {
                    var xo = Math.Sin(window.viewport.camera.rotation.z * 0.0174532925 - 3.14 / 2);
                    var yo = Math.Cos(window.viewport.camera.rotation.z * 0.0174532925 - 3.14 / 2);

                    window.viewport.camera.position.x -= xo * window.strafespeed;
                    window.viewport.camera.position.y -= yo * window.strafespeed;
                }

                window.viewport.camera.update();


            };


            #endregion

        }