/// <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


                            }
            );





        }
示例#2
0
        void Spawn(DudeAnimationInfo LoadedCharacter, Scene.Document LoadedScene)
        {
            var ViewSize = new Size { Width = 640, Height = 480 };

            var Container = new IHTMLDiv();
            Container.AttachToDocument();
            Container.style.SetSize(ViewSize.Width, ViewSize.Height + 22);
            Container.KeepInCenter();

            //Container.MakeCSSShaderCrumple();

            var Wallpaper = new IHTMLDiv().AttachTo(Container);
            Wallpaper.style.SetSize(ViewSize.Width, ViewSize.Height + 22);


            new power().ToBackground(Wallpaper.style);
            Wallpaper.style.position = IStyle.PositionEnum.absolute;
            Wallpaper.style.backgroundRepeat = "no-repeat";
            Wallpaper.style.backgroundPosition = "center center";





            var Margin = 48;
            var MarginSafe = 72;



            var CurrentFrame = LoadedScene.Frames.Randomize().First();
            //var CurrentFrame = LoadedScene.Frames.Single(f => f.Name == "C");

            var Room = new IHTMLDiv();



            Room.style.border = "1px solid #00ff00";
            Room.style.SetSize(ViewSize.Width, ViewSize.Height);
            Room.style.position = IStyle.PositionEnum.absolute;
            Room.style.overflow = IStyle.OverflowEnum.hidden;

            Room.AttachTo(Container);
            Room.style.SetLocation(0, 22);

            //Room.AttachToDocument();
            //Room.KeepInCenter();




            var tween = Room.ToOpacityTween();

            Action HideRoom = () => tween.Value = 1;
            Action ShowRoom = () => tween.Value = 0;

            HideRoom();

            //var GroundOverlay2 = new IHTMLDiv();

            //GroundOverlay2.style.backgroundColor = Color.Blue;
            ////GroundOverlay.style.Opacity = 0;

            //GroundOverlay2.style.position = IStyle.PositionEnum.absolute;
            //GroundOverlay2.style.SetLocation(0, 0, ViewSize.Width, ViewSize.Height);
            //GroundOverlay2.AttachTo(Room);

            var LostInTime_Images = new ImpAdventures.HTML.Pages.LostInTimeImages().Images;

            var BackgroundImage = new IHTMLImage();

            LostInTime_Images.FirstOrDefault(
                                   k => k.src.SkipUntilLastIfAny("/") == CurrentFrame.Image.Source.SkipUntilLastIfAny("/")
                               ).With(
                                   ImageSource =>
                                   {
                                       Console.WriteLine(ImageSource.src);
                                       BackgroundImage.src = ImageSource.src;
                                   }
                               );

            BackgroundImage.style.SetLocation(0, 0, ViewSize.Width, ViewSize.Height);
            BackgroundImage.alt = "BackgroundImage";
            BackgroundImage.AttachTo(Room);

            //GroundOverlay2.style.backgroundImage = "url(" + CurrentFrame.Image.Source + ")";
            //BackgroundImage.InvokeOnComplete(
            //    delegate
            //    {
            //        //BackgroundImage.style.backgroundColor = Color.Red;
            //        //BackgroundImage.style.SetLocation(0,0, ViewSize.Width, ViewSize.Height);
            //        BackgroundImage.AttachTo(GroundOverlay2);
            //    }
            //);


            var GroundOverlay = new IHTMLDiv();

            GroundOverlay.style.backgroundColor = Color.Blue;
            GroundOverlay.style.Opacity = 0;
            GroundOverlay.style.SetLocation(0, 0, ViewSize.Width, ViewSize.Height);
            GroundOverlay.AttachTo(Room);

            var Ground = new IHTMLDiv();

            Ground.style.SetLocation(0, 0, ViewSize.Width, ViewSize.Height);
            Ground.AttachTo(Room);




            var AnimateRoomChange = default(Action<Action>);

            #region TryToChangeRooms
            Func<TryToChangeRoomsArgs, bool> TryToChangeRooms =
                e =>
                {
                    if (e == null)
                        return false;

                    if (e.NextRoomSelector == null) throw new ArgumentNullException("NextRoomSelector");

                    var next = LoadedScene.Frames.SingleOrDefault(e.NextRoomSelector);

                    var r = next != null;

                    if (r)
                    {
                        AnimateRoomChange(
                            delegate
                            {
                                CurrentFrame = next;

                                Console.WriteLine("AnimateRoomChange");

                                LostInTime_Images.FirstOrDefault(
                                    k => k.src.SkipUntilLastIfAny("/") == CurrentFrame.Image.Source.SkipUntilLastIfAny("/")
                                ).With(
                                    ImageSource =>
                                    {
                                        Console.WriteLine(ImageSource.src);
                                        BackgroundImage.src = ImageSource.src;
                                    }
                                );

                                //GroundOverlay2.style.backgroundImage = "url(" + CurrentFrame.Image.Source + ")";
                                //BackgroundImage.src = CurrentFrame.Image.Source;

                                e.ReadyToTeleport();
                            }
                        );
                    }


                    return r;
                };
            #endregion


            var dude = CreateDude(LoadedCharacter);

            dude.Control.AttachTo(Ground);

            #region Doors
            var Doors = new[]
                {
                    new TryToChangeRoomsArgs
                            {
                                Condition = () => dude.CurrentLocation.X > ViewSize.Width - Margin,
                                NextRoomSelector = f => f.Name == CurrentFrame.Right,
                                ReadyToTeleport = delegate
                                {

                                    dude.TeleportTo(-MarginSafe, dude.CurrentLocation.Y);
                                    dude.LookAt(new Point(MarginSafe, (int)dude.CurrentLocation.Y));
                                }
                            },
                    new TryToChangeRoomsArgs
                            {
                                Condition = () => dude.CurrentLocation.X < Margin,
                                NextRoomSelector = f => f.Name == CurrentFrame.Left,
                                ReadyToTeleport = delegate
                                {

                                    dude.TeleportTo(ViewSize.Width + MarginSafe, dude.CurrentLocation.Y);
                                    dude.LookAt(new Point(ViewSize.Width - MarginSafe, (int)dude.CurrentLocation.Y));
                                }
                            },
                    new TryToChangeRoomsArgs
                            {
                                Condition = () => dude.CurrentLocation.Y < Margin,
                                NextRoomSelector = f => f.Name == CurrentFrame.Top,
                                ReadyToTeleport = delegate
                                {

                                     dude.TeleportTo(dude.CurrentLocation.X, ViewSize.Height + MarginSafe);
                                    dude.LookAt(new Point((int)dude.CurrentLocation.X, ViewSize.Height - MarginSafe));

                                }
                            },
                    new TryToChangeRoomsArgs
                            {
                                Condition = () => dude.CurrentLocation.Y > ViewSize.Height - Margin,
                                NextRoomSelector = f => f.Name == CurrentFrame.Bottom,
                                ReadyToTeleport = delegate
                                {

                                  dude.TeleportTo(dude.CurrentLocation.X, -Margin);
                                dude.LookAt(new Point((int)dude.CurrentLocation.X, MarginSafe));

                                }
                            }
                };
            #endregion

            Console.WriteLine(new { Doors = Doors.Length });

            Doors.WithEachIndex(
                (x, index) =>
                {
                    Console.WriteLine(new { index, x });
                    Console.WriteLine(new { index, x.Condition });
                }
            );


            var ChangeRoom = new ChangeRoom { autobuffer = true };
            var Talk = new Talk { autobuffer = true };
            var Argh_RChannel = new Argh_RChannel { autobuffer = true };
            var Argh_LChannel = new Argh_LChannel { autobuffer = true };
            var Argh_Disabled = false;
            var Argh_VolumeMultiplier = 1.0;

            #region Argh_Stereo
            Action<double, double> Argh_Stereo =
                (volume, balance) =>
                {
                    if (Argh_Disabled)
                        return;

                    Argh_RChannel.AttachToDocument();
                    Argh_LChannel.AttachToDocument();

                    Argh_RChannel.volume = Argh_VolumeMultiplier * volume * balance;
                    Argh_LChannel.volume = Argh_VolumeMultiplier * volume * (1 - balance);

                    Argh_RChannel.play();
                    Argh_LChannel.play();

                    Argh_RChannel = new Argh_RChannel { autobuffer = true };
                    Argh_LChannel = new Argh_LChannel { autobuffer = true };

                    Argh_Disabled = true;
                    Argh_VolumeMultiplier /= 2;

                    new Timer(t => Argh_Disabled = false).StartTimeout(800);
                    new Timer(t => Argh_VolumeMultiplier = 1).StartTimeout(5000);
                };
            #endregion

            #region PrintText
            Action<string, Action> PrintText =
                (text, done) =>
                {
                    Talk.AttachToDocument();
                    Talk.load();
                    Talk.volume = Math.Min(1, dude.Zoom.DynamicZoom / 4);
                    Talk.play();
                    Talk = new Talk { autobuffer = true };

                    text.Length.Range().AsyncForEach(
                        i =>
                        {
                            Wallpaper.innerText = text.Left(i + 1);

                            var c = text[i];

                            if (LoadedScene.SlowText.Contains("" + c))
                                return 100.Random();

                            return 50.Random();
                        }, done
                    );
                };
            #endregion

            Action<string, Action> PrintRandomText =
                (text, done) => PrintText(text.Split(LoadedScene.TextDelimiter).Randomize().First(), done);




            dude.DoneWalking +=
                delegate
                {
                    // compiler bug: cannot invoke Action<func, action> delegate ?

                    System.Console.WriteLine("done walking in " + CurrentFrame.Name + " at " + dude.CurrentLocation);

                    var xFirstOrDefault = Doors.FirstOrDefault(d => d.Condition());

                    System.Console.WriteLine("done walking in " + new { xFirstOrDefault });

                    // Doors null?
                    if (TryToChangeRooms(xFirstOrDefault))
                        return;


                    if (CurrentFrame.Items != null)
                    {
                        var item = CurrentFrame.Items.Where(
                            i => new Point(i.X.ToInt32(), i.Y.ToInt32()).GetRange(dude.CurrentLocation) < i.R.ToInt32()
                            ).FirstOrDefault();

                        if (item != null)
                        {


                            dude.IsSelected = false;
                            dude.LookDown();

                            PrintRandomText(item.Text,
                                delegate
                                {

                                    dude.WalkingOnce +=
                                        delegate
                                        {
                                            Wallpaper.innerText = "";
                                        };

                                    dude.IsSelected = true;
                                }
                            );
                        }
                    }

                };

            #region AnimateRoomChange
            AnimateRoomChange =
                ReadyToTeleport =>
                {
                    var Step1 = default(System.Action);
                    var Step2 = default(System.Action);
                    var Step3 = default(Action);

                    Step1 =
                        delegate
                        {
                            tween.Done -= Step1;

                            ReadyToTeleport();

                            tween.Done += Step2;

                            ShowRoom();
                        };

                    Step2 =
                        delegate
                        {
                            tween.Done -= Step2;

                            dude.DoneWalking += Step3;

                            dude.IsWalking = true;

                        };

                    Step3 =
                        delegate
                        {
                            dude.DoneWalking -= Step3;

                            dude.IsSelected = true;
                        };

                    dude.IsSelected = false;

                    tween.Done += Step1;
                    // go left
                    HideRoom();

                    // http://stackoverflow.com/questions/3009888/autoplay-audio-files-on-an-ipad-with-html5
                    ChangeRoom.AttachToDocument();
                    ChangeRoom.load();
                    ChangeRoom.volume = 0.2;
                    ChangeRoom.play();
                    ChangeRoom = new ChangeRoom();
                };
            #endregion

            var pointer_x = 0;
            var pointer_y = 0;

            #region onmousemove
            Container.onmousemove +=
                ev =>
                {
                    if (Native.Document.pointerLockElement == Container)
                    {
                        if (dude.IsSelected)
                        {
                            var volume = Math.Min(1, dude.Zoom.DynamicZoom / 4);
                            var balance = dude.CurrentLocation.X / ViewSize.Width;

                            pointer_x += ev.movementX;
                            pointer_y += ev.movementY;

                            pointer_x = Math.Min(ViewSize.Width - 0, Math.Max(0, pointer_x));
                            pointer_y = Math.Min(ViewSize.Height - 0, Math.Max(0, pointer_y));

                            var OffsetPosition = new Point(pointer_x, pointer_y

                            );

                            Console.WriteLine(OffsetPosition);

                            Argh_Stereo(volume, balance);
                            dude.WalkTo(OffsetPosition);
                        }
                    }
                };
            #endregion

            #region ontouchstart
            Container.ontouchstart +=
                ev =>
                {
                    ev.preventDefault();

                    System.Console.WriteLine(ev.CursorPosition);

                    if (dude.IsSelected)
                    {
                        var volume = Math.Min(1, dude.Zoom.DynamicZoom / 4);
                        var balance = dude.CurrentLocation.X / ViewSize.Width;

                        var ev_OffsetPosition = new Point(
                            ev.touches[0].clientX - Container.Bounds.Left,
                            ev.touches[0].clientY - Container.Bounds.Top
                            );

                        Argh_Stereo(volume, balance);
                        dude.WalkTo(ev_OffsetPosition);
                    }
                };
            #endregion

            #region onclick
            Container.onclick +=
                ev =>
                {
                    ev.preventDefault();

                    if (ev.MouseButton == IEvent.MouseButtonEnum.Middle)
                    {
                        if (Native.Document.pointerLockElement == Container)
                        {
                            Native.Document.exitPointerLock();
                            return;
                        }

                        pointer_x = (int)dude.CurrentLocation.X;
                        pointer_y = (int)dude.CurrentLocation.Y;

                        //Container.requestFullscreen();
                        Container.requestPointerLock();
                        return;
                    }

                    if (ev.Element != Ground)
                        return;

                    System.Console.WriteLine(ev.CursorPosition);

                    if (dude.IsSelected)
                    {
                        var volume = Math.Min(1, dude.Zoom.DynamicZoom / 4);
                        var balance = dude.CurrentLocation.X / ViewSize.Width;

                        Argh_Stereo(volume, balance);
                        dude.WalkTo(ev.OffsetPosition);
                    }
                };
            #endregion



            //GroundOverlay.onclick +=
            //    ev =>
            //    {
            //        if (ev.Element != GroundOverlay)
            //            return;

            //        System.Console.WriteLine(ev.CursorPosition);

            //        if (dude.IsSelected)
            //        {
            //            new Argh().play();

            //            dude.WalkTo(ev.OffsetPosition);
            //        }
            //    };


            dude.TeleportTo(ViewSize.Width / 2, (ViewSize.Height - MarginSafe) / 2);
            dude.LookDown();

            ShowRoom();

            dude.DoneWalkingOnce +=
                delegate
                {
                    PrintRandomText(
                        LoadedScene.IntroText,
                        delegate
                        {

                            dude.WalkingOnce +=
                              delegate
                              {
                                  Wallpaper.innerText = "";
                              };

                            dude.IsSelected = true;
                        }
                    );
                };

            dude.WalkToArc(MarginSafe, dude.Direction);

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

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


        // net use
        // OK           R:        \\192.168.1.12\x$         Microsoft Windows Network


        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20151003/ovrwindwheelactivity
        // subst b: s:\jsc.svn\examples\javascript\chrome\apps\ChromeAppWindowUDPPointerLock\ChromeAppWindowUDPPointerLock\bin\Debug\staging\ChromeAppWindowUDPPointerLock.Application\web

        // X:\jsc.svn\examples\javascript\chrome\apps\ChromeAppWindowUDPPointerLock\ChromeAppWindowUDPPointerLock\bin\Debug\staging\ChromeAppWindowUDPPointerLock.Application\web

        // logoff logon?
        // net start LanmanServer

        //        ---------------------------
        //Restoring Network Connections
        //---------------------------
        //An error occurred while reconnecting R: to
        //\\192.168.1.12\x$
        //Microsoft Windows Network: The specified network name is no longer available.


        //This connection has not been restored.
        //---------------------------
        //OK   
        //---------------------------



        //        ---------------------------
        //Restoring Network Connections
        //---------------------------
        //An error occurred while reconnecting R: to
        //\\192.168.1.12\x$
        //Microsoft Windows Network: Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.


        //This connection has not been restored.
        //---------------------------
        //OK   



        /// <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)
        {
            // how are we to make this into a chrome app?
            // "X:\jsc.svn\examples\javascript\chrome\apps\ChomeAlphaAppWindow\ChomeAlphaAppWindow.sln"

            // since now jsc shows ssl support
            // how about packaging the view-source for chrome too?

            // nuget, add chrome.

            #region += Launched chrome.app.window
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

            if (self_chrome_socket != null)
            {
                if (!(Native.window.opener == null && Native.window.parent == Native.window.self))
                {
                    Console.WriteLine("chrome.app.window.create, is that you?");

                    // pass thru
                }
                else
                {
                    // should jsc send a copresence udp message?
                    chrome.runtime.UpdateAvailable += delegate
                    {
                        new chrome.Notification(title: "UpdateAvailable");

                    };

                    chrome.app.runtime.Launched += async delegate
                    {
                        // 0:12094ms chrome.app.window.create {{ href = chrome-extension://aemlnmcokphbneegoefdckonejmknohh/_generated_background_page.html }}
                        Console.WriteLine("chrome.app.window.create " + new { Native.document.location.href });

                        new chrome.Notification(title: "Launched2");

                        var xappwindow = await chrome.app.window.create(
                               Native.document.location.pathname, options: null
                        );

                        //xappwindow.setAlwaysOnTop

                        xappwindow.show();

                        await xappwindow.contentWindow.async.onload;

                        Console.WriteLine("chrome.app.window loaded!");
                    };


                    return;
                }
            }
            #endregion


            // can we also test the shadow DOM ?
            // how does it work again?


            // now we have to update our alpha window/server window
            // to be in the correct context.

            // what about property window
            // back in the vb days we made one.
            // time to do one?



            #region UDPClipboardSend
            Action<string> UDPClipboardSend = async message =>
            {
                var n = await chrome.socket.getNetworkList();

                new IHTMLPre { new { n.Length } }.AttachToDocument();

                // LINQ and async wont mix for 2012?

                //foreach (var item in n.Where(x => x.prefixLength == 24))
                foreach (var item in n) if (item.prefixLength == 24)
                    {
                        new IHTMLPre { new { item.prefixLength, item.name, item.address } }.AttachToDocument();

                        //{ prefixLength = 64, name = {AE3B881D-488F-4C3A-93F8-7DA0D65B9300}, address = fe80::fc45:cae9:46ca:7b0f }
                        //about to bind... { port = 29129 }
                        //about to send... { Length = 0 }
                        //sent: -2
                        //{ prefixLength = 24, name = {AE3B881D-488F-4C3A-93F8-7DA0D65B9300}, address = 192.168.1.12 }
                        //about to bind... { port = 25162 }
                        //about to send... { Length = 0 }
                        //sent: 0


                        // X:\jsc.svn\examples\merge\TestDetectOpenFiles\TestDetectOpenFiles\Program.cs
                        // X:\jsc.svn\examples\javascript\chrome\apps\MulticastListenExperiment\MulticastListenExperiment\Application.cs

                        // https://code.google.com/p/chromium/issues/detail?id=455352

                        // X:\jsc.svn\examples\merge\TestDetectOpenFiles\TestDetectOpenFiles\Program.cs

                        // bind?

                        var data = Encoding.UTF8.GetBytes(message);	   //creates a variable b of type byte

                        // http://stackoverflow.com/questions/13691119/chrome-packaged-app-udp-sockets-not-working
                        // http://www.chinabtp.com/how-to-do-udp-broadcast-using-chrome-sockets-udp-api/

                        // chrome likes 0 too.
                        var port = new Random().Next(16000, 40000);
                        //var port = 0;
                        // 
                        //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument();

                        // where is bind async?
                        var socket = new UdpClient();
                        socket.Client.Bind(

                            //new IPEndPoint(IPAddress.Any, port: 40000)
                            new IPEndPoint(IPAddress.Parse(item.address), port)
                        );


                        //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();

                        // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                        var s = await socket.SendAsync(
                            data,
                            data.Length,
                            hostname: "239.1.2.3",
                            port: 49814
                        );

                        //new IHTMLPre { "sent: " + s }.AttachToDocument();


                        //socket.ReceiveAsync
                        //socket.Close();

                        //new IHTMLPre { $"sent: {s}" }.AttachToDocument();

                        // android cannot see it. why? because it needs to know which NIC to use.

                    }
            };
            #endregion



            new IHTMLButton { "ready1" }.AttachToDocument().onclick +=
                //async
                delegate
                {
                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150701

                    new MyShadow { }.AttachTo(Native.shadow);

                    #region CaptureMouse
                    {
                        // shadow will select div from chldren
                        var div = new IHTMLDiv { }.AttachTo(Native.document.documentElement);

                        new IHTMLPre { "drag me via CaptureMouse" }.AttachTo(div);
                        var xy = new IHTMLPre { "{}" }.AttachTo(div);

                        div.css.style.backgroundColor = "transparent";
                        div.css.style.transition = "background 500ms linear";

                        div.css.active.style.backgroundColor = "yellow";

                        Native.document.documentElement.style.cursor = IStyle.CursorEnum.move;

                        div.css.hover.style.backgroundColor = "cyan";

                        div.onmousemove +=
                            e =>
                            {
                                // we could tilt the svg cursor
                                // like we do on heat zeeker:D


                                //Native.document.title = new { e.CursorX, e.CursorY }.ToString();
                                xy.innerText = new { e.CursorX, e.CursorY }.ToString();

                            };

                        div.onmousedown +=
                            async e =>
                            {
                                e.CaptureMouse();

                                await div.async.onmouseup;
                            };
                    }
                    #endregion

                    {
                        // shadow will select div from chldren
                        var div = new IHTMLDiv { }.AttachTo(Native.document.documentElement);

                        new IHTMLPre { "click to  requestPointerLock, double click to stop" }.AttachTo(div);
                        var wasd = new IHTMLPre { "{}" }.AttachTo(div);
                        var xy = new IHTMLPre { "{}" }.AttachTo(div);

                        div.css.style.backgroundColor = "transparent";
                        div.css.style.transition = "background 500ms linear";

                        div.css.active.style.backgroundColor = "yellow";

                        Native.document.documentElement.style.cursor = IStyle.CursorEnum.move;

                        div.css.hover.style.backgroundColor = "cyan";





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

                        var keys_ad = 0;
                        var keys_ws = 0;
                        var keys_c = 0;

                        var mousebutton = 0;
                        var mousewheel = 0;

                        var x = 0;
                        var y = 0;


                        // what about 255.255.255.255 ?
                        chrome.socket.getNetworkList().ContinueWithResult(
                             async n =>
                             {
                                 // which networks should we notify of our data?

                                 //new IHTMLPre { new { n.Length } }.AttachToDocument();

                                 foreach (var item in n)
                                 {
                                     // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704
                                     // skip ipv6
                                     if (item.address.Contains(":"))
                                         continue;

                                     //if (item.prefixLength != 4)
                                     //    continue;


                                     #region other
                                     new IHTMLButton { "send onmouseup " + item.address }.AttachTo(div).With(
                                         async refresh =>
                                         {
                                             refresh.style.display = IStyle.DisplayEnum.block;

                                             // experimental until ref count 33?
                                             await refresh.async.onmousedown;

                                             refresh.disabled = true;

                                             while (await div.async.onmouseup)
                                             {


                                                 #region xml

                                                 var nmessage = x + ":" + y;
                                                 var Host = "";
                                                 var PublicPort = "";

                                                 var message =
                                                     new XElement("string",
                                                         new XAttribute("c", "" + 1),
                                                         new XAttribute("n", nmessage),
                                                         "Visit me at " + Host + ":" + PublicPort
                                                     ).ToString();

                                                 #endregion

                                                 var data = Encoding.UTF8.GetBytes(message);	   //creates a variable b of type byte

                                                 var port = new Random().Next(16000, 40000);

                                                 //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument();
                                                 // Z:\jsc.svn\examples\javascript\chrome\hybrid\HybridHopToUDPChromeApp\Application.cs
                                                 // where is bind async?
                                                 var socket = new UdpClient();
                                                 socket.Client.Bind(

                                                     //new IPEndPoint(IPAddress.Any, port: 40000)
                                                     new IPEndPoint(IPAddress.Parse(item.address), port)
                                                 );


                                                 //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();

                                                 // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                                                 var s = await socket.SendAsync(
                                                     data,
                                                     data.Length,
                                                     hostname: "239.1.2.3",
                                                     port: 40804
                                                 );

                                                 socket.Close();

                                             }
                                         }
                                     );

                                     new IHTMLButton { "send onmousemove " + item.address }.AttachTo(div).With(
                                       async refresh =>
                                       {
                                           refresh.style.display = IStyle.DisplayEnum.block;

                                           // experimental until ref count 33?
                                           await refresh.async.onmousedown;

                                           refresh.disabled = true;

                                           var port = new Random().Next(16000, 40000);

                                           //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument();

                                           // where is bind async?
                                           var socket = new UdpClient();
                                           socket.Client.Bind(

                                               //new IPEndPoint(IPAddress.Any, port: 40000)
                                               new IPEndPoint(IPAddress.Parse(item.address), port)
                                           );


                                           while (await div.async.onmousemove)
                                           {
                                               var nmessage = x + ":" + y;


                                               var data = Encoding.UTF8.GetBytes(nmessage);	   //creates a variable b of type byte



                                               //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();

                                               // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                                               var s = await socket.SendAsync(
                                                   data,
                                                   data.Length,
                                                   hostname: "239.1.2.3",
                                                   port: 41814
                                               );

                                               //socket.Close();

                                           }
                                       }
                                   );
                                     #endregion


                                     new IHTMLButton { "send onframe " + item.address }.AttachTo(div).With(
                                          async refresh =>
                                          {
                                              refresh.style.color = "blue";

                                              refresh.style.display = IStyle.DisplayEnum.block;

                                              // experimental until ref count 33?
                                              await refresh.async.onmousedown;

                                              UDPClipboardSend("mousedown...");


                                              refresh.disabled = true;

                                              var port = new Random().Next(16000, 40000);

                                              //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument();

                                              // where is bind async?
                                              var socket = new UdpClient();
                                              socket.Client.Bind(

                                                  //new IPEndPoint(IPAddress.Any, port: 40000)
                                                  new IPEndPoint(IPAddress.Parse(item.address), port)
                                              );


                                              // this will eat too much memory?
                                              //div.ownerDocument.defaultView.onframe +=
                                              div.onframe +=
                                                  delegate
                                                  {
                                                      // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704
                                                      var nmessage = x + ":" + y + ":" + keys_ad + ":" + keys_ws + ":" + keys_c + ":" + mousebutton + ":" + mousewheel;

                                                      UDPClipboardSend(nmessage);

                                                      var data = Encoding.UTF8.GetBytes(nmessage);	   //creates a variable b of type byte



                                                      //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();


                                                      // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                                                      socket.Send(
                                                          data,
                                                          data.Length,
                                                          hostname: "239.1.2.3",
                                                          port: 41814
                                                      );

                                                      // android doesnt get it?
                                                      // restart router?
                                                      // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160101/ovrwindwheelndkg
                                                      // why wont it make it?
                                                  };

                                              return;

                                              //while (await Native.window.async.onframe)
                                              //while (await div.async.onframe)
                                              while (await div.ownerDocument.defaultView.async.onframe)
                                              {
                                                  var nmessage = x + ":" + y + ":" + keys_ad + ":" + keys_ws + ":" + keys_c + ":" + mousebutton + ":" + mousewheel;


                                                  var data = Encoding.UTF8.GetBytes(nmessage);	   //creates a variable b of type byte



                                                  //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument();

                                                  // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs
                                                  var s = await socket.SendAsync(
                                                      data,
                                                      data.Length,
                                                      hostname: "239.1.2.3",
                                                      port: 41814
                                                  );

                                                  //socket.Close();

                                              }
                                          }
                                      );
                                 }
                             }
                        );


                        div.tabIndex = 1;

                        div.onkeydown +=
                             async e =>
                             {
                                 var A = e.KeyCode == 65;
                                 var D = e.KeyCode == 68;

                                 if (A || D)
                                 {
                                     keys_ad = e.KeyCode;

                                     //Native.document.title = new { e.CursorX, e.CursorY }.ToString();
                                     wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString();

                                     while ((await div.async.onkeyup).KeyCode != e.KeyCode) ;

                                     //var ee = await div.async.onkeyup;

                                     keys_ad = 0;

                                     wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString();

                                     return;
                                 }

                                 // CS
                                 // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704
                                 if (e.KeyCode == 67)
                                 {
                                     keys_c = e.KeyCode;

                                     //Native.document.title = new { e.CursorX, e.CursorY }.ToString();
                                     wasd.innerText = new { e.KeyCode, keys_ad, keys_ws, keys_c }.ToString();

                                     while ((await div.async.onkeyup).KeyCode != e.KeyCode) ;

                                     //var ee = await div.async.onkeyup;

                                     keys_c = 0;

                                     wasd.innerText = new { e.KeyCode, keys_ad, keys_ws, keys_c }.ToString();

                                     return;
                                 }

                                 {
                                     keys_ws = e.KeyCode;

                                     //Native.document.title = new { e.CursorX, e.CursorY }.ToString();
                                     wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString();

                                     while ((await div.async.onkeyup).KeyCode != e.KeyCode) ;
                                     //var ee = await div.async.onkeyup;

                                     keys_ws = 0;

                                     wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString();
                                 }
                             };


                        div.onmousewheel += e =>
                            {
                                // since we are a chrome app. is chrome sending us wheel delta too?
                                mousewheel += e.WheelDirection;
                            };

                        div.onmousemove +=
                            e =>
                            {
                                // we could tilt the svg cursor
                                // like we do on heat zeeker:D

                                x += e.movementX;
                                y += e.movementY;


                                //Native.document.title = new { e.CursorX, e.CursorY }.ToString();
                                xy.innerText = new { x, y }.ToString();

                            };

                        div.onmousedown +=
                            async e =>
                            {
                                // wont work for RemoteApp users tho

                                mousebutton = (int)e.MouseButton;

                                // await ?
                                div.requestPointerLock();
                                //e.CaptureMouse();

                                var ee = await div.async.onmouseup;
                                //var ee = await div.async.ondblclick;

                                if (ee.MouseButton == IEvent.MouseButtonEnum.Right)
                                    Native.document.exitPointerLock();

                                mousebutton = 0;

                            };
                    }


                };

        }