/// <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)
        {
            FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

            // http://html5doctor.com/drag-and-drop-to-server/

            #region ondrop
            Native.document.body.ondragover +=
                evt =>
                {
                    evt.stopPropagation();
                    evt.preventDefault();

                    evt.dataTransfer.dropEffect = "copy"; // Explicitly show this is a copy.


                    page.Header.style.color = JSColor.Green;


                    var types = evt.dataTransfer.types == null ? 0 : evt.dataTransfer.types.Length;

                    if (evt.dataTransfer.types != null)
                        foreach (var type in evt.dataTransfer.types.AsEnumerable())
                        {
                            Console.WriteLine(
                                new { type }
                                );
                        }

                    var items = evt.dataTransfer.items == null ? 0u : evt.dataTransfer.items.length;
                    var files = evt.dataTransfer.files == null ? 0u : evt.dataTransfer.files.length;



                    Console.WriteLine("ondragover: " +
                        new
                        {

                            types,
                            items,
                            files
                        }
                    );
                };


            Native.document.body.ondragleave +=
                delegate
                {
                    page.Header.style.color = JSColor.None;
                };

            #region DetectCanvasFromBytesExperiment
            Action<Form, WebBrowser, string, string, long> DetectCanvasFromBytesExperiment =
                (ff, web, ContentValue, src, ContentBytesLength) =>
                {
                    web.Navigated +=
                           async delegate
                           {
                               if (ContentValue != "png.png")
                                   return;

                               // X:\jsc.svn\examples\javascript\canvas\CanvasFromBytes\CanvasFromBytes\Application.cs
                               //Console.WriteLine("interesting, is it one of ours? " + new { ContentValue });
                               ff.Text = "interesting, is it one of ours? " + new { ContentValue };

                               var csrci = new IHTMLImage { src = src };

                               //await csrci.async.onlo
                               await csrci;

                               if (csrci.width != csrci.height)
                                   return;


                               var w = csrci.width;


                               // do the reverse
                               var z = new CanvasRenderingContext2D(w, w);
                               z.drawImage(csrci, 0, 0, w, w);
                               //z.canvas.AttachToDocument();

                               // whats the bytes?

                               var zbytes = z.bytes;

                               ff.Text = "will decode " + new { zbytes.Length, ContentBytesLength }.ToString();

                               #region decode
                               var decodebytes = await Task.Factory.StartNew(
                                   new { zbytes },
                                   scope =>
                                   {
                                       // Native.Console.WriteLine += ?

                                       // { Length = 2053956, u4 = 3c68746d } 

                                       Console.WriteLine(
                                        new
                                        {
                                            scope.zbytes.Length,

                                            u4 = new[] { 
                                            scope.zbytes[0 * 4 + 0],
                                            scope.zbytes[0 * 4 +1],
                                            scope.zbytes[0 * 4 +2],
                                            scope.zbytes[0 * 4 +3]
                                        }.ToHexString()
                                        }
                                       );


                                       // Uncaught Error: InvalidOperationException: { MethodToken = dAAABv_a4OTKgLfLC20SaJA } function is not available at { href =

                                       var wwbytes = new byte[scope.zbytes.Length / 4];
                                       var wi = 0;

                                       for (int i = 0; i < scope.zbytes.Length; i += 4)
                                       {
                                           // that be the red
                                           //wwbytes[wi] = scope.zbytes[i];

                                           // bet we need alpha
                                           wwbytes[wi] = scope.zbytes[i + 3];
                                           wi++;
                                       }



                                       return wwbytes;
                                   }
                               );
                               #endregion


                               var html = Encoding.UTF8.GetString(decodebytes);

                               ff.Text = "decoded " + new { html.Length, ContentBytesLength }.ToString();

                               //Console.WriteLine(new { html });


                               // um hide old data.
                               web.Hide();

                               var xweb = new WebBrowser { Dock = DockStyle.Fill };
                               xweb.AttachTo(ff);
                               xweb.DocumentText = html;
                               ff.Text = "!decoded " + new { html.Length, ContentBytesLength }.ToString();
                           };

                };
            #endregion


            Native.document.body.ondrop +=
                evt =>
                {
                    //if (evt.dataTransfer == null)
                    //    return;

                    var types = evt.dataTransfer.types == null ? 0 : evt.dataTransfer.types.Length;

                    var items = evt.dataTransfer.items == null ? 0u : evt.dataTransfer.items.length;
                    var files = evt.dataTransfer.files == null ? 0u : evt.dataTransfer.files.length;


                    Console.WriteLine("ondrop: " +
                        new
                        {

                            types,
                            items,
                            files
                        }
                    );


                    page.Header.style.color = JSColor.None;


                    //var xfiles = evt.dataTransfer.files.AsEnumerable().Concat(
                    //    from x in evt.dataTransfer.items.AsEnumerable()
                    //    let f = x.getAsFile()
                    //    where f != null
                    //    select f
                    //);

                    #region DataTable
                    if (evt.dataTransfer.items != null)
                    {
                        // X:\jsc.svn\examples\javascript\DragDataTableIntoCSVFile\DragDataTableIntoCSVFile\Application.cs

                        evt.dataTransfer.items.AsEnumerable().Where(
                            x =>

                                x.type.ToLower() ==

                                // let jsc type system sort it out?
                                // how much reflection does jsc give us nowadays?
                                typeof(DataTable).Name.ToLower()

                        ).WithEach(
                            async x =>
                            {
                                // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dfnReturnLink-0
                                var DataTable_xml = await x.getAsString();

                                var DataTable = StringConversionsForDataTable.ConvertFromString(DataTable_xml);

                                var ff = new Form { Text = new { typeof(DataTable).Name }.ToString() };

                                var g = new DataGridView { DataSource = DataTable, Dock = DockStyle.Fill };

                                ff.Controls.Add(g);


                                ff.Show();

                            }
                        );
                    }
                    #endregion

                    #region files
                    evt.dataTransfer.files.AsEnumerable().WithEachIndex(
                        (f, index) =>
                        {
                            Console.WriteLine(
                                new
                                {

                                    f.name,
                                    f.size,
                                    f.lastModifiedDate
                                }
                            );

                            var ff = new Form();
                            ff.PopupInsteadOfClosing(HandleFormClosing: false);



                            ff.Text = new { f.type, f.name, f.size }.ToString();


                            ff.Show();

                            ff.MoveTo(
                                evt.CursorX + 32 * index,
                                evt.CursorY + 24 * index
                            );

                            var fc = ff.GetHTMLTargetContainer();

                            fc.title = ff.Text;

                            #region image
                            var i = default(IHTMLImage);

                            if (f.type.StartsWith("image/"))
                            {
                                // um would we have a timing issue here?
                                f.ToDataURLAsync(
                                    src =>
                                    {
                                        i = new IHTMLImage { src = src }.AttachTo(fc);
                                        i.style.width = "100%";

                                        i.InvokeOnComplete(
                                            delegate
                                            {

                                                ff.ClientSize = new System.Drawing.Size(
                                                    // keep it reasonable!
                                                    i.width.Min(600),
                                                    i.height.Min(400)
                                                );

                                            }
                                        );
                                    }
                                );
                            }
                            #endregion

                            // http://html5doctor.com/drag-and-drop-to-server/

#if FUTURE
                            service.XUpload(f, delegate { });
#endif


                            var d = new FormData();

                            d.append("foo", f, f.name);

                            var xhr = new IXMLHttpRequest();

                            xhr.open(ScriptCoreLib.Shared.HTTPMethodEnum.POST, "/upload");

                            #region InvokeOnComplete
                            xhr.InvokeOnComplete(
                                delegate
                                {
                                    Console.WriteLine("upload complete!");

                                    SystemSounds.Beep.Play();

                                    //Console.Beep();
                                    XElement.Parse(xhr.responseText).Elements("ContentKey").WithEach(
                                        ContentKey =>
                                        {
                                            var __ContentKey = (Table1_ContentKey)int.Parse(ContentKey.Value);

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

                                            web.Hide();
                                            web.AttachTo(ff);


                                            var src = "/io/" + ContentKey.Value;

                                            if (i == null)
                                            {
                                                web.Show();
                                            }
                                            else
                                            {
                                                web.Navigated +=
                                                    delegate
                                                    {
                                                        i.Orphanize();
                                                        web.Show();
                                                    };
                                            }


                                            // "X:\jsc.svn\examples\javascript\canvas\CanvasFromBytes\png.png"
                                            DetectCanvasFromBytesExperiment(
                                                ff,
                                                web,
                                                 f.name,
                                                src,
                                               (long)f.size
                                            );

                                            web.Navigate(src);


                                            //if (i != null)
                                            //{
                                            //    i.src = src;
                                            //}

                                            __ContentKey.SetLeft(ff.Left);
                                            __ContentKey.SetTop(ff.Top);

                                            ff.LocationChanged +=
                                                delegate
                                                {
                                                    __ContentKey.SetLeft(ff.Left);
                                                    __ContentKey.SetTop(ff.Top);
                                                };

                                            ff.SizeChanged +=
                                                delegate
                                                {
                                                    __ContentKey.SetWidth(ff.Width);
                                                    __ContentKey.SetHeight(ff.Height);
                                                };

                                            ff.FormClosing +=
                                                delegate
                                                {
                                                    __ContentKey
                                                        .Delete();
                                                };


                                            #region onmousewheel
                                            ff.GetHTMLTarget().With(
                                                ffh =>
                                                {
                                                    dynamic ffhs = ffh.style;
                                                    // http://css-infos.net/property/-webkit-transition
                                                    //ffhs.webkitTransition = "webkitTransform 0.3s linear";

                                                    ffh.onmousewheel +=
                                                        e =>
                                                        {
                                                            e.preventDefault();
                                                            e.stopPropagation();


                                                            if (e.WheelDirection > 0)
                                                            {
                                                                ff.Width = (int)(ff.Width * 1.1);
                                                                ff.Height = (int)(ff.Height * 1.1);
                                                            }
                                                            else
                                                            {
                                                                ff.Width = (int)(ff.Width * 0.9);
                                                                ff.Height = (int)(ff.Height * 0.9);
                                                            }

                                                        };

                                                }
                                            );
                                            #endregion

                                        }
                                    );
                                }
                            );
                            #endregion


                            //------WebKitFormBoundaryDmGHAZzeMBbcD5mu
                            //Content-Disposition: form-data; name="foo"; filename="FlashHeatZeeker.UnitPedControl.ApplicationSprite.swf"
                            //Content-Type: application/x-shockwave-flash


                            //------WebKitFormBoundaryDmGHAZzeMBbcD5mu--

                            Console.WriteLine("before upload...");
                            xhr.send(d);
                        }
                    );
                    #endregion


                    // let's disable other handlers
                    //evt.dataTransfer = null;

                    evt.stopPropagation();
                    evt.stopImmediatePropagation();

                    evt.preventDefault();
                };
            #endregion

            #region restore
            {
                var index = 0;

                default(Table1_ContentKey).WithEach(
                    (__ContentKey, ContentBytesLength, ContentValue, Left, Top, Width, Height) =>
                    {

                        var ff = new Form();
                        ff.PopupInsteadOfClosing(HandleFormClosing: false);


                        ff.Text = new { __ContentKey, ContentValue, ContentBytesLength }.ToString();


                        ff.Show();

                        if (Left > 0)
                            ff.MoveTo(
                                Left,
                                Top
                            );
                        else

                            ff.MoveBy(
                                32 * index,
                                24 * index
                            );

                        index++;

                        #region onmousewheel
                        ff.GetHTMLTarget().With(
                            ffh =>
                            {
                                dynamic ffhs = ffh.style;
                                // http://css-infos.net/property/-webkit-transition
                                //ffhs.webkitTransition = "webkitTransform 0.3s linear";

                                ffh.onmousewheel +=
                                    e =>
                                    {
                                        e.preventDefault();
                                        e.stopPropagation();

                                        if (e.WheelDirection > 0)
                                        {
                                            ff.Width = (int)(ff.Width * 1.1);
                                            ff.Height = (int)(ff.Height * 1.1);
                                        }
                                        else
                                        {
                                            ff.Width = (int)(ff.Width * 0.9);
                                            ff.Height = (int)(ff.Height * 0.9);
                                        }

                                    };

                            }
                        );
                        #endregion



                        //var fc = ff.GetHTMLTargetContainer();
                        var src = "/io/" + __ContentKey;

                        //var i = new IHTMLImage { src = src }.AttachTo(fc);
                        //i.style.width = "100%";

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

                        web.AttachTo(ff);

                        //script: error JSC1000: No implementation found for this native method, please implement [System.Windows.Forms.WebBrowser.add_DocumentCompleted(System.Windows.Forms.WebBrowserDocumentCompletedEventHandler)]
                        //script: warning JSC1000: Did you reference ScriptCoreLib via IAssemblyReferenceToken?
                        //script: error JSC1000: error at DropFileIntoSQLite.Application+<>c__DisplayClass2e.<.ctor>b__15,
                        // assembly: V:\DropFileIntoSQLite.Application.exe
                        // type: DropFileIntoSQLite.Application+<>c__DisplayClass2e, DropFileIntoSQLite.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

                        //web.DocumentCompleted +=
                        //    delegate
                        //    {



                        //};

                        DetectCanvasFromBytesExperiment(
                            ff,
                            web,
                            ContentValue,
                            src,
                            ContentBytesLength
                        );


                        web.Navigate(src);

                        if (Width > 0)
                            ff.SizeTo(
                               Width,
                               Height
                           );
                        //else
                        //    i.InvokeOnComplete(
                        //        delegate
                        //        {


                        //            ff.ClientSize = new System.Drawing.Size(i.width, i.height);

                        //        }
                        //    );

                        ff.LocationChanged +=
                            delegate
                            {
                                __ContentKey.SetLeft(ff.Left);
                                __ContentKey.SetTop(ff.Top);
                            };

                        ff.SizeChanged +=
                            delegate
                            {
                                __ContentKey.SetWidth(ff.Width);
                                __ContentKey.SetHeight(ff.Height);
                            };

                        ff.FormClosing +=
                            delegate
                            {
                                __ContentKey.Delete();
                            };
                    }
                );
            }
            #endregion



            // can we write about this?
            #region bookmark launcher
            var href = @"javascript:
((function(h,i)
{ 
    

    var a=-1, 
    b='onreadystatechange', 
    c=document.getElementsByTagName('HEAD')[0], 
    d, 
    e, 
    f, 
    g=c.childNodes, 
    d; 

    e=document.createElement('base');   
    e.href='%%';
    c.appendChild(e);     

    d = function () 
    {  
        next: while (1)  
        {   
            a++;     
            if (a ==h.length)   
            {   
                i();    
                return;   
            }     

            /*
            for (f=0;f<g.length;f++)   
            {   
                var v =g[f];    
                var w =h[a];       

                if (v.nodeName =='SCRIPT')    
                    if (v.src ==w || v.src.substr(v.src.length - w.length - 1,w.length + 1) =='/' + w)    
                        continue next;   
            } */      
            e=document.createElement('SCRIPT');   
            e.src='%%' + h[a];     
            e[b in e?b:'onload']=  function()    
            {       
                var f=e.readyState;    
                if(f==null||f=='loaded'||f=='complete')     
                    d();    
            };  
 
        c.appendChild(e);     
        return;  
    } 
}; 
d();

}

)(['view-source'],function(){}))".Replace("%%", Native.Document.location + "");

            page.Header.draggable = true;
            page.Header.ondragstart +=
                e =>
                {
                    e.dataTransfer.setData("text/uri-list", href);
                };


            IStyleSheet.Default["#Header:hover"].style.color = "red";
            IStyleSheet.Default["#Header:hover"].style.cursor = IStyle.CursorEnum.pointer;

            #endregion


            new About().Show();
        }
        public ApplicationContent(
            IApp page,
            Abstractatech.JavaScript.FileStorage.IApplicationWebServiceX service,
            bool DisableBackground = false

            )
        {


            FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

            if (!DisableBackground)
            {
                #region  I want animated background!

                WebGLClouds.Application.Loaded +=
                    a =>
                    {
                        Native.Document.body.parentNode.insertBefore(
                             a.container.Orphanize(),
                              Native.Document.body
                        );
                        a.container.style.position = IStyle.PositionEnum.@fixed;

                    };


                new WebGLClouds.Application();
                #endregion
            }

            //var minsize = new IHTMLDiv().AttachToDocument();

            //minsize.style.SetSize(4000, 2000);




            var f = new Form
            {
                Text = "My Files",
                StartPosition = FormStartPosition.Manual,
                SizeGripStyle = SizeGripStyle.Hide
            };

            #region w
            var ff = new Form
            {
                StartPosition = FormStartPosition.Manual,
                SizeGripStyle = SizeGripStyle.Hide

            };

            var w = new WebBrowser
            {
                Dock = DockStyle.Fill
            }.AttachTo(ff);
            w.GetHTMLTarget().name = "view";

            w.Navigating +=
                delegate
                {
                    ff.Text = "Navigating";


                    if (Native.window.Width < 1024)
                        // docked?
                        if (ff.GetHTMLTarget().parentNode != null)
                            Native.window.scrollTo(ff.Left - 8, ff.Top - 8, TimeSpan.FromMilliseconds(300));

                };



            w.Navigated +=
                delegate
                {
                    if (w.Url.ToString() == "about:blank")
                    {

                        Native.window.scrollTo(0, 0, TimeSpan.FromMilliseconds(200));

                        ff.Text = "...";

                        "Web Files".ToDocumentTitle();

                        return;
                    }

                    //ff.Text = w.DocumentTitle;
                    ff.Text = Native.window.unescape(
                        w.Url.ToString().SkipUntilLastIfAny("/").TakeUntilLastIfAny(".")
                        );

                    ff.Text.ToDocumentTitle();


                };

            ff.FormClosing +=
                (sender, e) =>
                {
                    Console.WriteLine(new { e.CloseReason });

                    if (e.CloseReason == CloseReason.UserClosing)
                    {
                        e.Cancel = true;

                        w.Navigate("about:blank");
                    }

                };
            #endregion



            var content = f.GetHTMLTargetContainer();




            var hh = new HorizontalSplit
            {
                Minimum = 0.05,
                Maximum = 0.95,
                Value = 0.4,
            };

            hh.Container.AttachToDocument();
            hh.Container.style.position = IStyle.PositionEnum.absolute;
            hh.Container.style.left = "0px";
            hh.Container.style.top = "0px";
            hh.Container.style.right = "0px";
            hh.Container.style.bottom = "0px";

            hh.Split.Splitter.style.backgroundColor = "rgba(0,0,0,0.0)";


            #region AtResize
            Action AtResize = delegate
           {
               Native.Document.getElementById("feedlyMiniIcon").Orphanize();

               Native.Document.body.style.minWidth = "";

               if (ff.GetHTMLTarget().parentNode == null)
               {
                   Native.window.scrollTo(0, 0);
                   f.MoveTo(8, 8).SizeTo(Native.window.Width - 16, Native.window.Height - 16);

                   return;
               }

               if (f.GetHTMLTarget().parentNode == null)
               {
                   Native.window.scrollTo(0, 0);
                   ff.MoveTo(8, 8).SizeTo(Native.window.Width - 16, Native.window.Height - 16);

                   return;
               }

               if (Native.window.Width < 1024)
               {
                   Native.Document.body.style.minWidth = (Native.window.Width * 2) + "px";


                   f.MoveTo(8, 8).SizeTo(Native.window.Width - 16, Native.window.Height - 16);

                   ff.MoveTo(Native.window.Width + 8, 8).SizeTo(Native.window.Width - 16, Native.window.Height - 16);

                   // already scrolled...
                   if (w.Url.ToString() != "about:blank")
                       // docked?
                       if (ff.GetHTMLTarget().parentNode != null)
                           Native.window.scrollTo(ff.Left - 8, ff.Top - 8);

                   return;
               }




               f.MoveTo(16, 64).SizeTo(hh.LeftContainer.clientWidth - 32, Native.window.Height - 128);


               ff.MoveTo(
                   Native.window.Width - hh.RightContainer.clientWidth + 16

                   , 64).SizeTo(hh.RightContainer.clientWidth - 32, Native.window.Height - 128);

               //Console.WriteLine("LeftContainer " + new { hh.LeftContainer.clientWidth });
               //Console.WriteLine("RightContainer " + new { hh.RightContainer.clientWidth });
           };

            hh.ValueChanged +=
          delegate
          {
              AtResize();
          };

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

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


            //hh.Split.LeftScrollable = new IHTMLDiv { className = "SidebarForButtons" };


            ff.Show();
            f.Show();

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108
            //f.PopupInsteadOfClosing(SpecialNoMovement: true, NotifyDocked: AtResize);
            //ff.PopupInsteadOfClosing(SpecialNoMovement: true, HandleFormClosing: false, NotifyDocked: AtResize);


            var layout = new Abstractatech.JavaScript.FileStorage.HTML.Pages.App();

            layout.Container.AttachTo(content);

            Abstractatech.JavaScript.FileStorage.ApplicationContent.Target = "view";


            new Abstractatech.JavaScript.FileStorage.ApplicationContent(
                layout,
                service
            );







            "Web Files".ToDocumentTitle();
        }
        /// <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)
        {
            var random = new Random();
            device_id = random.Next();

            #region con
            var con = new ConsoleForm();

            con.InitializeConsoleFormWriter();
            con.StartPosition = FormStartPosition.Manual;
            con.Show();

            // make it slim
            con.Height = 100;

            // TopMost
            con.GetHTMLTarget().style.zIndex = 20002;
            con.Opacity = 0.9;




            Action Toggle =
                delegate
                {
                    if (con.WindowState == FormWindowState.Minimized)
                    {
                        con.WindowState = FormWindowState.Normal;

                    }
                    else
                    {
                        con.WindowState = FormWindowState.Minimized;


                    }

                    // put the console far right bottom
                    con.MoveTo(
                        Native.window.Width - con.Width,
                        Native.window.Height - con.Height
                    );

                };

            Action<int> AtKeyCode =
               KeyCode =>
               {
                   Console.WriteLine(
                       new { KeyCode }

                   );



                   // US
                   if (KeyCode == 222)
                   {
                       Toggle();
                   }
                   // EE
                   if (KeyCode == 192)
                   {
                       Toggle();
                   }
               };


#if onorientationchange
            Native.window.onorientationchange +=
                e =>
                {
                    Toggle();
                };
#endif

            Native.document.onkeyup +=
                e =>
                {
                    AtKeyCode(e.KeyCode);

                };

            Toggle();
            #endregion

            Console.WriteLine("console ready for " + new { id = device_id });

            var x = 0;
            var y = 0;

            #region Virtual Screen
            FormStyler.AtFormCreated = LikeDesktop;
            var fs = new Form { };

            //fs.FormBorderStyle = FormBorderStyle.None;

            fs.BackColor = Color.FromArgb(0, 148, 155);
            fs.Width = Native.screen.width / 4;
            fs.Height = Native.screen.height / 4;
            fs.Show();
            fs.Opacity = 0.5;

            FormStyler.AtFormCreated = LikeVirtualScreen;
            var fvs = new Form { Text = "Virtual Screen" };
            fvs.BackColor = Color.Transparent;
            FormStyler.AtFormCreated = FormStyler.LikeWindowsClassic;
            fvs.Width = Native.screen.width / 4;
            fvs.Height = Native.screen.height / 4;
            fvs.Show();
            fvs.Owner = fs;

            var fw = new Form { };

            fw.Width = Native.window.Width / 4;
            fw.Height = Native.window.Height / 4;
            fw.Show();
            fw.Owner = fvs;
            fw.Opacity = 0.8;

            KeepOwnedFormsLinkedToOwnerLocation(fs);
            KeepOwnedFormsLinkedToOwnerLocation(fvs);
            KeepOwnedFormsLinkedToOwnerLocation(fw);
            #endregion


            // doesnt work yet?
            //fw.SizeGripStyle = SizeGripStyle.Hide;

            var svg = new ISVGSVGElement().AttachTo(page.content);
            svg.style.SetLocation(0, 0);

            var vsvg = new ISVGSVGElement().AttachTo(fvs.GetHTMLTarget());
            vsvg.style.SetLocation(0, 0);

            #region VirtualScreenUpdate
            Action VirtualScreenUpdate = delegate
            {
                if (fs.Capture)
                    return;

                // dragging it?
                if (fvs.Capture)
                    return;

                var max_right = fvs.OwnedForms.Max(k => k.Right);
                var min_left = fvs.OwnedForms.Min(k => k.Left);

                var max_bottom = fvs.OwnedForms.Max(k => k.Bottom);
                var min_top = fvs.OwnedForms.Min(k => k.Top);

                DisableKeepOwnedFormsLinkedToOwnerLocation = true;

                fvs.Left = min_left;
                fvs.Top = min_top;
                fvs.Width = max_right - min_left;
                fvs.Height = max_bottom - min_top;

                page.content.style.SetLocation(
                    (min_left - fw.Left) * 4,
                    (min_top - fw.Top) * 4,
                    (max_right - min_left) * 4,
                    (max_bottom - min_top) * 4
                );



                DisableKeepOwnedFormsLinkedToOwnerLocation = false;

            };
            #endregion


            fw.LocationChanged +=
                delegate
                {
                    VirtualScreenUpdate();
                };

            #region AtResize
            Action AtResize = delegate
            {
                // screen can change, but only once, when window is moved to the other monitor?
                fs.Text = "Screen " + new { Native.screen.width, Native.screen.height };
                fs.Width = Native.screen.width / 4;
                fs.Height = Native.screen.height / 4;

                fw.Text = " " + new { Native.window.Width, Native.window.Height
#if onorientationchange                    
                    , Native.window.orientation 
#endif
                };
                fw.Width = Native.window.Width / 4;
                fw.Height = Native.window.Height / 4;

                VirtualScreenUpdate();
            };



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

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

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

            new ScriptCoreLib.JavaScript.Runtime.Timer(
                delegate
                {
                    AtResize();
                }
            ).StartInterval(1000 / 2);
            #endregion


            // what is attaching what?
            // what about await
            var svgcursor1ghost = new cursor1().AttachTo(page.content).ToSVG();

            var svgcursor1 = new cursor1().AttachTo(page.content).ToSVG();

            svgcursor1.fill += svgcursor1ghost.fill;

            var vcursor = new cursor1().AttachTo(fvs.GetHTMLTarget()).ToSVG();

            var Shadows = new List<Form>();

            Func<Form, Form> CreateShadow =
                _fw =>
                {
                    FormStyler.AtFormCreated = LikeVirtualWindow;
                    var fwshadow = new Form();
                    Shadows.Add(fwshadow);

                    fwshadow.BackColor = Color.Transparent;
                    FormStyler.AtFormCreated = FormStyler.LikeWindowsClassic;
                    fwshadow.Width = Native.screen.width / 4;
                    fwshadow.Height = Native.screen.height / 4;
                    fwshadow.Show();


                    Action fwshadow_update = delegate
                    {

                        fwshadow.MoveTo(_fw.Left, _fw.Top);
                        fwshadow.SizeTo(_fw.Width, _fw.Height);
                    };

                    _fw.LocationChanged +=
                        delegate
                        {
                            fwshadow_update();
                        };

                    _fw.SizeChanged +=
                        delegate
                        {
                            fwshadow_update();

                        };

                    fwshadow_update();

                    _fw.BringToFront();

                    return fwshadow;
                };

            Shadows.Add(CreateShadow(fw));

            bool canexit = false;
            bool canenter = true;

            Action at_exit_MultiMouseMode = delegate
            {
                //Console.WriteLine("at_exit_MultiMouseMode");
            };

            Action at_enter_MultiMouseMode = delegate
            {

                //Console.WriteLine("at_enter_MultiMouseMode");
            };

            Action<IEvent.MouseButtonEnum> at_mousedown = button =>
            {

                //Console.WriteLine("at_enter_mousedown: " + button);
            };


            Action at_mouseup = delegate
            {

                //Console.WriteLine("at_enter_mouseup");
            };




            var path = new ISVGPathElement().AttachTo(svg);
            path.setAttribute("style", "stroke: black; stroke-width: 4; fill: none;");

            var path_d = "";



            var vpath = new ISVGPathElement().AttachTo(vsvg);
            vpath.setAttribute("style", "stroke: black; stroke-width: 1; fill: none;");

            var vpath_d = "";

            bool internal_ismousedown = false;

            Action<IEvent.MouseButtonEnum> internal_mousedown = button =>
            {
                internal_ismousedown = true;

                path = new ISVGPathElement().AttachTo(svg);

                if (button == IEvent.MouseButtonEnum.Left)
                    path.setAttribute("style", "stroke: black; stroke-width: 4; fill: none;");
                else
                    path.setAttribute("style", "stroke: rgb(0, 108, 115); stroke-width: 32; fill: none;");

                path_d = "";


                vpath = new ISVGPathElement().AttachTo(vsvg);

                if (button == IEvent.MouseButtonEnum.Left)
                    vpath.setAttribute("style", "stroke: black; stroke-width: 1; fill: none;");
                else
                    vpath.setAttribute("style", "stroke: rgb(0, 108, 115); stroke-width: 8; fill: none;");

                vpath_d = "";

                svgcursor1.fill(0, 0, 255);
                vcursor.fill(0, 0, 255);

                //path.d = "    M100,50  L10,10   L200,200   ";
                path_d += " M" + x + "," + y;
                path.d = path_d;

                vpath_d += " M" + (x / 4) + "," + (y / 4);
                vpath.d = vpath_d;
            };

            Action<IEvent.MouseButtonEnum> mousedown = button =>
            {
                at_mousedown(button);
                internal_mousedown(button);
            };

            Action internal_mouseup = delegate
            {
                internal_ismousedown = false;





                svgcursor1.fill(0, 255, 0);
                vcursor.fill(0, 255, 0);
            };

            Action mouseup = delegate
            {
                at_mouseup();
                internal_mouseup();
            };



            #region exit_MultiMouseMode
            Action internal_exit_MultiMouseMode = delegate
            {
                svgcursor1.fill(0, 0, 0);
                vcursor.fill(0, 0, 0);

                con.Opacity = 0.9;
                page.content.style.Opacity = 0.3;
                page.content.style.zIndex = 0;

                page.content.style.backgroundColor = "rgba(0, 148, 155, 1)";
                Native.Document.body.style.backgroundColor = "black";

                page.content.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "blur(3px)";
                    }
                );

                page.info.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "";
                    }
                );

                Shadows.WithEach(
                   f =>
                       f.GetHTMLTarget().style.With(
                           (dynamic s) =>
                           {
                               s.webkitFilter = "";
                           }
                       )
                 );


                fs.FormsByOwnership().WithEach(
                 f =>
                     f.GetHTMLTarget().style.With(
                         (dynamic s) =>
                         {
                             s.webkitFilter = "";

                         }
                     )
            );


                fvs.OwnedForms.WithEach(
                    k =>
                    {
                        k.GetHTMLTarget().style.display = IStyle.DisplayEnum.block;
                    }
                );




            };

            Action exit_MultiMouseMode = delegate
            {
                if (!canexit)
                    return;

                canexit = false;
                canenter = true;

                at_exit_MultiMouseMode();
                internal_exit_MultiMouseMode();
            };
            #endregion

            #region enter_MultiMouseMode
            Action internal_enter_MultiMouseMode = delegate
            {
                svgcursor1.fill(255, 0, 0);
                vcursor.fill(255, 0, 0);
                con.Opacity = 0.5;

                page.content.style.Opacity = 1.0;
                page.content.style.backgroundColor = "";
                Native.Document.body.style.backgroundColor = "rgba(0, 148, 155, 1)";

                page.content.style.zIndex = 20000;
                con.GetHTMLTarget().style.zIndex = 20002;
                page.content.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "";
                    }
                );

                page.info.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "blur(3px)";
                    }
                );


                fvs.OwnedForms.WithEach(
                     k =>
                     {
                         k.GetHTMLTarget().style.display = IStyle.DisplayEnum.none;
                     }
                 );

                Shadows.WithEach(
                  f =>
                      f.GetHTMLTarget().style.With(
                          (dynamic s) =>
                          {
                              s.webkitFilter = "blur(3px)";
                          }
                      )
                );


                fs.FormsByOwnership().WithEach(
                    f =>
                        f.GetHTMLTarget().style.With(
                            (dynamic s) =>
                            {
                                s.webkitFilter = "blur(3px)";
                            }
                        )
                );
            };

            Action enter_MultiMouseMode = delegate
            {
                if (!canenter)
                    return;

                canexit = true;
                canenter = false;

                at_enter_MultiMouseMode();
                internal_enter_MultiMouseMode();
            };
            #endregion





            #region onmousemove



            Native.Document.body.onmouseup +=
              e =>
              {
                  if (Native.Document.pointerLockElement == Native.Document.body)
                  {
                      mouseup();
                      return;
                  }
              };

            Native.Document.body.onmousedown +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        mousedown(e.MouseButton);
                        return;
                    }

                    Console.WriteLine("requesting MultiMouse mode!");

                    x = e.CursorX;
                    y = e.CursorY;
                    e.preventDefault();
                    Native.Document.body.requestPointerLock();

                };

            Action<int, int> at_set_cursor_position = delegate { };


            var pxx = 0;
            var pyy = 0;

            var ghost_busy = false;

            Action<int, int> internal_set_cursor_position =
                 (xx, yy) =>
                 {
                     // already set to that exact location!
                     if (pxx == xx)
                         if (pyy == yy)
                             return;


                     pxx = xx;
                     pyy = yy;

                     vcursor.Element.style.SetSize(
                           cursor1.ImageDefaultWidth / 4,
                           cursor1.ImageDefaultHeight / 4
                       );

                     vcursor.Element.style.SetLocation(
                           (xx - 14) / 4,
                           (yy - (64 - 56)) / 4
                       );


                     svgcursor1.Element.style.SetLocation(

                         xx - 14,

                         // inscaope/svg Y is upside down!
                         yy - (64 - 56)

                     );

                     if (!ghost_busy)
                     {
                         ghost_busy = true;

                         svgcursor1ghost.Element.style.Opacity = 0.2;
                         svgcursor1ghost.Element.style.With(
                                (dynamic s) => s.webkitTransition = "all 0.5s linear"
                         );

                         svgcursor1ghost.Element.style.SetLocation(

                            pxx - 14,

                            // inscaope/svg Y is upside down!
                            pyy - (64 - 56)

                        );

                         new ScriptCoreLib.JavaScript.Runtime.Timer(
                             delegate
                             {
                                 svgcursor1ghost.Element.style.SetLocation(

                                    pxx - 14,

                                    // inscaope/svg Y is upside down!
                                    pyy - (64 - 56)

                                );

                                 ghost_busy = false;
                             }
                         ).StartTimeout(500);
                     }


                     // if this window will be activated next time we can continue where we were
                     // told to..
                     x = xx;
                     y = yy;

                     if (internal_ismousedown)
                     {
                         path_d += " L" + x + "," + y;
                         path.d = path_d;

                         vpath_d += " L" + (x / 4) + "," + (y / 4);
                         vpath.d = vpath_d;
                     }

                 };

            Action<int, int> set_cursor_position =
                (xx, yy) =>
                {
                    at_set_cursor_position(xx, yy);
                    internal_set_cursor_position(xx, yy);
                };

            Native.Document.body.onmousemove +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        enter_MultiMouseMode();

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

                        // clip it
                        // fullscreen behaves differently?
                        x = x.Min(fvs.Width * 4).Max(0);
                        y = y.Min(fvs.Height * 4).Max(0);

                        set_cursor_position(x, y);
                    }
                    else
                    {
                        exit_MultiMouseMode();
                    }

                };
            #endregion

            internal_exit_MultiMouseMode();
            internal_set_cursor_position(0, 0);

            Native.document.body.ontouchstart +=
                 e =>
                 {
                     e.preventDefault();
                     e.stopPropagation();

                     e.touches[0].With(
                         touch =>
                         {
                             // how do we enter?
                             enter_MultiMouseMode();
                             // exit by broswer history move?

                             set_cursor_position(touch.clientX, touch.clientY);

                             // ipad has 11 touchpoints. multiply that with the number of devices/
                             // for now we support 1 pointer per session :)

                             if (e.touches.length == 1)
                                 mousedown(IEvent.MouseButtonEnum.Left);
                             else
                                 mousedown(IEvent.MouseButtonEnum.Right);

                         }
                     );
                 };

            Native.document.body.ontouchend +=
               e =>
               {

                   e.preventDefault();
                   e.stopPropagation();



                   // ipad has 11 touchpoints. multiply that with the number of devices/
                   // for now we support 1 pointer per session :)

                   if (e.touches.length == 0)
                       mouseup();
                   else
                       mousedown(IEvent.MouseButtonEnum.Left);

               };

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


                     e.touches[0].With(
                         touch =>
                         {
                             set_cursor_position(touch.clientX, touch.clientY);
                         }
                     );
                 };



            #region onmessage

            bool disable_bind_reconfigure = false;


            Action<int, int> internal_reconfigure =
                delegate { };

            Action<MessageEvent, XElement> internal_onmessage =
                (e, xml) =>
                {
                    device_onmessage(0, xml);
                };

            Native.window.onmessage +=
                e =>
                {
                    // who sent this? :P
                    var source = (string)e.data;
                    //var now = DateTime.Now;
                    //Console.WriteLine(now + " " + source);


                    var xml = XElement.Parse(source);




                    internal_onmessage(e, xml);
                };

            var friendly_devices = new
            {
                source_device_id = 0,
                f = default(Form),
                children = new
                {
                    child_id = 0,
                    fc = default(Form)
                }.ToEmptyList()
            }.ToEmptyList();

            #region device_onmessage
            this.device_onmessage =
                (source_device_id, xml) =>
                {
                    // mothership to local network?
                    // source_device_id = 0 means it came from one of our virtual screens?

                    if (xml.Name.LocalName == "at_mousedown")
                    {
                        int button = int.Parse(xml.Attribute("button").Value);
                        internal_mousedown((IEvent.MouseButtonEnum)button);
                    }

                    if (xml.Name.LocalName == "at_mouseup")
                    {
                        internal_mouseup();
                    }

                    if (xml.Name.LocalName == "at_enter_MultiMouseMode")
                    {
                        internal_enter_MultiMouseMode();
                    }

                    if (xml.Name.LocalName == "at_exit_MultiMouseMode")
                    {
                        internal_exit_MultiMouseMode();
                    }

                    if (xml.Name.LocalName == "at_set_cursor_position")
                    {
                        int xx = int.Parse(xml.Attribute("x").Value);
                        int yy = int.Parse(xml.Attribute("y").Value);

                        internal_set_cursor_position(xx, yy);
                    }


                };
            #endregion

            var ListOfChildren = new { child_id = 0, fc = default(Form) }.ToEmptyList();

            // when is this called?
            this.device_bind =
                (mothership_postXElement) =>
                {
                    // we might now be able to invoke the server, and via that any other device
                    Console.WriteLine("device_bind");

                    #region at_enter_MultiMouseMode
                    at_enter_MultiMouseMode +=
                        delegate
                        {
                            var xml = new XElement("at_enter_MultiMouseMode");

                            mothership_postXElement(xml);
                        };
                    #endregion

                    #region at_exit_MultiMouseMode
                    at_exit_MultiMouseMode +=
                        delegate
                        {
                            mothership_postXElement(new XElement("at_exit_MultiMouseMode"));
                        };
                    #endregion

                    #region at_mousedown
                    at_mousedown +=
                      button =>
                      {
                          mothership_postXElement(new XElement("at_mousedown", new XAttribute("button", "" + (int)button)));
                      };
                    #endregion

                    #region at_mouseup
                    at_mouseup +=
                     delegate
                     {
                         mothership_postXElement(new XElement("at_mouseup"));
                     };
                    #endregion

                    #region at_set_cursor_position
                    at_set_cursor_position +=
                       (xx, yy) =>
                       {

                           var xml = new XElement("at_set_cursor_position",
                               // int not yet supported?
                                   new XAttribute("x", "" + xx),
                                   new XAttribute("y", "" + yy)
                               );

                           mothership_postXElement(
                               xml
                           );



                       };
                    #endregion

                    // now we can reply..
                    this.device_onmessage +=
                       (source_device_id, xml) =>
                       {
                           #region at_virtualwindowsync_reconfigure
                           if (source_device_id != 0)
                               if (xml.Name.LocalName == "at_virtualwindowsync_reconfigure")
                               {
                                   int __device_id = int.Parse(xml.Attribute("device_id").Value);

                                   if (__device_id == device_id)
                                   {
                                       // are we being reconfigured?

                                       friendly_devices.Where(k => k.source_device_id == source_device_id).WithEach(
                                           q =>
                                           {
                                               int dx = int.Parse(xml.Attribute("dx").Value);
                                               int dy = int.Parse(xml.Attribute("dy").Value);
                                               disable_bind_reconfigure = true;

                                               q.f.MoveTo(
                                                   fw.Left - dx,
                                                   fw.Top - dy
                                               );
                                               disable_bind_reconfigure = false;

                                           }
                                       );
                                   }
                               }
                           #endregion

                           #region at_virtualwindowsync
                           if (source_device_id != 0)
                               if (xml.Name.LocalName == "at_virtualwindowsync")
                               {
                                   Console.WriteLine("got at_virtualwindowsync");

                                   // do we know this device?
                                   var q = friendly_devices.FirstOrDefault(k => k.source_device_id == source_device_id);

                                   int w = int.Parse(xml.Attribute("w").Value);
                                   int h = int.Parse(xml.Attribute("h").Value);

                                   Action reposition = delegate { };

                                   if (q == null)
                                   {
                                       var fc = new Form { Text = new { source_device_id }.ToString() };

                                       q = new { source_device_id, f = fc, children = new { child_id = 0, fc = default(Form) }.ToEmptyList() };

                                       friendly_devices.Add(q);

                                       q.f.StartPosition = FormStartPosition.Manual;
                                       q.f.Show();
                                       // show should respect opacity?
                                       q.f.Opacity = 0.3;


                                       // where to put it?
                                       // left or right?

                                       var max_right = fvs.OwnedForms.Max(k => k.Right);
                                       var min_left = fvs.OwnedForms.Min(k => k.Left);

                                       if (source_device_id < device_id)
                                           q.f.Left = min_left - w;
                                       else
                                           q.f.Left = max_right;

                                       q.f.Top = fw.Top;
                                       q.f.Owner = fvs;

                                       var fcShadow = CreateShadow(q.f);
                                       Shadows.Add(fcShadow);

                                       #region from now on if we move any of our screens
                                       // in relation to this source_device_id we have to notify it

                                       Action SendDelta = delegate
                                       {
                                           var pdx = fc.Left - fw.Left;
                                           var pdy = fc.Top - fw.Top;

                                           mothership_postXElement(
                                             new XElement("at_virtualwindowsync_reconfigure",
                                                 new XAttribute("device_id", "" + source_device_id),
                                                 new XAttribute("dx", "" + pdx),
                                                 new XAttribute("dy", "" + pdy)
                                             )
                                           );
                                       };

                                       fw.LocationChanged +=
                                           delegate
                                           {
                                               if (disable_bind_reconfigure)
                                                   return;

                                               SendDelta();
                                           };

                                       fc.LocationChanged +=
                                           delegate
                                           {
                                               if (disable_bind_reconfigure)
                                                   return;


                                               SendDelta();
                                           };


                                       #endregion


                                   }

                                   // thanks for letting us know that you changed your size...
                                   q.f.Width = w;
                                   q.f.Height = h;


                                   xml.Elements("child").WithEach(
                                       cxml =>
                                       {
                                           // any new children?
                                           int child_id = int.Parse(cxml.Attribute("child_id").Value);

                                           int pdx = int.Parse(cxml.Attribute("pdx").Value);
                                           int pdy = int.Parse(cxml.Attribute("pdy").Value);

                                           int cw = int.Parse(cxml.Attribute("w").Value);
                                           int ch = int.Parse(cxml.Attribute("h").Value);

                                           var cq = q.children.FirstOrDefault(k => k.child_id == child_id);

                                           if (cq == null)
                                           {
                                               var fc = new Form { Text = new { source_device_id, child_id }.ToString() };

                                               cq = new { child_id, fc };

                                               q.children.Add(cq);

                                               cq.fc.StartPosition = FormStartPosition.Manual;
                                               cq.fc.Show();
                                               // show should respect opacity?
                                               cq.fc.Opacity = 0.2;

                                               // if this child needs to be between then add it
                                               // before reposition

                                               cq.fc.Owner = fvs;

                                               var fcShadow = CreateShadow(cq.fc);
                                               Shadows.Add(fcShadow);

                                           }


                                           cq.fc.Left = q.f.Left + pdx;
                                           cq.fc.Top = q.f.Top + pdy;

                                           // thanks for letting us know that you changed your size...
                                           cq.fc.Width = cw;
                                           cq.fc.Height = ch;
                                       }
                                   );

                               }
                           #endregion

                       };

                    // lets tell the world about virtual screens owned by us.
                    // lets start by advertising our size.

                    #region at_virtualwindowsync
                    var t = new ScriptCoreLib.JavaScript.Runtime.Timer(
                        delegate
                        {
                            // do we know whats the dx to other windows?
                            var xml = new XElement("at_virtualwindowsync",
                                // int not yet supported?
                                new XAttribute("w", "" + fw.Width),
                                new XAttribute("h", "" + fw.Height)


                            );

                            #region what about children?
                            ListOfChildren.WithEach(
                                c =>
                                {
                                    var pdx = c.fc.Left - fw.Left;
                                    var pdy = c.fc.Top - fw.Top;

                                    xml.Add(

                                        new XElement("child",
                                            new XAttribute("child_id", "" + c.child_id),
                                        // int not yet supported?
                                            new XAttribute("pdx", "" + pdx),
                                            new XAttribute("pdy", "" + pdy),
                                            new XAttribute("w", "" + c.fc.Width),
                                            new XAttribute("h", "" + c.fc.Height)
                                        )

                                    );
                                }
                            );
                            #endregion


                            mothership_postXElement(
                              xml
                            );

                            Console.WriteLine("sent at_virtualwindowsync");

                        }
                    );

                    t.StartInterval(5000);
                    #endregion

                };

            Action<IWindow, Form> bind =
                (w, fc) =>
                {
                    this.device_bind(w.postXElement);

                    internal_onmessage +=
                        (e, xml) =>
                        {
                            if (xml.Name.LocalName == "reconfigure")
                            {
                                // how do we know this reconfigrue event is for us?

                                if (e.source == w)
                                {
                                    disable_bind_reconfigure = true;

                                    int dx = int.Parse(xml.Attribute("dx").Value);
                                    int dy = int.Parse(xml.Attribute("dy").Value);

                                    //Console.WriteLine("reconfigure " + new { dx, dy, fw.Left });

                                    //fw.Left += dx;
                                    //fw.Top += dy;


                                    fc.MoveTo(
                                        fw.Left - dx,
                                        fw.Top - dy
                                    );

                                    disable_bind_reconfigure = false;
                                }
                            }
                        };

                    Action SendDelta = delegate
                    {
                        var pdx = fc.Left - fw.Left;
                        var pdy = fc.Top - fw.Top;

                        w.postXElement(
                          new XElement("reconfigure",
                              new XAttribute("dx", "" + pdx),
                              new XAttribute("dy", "" + pdy)
                          )
                        );
                    };

                    fw.LocationChanged +=
                        delegate
                        {
                            if (disable_bind_reconfigure)
                                return;

                            SendDelta();
                        };

                    fc.LocationChanged +=
                        delegate
                        {
                            if (disable_bind_reconfigure)
                                return;


                            SendDelta();
                        };
                };
            #endregion


            #region opener
            Native.window.opener.With(
                w =>
                {
                    // disable features
                    page.info.Hide();

                    Console.WriteLine("we have opener: " + w.document.location.href);

                    var fc = new Form { Text = "opener" };

                    fc.Owner = fvs;

                    Action cAtResize = delegate
                    {
                        fc.Text = "Opener " + new { w.Width, w.Height };
                        fc.Width = w.Width / 4;
                        fc.Height = w.Height / 4;
                    };

                    w.onresize += delegate
                    {
                        cAtResize();
                    };

                    var ct = new ScriptCoreLib.JavaScript.Runtime.Timer(
                       delegate
                       {
                           cAtResize();
                       }
                    );

                    ct.StartInterval(1000 / 15);

                    cAtResize();

                    fc.StartPosition = FormStartPosition.Manual;
                    fc.Show();
                    fc.Opacity = 0.7;
                    fc.BackColor = Color.Transparent;

                    var fcShadow = CreateShadow(fc);
                    Shadows.Add(fcShadow);



                    Native.window.requestAnimationFrame +=
                        delegate
                        {
                            // ScriptCoreLib Windows Forms has a few bugs:P
                            fc.MoveTo(fw.Left - fc.Width, fw.Top);

                            bind(w, fc);
                        };

                }
            );
            #endregion

            #region make info clickable

            page.info.onmousedown +=
             e =>
             {
                 if (internal_ismousedown)
                     return;

                 e.stopPropagation();
             };

            page.info.ontouchstart +=
              e =>
              {
                  if (internal_ismousedown)
                      return;


                  e.stopPropagation();
              };

            page.info.ontouchmove +=
          e =>
          {
              if (internal_ismousedown)
                  return;


              e.stopPropagation();
          };

            page.info.ontouchend +=
     e =>
     {
         if (internal_ismousedown)
             return;

         e.stopPropagation();
     };
            #endregion

            #region OpenChildSession



            page.OpenChildSession.onclick +=
                e =>
                {
                    e.preventDefault();

                    Console.WriteLine("open child session...");

                    Native.window.open(
                        Native.Document.location.href,
                        "_blank", 400, 400, true).With(
                        w =>
                        {
                            w.onload +=
                                delegate
                                {
                                    if (w.document.location.href == "about:blank")
                                        return;

                                    Console.WriteLine("child onload " + w.document.location.href);

                                    var fc = new Form { Text = "child" };



                                    Action cAtResize = delegate
                                    {
                                        fc.Text = "Child " + new { w.Width, w.Height };
                                        fc.Width = w.Width / 4;
                                        fc.Height = w.Height / 4;

                                        VirtualScreenUpdate();
                                    };

                                    w.onresize += delegate
                                    {
                                        cAtResize();

                                    };

                                    var ct = new ScriptCoreLib.JavaScript.Runtime.Timer(
                                       delegate
                                       {
                                           cAtResize();
                                       }
                                    );

                                    ct.StartInterval(1000 / 2);

                                    //cAtResize();

                                    fc.StartPosition = FormStartPosition.Manual;
                                    fc.Show();
                                    fc.Opacity = 0.5;
                                    // first child could be a monitor to our right
                                    fc.MoveTo(fw.Right, fw.Top);
                                    fc.Owner = fvs;
                                    fc.BackColor = Color.Transparent;

                                    fc.Width = 400 / 4;
                                    fc.Height = 400 / 4;

                                    VirtualScreenUpdate();



                                    fc.LocationChanged +=
                                        delegate
                                        {
                                            VirtualScreenUpdate();

                                        };

                                    var fcShadow = CreateShadow(fc);
                                    Shadows.Add(fcShadow);

                                    var token = new { child_id = random.Next(), fc };

                                    ListOfChildren.Add(token);

                                    #region FormClosing
                                    w.onbeforeunload +=
                                        delegate
                                        {
                                            if (fc == null)
                                                return;

                                            w = null;

                                            ct.Stop();
                                            fc.Close();
                                            fc = null;
                                        };

                                    Native.window.onbeforeunload +=
                                        delegate
                                        {
                                            if (w == null)
                                                return;

                                            w.close();
                                            w = null;
                                        };

                                    fc.FormClosing +=
                                        delegate
                                        {

                                            if (w == null)
                                                return;

                                            ListOfChildren.Remove(token);
                                            Shadows.Remove(fcShadow);

                                            fc = null;

                                            w.close();
                                            w = null;
                                        };
                                    #endregion



                                    bind(w, fc);


                                };
                        }
                    );
                };
            #endregion





            Native.document.documentElement.style.overflow = IStyle.OverflowEnum.hidden;
        }
        public static void InitializeContent()
        {
            #region tutorial step 2
            #region arena
            var map = new Point(2000, 2000);

            var arena = new ArenaControl();

            arena.Layers.Canvas.style.backgroundColor =
                Color.FromGray(0xc0);
            arena.SetLocation(
                Rectangle.Of(0, 0, Native.window.Width, Native.window.Height));

            arena.SetCanvasSize(map);

            arena.Control.AttachToDocument();


            arena.DrawTextToInfo(Title, new Point(8, 8), Color.Blue);

            Native.window.onresize +=
                delegate
                {
                    arena.SetLocation(
                        Rectangle.Of(0, 0, Native.window.Width, Native.window.Height));

                    arena.SetCanvasPosition(
                        arena.CurrentCanvasPosition
                        );
                };
            #endregion
            #endregion


            var pending = default(Dude2);

            #region arsenal
            var arsenal = new Dictionary<string, DudeAnimationInfo>
            {
                {"Soldier", 
                    new DudeAnimationInfo 
                    { 
                        Frames_Stand = Frames.WolfSoldier,
                        Frames_Walk = Frames.WolfSoldier_Walk
                    }
                },
                {"Imp", 
                    new DudeAnimationInfo 
                    { 
                        Frames_Stand = Frames.DoomImp,
                        Frames_Walk = Frames.DoomImp_Walk
                    }
                }
            };
            #endregion


            #region tutorial step 3

            Func<DudeAnimationInfo, Point, Dude2> CreateActor =
                (_frames, _coords) =>
                {
                    var actor = new Dude2();

                    actor.Frames = _frames.Frames_Stand;
                    actor.AnimationInfo.Frames_Stand = _frames.Frames_Stand;
                    actor.AnimationInfo.Frames_Walk = _frames.Frames_Walk;
                    actor.Zoom.DynamicZoomFunc = a => 1;
                    actor.SetSize(48, 72);
                    actor.TeleportTo(_coords.X, _coords.Y);
                    actor.Zoom.StaticZoom = DefaultActiorZoom;
                    actor.Direction = Math.PI * 0.5;
                    actor.Control.AttachTo(arena.Layers.Canvas);
                    //actor.HasShadow = _frames.Frames_Stand.Length > 1;
                    if (_frames.Frames_Stand.Length == 1)
                        actor.Shadow.style.Opacity = 0.4;
                    actor.AnimationInfo.WalkAnimationInterval = 1000 / 30;
                    return actor;
                };

            var actors = new List<Dude2>
            {

            };

            var selection = from i in actors
                            where i.IsSelected
                            select i;

            arena.ApplySelection +=
                (rect, ev) =>
                {
                    if (pending != null)
                        return;

                    foreach (var v in actors)
                        v.IsSelected = rect.Contains(v.CurrentLocation.ToInt32());
                };

            var Argh = new Argh();
            var Affirmative = new Affirmative();
            var ghoullaugh = new ghoullaugh();
            var sheep = new sheep();
            var pig = new pig();
            var click = new click().AttachToDocument();

            arena.SelectionClick +=
                (p, ev) =>
                {
                    if (pending != null)
                        return;

                    foreach (var v in selection)
                    {
                        if (v.AnimationInfo.Frames_Stand[0].Source == MyFrames.ManWithHorns.Frames_Stand[0].Source)
                        {
                            ghoullaugh.play();
                            ghoullaugh = new ghoullaugh();
                        }
                        else if (v.AnimationInfo.Frames_Stand[0].Source == MyFrames.ThePig.Frames_Stand[0].Source)
                        {
                            pig.play();
                            pig = new pig();
                        }
                        else if (v.AnimationInfo.Frames_Stand[0].Source == MyFrames.TheSheep.Frames_Stand[0].Source)
                        {
                            sheep.play();
                            sheep = new sheep();
                        }
                        else if (v.AnimationInfo.Frames_Stand[0].Source == Frames.WolfSoldier[0].Source)
                        {
                            Affirmative.play();
                            Affirmative = new Affirmative();
                        }
                        else
                        {
                            Argh.play();
                            Argh = new Argh();
                        }



                        v.WalkTo(p.ToDouble());

                        // move in group formation
                        p.X += 16;
                        p.Y += 16;
                    }
                };


            #endregion

            #region tutorial step 4



            #region CreateDialogAt
            var CreateDialogAt =
                new
                {
                    //Dialog = default(IHTMLDiv),
                    Content = default(IHTMLDiv),
                    Width = default(string)
                }
                .ToFunc(
                (Point pos, string width) =>
                {
                    var f = new Form();

                    f.Show();

                    f.SizeTo(200, 200);


                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20151115/audio
                    //f.PopupInsteadOfClosing();

                    f.MoveTo(pos.X, pos.Y);
                    //f.SizeTo(


                    //var dialog = new IHTMLDiv();

                    //dialog.style.SetLocation(pos.X, pos.Y);

                    //dialog.style.backgroundColor = Color.Gray;
                    //dialog.style.padding = "1px";

                    //var caption = new IHTMLDiv().AttachTo(dialog);

                    //caption.style.backgroundColor = Color.Blue;
                    //caption.style.width = width;
                    //caption.style.height = "0.5em";
                    //caption.style.cursor = IStyle.CursorEnum.move;

                    //var drag = new DragHelper(caption);

                    //drag.Position = pos;
                    //drag.Enabled = true;
                    //drag.DragMove +=
                    //    delegate
                    //    {
                    //        dialog.style.SetLocation(drag.Position.X, drag.Position.Y);
                    //    };

                    var _content = new IHTMLDiv().AttachTo(f.GetHTMLTargetContainer());

                    _content.style.textAlign = IStyle.TextAlignEnum.center;
                    _content.style.backgroundColor = Color.White;
                    _content.style.padding = "1px";

                    //dialog.AttachToDocument();

                    return new
                    { //Dialog = dialog,
                        Content = _content,
                        Width = width
                    };
                }
            );
            #endregion

            #region dialog
            var toolbar = CreateDialogAt(new Point(2, 2), "8em");

            var combo = new IHTMLSelect();
            var build = new IHTMLButton();

            build.style.SetSize(72, 72);
            build.style.padding = "0px";

            var avatar = new IHTMLImage().AttachTo(build);
            var remove = new IHTMLButton("Remove");


            combo.AttachTo(toolbar.Content);
            new IHTMLBreak().AttachTo(toolbar.Content);
            build.AttachTo(toolbar.Content);
            new IHTMLBreak().AttachTo(toolbar.Content);
            remove.AttachTo(toolbar.Content);
            new IHTMLBreak().AttachTo(toolbar.Content);
            #endregion


            #region GetSelectedArsenal
            Func<DudeAnimationInfo> GetSelectedArsenal =
                () =>
                {
                    if (arsenal.ContainsKey(combo[combo.selectedIndex].value))
                        return arsenal[combo[combo.selectedIndex].value];

                    return null;
                };
            #endregion

            Action Refresh =
                delegate
                {
                    var i = GetSelectedArsenal();

                    if (i != null)
                        avatar.src = i.Images.Random().src;
                };

            combo.Add(arsenal.Keys.ToArray());
            Refresh();

            combo.onchange +=
                delegate
                {
                    Refresh();



                    click.play();
                    click = new click().AttachToDocument();
                };

            #region pending actor

            arena.MouseMove +=
                p =>
                {
                    if (pending == null)
                        return;

                    pending.TeleportTo(p.X, p.Y);
                };

            arena.Layers.User.oncontextmenu +=
                e =>
                {
                    e.preventDefault();

                    if (pending != null)
                    {
                        pending.Control.Orphanize();
                        pending = null;
                        arena.ShowSelectionRectangle = true;

                        return;
                    }

                    actors.ForEach(
                        k => k.IsSelected = false
                            );
                };

            arena.SelectionClick +=
                (p, ev) =>
                {
                    if (pending == null)
                    {

                        return;
                    }

                    pending.TeleportTo(p.X, p.Y);

                    actors.Add(pending);

                    pending.IsHot = false;


                    var x = GetSelectedArsenal();
                    pending = CreateActor(x,
                       new Point(
                           Native.window.Width / 2,
                           Native.window.Height / 2
                           )
                   );

                    pending.IsHot = true;


                    click.play();
                    click = new click().AttachToDocument();
                };

            build.onclick +=
                delegate
                {
                    if (pending != null)
                    {
                        pending.Control.Orphanize();
                        pending = null;

                        return;
                    }

                    var x = GetSelectedArsenal();

                    pending = CreateActor(x,
                        new Point(
                            Native.window.Width / 2,
                            Native.window.Height / 2
                            )
                    );

                    pending.IsHot = true;
                    arena.ShowSelectionRectangle = false;

                    click.play();
                    click = new click().AttachToDocument();
                };
            #endregion

            remove.onclick +=
                delegate
                {
                    foreach (var v in selection.ToArray())
                    {
                        v.Control.Orphanize();
                        actors.Remove(v);
                    }


                    click.play();
                    click = new click().AttachToDocument();
                };

            #endregion

            if (FilterToImpAndSoldier)
            { }
            else
            {
                #region step 6

                {
                    var n = "NPC";

                    arsenal.Add(n, MyFrames.NPC3);
                    combo.Add(n);
                }

                #endregion


                {
                    var n = "ManWithHorns";

                    arsenal.Add(n, MyFrames.ManWithHorns);
                    combo.Add(n);
                }
                {
                    var n = "TheSheep";

                    arsenal.Add(n, MyFrames.TheSheep);
                    combo.Add(n);
                }
                {
                    var n = "ThePig";

                    arsenal.Add(n, MyFrames.ThePig);
                    combo.Add(n);
                }

                {
                    var n = "TheCactus";

                    arsenal.Add(n, MyFrames.TheCactus);
                    combo.Add(n);
                }
            }


            if (BeforeAddingDebris != null)
                BeforeAddingDebris(arena.Layers.Canvas);

            3.Times(
              delegate()
              {
                  new DebrisImages().Images.ForEach(
                      img => img.AttachTo(arena.Layers.Canvas).style.SetLocation(map.X.Random(), map.Y.Random())
                  );
              }
      );

            16.Times(
                delegate()
                {
                    actors.Add(
                        CreateActor(arsenal.Random().Value, new Point(map.X.Random(), map.Y.Random()))
                        );
                }
            );
        }
        // problems with roslyn build?
        public static void InitializeSidebarBehaviour(
            IApp page, 
            Form f, 
            bool HandleClosed = true,
            bool HandleDragToLeft = true
            )
        {
            var tt = f.GetHTMLTarget();

            //page.SidebarInfo.style.tr
            page.SidebarInfo.style.With(
                (dynamic s) => s.webkitTransition = "all 0.3s linear"
            );


            var IsMinimized = false;


            #region Minimize
            Action Minimize =
                delegate
                {
                    if (IsMinimized)
                        return;


                    var t = tt;
                    dynamic style = t.style;


                    var old = new { f.Left, f.Top, f.Height };

                    // http://developer.apple.com/library/safari/documentation/AudioVideo/Reference/WebKitTransitionEventClassReference/WebKitTransitionEvent/WebKitTransitionEvent.html

                    var cleartransition = new ScriptCoreLib.JavaScript.Runtime.Timer(
                        delegate
                        {
                            style.webkitTransition = "";
                            style = null;
                            IsMinimized = false;

                            f.MoveTo(
                                old.Left.Max(page.Sidebar.clientWidth + 12)
                                , old.Top);

                            // prevent drawing artifacts
                            tt.style.transform = "";

                        }
                    );

                    Action DoRestore = null;

                    DoRestore = delegate
                    {
                        if (t == null)
                            return;
                        DoRestore = null;

                        Console.WriteLine("DoRestore");

                        style.webkitTransition = "all 0.3s linear";

                        t.style.transform = "scale(1)";

                        t.style.left = old.Left.Max(page.Sidebar.clientWidth + 12) + "px";
                        t.style.top = old.Top + "px";

                        //t.style.Opacity = 1;
                        f.Opacity = 1;
                        t = null;
                        page.SidebarInfo.style.marginTop = (0) + "px";
                    };



                    var clicktorestore = new ScriptCoreLib.JavaScript.Runtime.Timer(
                        delegate
                        {
                            style.webkitTransition = "";

                            page.SidebarOverlay.onclick +=
                                delegate
                                {

                                    if (DoRestore != null)
                                        DoRestore();

                                };

                            f.Resize +=
                                delegate
                                {
                                    if (DoRestore != null)
                                        DoRestore();
                                };
                        }
                    );

                    t.addEventListener("webkitTransitionEnd",
                           ee =>
                           {
                               if (t == null)
                               {
                                   // script: error JSC1000: No implementation found for this native method, please implement [static Microsoft.CSharp.RuntimeBinder.Binder.UnaryOperation(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Linq.Expressions.ExpressionType, System.Type, System.Collections.Generic.IEnumerable`1[[Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]])]

                                   if ((object)style != null)
                                       cleartransition.StartTimeout(300);

                                   return;
                               }

                               Console.WriteLine("webkitTransitionEnd");

                               clicktorestore.Stop();
                               clicktorestore.StartTimeout(300);
                           }
                       );

                    // http://www.the-art-of-web.com/css/css-animation/
                    t.style.transformOrigin = "0% 0%";

                    var scale = (double)(page.Sidebar.clientWidth - 10) / (double)f.Width;
                    page.SidebarInfo.style.marginTop = (f.Height * scale + 20) + "px";


                    style.webkitTransition = "all 0.2s linear";

                    t.style.transform = "scale(" + scale + ")";
                    t.style.left = "0.2em";
                    t.style.top = "0.2em";
                    //t.style.Opacity = 0.5;

                    f.Opacity = 0.5;

                    IsMinimized = true;

                };
            #endregion

            if (HandleDragToLeft)
                new ScriptCoreLib.JavaScript.Runtime.Timer(
                    delegate
                    {
                        // popup mode?
                        if (f.GetHTMLTarget().parentNode == null)
                            return;



                        if (IsMinimized)
                        {
                            return;
                        }


                        if (tt.offsetLeft < page.Sidebar.clientWidth)
                        {
                            page.SidebarOverlay.style.Opacity = 0.2;

                            var scale = (double)(page.Sidebar.clientWidth - 10) / ((double)tt.clientHeight);
                            Console.WriteLine(new { scale });
                            page.SidebarInfo.style.marginTop = (f.Height * scale + 20) + "px";


                            if (f.Capture)
                                return;

                            Console.WriteLine(new { f.WindowState });

                            if (f.WindowState != FormWindowState.Normal)
                                return;


                            Minimize();

                        }
                        else
                        {
                            page.SidebarInfo.style.marginTop = (0) + "px";
                        }
                        page.SidebarOverlay.style.Opacity = 0;
                    }
                ).StartInterval(100);


            if (HandleClosed)
            {
                f.FormClosing += (s, e) =>
                {
                    if (e.CloseReason == System.Windows.Forms.CloseReason.UserClosing)
                    {
                        e.Cancel = true;

                        Minimize();
                    }
                };

            }


            dynamic xstyle = page.SidebarOverlay.style;
            xstyle.webkitTransition = "all 0.3s linear";
            page.SidebarOverlay.onmouseout +=
                delegate
                {
                    page.SidebarOverlay.style.Opacity = 0;

                };
            page.SidebarOverlay.onmouseover +=
             delegate
             {
                 page.SidebarOverlay.style.Opacity = 0.3;
             };

            page.SidebarOverlay.onclick +=
                    delegate
                    {
                        if (IsMinimized)
                            return;
                        Minimize();



                    };


            #region enforce overflow:hidden
            Native.window.onscroll +=
                e =>
                {
                    e.preventDefault();
                    e.stopPropagation();

                    //Console.WriteLine("Window onscroll ");

                    Native.Document.body.scrollTop = 0;
                    Native.Document.body.scrollLeft = 0;
                };
            #endregion

        }
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            // localStorage not available on android webview!
            //E/Web Console( 3751): Uncaught TypeError: Cannot set property '20130329 Hello world' of null at http://192.168.1.107:25459/view-source:32300


            FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

            new GrayPatternBackground.HTML.Images.FromAssets.background().ToDocumentBackground();

            Console.WriteLine("serial 57770");

            "My Notez (loading...)".ToDocumentTitle();


            service.AtPendingActions +=
                count =>
                {
                    if (service.ServicePending.ElapsedMilliseconds > 500)
                    {
                        if (service.ServicePending.ElapsedMilliseconds > 4000)
                        {
                            "My Notez (offline)".ToDocumentTitle();
                            return;
                        }

                        "My Notez (pending)".ToDocumentTitle();
                        return;
                    }

                    "My Notez".ToDocumentTitle();
                };

            Native.window.onbeforeunload +=
                e =>
                {
                    if (service.ServicePending.IsRunning)
                        e.Text = "The changes made here have not yet made it to the server.";
                };

            var storage = new MyLocalStorage
            {

                AtRemove =
                    x => service.remove_LocalStorage(x),

                AtSetItem =
                    (key, value) =>
                    {
                        service.set_LocalStorage(key, value);
                    }
            };

            Console.WriteLine("Do we have localStorage? [2]");

            Native.window.localStorage.With(
                localStorage =>
                {
                    Console.WriteLine("This browser has localStorage. Lets sync with that. [2]");

                    for (uint i = 0; i < localStorage.length; i++)
                    {
                        var key = localStorage.key(i);
                        var value = localStorage[key];

                        storage[key] = value;
                    }

                    // jsc why aint ths working?
                    //storage.AtRemove += localStorage.removeItem;
                    storage.AtRemove += key => localStorage.removeItem(key);
                    storage.AtSetItem += (key, value) => { localStorage[key] = value; };

                }
            );

            #region done
            Action done = delegate
                {



                    var hh = new HorizontalSplit
                    {
                        Minimum = 0.05,
                        Maximum = 0.95,
                        Value = 0.4,
                    };


                    hh.Container.AttachToDocument();
                    hh.Container.style.position = IStyle.PositionEnum.absolute;
                    hh.Container.style.left = "0px";
                    hh.Container.style.top = "0px";
                    hh.Container.style.right = "0px";
                    hh.Container.style.bottom = "0px";

                    hh.Split.Splitter.style.backgroundColor = "rgba(0,0,0,0.0)";


                    //var vv = new VerticalSplit
                    var f = new Form
                    {
                        StartPosition = FormStartPosition.Manual,
                        SizeGripStyle = SizeGripStyle.Hide,

                        Text = "Entries"
                    };

                    var f1 = new Form
                    {
                        StartPosition = FormStartPosition.Manual,
                        SizeGripStyle = SizeGripStyle.Hide,

                        Text = "My Files"
                    };

                    f1.Show();


                    var f2 = new Form
                    {
                        StartPosition = FormStartPosition.Manual,
                        SizeGripStyle = SizeGripStyle.Hide,

                        Text = "..."
                    };

                    f2.Show();

                    var w = new WebBrowser
                    {
                        Dock = DockStyle.Fill
                    };
                    w.GetHTMLTarget().name = "viewer";
                    w.AttachTo(f2);

                    w.Navigating +=
                        delegate
                        {
                            f2.Text = "Navigating";

                        };

                    w.Navigated +=
                       delegate
                       {
                           if (w.Url.ToString() == "about:blank")
                           {

                               f2.Text = "...";


                               return;
                           }

                           //ff.Text = w.DocumentTitle;
                           f2.Text = Native.window.unescape(
                               w.Url.ToString().SkipUntilLastIfAny("/").TakeUntilLastIfAny(".")
                               );



                       };

                    Native.window.requestAnimationFrame +=
                        delegate
                        {

                            var layout = new Abstractatech.JavaScript.FileStorage.HTML.Pages.App();

                            layout.Container.AttachTo(f1.GetHTMLTargetContainer());

                            Abstractatech.JavaScript.FileStorage.ApplicationContent.Target = w.GetHTMLTarget().name;


                            new Abstractatech.JavaScript.FileStorage.ApplicationContent(
                                layout,
                                service.service
                            );

                        };


                    var LeftScrollable = new IHTMLDiv { className = "SidebarForButtons" }.AttachTo(f.GetHTMLTargetContainer());

                    LeftScrollable.style.backgroundColor = "white";

                    var CreateNew = new IHTMLButton { innerText = "+ create new", className = "SidebarButton" }.AttachTo(
                      LeftScrollable
                     );

                    var ff = new Form
                    {
                        StartPosition = FormStartPosition.Manual,
                        SizeGripStyle = SizeGripStyle.Hide

                    };



                    f.Show();
                    ff.Show();




                    //var text = new TextEditor(hh.Split.RightScrollable);
                    var text = new TextEditor(ff.GetHTMLTargetContainer());

                    text.ContainerForBorders.style.border = "";

                    text.Control.style.position = IStyle.PositionEnum.absolute;
                    text.Control.style.left = "0px";
                    text.Control.style.top = "0px";
                    text.Control.style.right = "0px";
                    text.Control.style.bottom = "0px";


                    //Native.Window.onresize +=
                    //    delegate
                    //    {
                    //        var TopToolbarHeight = text.TopToolbar.clientHeight;

                    //        //Console.WriteLine(new { TopToolbarHeight });

                    //        text.DesignerContainer.style.top = (TopToolbarHeight + 4) + "px";
                    //        text.SourceContainer.style.top = (TopToolbarHeight + 4) + "px";

                    //    };


                    #region DesignerContainer
                    text.DesignerContainer.style.position = IStyle.PositionEnum.absolute;
                    text.DesignerContainer.style.left = "0px";
                    text.DesignerContainer.style.top = "3em";
                    text.DesignerContainer.style.right = "0px";
                    text.DesignerContainer.style.bottom = "3em";
                    text.DesignerContainer.style.height = "";

                    text.Frame.style.position = IStyle.PositionEnum.absolute;
                    text.Frame.style.left = "0px";
                    text.Frame.style.top = "0px";
                    //text.Frame.style.right = "0px";
                    //text.Frame.style.bottom = "0px";
                    text.Frame.style.width = "100%";
                    text.Frame.style.height = "100%";
                    #endregion


                    #region SourceContainer
                    text.SourceContainer.style.position = IStyle.PositionEnum.absolute;
                    text.SourceContainer.style.left = "0px";
                    text.SourceContainer.style.top = "3em";
                    text.SourceContainer.style.right = "0px";
                    text.SourceContainer.style.bottom = "3em";
                    text.SourceContainer.style.height = "";

                    text.TextArea.style.position = IStyle.PositionEnum.absolute;
                    text.TextArea.style.left = "0px";
                    text.TextArea.style.top = "0px";
                    //text.Frame.style.right = "0px";
                    //text.Frame.style.bottom = "0px";
                    text.TextArea.style.width = "100%";
                    text.TextArea.style.height = "100%";
                    #endregion

                    text.BottomToolbarContainer.style.position = IStyle.PositionEnum.absolute;
                    text.BottomToolbarContainer.style.left = "0px";
                    text.BottomToolbarContainer.style.right = "0px";
                    text.BottomToolbarContainer.style.bottom = "0px";

                    var oldtitle = "";

                    Action DoRefresh = delegate { };

                    #region DoCreateNew
                    Action DoCreateNew = delegate
                    {
                        oldtitle = "";

                        #region default text
                        var now = DateTime.Now;


                        var yyyy = now.Year;
                        var mm = now.Month;
                        var dd = now.Day;


                        var yyyymmdd = yyyy
                            + mm.ToString().PadLeft(2, '0')
                            + dd.ToString().PadLeft(2, '0');

                        string header = yyyymmdd + @" New Header " + storage.Keys.Count();


                        text.InnerHTML = @"
<div><font face='Verdana' size='5' color='#0000fc'>" + header + @"</font></div><div><br /></div><blockquote style='margin: 0 0 0 40px; border: none; padding: 0px;'></blockquote><font face='Verdana'>This is your content.</font>
            ";
                        #endregion



                        DoRefresh();
                    };

                    CreateNew.onclick +=
                        delegate
                        {
                            DoCreateNew();
                        };
                    #endregion




                    var buttons = new List<IHTMLButton>();

                    Action EitherCreateNewOrSelectFirst = delegate
                    {
                        if (buttons.Count == 0)
                        {
                            DoCreateNew();
                        }
                        else
                        {
                            if (buttons.Any(k => k.innerText == oldtitle))
                            {
                                //already selected
                            }
                            else
                            {
                                oldtitle = buttons.First().innerText;

                                text.InnerHTML = storage[oldtitle];
                            }
                        }
                    };


                    #region Remove this document
                    var remove = text.AddButton(null, "Remove this document",
                          delegate
                          {
                              var button = buttons.FirstOrDefault(k => k.innerText == oldtitle);

                              if (button == null)
                                  return;

                              //Native.Window.localStorage.removeItem(button.innerText);
                              storage.Remove(button.innerText);


                              button.Orphanize();
                              buttons.Remove(button);

                              EitherCreateNewOrSelectFirst();
                          }
                      );
                    #endregion


                    IHTMLElement remove_element = remove;
                    remove_element.style.Float = IStyle.FloatEnum.right;

                    text.BottomToolbar.appendChild(remove_element);

                    #region new_SidebarButton
                    Func<IHTMLButton> new_SidebarButton =
                        delegate
                        {
                            var button = new IHTMLButton { className = "SidebarButton" }.AttachTo(
                                           LeftScrollable
                                        );

                            button.onclick +=
                                delegate
                                {
                                    oldtitle = "";
                                    text.InnerHTML = storage[button.innerText];
                                    DoRefresh();

                                };

                            button.oncontextmenu +=
                               e =>
                               {
                                   e.preventDefault();

                                   storage.Remove(button.innerText);


                                   button.Orphanize();
                                   buttons.Remove(button);

                                   EitherCreateNewOrSelectFirst();
                               };

                            buttons.Add(button);

                            return button;
                        };
                    #endregion

                    #region DoRefresh
                    DoRefresh = delegate
                   {
                       // what has changed
                       // text not default anymore?
                       // title change?


                       // document unloaded?
                       if (text.Document == null)
                           return;

                       var xml = text.Document.body.AsXElement();

                       // script: error JSC1000: No implementation found for this native method, please implement [static System.String.IsNullOrWhiteSpace(System.String)]

                       xml.Elements().FirstOrDefault(k => !string.IsNullOrWhiteSpace(k.Value)).With(
                           TitleElement =>
                           {
                               // take no action for no title
                               if (string.IsNullOrWhiteSpace(TitleElement.Value))
                                   return;

                               // is there a buttn with old title?


                               var button = buttons.FirstOrDefault(
                                   k =>
                                   {
                                       if (oldtitle == "")
                                       {
                                           return k.innerText == TitleElement.Value;
                                       }

                                       return k.innerText == oldtitle;
                                   }
                               );

                               if (button == null)
                               {
                                   button = new_SidebarButton();
                               }

                               button.innerText = TitleElement.Value;

                               buttons.WithEach(
                                   x => x.setAttribute("data-active", x == button)
                               );


                               if (oldtitle != "")
                               {
                                   if (oldtitle != TitleElement.Value)
                                       storage.Remove(oldtitle);


                               }

                               ff.Text = TitleElement.Value;

                               // src="http://192.168.1.100:5763/

                               var innerHTML = text.InnerHTML;

                               var href = Native.Document.location.href.TakeUntilLastOrEmpty("/");

                               // keep only relative paths to current host
                               var xinnerHTML = innerHTML.Replace("src=\"" + href + "/", "src=\"/");

                               if (innerHTML != xinnerHTML)
                               {
                                   text.InnerHTML = xinnerHTML;
                               }

                               storage[TitleElement.Value] = xinnerHTML;
                               oldtitle = TitleElement.Value;
                               //Console.WriteLine("TitleElement: " + TitleElement.Value);
                           }
                       );

                       // whats the title?
                   };
                    #endregion



                    foreach (var button_text in storage.Keys)
                    {
                        new_SidebarButton().innerText = button_text;
                    }



                    new ScriptCoreLib.JavaScript.Runtime.Timer(
                        t =>
                        {
                            DoRefresh();



                        }
                    ).StartInterval(500);


                    EitherCreateNewOrSelectFirst();








                    #region AtResize
                    Action AtResize = delegate
                    {
                        Native.Document.getElementById("feedlyMiniIcon").Orphanize();

                        Native.Document.body.style.minWidth = "";

                        //if (ff.GetHTMLTarget().parentNode == null)
                        //{
                        //    Native.Window.scrollTo(0, 0);
                        //    f.MoveTo(8, 8).SizeTo(Native.Window.Width - 16, Native.Window.Height - 16);

                        //    return;
                        //}

                        //if (f.GetHTMLTarget().parentNode == null)
                        //{
                        //    Native.Window.scrollTo(0, 0);
                        //    ff.MoveTo(8, 8).SizeTo(Native.Window.Width - 16, Native.Window.Height - 16);

                        //    return;
                        //}

                        //if (Native.Window.Width < 1024)
                        //{
                        //    Native.Document.body.style.minWidth = (Native.Window.Width * 2) + "px";


                        //    f.MoveTo(8, 8).SizeTo(Native.Window.Width - 16, Native.Window.Height - 16);

                        //    ff.MoveTo(Native.Window.Width + 8, 8).SizeTo(Native.Window.Width - 16, Native.Window.Height - 16);

                        //    // already scrolled...
                        //    if (w.Url.ToString() != "about:blank")
                        //        // docked?
                        //        if (ff.GetHTMLTarget().parentNode != null)
                        //            Native.Window.scrollTo(ff.Left - 8, ff.Top - 8);

                        //    return;
                        //}




                        f.MoveTo(16, 16).SizeTo(hh.LeftContainer.clientWidth - 32, Native.window.Height / 3 - 16 - 4);
                        f1.MoveTo(16, Native.window.Height / 3 + 4).SizeTo(hh.LeftContainer.clientWidth - 32, Native.window.Height / 3 - 8);
                        f2.MoveTo(16, Native.window.Height / 3 * 2 + 4).SizeTo(hh.LeftContainer.clientWidth - 32, Native.window.Height / 3 - 16);


                        ff.MoveTo(
                            Native.window.Width - hh.RightContainer.clientWidth + 16

                            , 16).SizeTo(hh.RightContainer.clientWidth - 32, Native.window.Height - 32);

                        //Console.WriteLine("LeftContainer " + new { hh.LeftContainer.clientWidth });
                        //Console.WriteLine("RightContainer " + new { hh.RightContainer.clientWidth });
                    };

                    hh.ValueChanged +=
                  delegate
                  {
                      AtResize();
                  };

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

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

                    ff.PopupInsteadOfClosing(SpecialNoMovement: true, NotifyDocked: AtResize);
                    f.PopupInsteadOfClosing(SpecialNoMovement: true, NotifyDocked: AtResize);
                    f1.PopupInsteadOfClosing(SpecialNoMovement: true, NotifyDocked: AtResize);
                    f2.PopupInsteadOfClosing(SpecialNoMovement: true, NotifyDocked: AtResize);


                };
            #endregion

            var tt = default(ScriptCoreLib.JavaScript.Runtime.Timer);

            Action done_timeout = delegate
            {
                if (done == null)
                    return;

                tt.Stop();
                done();
                done = null;
            };


            service.get_LocalStorage(
                //add_localStorage: (key, value) => Native.Window.localStorage[key] = value,
                add_localStorage:
                    (key, value) =>
                    {
                        // what if we are resuming from offline edit.
                        // merge?


                        // keep the one we got from localStorage, because it has longer entry?
                        if (storage[key].Length > value.Length)
                            return;

                        storage[key] = value;
                    },

                done: done_timeout
            );


            // either server responds in 2000 or we consider us offline...
            tt = new ScriptCoreLib.JavaScript.Runtime.Timer(
                delegate
                {
                    done_timeout();
                }
            );

            tt.StartTimeout(3000);

        }
		//488: { SourceMethod = Void.ctor(ChromeAppWindowForm.HTML.Pages.IApp), i = [0x02f9]
		//		brtrue.s   +0 -1 }
		//248c:02:01:1e RewriteToAssembly error: System.ArgumentException: Value does not fall within the expected range.

		/// <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)
		{
			// can we get the resize grip to work?
			// X:\jsc.svn\examples\javascript\chrome\apps\ChromeAppWindowMouseCapture\ChromeAppWindowMouseCapture\Application.cs

			#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?");

					// X:\jsc.svn\examples\javascript\chrome\apps\ChromeFormsWebBrowserExperiment\ChromeFormsWebBrowserExperiment\Application.cs


					#region __WebBrowser.InitializeInternalElement
					__WebBrowser.InitializeInternalElement = that =>
					{
						var webview = Native.document.createElement("webview");
						// You do not have permission to use <webview> tag. Be sure to declare 'webview' permission in your manifest. 
						webview.setAttribute("partition", "p1");

						that.InternalElement = (IHTMLIFrame)(object)webview;

					};
					#endregion


					// pass thru
					return;

				}
				// should jsc send a copresence udp message?


				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");

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

					var o = new object();
					var hidden = o == o;
					var alphaEnabled = o == o;
					var alwaysOnTop = o == o;


					var options = new
					{
						//allow webkitAppRegion
						frame = "none",
						hidden,
						alphaEnabled,
						alwaysOnTop
					};

					// The URL used for window creation must be local for security reasons.

					var xappwindow = await chrome.app.window.create(
						   Native.document.location.pathname,
						   //Native.document.location.pathname + "#http://example.com", 
						   options
					);

					//xappwindow.set

					// can we prevent the white page from appearing?
					await xappwindow.contentWindow.async.onload;

					xappwindow.contentWindow.document.title = "http://example.com";

					await Task.Delay(100);
					//await Task.Delay(200);

					xappwindow.show();

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


				return;
			}
			#endregion

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

			// X:\jsc.svn\core\ScriptCoreLib.Windows.Forms\ScriptCoreLib.Windows.Forms\JavaScript\BCLImplementation\System\Windows\Forms\Form\Form..ctor.cs
			//CaptionForeground.className = "caption";

			// Could not load file or assembly 'ScriptCoreLib' or one of its dependencies. The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))

			var css = Native.css[typeof(Form)][" .caption"];
			//var css = IStyleSheet.all[" .caption"];


			//new IHTMLPre { new { css.rule.selectorText } }.AttachToDocument();


			// https://code.google.com/p/chromium/issues/detail?id=229330
			(css.style as dynamic).webkitAppRegion = "drag";

			//(ff.CaptionForeground.style as dynamic).webkitAppRegion = "drag";

			FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

			var ShadowRightBottom = 8;

			var f = new Form
			{

				ShowIcon = false,

				Text = Native.document.title,

				//Text = Native.document.location.hash,
				StartPosition = FormStartPosition.Manual
			};


			f.MoveTo(0, 0).SizeTo(
					Native.window.Width - ShadowRightBottom,
					Native.window.Height - ShadowRightBottom
				);

			//f.Opacity = 0.5;

			f.Show();


			var t = new TrackBar
			{

				Maximum = 100,
				Minimum = 40,

				Dock = DockStyle.Top
			};
			t.AttachTo(f);
			t.ValueChanged += delegate
			{
				f.Opacity = (double)t.Value / (double)t.Maximum;

			};
			f.Opacity = 0.8;

			var w = new WebBrowser
			{

				// this wont work?
				//Dock = DockStyle.Fill

			}.AttachTo(f);

			w.Navigate(
				Native.document.title
			);



			f.FormClosed +=
				delegate
			{
				// close the appwindow

				// DWM animates the close.
				Native.window.close();
			};

			f.SizeChanged +=
				delegate
			{
				Native.window.resizeTo(
					f.Width + ShadowRightBottom,
					f.Height + ShadowRightBottom
				);

			};

			Native.window.onresize +=
				delegate
			{
				// outer frame is resized
				f.SizeTo(
					Native.window.Width - ShadowRightBottom,
					Native.window.Height - ShadowRightBottom
				);

			};

			// activate resize grip to window width?
		}
        /// <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)
        {
            DiagnosticsConsole.ApplicationContent.BindKeyboardToDiagnosticsConsole();

            FormStyler.AtFormCreated =
                  s =>
                  {

                      FormStyler.LikeVisualStudioMetro(s);

                      s.TargetOuterBorder.style.borderColor = ScriptCoreLib.JavaScript.Runtime.JSColor.FromRGB(0, 127, 0);
                      s.Caption.style.backgroundColor = ScriptCoreLib.JavaScript.Runtime.JSColor.FromRGB(0, 127, 0);
                      s.TargetOuterBorder.style.boxShadow = "rgba(0, 127, 0, 0.3) 0px 0px 6px 3px";
                  };

            //FormStyler.AtFormCreated = FormStyler.LikeWindows3;

            var SidebarIdleWidth = 32;

            var f = new Form { Text = "Sidebar" };

            GrayScaleRule.InitializeGrayScaleFor("CLRForm");
            f.GetHTMLTarget().className = "CLRForm";


            #region WhileDragging


            Action WhileDragging = null;

            WhileDragging = delegate
            {
                if (f.Left == 0)
                {
                    f.GetHTMLTarget().className = "CLRForm_nohover";
                    f.Text = "Sidebar (docked)";
                }
                else if (f.Capture)
                {
                    f.GetHTMLTarget().className = "";
                    f.Text = "Sidebar (dragging)";
                }
                else
                {
                    f.GetHTMLTarget().className = "CLRForm";
                    f.Text = "Sidebar";

                }
                Native.window.requestAnimationFrame += WhileDragging;
            };
            Native.window.requestAnimationFrame += WhileDragging;
            #endregion


            var c = new Sidebar { Dock = DockStyle.Fill }.AttachTo(f);

            f.Show();

            Action<int> SetLeftSidebarWidth =
                 w =>
                 {
                     page.SidebarContainer.style.width = w + "px";
                     page.DocumentContent.style.left = w + "px";
                 };

            Action<int> SetRightSidebarWidth =
               w =>
               {
                   page.RightSidebarContainer.style.width = w + "px";
                   page.DocumentContent.style.right = w + "px";
               };

            #region LocationChanged
            var LocationChangedDisabled = false;
            f.LocationChanged +=
                delegate
                {
                    if (LocationChangedDisabled)
                        return;

                    if (f.Left == 0)
                        return;

                    if (f.Right == Native.window.Width)
                        return;

                    SetLeftSidebarWidth(SidebarIdleWidth);
                    SetRightSidebarWidth(SidebarIdleWidth);

                    if (f.Left < SidebarIdleWidth && c.checkBox1.Checked)
                        page.SidebarContainer.style.backgroundColor = JSColor.Blue;
                    else
                        page.SidebarContainer.style.backgroundColor = JSColor.Gray;

                    if (f.Right > Native.window.Width - SidebarIdleWidth && c.checkBox2.Checked)
                        page.RightSidebarContainer.style.backgroundColor = JSColor.Blue;
                    else
                        page.RightSidebarContainer.style.backgroundColor = JSColor.Gray;
                };
            #endregion



            #region Capture
            var tt = new ScriptCoreLib.JavaScript.Runtime.Timer();

            Action AtCapture = null;

            tt.Tick +=
                delegate
                {
                    if (LocationChangedDisabled)
                        return;

                    if (f.Left == 0)
                        return;

                    if (f.Right == Native.window.Width)
                        return;

                    if (f.Capture)
                    {
                        if (AtCapture != null)
                            AtCapture();

                        return;
                    }


                    if (f.Left < SidebarIdleWidth)
                    {
                        if (c.checkBox1.Checked)
                        {
                            var fs = f.Size;

                            SetLeftSidebarWidth(f.ClientSize.Width);
                            f.MoveTo(0, 0);
                            f.SizeTo(f.ClientSize.Width, page.SidebarContainer.clientHeight);
                            f.MinimumSize = new System.Drawing.Size(SidebarIdleWidth, Native.window.Height);
                            f.MaximumSize = new System.Drawing.Size(Native.window.Width - page.RightSidebarContainer.clientWidth, Native.window.Height);


                            var done = false;
                            Action<IEvent> onresize =
                                delegate
                                {
                                    if (done)
                                        return;
                                    f.SizeTo(f.ClientSize.Width, page.SidebarContainer.clientHeight);
                                    f.MinimumSize = new System.Drawing.Size(SidebarIdleWidth, Native.window.Height);
                                    f.MaximumSize = new System.Drawing.Size(Native.window.Width - page.RightSidebarContainer.clientWidth, Native.window.Height);


                                };

                            Native.window.onresize += onresize;

                            AtCapture = delegate
                            {
                                done = true;

                                AtCapture = null;
                                f.MinimumSize = new System.Drawing.Size(100, 100);
                                f.SizeTo(fs.Width, fs.Height);
                            };
                        }
                    }
                    else if (f.Right > (Native.window.Width - SidebarIdleWidth))
                    {
                        if (c.checkBox2.Checked)
                        {

                            var fs = f.Size;

                            SetRightSidebarWidth(f.ClientSize.Width);
                            f.MoveTo(page.RightSidebarContainer.offsetLeft, 0);
                            f.SizeTo(f.ClientSize.Width, page.RightSidebarContainer.clientHeight);
                            f.MinimumSize = new System.Drawing.Size(SidebarIdleWidth, Native.window.Height);
                            f.MaximumSize = new System.Drawing.Size(Native.window.Width, Native.window.Height);

                            var done = false;
                            Action<IEvent> onresize =
                                delegate
                                {
                                    if (done)
                                        return;

                                    f.MoveTo(page.RightSidebarContainer.offsetLeft, 0);
                                    f.SizeTo(f.ClientSize.Width, page.RightSidebarContainer.clientHeight);
                                    f.MinimumSize = new System.Drawing.Size(SidebarIdleWidth, Native.window.Height);
                                    f.MaximumSize = new System.Drawing.Size(Native.window.Width, Native.window.Height);
                                };

                            Native.window.onresize += onresize;


                            AtCapture = delegate
                            {
                                done = true;
                                AtCapture = null;
                                f.MinimumSize = new System.Drawing.Size(100, 100);
                                f.SizeTo(fs.Width, fs.Height);
                            };
                        }
                    }
                };
            tt.StartInterval(100);
            #endregion

            SetLeftSidebarWidth(SidebarIdleWidth);
            SetRightSidebarWidth(SidebarIdleWidth);

            #region SizeChanged
            var PrevRight = 0;

            f.SizeChanged +=
                delegate
                {
                    if (LocationChangedDisabled)
                        return;

                    if (f.Left == 0)
                    {
                        SetLeftSidebarWidth(f.Width);
                    }
                    else
                    {
                        //if (f.Left == page.RightSidebarContainer.offsetLeft)
                        //{
                        //    LocationChangedDisabled = true;
                        //    f.Left = Native.Window.Width - f.Width;
                        //    SetRightSidebarWidth(f.Width);
                        //    LocationChangedDisabled = false;
                        //}
                    }

                    PrevRight = f.Right;
                };
            #endregion

            #region AtButton1
            Action AtButton1 =
                delegate
                {
                    c.button1.Enabled = false;
                    c.button2.Enabled = true;

                    var cl = f.Location;
                    var cs = f.ClientSize;


                    var cc = f.GetHTMLTarget();

                    var IsLeft = f.Left < (Native.window.Width - f.Width) / 2;

                    if (IsLeft)
                    {
                        f.MoveTo(0, 0);
                    }
                    else
                    {
                        f.MoveTo(page.RightSidebarContainer.offsetLeft, 0);
                    }

                    f.FormBorderStyle = FormBorderStyle.None;

                    Native.window.requestAnimationFrame +=
                        delegate
                        {
                            f.Height = Native.window.Height;
                        };

                    c.button2.Click +=
                          delegate
                          {
                              if (cc == null)
                                  return;

                              c.button1.Enabled = true;
                              c.button2.Enabled = false;

                              cc.AttachToDocument();


                              cc = null;

                              f.ClientSize = cs;
                              f.Location = cl;

                              //if (c.checkBox1.Checked)
                              f.FormBorderStyle = FormBorderStyle.Sizable;

                              SetLeftSidebarWidth(SidebarIdleWidth);
                          };

                    cc.AttachTo(page.SidebarContainer);
                };
            #endregion

            #region button1
            c.button1.Click +=
                delegate
                {
                    AtButton1();
                };
            #endregion

            c.button2.Enabled = false;

            c.button3.Click +=
                delegate
                {
                    c.checkBox1.Enabled = false;
                    c.checkBox2.Enabled = false;
                    c.button3.Enabled = false;

                    //f.PopupInsteadOfClosing(
                    //    HandleFormClosing: true
                    //);
                };

            f.FormClosing +=
                (ss, ee) =>
                {
                    if (c.button3.Enabled)
                    {
                        // not yet popup mode
                        ee.Cancel = true;
                        if (c.button1.Enabled)
                            AtButton1();

                    }

                };

            //f.FormClosed +=
            //    delegate
            //    {
            //        Native.Document.body.Clear();

            //        Native.Window.close();
            //    };


            @"Hello world".ToDocumentTitle();
            // Send data from JavaScript to the server tier
            //service.WebMethod2(
            //    @"A string from JavaScript.",
            //    value => value.ToDocumentTitle()
            //);


            //#region snippet http://my.jsc-solutions.net/#TestPackageAsApplication

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

            //        dragme.AllowToDragAsApplicationPackage();
            //    }
            //);

            //#endregion

        }
		public static void Invoke(
			string AppSource
		)
		{
			Console.WriteLine("enter TheServerWithAppWindow.Invoke");


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

				#region __WebBrowser.InitializeInternalElement
				__WebBrowser.InitializeInternalElement = that =>
				{
					var webview = Native.document.createElement("webview");
					// You do not have permission to use <webview> tag. Be sure to declare 'webview' permission in your manifest. 
					webview.setAttribute("partition", "p1");
					webview.setAttribute("allowtransparency", "true");

					// wont work?
					// http://stackoverflow.com/questions/25421586/webview-in-chrome-packaged-app-cannot-be-full-screen
					webview.setAttribute("allowfullscreen", "true");

					webview.style.Opacity = 0.0;


					// 2012 for web faults..
					// 2012 for desktop faults..
					// 2013 for web works. roslynctp 0.5

					webview.addEventListener("loadstop", async e =>
							 {
								 Console.WriteLine("loadstop");
								 // prevent showing white while loading...



								 // http://stackoverflow.com/questions/21624897/how-can-a-chrome-packaged-app-interact-with-a-webview-listen-to-events-fired-fr

								 IWindow contentWindow = (webview as dynamic).contentWindow;

								 // https://groups.google.com/a/chromium.org/forum/#!topic/chromium-apps/gOKDKDk99pQ
								 // X:\jsc.svn\examples\javascript\WebGL\WebGLTiltShift\WebGLTiltShift\Application.cs
								 // X:\jsc.svn\examples\javascript\chrome\apps\ChromeWebviewFullscreen\ChromeWebviewFullscreen\Application.cs

								 // this will break the async even for roslyn ctp 0.5

								 new { }.With(
									 async delegate
								 {
									 retry:
									 {
										 Console.WriteLine("awaiting to go fullscreen");

										 await contentWindow.postMessageAsync("virtual webview.requestFullscreen");

										 Console.WriteLine("awaiting to go fullscreen. go!");


										 // this makes webview reload. thats bad.
										 //that.FindForm().FormBorderStyle = FormBorderStyle.None;


										 // http://stackoverflow.com/questions/15451888/how-can-i-make-a-chrome-packaged-app-which-runs-in-fullscreen-at-startup
										 chrome.app.window.current().fullscreen();
										 //webview.requestFullscreen();
										 goto retry;
									 }
								 }
								 );


								 await Task.Delay(100);

								 //webview.style.display = IStyle.DisplayEnum.block;
								 webview.style.Opacity = 1.0;
							 }
					 );



					#region permissionrequest
					// https://github.com/GoogleChrome/chromium-webview-samples
					// permissionrequest
					// https://developer.chrome.com/apps/tags/webview#type-WebRequestEventInteface
					webview.addEventListener("permissionrequest",
						(e) =>
								{
									// https://code.google.com/p/chromium/issues/detail?id=141198

									//% c9:176376ms permissionrequest { { permission = pointerLock } }
									//Uncaught TypeError: Cannot read property 'allow' of undefined
									//< webview >: The permission request for "pointerLock" has been denied.

									// X:\jsc.internal.git\market\chrome\ChromeMyJscSolutionsNet\ChromeMyJscSolutionsNet\Application.cs

									// https://chromium.googlesource.com/chromium/src/+/git-svn/chrome/common/extensions/api/webview_tag.json
									// https://bugzilla.mozilla.org/show_bug.cgi?id=896143
									// https://developer.chrome.com/apps/tags/webview#event-permissionrequest
									// https://code.google.com/p/chromium/issues/detail?id=153540

									//  The permission request for "pointerLock" has been denied.
									// http://stackoverflow.com/questions/16302627/geolocation-in-a-webview-inside-a-chrome-packaged-app
									// http://git.chromium.org/gitweb/?p=chromium.git;a=commitdiff;h=e1d226c0ea739adaed36cc4b617f7a387d44eca0

									string permission = (e as dynamic).permission;
									xwebviewPointerLockPermissionRequest e_request = (e as dynamic).request;

									Console.WriteLine("permissionrequest " + new
									{
										permission,
										e,
										e_request
									});
									//% c9:167409ms permissionrequest { { permission = pointerLock } }
									//Uncaught TypeError: Cannot read property 'allow' of undefined

									e.preventDefault();


									//9:122010ms permissionrequest { { permission = pointerLock, e = [object Event], e_request = [object Object] } }
									//9:122028ms delay permissionrequest { { permission = pointerLock, e = [object Event], delay_e_request = [object Object] } }
									//Uncaught Error: < webview >: Permission has already been decided for this "permissionrequest" event. 

									//Expando.

									if (e_request != null)
										e_request.allow();

									//Task.Delay(1).ContinueWith(
									//    delegate
									//{
									//    xPointerLockPermissionRequest delay_e_request = (e as dynamic).request;

									//    Console.WriteLine("delay permissionrequest " + new { permission, e, delay_e_request });


									//    if (delay_e_request != null)
									//        delay_e_request.allow();
									//}
									//);
								}
					);
					#endregion


					that.InternalElement = (IHTMLIFrame)(object)webview;

					// src was not copied for some reason. force it.
					that.Size = that.Size;
					that.Refresh();

				};
				#endregion

				var css = Native.css[typeof(Form)][" .caption"];
				(css.style as dynamic).webkitAppRegion = "drag";


				// FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

				// only if the host does alpha?
				var ShadowRightBottom = 8;

				#region Form
				var f = new Form
				{

					ShowIcon = false,

					Text = Native.document.title,

					//Text = Native.document.location.hash,
					StartPosition = FormStartPosition.Manual
				};


				f.MoveTo(0, 0).SizeTo(
						Native.window.Width - ShadowRightBottom,
						Native.window.Height - ShadowRightBottom
					);

				//f.Opacity = 0.5;

				f.Show();
				#endregion





				var w = new WebBrowser
				{

					// this wont work?
					//Dock = DockStyle.Fill

				}.AttachTo(f);

				w.Navigate(
					Native.document.title
				);


				f.FormClosing +=
					(sender, e) =>
					{
						// X:\jsc.svn\examples\javascript\chrome\apps\ChromeWebviewFullscreen\ChromeWebviewFullscreen\Application.cs
						if (chrome.app.window.current().isFullscreen())
						{
							e.Cancel = true;

							chrome.app.window.current().restore();
							return;
						}
					};

				f.FormClosed +=
					delegate
				{
					// close the appwindow

					// DWM animates the close.
					Native.window.close();
				};

				{
					var cs = f.ClientSize;

					w.SizeTo(
						cs.Width,
						cs.Height
						);
				}


				f.SizeChanged +=
					delegate
				{
					var cs = f.ClientSize;

					w.SizeTo(
						cs.Width,
						cs.Height
						);

					Native.window.resizeTo(
						f.Width + ShadowRightBottom,
						f.Height + ShadowRightBottom
					);

				};

				Native.window.onresize +=
					delegate
				{
					if (chrome.app.window.current().isFullscreen())
					{
						f.SizeGripStyle = SizeGripStyle.Hide;
						f.SizeTo(
					 Native.window.Width,
					 Native.window.Height
				 );
						return;
					}

					f.SizeGripStyle = SizeGripStyle.Auto;
					// outer frame is resized
					f.SizeTo(
						Native.window.Width - ShadowRightBottom,
						Native.window.Height - ShadowRightBottom
					);

				};

				return;
			}

			// looks like alpha is still not available for chrome, nor is it available if aero is disabled, red.
			// Unchecked runtime.lastError while running app.window.create: The alphaEnabled option requires dev channel or newer
			var alphaEnabled = true;
			//chrome.AppWindow

			Console.WriteLine("before invoke ChromeTCPServer.TheServer.InvokeAsync " + new { alphaEnabled });

			ChromeTCPServer.TheServer.InvokeAsync(AppSource, async uri =>
			{
				var o = new object();
				var hidden = o == o;


				var alwaysOnTop = o == o;


				var options = new
				{
					//allow webkitAppRegion
					frame = "none",
					//hidden,
					alphaEnabled,
					alwaysOnTop
				};

				// The URL used for window creation must be local for security reasons.

				Console.WriteLine("before app.window.create");

				//				24950ms before app.window.create
				//view - source:51336 25004ms { { socketId = 21, port = 19866, xmessage = < string reason = "" c = "1" preview = "" n = "Audi Visualization" > Visit me at 192.168.1.200:8324 </ string > } }
				//				view - source:51336 25045ms after app.window.create { { xappwindow = null } }

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

				Console.WriteLine("after app.window.create " + new { xappwindow });
				// 20265ms after app.window.create {{ xappwindow = null }}

				// X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeAudi\Application.cs
				// why the ef is it null?
				if (xappwindow == null)
					return;

				//xappwindow.set

				// can we prevent the white page from appearing?
				await xappwindow.contentWindow.async.onload;

				//xappwindow.contentWindow.document.title = "http://example.com";
				xappwindow.contentWindow.document.title = uri;

				await Task.Delay(100);
				//await Task.Delay(200);

				xappwindow.show();
			}
			);


		}
示例#10
0
            public a(IBeforeLogin ee)
            {
                //FormStyler.AtFormCreated = FormStyler.LikeVisualStudioMetro;
                //FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

                var ff = new Form { FormBorderStyle = FormBorderStyle.None };


                var ScrollArea = new App().ScrollArea.AttachTo(ff.GetHTMLTargetContainer());



                //ScrollArea.style.backgroundColor = "#185D7B";
                //ScrollArea.style.backgroundColor = "#185D7B";
                ScrollArea.style.backgroundColor = "#105070";

                var SidebarWidth = 172;

                ff.MoveTo(SidebarWidth, 0);

                Action AtResize = delegate
                {

                    ff.SizeTo(Native.window.Width - SidebarWidth, Native.window.Height);
                };

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

                    };

                AtResize();
                var iii = global::CSSMinimizeFormToSidebar.ApplicationExtension.InitializeSidebarBehaviour(
                  ff,

                  // should be handle close instead!
                  HandleClosed: true,
                  HandleDragToLeft: false
                );

                iii.SidebarText.className = "AppPreviewText";
                //iii.SidebarText.innerText = "My Appz";
                //iii.SidebarText.innerText = "Synchronizing...";
                //var finish = iii.SidebarText.ToASCIIStyledLoadAnimation("My Appz");


                //Native.Document.body.style.backgroundColor = "#105070";
                Native.document.body.style.backgroundColor = "#185D7B";

                Native.window.onresize +=
                    delegate
                    {
                        // lets not centerize
                        //ff.Show();
                    };


                //var page = new App();

                //page.ScrollArea.AttachToDocument();

                var count = 0;

                var yield_BringToFront = false;

                var icon_throttle = 0;

                #region yield
                yield_ACTION_MAIN yield = (
                            packageName,
                            name,
                            __IsCoreAndroidWebServiceActivity,
                            label
                        ) =>
                {

                    if (string.IsNullOrEmpty(label))
                        label = packageName;

                    var IsCoreAndroidWebServiceActivity = System.Convert.ToBoolean(__IsCoreAndroidWebServiceActivity);

                    count++;

                    var a = new AppPreview();

                    #region icon
                    if (packageName != "foo")
                    {
                        // see also: X:\jsc.svn\examples\javascript\ImageCachedIntoLocalStorageExperiment\ImageCachedIntoLocalStorageExperiment\Application.cs

                        // extension to the system
                        // data.icon[packageName].With

                        Action loadicon = delegate
                        {
                            new ScriptCoreLib.JavaScript.Runtime.Timer(
                                delegate
                                {
                                    new IHTMLImage { src = "/icon/" + packageName }.InvokeOnComplete(
                                        i =>
                                        {
                                            var dataURL = i.toDataURL();

                                            // Uncaught QuotaExceededError: An attempt was made to add something to storage that exceeded the quota. 
                                            // http://stackoverflow.com/questions/6276282/how-can-i-request-an-increase-to-the-html5-localstorage-size-on-ipad-like-the-f

                                            //message: "An attempt was made to add something to storage that exceeded the quota."
                                            //name: "QuotaExceededError"



                                            a.Icon.src = dataURL;

                                            try
                                            {
                                                Native.window.localStorage[new { packageName }] = dataURL;
                                            }
                                            catch (Exception err)
                                            {
                                                Console.WriteLine(new { packageName, error = new { err.Message } });
                                            }
                                        }
                                    );
                                }
                            ).StartTimeout(icon_throttle);
                        };

                        // VirtualDictionary?
                        Native.window.localStorage[new { packageName }].With(
                            dataURL =>
                            {
                                Console.WriteLine("load from localstorage: " + new { packageName });

                                a.Icon.src = dataURL;

                                loadicon = delegate { };
                            }
                        );

                        loadicon();

                        icon_throttle += 900;

                    }
                    #endregion


                    //a.Icon.src = "/icon/" + packageName;

                    //a.Icon.src = "data:image/png;base64," + icon_base64;
                    a.Label.innerText = label;

                    if (yield_BringToFront)
                    {
                        Console.WriteLine("yield_BringToFront " + new { packageName });

                        ScrollArea.insertBefore(a.Container, ScrollArea.firstChild);
                    }
                    else
                    {
                        a.Container.AttachTo(ScrollArea);
                    }


                    //(page.gauge_layer1.style as dynamic).webkitTransition = "-webkit-transform 0.7s ease-in";

                    //-webkit-transition: filter 0.3s linear;
                    __Form __ff = ff;
                    (__ff.HTMLTarget.style as dynamic).webkitTransition = "-webkit-filter 0.7s ease-in";


                    #region onclick
                    Action<bool> onclick =
                        CanAutoLaunch =>
                        {


                            Console.WriteLine(new { label });
                            var content = new windows.ApplicationControl();


                            var f = new Form { Text = label, ShowIcon = false };
                            f.ClientSize = content.Size;

                            f.FormClosed +=
                                delegate
                                {
                                    (__ff.HTMLTarget.style as dynamic).webkitFilter = "blur(0px) brightness(1.0)";
                                };

                            f.Shown += delegate
                            {
                                ;
                                (__ff.HTMLTarget.style as dynamic).webkitFilter = "blur(4px) brightness(0.8)";
                            };

                            f.Show();


                            //FormAsPopupExtensionsForConsoleFormPackage.PopupInsteadOfClosing(
                            //    f,
                            //    HandleFormClosing: false,

                            //    NotifyDocked:
                            //        delegate
                            //        {
                            //            (__ff.HTMLTarget.style as dynamic).webkitFilter = "blur(4px) brightness(0.8)";
                            //        },

                            //        NotifyFloat:
                            //         delegate
                            //         {
                            //             (__ff.HTMLTarget.style as dynamic).webkitFilter = "blur(0px)  brightness(1.0)";
                            //         },
                            //    SpecialCloseOnLeft: delegate
                            //    {
                            //        Console.WriteLine("SpecialCloseOnLeft");

                            //        service.Launch(
                            //            packageName,
                            //            name,
                            //            DisableCallbackToken: "true"
                            //        );

                            //        //f.Close();
                            //    }
                            //);

                            if (CanAutoLaunch && IsCoreAndroidWebServiceActivity)
                            {

                                f.Opacity = 0.5;

                                var w = new WebBrowser();
                                w.Dock = DockStyle.Fill;

                                f.Controls.Add(w);

                                service.Launch(
                                    packageName,
                                    name,

                                    yield_port:
                                    // we should remember the port
                                    // to launch it offline via AppCache
                                        port =>
                                        {
                                            Console.WriteLine(new { port });

                                            // close to left sidebar!
                                            // broken?
                                            //ff.Close();


                                            f.Opacity = 1.0;

                                            var uri = Native.document.location.protocol
                                                + "//"
                                                + Native.document.location.host.TakeUntilIfAny(":")
                                                + ":" + port;

                                            //w.Navigated +=
                                            //    delegate
                                            //    {
                                            //        Console.WriteLine("WebBrowser Navigated " + new { packageName, uri, Abstractatech.JavaScript.FormAsPopup.FormAsPopupExtensionsForConsoleFormPackageMediator.InternalPopupHasFrame });

                                            //        // FormAsPopupExtensionsForConsoleFormPackageMediator

                                            //        if (Abstractatech.JavaScript.FormAsPopup.FormAsPopupExtensionsForConsoleFormPackageMediator.InternalPopupHasFrame)
                                            //        {

                                            //        }
                                            //    };

                                            w.Navigate(uri);

                                            f.ClientSize = content.Size;
                                        }
                                );
                            }
                            else
                            {
                                f.Controls.Add(content);
                                content.Dock = DockStyle.Fill;




                                content.Label.Text = label;
                                content.Package.Text = packageName;

                                //a.Icon.cloneNode(true).AttachTo(

                                //    ScriptCoreLib.JavaScript.Windows.Forms.Extensions.GetHTMLTargetContainer(content.Icon)

                                //);

                                content.Uninstall.Click +=
                                    delegate
                                    {
                                        service.Remove(
                                           packageName,
                                           name
                                        );

                                        //f.Hide();

                                        // http://www.w3schools.com/cssref/pr_text_text-decoration.asp
                                        a.Label.style.textDecoration = "line-through";

                                        f.Close();
                                    };

                                content.Launch.Click +=
                                    delegate
                                    {
                                        // level 1
                                        // run on android

                                        // level 2
                                        // run as float

                                        // level 3 
                                        // run here as iframe

                                        // level 4
                                        // run here as js import

                                        service.Launch(
                                            packageName,
                                            name,

                                            yield_port:
                                                port =>
                                                {
                                                    Console.WriteLine(new { port });
                                                    // close to left sidebar!
                                                    ff.Close();


                                                    var uri = Native.Document.location.protocol
                                                        + "//"
                                                        + Native.Document.location.host.TakeUntilIfAny(":")
                                                        + ":" + port;

                                                    var w = new WebBrowser();

                                                    f.Controls.Add(w);
                                                    w.Dock = DockStyle.Fill;
                                                    w.Navigate(uri);

                                                    f.ClientSize = content.Size;
                                                }
                                        );

                                    };
                            }
                        };
                    #endregion

                    a.Clickable.oncontextmenu +=
                       e =>
                       {
                           e.preventDefault();

                           onclick(false);
                       };

                    a.Clickable.onclick +=
                        e =>
                        {
                            e.preventDefault();

                            onclick(true);
                        };

                };
                #endregion


                #region more
                var skip = 0;
                var take = 32;



                {


                    Action done = delegate { };


                    Action MoveNext = delegate
                    {
                        icon_throttle = 0;

                        //more.disabled = true;
                        //more.innerText = "checking for more...";

                        Console.WriteLine("MoveNext: " + new { skip, take });

                        service.queryIntentActivities(
                            yield,
                            skip: "" + skip,
                            take: "" + take,
                            yield_done: done

                        );


                        //service.File_list("",
                        //    ydirectory: ydirectory,
                        //    yfile: yfile,
                        //    sskip: skip.ToString(),
                        //    stake: take.ToString(),
                        //    done: done
                        //);

                        skip += take;

                    };

                    done = delegate
                    {
                        //more.innerText = getmore;
                        //more.disabled = false;

                        if (count == skip)
                        {
                            //Native.Document.body.With(
                            //     body =>
                            //     {
                            //         if (more.disabled)
                            //             return;

                            //         if (body.scrollHeight - 1 <= Native.Window.Height + body.scrollTop)
                            //         {
                            MoveNext();
                            //          }

                            //      }
                            //);
                        }
                        else
                        {
                            //finish();
                            yield_BringToFront = true;

                            service.oninstall(yield);

                        }
                    };



                    MoveNext();

                    //more.onclick += delegate
                    //{
                    //    MoveNext();
                    //};



                    //Native.Window.onscroll +=
                    //      e =>
                    //      {

                    //          Native.Document.body.With(
                    //              body =>
                    //              {
                    //                  if (more.disabled)
                    //                      return;

                    //                  if (body.scrollHeight - 1 <= Native.Window.Height + body.scrollTop)
                    //                  {
                    //                      MoveNext();
                    //                  }

                    //              }
                    //        );

                    //      };
                }
                //);
                #endregion


            }
示例#11
0
        /// <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)
        {
            //content.AttachControlTo(page.Content);
            //content.AutoSizeControlTo(page.ContentSize);

            FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat;

            // I want animated background!
            new WebGLClouds.Application();

            //Native.Document.body.lastChild.MoveNodeToFirst();

            var f = new Form();

            content.BackColor = Color.Transparent;
            content.Dock = DockStyle.Fill;
            content.AttachTo(f);

            f.Show();


            @"Hello world".ToDocumentTitle();
            // Send data from JavaScript to the server tier
            service.WebMethod2(
                @"A string from JavaScript.",
                value => value.ToDocumentTitle()
            );


            Action ResizeMargin = delegate
            {
                if (f.GetHTMLTarget().parentNode == null)
                    Native.Document.body.style.marginLeft = 16 + "px";
                else
                    Native.Document.body.style.marginLeft = (f.Width + 32) + "px";
            };

            Action AtResize = delegate
            {
                ResizeMargin();

                f.MoveTo(16, 16);
                f.SizeTo(
                    f.Width,
                    f.Height.Min(Native.window.Height - 32)
                );
            };

            // why this not working?
            //f.SizeChanged +=
            content.ClientSizeChanged +=
                delegate
                {
                    ResizeMargin();
                };


            //new ScriptCoreLib.JavaScript.Runtime.Timer(
            //    delegate
            //    {

            //    }
            //).StartInterval();

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

            AtResize();


            f.PopupInsteadOfClosing(SpecialNoMovement: true);
        }