/// <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 = null)
        {
            { THREE.SkinnedMesh ref0; }
            { THREE.SpeedBlendCharacter ref0; }

//			will skip DefineVersionInfoResource
//102c: 02:01:1e RewriteToAssembly error: System.NotSupportedException: Type 'xchrome.BCLImplementation.System.Net.Sockets.__TcpListener' was not completed.


			#region AtFormCreated
			FormStyler.AtFormCreated =
                 s =>
                 {
                     s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

                     // this is working?
                     var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
                 };
			#endregion

#if false
			#region ChromeTCPServer
			dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

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


                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                    AppSource.Text,
                    AtFormCreated: FormStyler.AtFormCreated
                );

                return;
            }
			#endregion
#endif

			var fov = 40;

            #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 player_model_objects = new THREE.Object3D();
            var player_position_x = 0.0f;
            var player_position_y = 0.0f;
            var player_position_z = 0.0f;
            var player_position_direction = 0;
            var player_camera_speed = 300;
            var player_camera_distance = 5;
            var player_camera_x = 0.0f;
            var player_camera_y = 0.0f;
            var player_camera_z = 0.0f;
            var player_motion = default(motion);

            //var width = Native.window.Width;
            //var height = Native.window.Height;

            var clock = new Stopwatch();
            clock.Start();
            //var clock = new THREE.Clock();

            var scene = new THREE.Scene();
            scene.fog = new THREE.FogExp2(0x000000, 0.05f);

            scene.add(player_model_objects);

            var camera = new THREE.PerspectiveCamera(fov,
                Native.window.aspect,
                //width / height,
                1, 1000);

            scene.add(camera);

            #region light

            var light = new THREE.DirectionalLight(0xffffff, 1.5);

            light.position.set(1, 1, 1).normalize();

            light.castShadow = true;




            scene.add(light);




            #endregion

            var md2frames = new md2frames();

            var moveState_moving = false;
            var moveState_front = false;
            var moveState_Backwards = false;
            var moveState_left = false;
            var moveState_right = false;
            var moveState_speed = .1;
            var moveState_angle = 0;

            #region move
            Action move = delegate
            {
                //            if(player.model.motion !== 'run' && player.model.state === 'stand'){

                //    changeMotion('run');

                //}

                //if(player.model.motion !== 'crwalk' && player.model.state === 'crstand'){

                //    changeMotion('crwalk');

                //}

                var speed = moveState_speed;

                //if(player.model.state === 'crstand'){speed *= .5;}

                //if(player.model.state === 'freeze') {speed *= 0;}



                var direction = moveState_angle;

                if (moveState_front && !moveState_left && !moveState_Backwards && !moveState_right) { direction += 0; }
                if (moveState_front && moveState_left && !moveState_Backwards && !moveState_right) { direction += 45; }
                if (!moveState_front && moveState_left && !moveState_Backwards && !moveState_right) { direction += 90; }
                if (!moveState_front && moveState_left && moveState_Backwards && !moveState_right) { direction += 135; }
                if (!moveState_front && !moveState_left && moveState_Backwards && !moveState_right) { direction += 180; }
                if (!moveState_front && !moveState_left && moveState_Backwards && moveState_right) { direction += 225; }
                if (!moveState_front && !moveState_left && !moveState_Backwards && moveState_right) { direction += 270; }
                if (moveState_front && !moveState_left && !moveState_Backwards && moveState_right) { direction += 315; }



                player_model_objects.rotation.y = (float)(direction * Math.PI / 180);

                player_position_x -= (float)(Math.Sin(direction * Math.PI / 180) * speed);
                player_position_z -= (float)(Math.Cos(direction * Math.PI / 180) * speed);

            };
            #endregion

            #region camera rotation


            Action rotate = delegate { };

            var pointer_x = 0f;
            var pointer_y = 0f;
            var oldPointerX = 0f;
            var oldPointerY = 0f;

            container.onmousemove +=
                e =>
                {
                    if (Native.document.pointerLockElement == container)
                    {
                        oldPointerX = 0;
                        oldPointerY = 0;
                        pointer_x = e.movementX * 0.01f;
                        pointer_y = -e.movementY * 0.01f;
                        rotate();
                        return;
                    }

                    pointer_x = (e.CursorX / Native.window.Width) * 2 - 1;
                    pointer_y = -(e.CursorY / Native.window.Height) * 2 + 1;
                    rotate();
                };


            container.onmouseup +=
              e =>
              {
                  rotate = delegate { };

                  Native.document.exitPointerLock();
              };

            container.onmousedown +=
                e =>
                {

                    oldPointerX = pointer_x;
                    oldPointerY = pointer_y;

                    rotate = delegate
                    {
                        player_camera_x += (oldPointerX - pointer_x) * player_camera_speed;
                        player_camera_y += (oldPointerY - pointer_y) * player_camera_speed;

                        if (player_camera_y > 150)
                        {
                            player_camera_y = 150;
                        }

                        if (player_camera_y < -150)
                        {
                            player_camera_y = -150;
                        }

                        moveState_angle = Convert.ToInt32(player_camera_x / 2) % 360;

                        oldPointerX = pointer_x;
                        oldPointerY = pointer_y;

                    };

                    Console.WriteLine("requestPointerLock");
                    container.requestPointerLock();
                };

            #endregion

            var renderer = new THREE.WebGLRenderer();
            //renderer.setSize(width, height);
            renderer.setSize();
            renderer.shadowMapEnabled = true;
            renderer.shadowMapSoft = true;
            renderer.domElement.AttachTo(container);




            #region create field


            var planeGeometry = new THREE.PlaneGeometry(1000, 1000);
            var planeMaterial = new THREE.MeshLambertMaterial(
                new
                {
                    map = THREE.ImageUtils.loadTexture(new HTML.Images.FromAssets.bg().src),
                    color = 0xffffff
                }
            );

            planeMaterial.map.repeat.x = 300;
            planeMaterial.map.repeat.y = 300;
            planeMaterial.map.wrapS = THREE.RepeatWrapping;
            planeMaterial.map.wrapT = THREE.RepeatWrapping;
            var plane = new THREE.Mesh(planeGeometry, planeMaterial);
            plane.castShadow = false;
            plane.receiveShadow = true;


            {

                var parent = new THREE.Object3D();
                parent.add(plane);
                parent.rotation.x = -Math.PI / 2;

                scene.add(parent);
            }

            var random = new Random();
            var meshArray = new List<THREE.Mesh>();
            var geometry = new THREE.CubeGeometry(1, 1, 1);

            for (var i = 0; i < 100; i++)
            {

                var ii = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial(
                    new
                    {
                        color = (Convert.ToInt32(0xffffff * random.NextDouble()))
                    }));
                ii.position.x = i % 2 * 5 - 2.5f;
                ii.position.y = .5f;
                ii.position.z = -1 * i * 4;
                ii.castShadow = true;
                ii.receiveShadow = true;


                meshArray.Add(ii);

                scene.add(ii);

            }
            #endregion







            //load converted md2 data

            var material = new THREE.MeshPhongMaterial(
                new
                {
                    map = THREE.ImageUtils.loadTexture(
                        new HTML.Images.FromAssets._1().src
                    ),
                    ambient = 0x999999,
                    color = 0xffffff,
                    specular = 0xffffff,
                    shininess = 25,
                    morphTargets = true
                }
            );




            var loader = new THREE.JSONLoader();

            loader.load(
                new global::WebGLYomotsuTPS.Design.droid().Content.src,
                            xgeometry =>
                            {
                                var md2meshBody = new THREE.MorphAnimMesh(xgeometry, material);

                                md2meshBody.rotation.y = (float)(-Math.PI / 2);
                                md2meshBody.scale.set(.02, .02, .02);
                                md2meshBody.position.y = .5f;
                                md2meshBody.castShadow = true;
                                md2meshBody.receiveShadow = false;

                                #region player_motion
                                Action<motion> player_changeMotion = motion =>
                                {
                                    Console.WriteLine(
                                        new { motion, md2frames.run, md2frames.stand });

                                    player_motion = motion;

                                    //    player.state = md2frames[motion][3].state;

                                    var animMin = motion.min;
                                    var animMax = motion.max;
                                    var animFps = motion.fps;

                                    md2meshBody.time = 0;
                                    md2meshBody.duration = (int)(
                                        1000 * ((animMax - animMin) / (double)animFps)
                                    );
                                    Native.document.title = new { animMin, animMax }.ToString();

                                    md2meshBody.setFrameRange(animMin, animMax);
                                };

                                player_changeMotion(md2frames.stand);
                                #endregion

                                player_model_objects.add(md2meshBody);

                                #region onkeydown
                                Native.document.onkeydown +=
                                    e =>
                                    {
                                        if (e.KeyCode == 67)
                                        {
                                            if (player_motion == md2frames.stand)
                                                player_changeMotion(md2frames.crstand);
                                            else if (player_motion == md2frames.crstand)
                                                player_changeMotion(md2frames.stand);

                                        }
                                        else if (e.KeyCode == 87)
                                        {
                                            moveState_front = true;
                                            moveState_Backwards = false;
                                        }
                                        else if (e.KeyCode == 83)
                                        {
                                            moveState_front = false;
                                            moveState_Backwards = true;
                                        }
                                        else if (e.KeyCode == 65)
                                        {
                                            moveState_left = true;
                                            moveState_right = false;
                                        }
                                        else if (e.KeyCode == 68)
                                        {
                                            moveState_left = false;
                                            moveState_right = true;
                                        }

                                        var isStand = player_motion == md2frames.stand;
                                        Console.WriteLine(
                                            new { e.KeyCode, moveState_front, moveState_Backwards, isStand }
                                            );

                                        if (moveState_front || moveState_Backwards || moveState_left || moveState_right)
                                            if (player_motion == md2frames.stand)
                                                player_changeMotion(md2frames.run);
                                            else if (player_motion == md2frames.crstand)
                                                player_changeMotion(md2frames.crwalk);
                                    };
                                #endregion

                                #region onkeyup
                                Native.document.onkeyup +=
                                    e =>
                                    {
                                        if (e.KeyCode == 87)
                                        {
                                            moveState_front = false;
                                        }
                                        else if (e.KeyCode == 83)
                                        {
                                            moveState_Backwards = false;
                                        }
                                        else if (e.KeyCode == 65)
                                        {
                                            moveState_left = false;
                                        }
                                        else if (e.KeyCode == 68)
                                        {
                                            moveState_right = false;
                                        }

                                    };
                                #endregion




                                #region loop


                                Native.window.onframe += delegate
                                {
                                    if (moveState_front || moveState_Backwards || moveState_left || moveState_right)
                                        move();
                                    else
                                        if (player_motion == md2frames.run)
                                        player_changeMotion(md2frames.stand);
                                    else if (player_motion == md2frames.crwalk)
                                        player_changeMotion(md2frames.crstand);



                                    player_model_objects.position.x = player_position_x;
                                    player_model_objects.position.y = player_position_y;
                                    player_model_objects.position.z = player_position_z;

                                    // camera rotate x
                                    camera.position.x = (float)(player_position_x + player_camera_distance * Math.Sin((player_camera_x) * Math.PI / 360.0));
                                    camera.position.z = (float)(player_position_z + player_camera_distance * Math.Cos((player_camera_x) * Math.PI / 360.0));

                                    //camera rotate y
                                    //camera.position.x = player.position.x + player.camera.distance * Math.cos( (player.camera.y) * Math.PI / 360 );
                                    camera.position.y = (float)(player_position_y + player_camera_distance * Math.Sin((player_camera_y) * Math.PI / 360.0));
                                    //camera.position.z = player.position.z + player.camera.distance * Math.cos( (player.camera.y) * Math.PI / 360 );

                                    camera.position.y += 1;
                                    //console.log(camera.position.z)

                                    var vec3 = new THREE.Vector3(player_position_x, player_position_y, player_position_z);

                                    camera.lookAt(vec3);



                                    #region model animation

                                    var delta = clock.ElapsedMilliseconds * 0.001;
                                    clock.Restart();

                                    var isEndFleame = (player_motion.max == md2meshBody.currentKeyframe);
                                    var isAction = player_motion.action;

                                    var x = (isAction && !isEndFleame);

                                    if (!isAction || x)
                                    {
                                        md2meshBody.updateAnimation(1000 * delta);
                                    }
                                    else if (player_motion.state == "freeze")
                                    {
                                        //dead...
                                    }
                                    else
                                    {
                                        player_changeMotion(player_motion);
                                    }
                                    #endregion

                                    renderer.render(scene, camera);


                                };

                                #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

                                #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(IDefault page = null)
        {
            // var THREE = { REVISION: '67' };
            Native.document.title = new { THREE.REVISION }.ToString();
            // works on IE11
            //DiagnosticsConsole.ApplicationContent.BindKeyboardToDiagnosticsConsole();


            //var fov = 40;
            var fov = 100;

            #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 width = Native.window.Width;
            var height = Native.window.Height;



            var scene = new THREE.Scene();

            var camera = new THREE.PerspectiveCamera(
                fov,
                Native.window.aspect,
                1,
                1000
            ).AttachTo(scene);

            //camera.AttachTo(scene);
            //scene.add(camera);



            //var ambient = new THREE.AmbientLight( 0xffffff);

            //scene.add( ambient );

            var light = new THREE.DirectionalLight(0xffffff, 0.8);
            light.position.set(1, 1, 1).normalize();
            scene.add(light);

            var light2 = new THREE.DirectionalLight(0xffffff);
            light2.position.set(-1, -1, -1).normalize();
            scene.add(light2);



            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(width, height);
            renderer.domElement.AttachTo(container);

            var md2frames = new md2frames();

            //load converted md2 data

            var material = new THREE.MeshPhongMaterial(
                new
                {
                    map = THREE.ImageUtils.loadTexture(
                        new HTML.Images.FromAssets._1().src
                    ),
                    ambient = 0x999999,
                    color = 0xffffff,
                    specular = 0xffffff,
                    shininess = 25,
                    morphTargets = true
                }
            );



            #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

            new THREE.JSONLoader().load(
                new global::WebGLYomotsuMD2Model.Design.tris_md2().Content.src,
                new Action<object>(
                    geometry =>
                    {
                        var player_mesh = new THREE.MorphAnimMesh(geometry, material);

                        player_mesh.rotation.y = (float)(-Math.PI / 2);
                        player_mesh.scale.set(2, 2, 2);
                        player_mesh.castShadow = true;
                        player_mesh.receiveShadow = false;

                        #region player_motion
                        var player_motion = default(motion);
                        Action<motion> player_changeMotion = motion =>
                        {
                            player_motion = motion;

                            //    player.state = md2frames[motion][3].state;

                            var animMin = motion.min;
                            var animMax = motion.max;
                            var animFps = motion.fps;

                            player_mesh.time = 0;
                            player_mesh.duration = 1000 * ((animMax - animMin) / animFps);

                            //Console.WriteLine(
                            //    "setFrameRange " +
                            //    new
                            //    {
                            //        motion.min,
                            //        motion.max,
                            //        motion.fps
                            //    }
                            //    );

                            player_mesh.setFrameRange(animMin, animMax);
                        };

                        player_changeMotion(md2frames.stand);
                        #endregion


                        //player_mesh.att
                        scene.add(player_mesh);

                        var theta = 0;

                        //var clock = new THREE.Clock();

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

                        #region loop


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

                            var isEndFleame = (player_motion.max == player_mesh.currentKeyframe);
                            var isAction = player_motion.action;

                            var x = (isAction && !isEndFleame);

                            if (!isAction || x)
                            {

                                player_mesh.updateAnimation(1000 * delta);

                            }
                            else if (player_motion.state == "freeze")
                            {

                                //dead...

                            }
                            else
                            {

                                player_changeMotion(player_motion);

                            }


                            camera.position.x = (float)(150 * Math.Sin(theta / 2 * Math.PI / 360));
                            camera.position.y = (float)(150 * Math.Sin(theta / 2 * Math.PI / 360));
                            camera.position.z = (float)(150 * Math.Cos(theta / 2 * Math.PI / 360));

                            camera.lookAt(scene.position);

                            theta++;



                            renderer.render(scene, camera);


                        };

                        #endregion

                        #region Toolbar
                        var toolbar = new Toolbar();

                        if (page != null)
                        {
                            toolbar.Container.style.Opacity = 0.7;
                            toolbar.Container.AttachToDocument();
                            toolbar.Container.style.position = IStyle.PositionEnum.absolute;
                            toolbar.Container.style.right = "0";
                            toolbar.Container.style.bottom = "0";

                            toolbar.HideButton.onclick +=
                                    delegate
                                    {
                                        // ScriptCoreLib.Extensions
                                        toolbar.HideTarget.ToggleVisible();
                                    };


                            Action<IHTMLButton, motion> bind =
                                (btn, value) => btn.onclick += delegate { player_changeMotion(value); };

                            bind(toolbar.Stand, md2frames.stand);
                            bind(toolbar.Run, md2frames.run);
                            bind(toolbar.Attack, md2frames.attack);
                            bind(toolbar.Pain1, md2frames.pain1);
                            bind(toolbar.Pain2, md2frames.pain2);
                            bind(toolbar.Pain3, md2frames.pain3);
                            bind(toolbar.Jump, md2frames.jump);
                            bind(toolbar.Flip, md2frames.flip);
                            bind(toolbar.Salute, md2frames.salute);
                            bind(toolbar.Taunt, md2frames.taunt);
                            bind(toolbar.Wave, md2frames.wave);
                            bind(toolbar.Point, md2frames.point);
                            bind(toolbar.Crstand, md2frames.crstand);
                            bind(toolbar.Crwalk, md2frames.crwalk);
                            bind(toolbar.Crattack, md2frames.crattack);
                            bind(toolbar.Crpain, md2frames.crpain);
                            bind(toolbar.Crdeath, md2frames.crdeath);
                            bind(toolbar.Death1, md2frames.death1);
                            bind(toolbar.Death2, md2frames.death2);
                            bind(toolbar.Death3, md2frames.death3);
                        }
                        #endregion



                    }
                )
            );


            //var ze = new ZeProperties();

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

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


        }