Example #1
0
        /// <summary>
        /// performs a regular GetAll of T, where T is IHasDependencyOf THasA, sorted by the Dependency
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="THasA"></typeparam>
        /// <param name="store"></param>
        public static List <T> GetAllHasADependency <T, THasA>(this ISearchableStore store)
            where T : IHasId, IHasDependencyOf <THasA>
        {
            if (store == null)
            {
                return(null);
            }

            var list = store.GetAll <T>();

            List <IHasDependencyOf <THasA> > depList = new List <IHasDependencyOf <THasA> >();

            list.WithEach(x =>
            {
                depList.Add(x);
            });

            //sort deplist
            depList = DependencyUtil.SortHasADependencies(depList);


            //convert to T
            List <T> returnValue = new List <T>();

            depList.WithEach(x =>
            {
                returnValue.Add((T)x);
            });

            return(returnValue);
        }
Example #2
0
 /// <summary>
 /// copies items between stores
 /// </summary>
 /// <param name="store"></param>
 /// <param name="storeToMoveTo"></param>
 /// <param name="itemsToMove"></param>
 public static void CopyItems(this IStore store, IStore storeToMoveTo, List<StoredObjectId> itemsToMove)
 {
     itemsToMove.WithEach(x =>
     {
         CopyItem(store, storeToMoveTo, x);
     });
 }
Example #3
0
 /// <summary>
 /// copies items between stores
 /// </summary>
 /// <param name="store"></param>
 /// <param name="storeToMoveTo"></param>
 /// <param name="itemsToMove"></param>
 public static void CopyItems(this IStore store, IStore storeToMoveTo, List <StoredObjectId> itemsToMove)
 {
     itemsToMove.WithEach(x =>
     {
         CopyItem(store, storeToMoveTo, x);
     });
 }
Example #4
0
        /// <summary>
        /// splits items out from a store and creates a new store for them
        /// </summary>
        /// <param name="store"></param>
        /// <param name="itemsToRemove"></param>
        public static NaturalInMemoryStore SplitFromStore(this IStore store, List <StoredObjectId> itemsToRemove)
        {
            if (store == null)
            {
                return(null);
            }

            if (itemsToRemove == null || itemsToRemove.Count == 0)
            {
                return(null);
            }

            NaturalInMemoryStore returnValue = new NaturalInMemoryStore();

            itemsToRemove.WithEach(x =>
            {
                var item = store.Get(x);
                if (item != null)
                {
                    //move the item from one store to the other
                    returnValue.SaveItem(item);
                    store.DeleteItem(item.GetStoredObjectId());
                }
            });

            return(returnValue);
        }
Example #5
0
        public virtual List <T> Search <T>(SearchFilter filter) where T : IHasId
        {
            Condition.Requires(filter).IsNotNull();

            List <T> returnValue = new List <T>();
            Type     filterType  = typeof(T);

            //lock and retrieve the values
            List <IHasId> vals = this.SearchStrategy(filter);

            vals.WithEach(x =>
            {
                //if the item is the wrong type, skip it
                var type = x.GetType();
                if (filterType.IsAssignableFrom(type))
                {
                    if (filter.Filter((T)x))
                    {
                        returnValue.Add((T)x);
                    }
                }
            });

            return(returnValue);
        }
Example #6
0
 public ICommitBag MarkItemsSaved(List<IHasId> objs)
 {
     objs.WithEach(x =>
     {
         this.MarkItemSaved(x);
     });
     return this;
 }
Example #7
0
 public ICommitBag MarkItemsSaved(List <IHasId> objs)
 {
     objs.WithEach(x =>
     {
         this.MarkItemSaved(x);
     });
     return(this);
 }
Example #8
0
 public ICommitBag MarkItemsDeleted(List <StoredObjectId> objs)
 {
     objs.WithEach(x =>
     {
         this.MarkItemDeleted(x);
     });
     return(this);
 }
Example #9
0
        /// <summary>
        /// with a list of dependencies and a dependency,return all it depends on, sorted from least dependent to most.
        /// Note: it just returns the exact dependency tree for the rootDep, and does not include any dependencies that
        /// are less dependant within the provided set.
        /// </summary>
        /// <param name="alldeps"></param>
        /// <param name="rootDep"></param>
        /// <returns></returns>
        public static List <NamedDependency> GetSortedDependencies(List <NamedDependency> alldeps, NamedDependency rootDep)
        {
            //if we have no dependencies, carry on
            if (rootDep.Prerequisites == null || rootDep.Prerequisites.Count == 0)
            {
                return(null);
            }

            //define strategy to find dependencies with the provided names
            Func <List <string>, List <NamedDependency> > lookupDeps = (depNames) =>
            {
                return(alldeps.Filter((nd) =>
                {
                    return depNames.Contains(nd.Self);
                }));
            };

            //walk the dependency starting at the root dependency
            List <NamedDependency> depTree  = new List <NamedDependency>();      //tree to build
            List <NamedDependency> iterDeps = lookupDeps(rootDep.Prerequisites); //temp iterator

            while (iterDeps != null && iterDeps.Count > 0)
            {
                List <string> nextDeps = new List <string>();

                iterDeps.WithEach(dep =>
                {
                    //add to tree if it hasn't happened
                    if (depTree.Exists(x => x.Self == dep.Self))
                    {
                        depTree.Add(dep);

                        //aggregate the next deps to iterate on
                        nextDeps.AddRange(dep.Prerequisites);
                    }
                });

                //iterate
                iterDeps = lookupDeps(nextDeps);
            }

            //now sort this limited set using the regular sort routine
            var sortedDeps = Sort(depTree);

            //build the return list
            List <NamedDependency> returnValue = new List <NamedDependency>();

            sortedDeps.WithEach(key =>
            {
                var depInstance = depTree.SingleOrDefault(x => x.Self == key.Self);
                if (depInstance != null)
                {
                    returnValue.Add(depInstance);
                }
            });
            return(returnValue);
        }
Example #10
0
        /// <summary>
        /// examines all eviction conditions and removes items that have an eviction condition of true.
        /// If an item's eviction condition is mutable, it will be mutated (eg. touched) on every get
        /// </summary>
        public void Evict()
        {
            List <ContextualIHasIdDecoration> itemsToEvict = new List <ContextualIHasIdDecoration>();

            //search the eviction store for evicts
            var evictions = this.ExpirableStore.GetAll();

            foreach (var each in evictions)
            {
                var eachItem = each as ContextualIHasIdDecoration;
                if (eachItem != null && eachItem.Context != null)
                {
                    IExpirable exp = eachItem.Context as IExpirable;
                    if (exp.IsExpired())
                    {
                        itemsToEvict.Add(eachItem);
                    }
                }
            }

            //build deletes and commit them
            var mainCommitBag = new CommitBag();
            var expCommitBag  = new CommitBag();

            itemsToEvict.WithEach(x =>
            {
                StoredObjectId soid = x.Id as StoredObjectId;
                mainCommitBag.MarkItemDeleted(soid);
                expCommitBag.MarkItemDeleted(x.GetStoredObjectId());
            });

            //remove the item specified by the expirable policy.
            this.Commit(mainCommitBag);

            //now delete from the expiry store
            this.ExpirableStore.Commit(expCommitBag);

            //raise events (outside of state lock)
            itemsToEvict.WithEach(x =>
            {
                this.OnItemEvicted(x, x.Context as IExpirable);
            });
        }
Example #11
0
        public static List <TestOfResult> Test <T>(T item, List <ITestOf <T> > tests)
        {
            List <TestOfResult> rv = new List <TestOfResult>();

            tests.WithEach((test) =>
            {
                rv.Add(Test(item, test));
            });
            return(rv);
        }
Example #12
0
        public static string DehydrateList(List <IHasId> list)
        {
            StringBuilder sb = new StringBuilder();

            list.WithEach(x =>
            {
                sb.AppendLine(Dehydrate(x));
            });
            return(sb.ToString());
        }
Example #13
0
        public static List<TConverted> ConvertListTo<TConverted, TFrom>(this List<TFrom> list)
        {
            List<TConverted> returnValue = new List<TConverted>();

            list.WithEach(x =>
            {
                returnValue.Add(x.ConvertTo<TConverted>());
            });

            return returnValue;
        }
Example #14
0
        public DependencyDecoration(IOperation decorated, List <string> prerequisiteOperationIds)
            : base(decorated)
        {
            //we can only have one dependency decoration per cake
            if (decorated.HasDecoration <DependencyDecoration>())
            {
                throw new InvalidOperationException("already decorated");
            }

            this.Dependency = new DependencyOf <string>(this.Id);
            prerequisiteOperationIds.WithEach(x => { this.Dependency.Prerequisites.Add(x); });
        }
        /// <summary>
        /// sorts types that are decorated with DependencyAttribute.  If the type does not have a DependencyAttribute
        /// with the provided classification, it is returned at the beginning (least dependent) of the list with a null dependency.
        /// </summary>
        /// <param name="types"></param>
        /// <returns></returns>
        public static List <Tuple <Type, NamedDependency> > GetAttributeAndSort(List <Type> types, string dependencyName)
        {
            //build type map and dep list
            List <Tuple <Type, NamedDependency> > returnValue = new List <Tuple <Type, NamedDependency> >();

            Dictionary <string, Type>          depName2Type = new Dictionary <string, Type>();
            Dictionary <Type, NamedDependency> type2dep     = new Dictionary <Type, NamedDependency>();
            List <NamedDependency>             deps         = new List <NamedDependency>();

            types.WithEach(type =>
            {
                //build it
                var dep = BuildNamedDependencyFromTypeAttributes(type, dependencyName);

                //add to type2dep
                type2dep[type] = dep;

                //add to depName2Type if there is a dep
                if (dep != null)
                {
                    deps.Add(dep);

                    //register the type's dependency by self name
                    depName2Type[dep.Self] = type;
                }
            });

            //sort the deps, get the names back
            var stringDeps = NamedDependency.Sort(deps);

            stringDeps.WithEach(depName =>
            {
                //with the dep name, look in the map to get the type
                var type = depName2Type[depName.Self];
                //using the type, get the dep itself
                var dep = type2dep[type];

                returnValue.Add(new Tuple <Type, NamedDependency>(type, dep));
            });

            //now prepend list with types that have no dependency
            var depTypes   = depName2Type.Values.ToList();
            var noDepTypes = types.Where(type => depTypes.Contains(type) == false);

            noDepTypes.WithEach(type =>
            {
                returnValue.Insert(0, new Tuple <Type, NamedDependency>(type, null));
            });
            return(returnValue);
        }
Example #16
0
        /// <summary>
        /// takes a list of dependencies and returns them sorted from least dependent to most
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="deps"></param>
        /// <returns></returns>
        public static List <T> Sort(List <DependencyOf <T> > deps)
        {
            List <T> returnValue = new List <T>();

            DependencySorter <T> sorter = new DependencySorter <T>();

            List <T> items = new List <T>();

            deps.WithEach(dep =>
            {
                items.Add(dep.Self);
            });
            sorter.AddObjects(items.ToArray());

            deps.WithEach(dep =>
            {
                sorter.SetDependencies(dep.Self, dep.Prerequisites.ToArray());
            });

            returnValue = sorter.Sort().ToList();

            return(returnValue);
        }
Example #17
0
        public static void SaveItemsIfUniqueElseThrow(this IStore store, List<IHasId> objs)
        {
            if (store == null)
                return;

            objs.WithEach(obj =>
            {
                //throw if the item exists
                var dup = store.Get(obj.GetStoredObjectId());
                if (dup != null)
                    throw new InvalidOperationException("Item already exists " + obj.Id.ToString());
            });

            store.Commit(new CommitBag().MarkItemsSaved(objs));
        }
Example #18
0
        /// <summary>
        /// serializes the list of nodes by dehydrating each node and adding to a delimited string
        /// </summary>
        /// <param name="nodes"></param>
        /// <returns></returns>
        public static string DehydrateNodeList(List <GraphNode> nodes)
        {
            if (nodes == null)
            {
                return(null);
            }

            List <string> lines = new List <string>();

            nodes.WithEach(node =>
            {
                lines.Add(node.GetValue());
            });
            var rv = LengthEncoder.LengthEncodeList(lines.ToArray());

            return(rv);
        }
Example #19
0
        public static Dictionary <Type, List <IHasId> > SplitItemsByType(this List <IHasId> list)
        {
            Dictionary <Type, List <IHasId> > returnValue = new Dictionary <Type, List <IHasId> >();

            list.WithEach(x =>
            {
                Type type = x.GetType();
                if (!returnValue.ContainsKey(type))
                {
                    returnValue.Add(type, new List <IHasId>());
                }

                returnValue[type].Add(x);
            });

            return(returnValue);
        }
Example #20
0
        public DependencyDecoration(ITask decorated, List <string> prerequisiteTaskIds)
            : base(decorated.Triggered())
        {
            //^^^^ notice how we have applied the trigger decoration in the base CTOR.  this gives us conditions to add our dependency to

            //we can only have one dependency decoration per cake
            if (decorated.HasDecoration <DependencyDecoration>())
            {
                throw new InvalidOperationException("already decorated");
            }

            this.Dependency = new DependencyOf <string>(this.Id);
            prerequisiteTaskIds.WithEach(x => { this.Dependency.Prerequisites.Add(x); });

            //wire the dependency condition
            this.PerformTrigger.AppendAnd(StrategizedCondition.New((() => { return(this.AreAllPrerequisiteTasksComplete()); })));
            this.CancelTrigger.AppendAnd(StrategizedCondition.New((() => { return(this.AreAnyPrerequisiteTasksCancelledOrErrored()); })));
        }
Example #21
0
        public static Type FindTypeByName(this List <Type> types, string typeName)
        {
            if (types != null && types.Count > 0)
            {
                foreach (var each in types)
                {
                    if (each.Name == typeName)
                    {
                    }
                }
            }
            return(null);

            types.WithEach(x =>
            {
            }, (x) =>
            {
            });
        }
Example #22
0
        public static void SaveItemsIfUniqueElseThrow(this IStore store, List <IHasId> objs)
        {
            if (store == null)
            {
                return;
            }

            objs.WithEach(obj =>
            {
                //throw if the item exists
                var dup = store.Get(obj.GetStoredObjectId());
                if (dup != null)
                {
                    throw new InvalidOperationException("Item already exists " + obj.Id.ToString());
                }
            });

            store.Commit(new CommitBag().MarkItemsSaved(objs));
        }
Example #23
0
        public virtual List <IHasId> Search(LogicOfTo <IHasId, bool> filter)
        {
            Condition.Requires(filter).IsNotNull();

            List <IHasId> returnValue = new List <IHasId>();

            //#if DEBUG
            //            Debug.WriteLine(string.Format("Id:{0}  Thread:{1}  Type:{2} Store search starts", (this as IHasId).With(o => o.Id).With(o => o.ToString()), Thread.CurrentThread.ManagedThreadId, this.GetType().FullName));
            //#endif

            //lock and retrieve the values
            List <IHasId> vals = new List <IHasId>();

            lock (this._stateLock)
            {
                vals.AddRange(this.Dictionary.Values);
            }

            vals.WithEach(x =>
            {
                //if the item is the wrong type, skip it
                LogicOfTo <IHasId, bool> logic = filter.Perform(x) as LogicOfTo <IHasId, bool>;
                if (logic.Result)
                {
                    returnValue.Add(x);
                }
            });

            //#if DEBUG
            //            returnValue.WithEach(x =>
            //            {
            //                Debug.WriteLine(string.Format("Id:{0}  Thread:{1}  Type:{2} Store search returns {3}", (this as IHasId).With(o => o.Id).With(o => o.ToString()), Thread.CurrentThread.ManagedThreadId, this.GetType().FullName, x.GetStoredObjectId().ToString()));
            //            });
            //            Debug.WriteLine(string.Format("Id:{0}  Thread:{1}  Type:{2} Store search ends", (this as IHasId).With(o => o.Id).With(o => o.ToString()), Thread.CurrentThread.ManagedThreadId, this.GetType().FullName));

            //#endif

            return(returnValue);
        }
Example #24
0
        /// <summary>
        /// If an object aggregates (rather than inherits) a dependency, we want to sort on the dependency
        /// but return the object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <returns></returns>
        public static List <IHasDependencyOf <T> > SortHasADependencies <T>(this List <IHasDependencyOf <T> > items)
        {
            List <IHasDependencyOf <T> > returnValue = new List <IHasDependencyOf <T> >();

            //build a dictionary of the HasA, keyed by T, the dependency type
            //build a list of the dependency containers
            Dictionary <T, IHasDependencyOf <T> > map  = new Dictionary <T, IHasDependencyOf <T> >();
            List <IDependencyOf <T> >             deps = new List <IDependencyOf <T> >();

            items.WithEach(x =>
            {
                if (x.Dependency != null)
                {
                    map[x.Dependency.Self] = x; //key each item by the Self dependency value
                    deps.Add(x.Dependency);     //aggregate list of the dependencies themselves (which we will later sort and then pull values from using the keyed map above)
                }
            });

            returnValue = SortDependenciesAndLookupValues <T, IHasDependencyOf <T> >(deps, map);

            return(returnValue);
        }
Example #25
0
        public virtual List<IHasId> Search(LogicOfTo<IHasId, bool> filter)
        {
            Condition.Requires(filter).IsNotNull();

            List<IHasId> returnValue = new List<IHasId>();

            //#if DEBUG
            //            Debug.WriteLine(string.Format("Id:{0}  Thread:{1}  Type:{2} Store search starts", (this as IHasId).With(o => o.Id).With(o => o.ToString()), Thread.CurrentThread.ManagedThreadId, this.GetType().FullName));
            //#endif

            //lock and retrieve the values
            List<IHasId> vals = new List<IHasId>();
            lock (this._stateLock)
            {
                vals.AddRange(this.Dictionary.Values);
            }

            vals.WithEach(x =>
            {
                //if the item is the wrong type, skip it
                LogicOfTo<IHasId, bool> logic = filter.Perform(x) as LogicOfTo<IHasId, bool>;
                if(logic.Result)
                {
                    returnValue.Add(x);
                }
            });

            //#if DEBUG
            //            returnValue.WithEach(x =>
            //            {
            //                Debug.WriteLine(string.Format("Id:{0}  Thread:{1}  Type:{2} Store search returns {3}", (this as IHasId).With(o => o.Id).With(o => o.ToString()), Thread.CurrentThread.ManagedThreadId, this.GetType().FullName, x.GetStoredObjectId().ToString()));
            //            });
            //            Debug.WriteLine(string.Format("Id:{0}  Thread:{1}  Type:{2} Store search ends", (this as IHasId).With(o => o.Id).With(o => o.ToString()), Thread.CurrentThread.ManagedThreadId, this.GetType().FullName));

            //#endif

            return returnValue;
        }
Example #26
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)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                10000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);


            var mouseX = 0;
            var mouseY = 0;
            var st     = new Stopwatch();
            st.Start();


            Native.window.document.onmousemove +=
                e =>
            {
                mouseX = e.CursorX - Native.window.Width / 2;
                mouseY = e.CursorY - Native.window.Height / 2;
            };


            Native.window.onframe +=
                delegate
            {
                oo.WithEach(
                    x =>
                    x.rotation.y = (st.ElapsedMilliseconds + mouseX * 100) * 0.00001
                    );


                camera.position.x += (mouseX - camera.position.x) * .05;
                camera.position.y += (-mouseY - camera.position.y) * .05;

                camera.lookAt(scene.position);

                renderer.render(scene, camera);
            };

            Native.window.onresize +=
                delegate
            {
                camera.aspect = window.aspect;
                camera.updateProjectionMatrix();

                renderer.setSize(window.Width, window.Height);
            };
            #endregion

            // why isnt it being found?
            new global::WebGLColladaExperiment.THREE_ColladaAsset(

                // we get purple small thingy
                "assets/WebGLHeatZeekerColladaExperiment/Promotion3D_daytime.dae"

                // maybe sketchup doesnt know how to export colors?
                //"assets/WebGLHeatZeekerColladaExperiment/sam_site.dae"
                ).Source.Task.ContinueWithResult(
                dae =>
            {
                dae.position.y = -40;
                //dae.position.z = 280;
                scene.add(dae);
                oo.Add(dae);

                dae.scale = new THREE.Vector3(2, 2, 2);
            }
                );
        }
        // http://youtu.be/Lo1IU8UAutE
        // 60hz 2160 4K!

        // The equirectangular projection was used in map creation since it was invented around 100 A.D. by Marinus of Tyre. 

        //        C:\Users\Arvo> "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hzsky.png" "/sdcard/oculus/360photos/"
        //1533 KB/s(3865902 bytes in 2.461s)

        //C:\Users\Arvo> "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hznosky.png" "/sdcard/oculus/360photos/"
        //1556 KB/s(2714294 bytes in 1.703s)

        //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hz2048c3840x2160.png" "/sdcard/oculus/360photos/"



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

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

        // the eye nor the display will be able to do any stereo
        // until tech is near matrix capability. 2019?

        // cubemap can be used for all long range scenes
        // http://www.imdb.com/title/tt0112111/?ref_=nv_sr_1


        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150808/cubemapcamera
        // subst a: s:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360HZ\Chrome360HZ\bin\Debug\staging\Chrome360HZ.Application\web
        // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360HZ\Chrome360HZ\bin\Debug\staging\Chrome360HZ.Application\web

        // ColladaLoader: Empty or non-existing file (assets/Chrome360HZ/S6Edge.dae)

        /// <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 =
            //s =>
            //{
            //    s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

            //    //var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
            //    var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDragWithShadow().AttachTo(s.Context.GetHTMLTarget());



            //    s.Context.GetHTMLTarget().style.backgroundColor = "#efefef";
            //    //s.Context.GetHTMLTarget().style.backgroundColor = "#A26D41";

            //};

#if AsWEBSERVER
            #region += Launched chrome.app.window
            // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

            if (self_chrome_socket != null)
            {
                // if we run as a server. we can open up on android.

                //chrome.Notification.DefaultTitle = "Nexus7";
                //chrome.Notification.DefaultIconUrl = new x128().src;
                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                     AppSource.Text
                //, AtFormCreated: FormStyler.AtFormCreated

                //AtFormConstructor:
                //    f =>
                //    {
                //        //arg[0] is typeof System.Int32
                //        //script: error JSC1000: No implementation found for this native method, please implement [static System.Drawing.Color.FromArgb(System.Int32)]

                //        // X:\jsc.svn\examples\javascript\forms\Test\TestFromArgb\TestFromArgb\ApplicationControl.cs

                //        f.BackColor = System.Drawing.Color.FromArgb(0xA26D41);
                //    }
                );
                return;
            }
            #endregion
#else

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

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

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

                    //};

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

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

                        // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions
                        var xappwindow = await chrome.app.window.create(
                               Native.document.location.pathname, options: new
                               {
                                   alwaysOnTop = true,
                                   visibleOnAllWorkspaces = true
                               }
                        );

                        //xappwindow.setAlwaysOnTop

                        xappwindow.show();

                        await xappwindow.contentWindow.async.onload;

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


                    return;
                }
            }
            #endregion


#endif

            //const int size = 128;
            //const int size = 256; // 6 faces, 12KB
            //const int size = 512; // 6 faces, ?

            // WebGL: drawArrays: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.

            //const int size = 720; // 6 faces, ?
            //const int size = 1024; // 6 faces, ?
            //const int size = 1024; // 6 faces, ?
            //const int cubefacesize = 2048; // 6 faces, ?
            const int cubefacesize = 512; // 6 faces, ?



            var uizoom = 0.05;

            var far = 0xfffff;

            Native.css.style.backgroundColor = "blue";
            Native.css.style.overflow = IStyle.OverflowEnum.hidden;

            Native.body.Clear();

            new IHTMLPre { "can we stream it into VR, shadertoy, youtube 360, youtube stereo yet?" }.AttachToDocument();


            var sw = Stopwatch.StartNew();

            var pause = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox, title = "pause" }.AttachToDocument();


            pause.onchange += delegate
            {

                if ([email protected])
                    sw.Stop();
                else
                    sw.Start();


            };

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

            #region scene
            var window = Native.window;


            // what about physics and that portal rendering?

            // if we are running as a chrome web server, we may also be opened as android ndk webview app
            //var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: window.aspect, near: 1, far: 2000);
            // once we update source
            // save the source
            // manually recompile 
            //cameraPX.position.z = 400;

            //// the camera should be close enough for the object to float off the FOV of PX
            //cameraPX.position.z = 200;

            // scene
            // can we make the 3D object orbit around us ?
            // and
            // stream it to vr?
            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x303030);
            scene.add(ambient);

            // should we fix jsc to do a more correct IDL?
            //var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
            //directionalLight.position.set(0, 0, 1);
            //scene.add(directionalLight);

            #region light
            //var light = new THREE.DirectionalLight(0xffffff, 1.0);
            var light = new THREE.DirectionalLight(0xffffff, 2.5);
            //var light = new THREE.DirectionalLight(0xffffff, 2.5);
            //var light = new THREE.DirectionalLight(0xffffff, 1.5);
            //var lightOffset = new THREE.Vector3(0, 1000, 2500.0);
            var lightOffset = new THREE.Vector3(
                2000,
                700,

                // lower makes longer shadows 
                700.0
                );
            light.position.copy(lightOffset);
            light.castShadow = true;

            var xlight = light as dynamic;
            xlight.shadowMapWidth = 4096;
            xlight.shadowMapHeight = 2048;

            xlight.shadowDarkness = 0.1;
            //xlight.shadowDarkness = 0.5;

            xlight.shadowCameraNear = 10;
            xlight.shadowCameraFar = 10000;
            xlight.shadowBias = 0.00001;
            xlight.shadowCameraRight = 4000;
            xlight.shadowCameraLeft = -4000;
            xlight.shadowCameraTop = 4000;
            xlight.shadowCameraBottom = -4000;

            xlight.shadowCameraVisible = true;

            scene.add(light);
            #endregion




            // whats WebGLRenderTargetCube do?

            // WebGLRenderer preserveDrawingBuffer 



            var renderer0 = new THREE.WebGLRenderer(

                new
                {
                    antialias = true,
                    alpha = true,
                    preserveDrawingBuffer = true
                }
            );

            // https://github.com/mrdoob/three.js/issues/3836

            // the construct. white bg
            renderer0.setClearColor(0xfffff, 1);

            //renderer.setSize(window.Width, window.Height);
            renderer0.setSize(cubefacesize, cubefacesize);

            //renderer0.domElement.AttachToDocument();
            //rendererPX.domElement.style.SetLocation(0, 0);
            //renderer0.domElement.style.SetLocation(4, 4);


            // top

            // http://stackoverflow.com/questions/27612524/can-multiple-webglrenderers-render-the-same-scene


            // need a place to show the cubemap face to GUI 
            // how does the stereo OTOY do it?
            // https://www.opengl.org/wiki/Sampler_(GLSL)

            // http://www.richardssoftware.net/Home/Post/25

            // [+X, –X, +Y, –Y, +Z, –Z] fa



            // move up
            //camera.position.set(-1200, 800, 1200);
            //var cameraoffset = new THREE.Vector3(0, 15, 0);
            var cameraoffset = new THREE.Vector3(-1200, 800, 1200);

            #region y
            // need to rotate90?
            var cameraNY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraNY.lookAt(new THREE.Vector3(0, -1, 0));
            cameraNY.position.add(cameraoffset);

            //cameraNY.lookAt(new THREE.Vector3(0, 1, 0));
            var canvasNY = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNY.canvas.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 2);
            canvasNY.canvas.title = "NY";
            canvasNY.canvas.AttachToDocument();
            canvasNY.canvas.style.transformOrigin = "0 0";
            canvasNY.canvas.style.transform = "scale(" + uizoom + ")";

            var cameraPY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraPY.lookAt(new THREE.Vector3(0, 1, 0));
            cameraPY.position.add(cameraoffset);
            //cameraPY.lookAt(new THREE.Vector3(0, -1, 0));
            var canvasPY = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPY.canvas.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 0);
            canvasPY.canvas.title = "PY";
            canvasPY.canvas.AttachToDocument();
            canvasPY.canvas.style.transformOrigin = "0 0";
            canvasPY.canvas.style.transform = "scale(" + uizoom + ")";
            #endregion

            // transpose xz?

            #region x
            var cameraNX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraNX.lookAt(new THREE.Vector3(0, 0, 1));
            cameraNX.position.add(cameraoffset);
            //cameraNX.lookAt(new THREE.Vector3(0, 0, -1));
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNX.lookAt(new THREE.Vector3(1, 0, 0));
            var canvasNX = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNX.canvas.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 2, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasNX.canvas.title = "NX";
            canvasNX.canvas.AttachToDocument();
            canvasNX.canvas.style.transformOrigin = "0 0";
            canvasNX.canvas.style.transform = "scale(" + uizoom + ")";

            var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraPX.lookAt(new THREE.Vector3(0, 0, -1));
            cameraPX.position.add(cameraoffset);
            //cameraPX.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPX.lookAt(new THREE.Vector3(1, 0, 0));
            //cameraPX.lookAt(new THREE.Vector3(-1, 0, 0));
            var canvasPX = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPX.canvas.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 0, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasPX.canvas.title = "PX";
            canvasPX.canvas.AttachToDocument();
            canvasPX.canvas.style.transformOrigin = "0 0";
            canvasPX.canvas.style.transform = "scale(" + uizoom + ")";
            #endregion



            #region z
            var cameraNZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, -1));
            cameraNZ.lookAt(new THREE.Vector3(1, 0, 0));
            cameraNZ.position.add(cameraoffset);
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, 1));
            var canvasNZ = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNZ.canvas.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 3, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasNZ.canvas.title = "NZ";
            canvasNZ.canvas.AttachToDocument();
            canvasNZ.canvas.style.transformOrigin = "0 0";
            canvasNZ.canvas.style.transform = "scale(" + uizoom + ")";

            var cameraPZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraPZ.lookAt(new THREE.Vector3(1, 0, 0));
            cameraPZ.lookAt(new THREE.Vector3(-1, 0, 0));
            cameraPZ.position.add(cameraoffset);
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, -1));
            var canvasPZ = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPZ.canvas.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasPZ.canvas.title = "PZ";
            canvasPZ.canvas.AttachToDocument();
            canvasPZ.canvas.style.transformOrigin = "0 0";
            canvasPZ.canvas.style.transform = "scale(" + uizoom + ")";
            #endregion




            // c++ alias locals would be nice..
            var canvas0 = (IHTMLCanvas)renderer0.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


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

            //canvas0.css.active.style.cursor = IStyle.CursorEnum.move;

            #region onmousedown
            Native.body.onmousedown +=
                async e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                        return;

                    // movementX no longer works
                    old = new
                    {


                        e.CursorX,
                        e.CursorY
                    };


                    //e.CaptureMouse();
                    var release = e.Element.CaptureMouse();
                    await e.Element.async.onmouseup;

                    release();


                };
            #endregion



            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            Native.body.onmousemove +=
                e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                    {
                        Native.body.style.cursor = [email protected];
                        return;
                    }

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


                    Native.body.style.cursor = IStyle.CursorEnum.move;

                    var pointerLock = canvas0 == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion

            // THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(78,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll
            // THREE.WebGLProgram: gl.getProgramInfoLog() (79,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll

            // http://www.roadtovr.com/youtube-confirms-stereo-3d-360-video-support-coming-soon/
            // https://www.youtube.com/watch?v=D-Wl9jAB45Q



            #region spherical
            var gl = new WebGLRenderingContext(alpha: true, preserveDrawingBuffer: true);
            var c = gl.canvas.AttachToDocument();

            //  3840x2160

            //c.style.SetSize(3840, 2160);

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


            c.width = 3840;
            c.height = 2160;


            //c.width = 3840 * 2;
            //c.height = 2160 * 2;


            //c.width = 3840;
            //c.height = 2160;
            // 1,777777777777778

            // https://www.youtube.com/watch?v=fTfJwzRsE-w
            //c.width = 7580;
            //c.height = 3840;
            //1,973958333333333

            //7580
            //    3840

            // wont work
            //c.width = 8192;
            //c.height = 4096;


            // this has the wrong aspect?
            //c.width = 6466;
            //c.height = 3232;

            new IHTMLPre { new { c.width, c.height } }.AttachToDocument();

            //6466x3232

            //var suizoom = 720f / c.height;
            //var suizoom = 360f / c.height;
            var suizoom = 480f / c.width;

            c.style.transformOrigin = "0 0";
            c.style.transform = "scale(" + suizoom + ")";
            c.style.backgroundColor = "yellow";
            c.style.position = IStyle.PositionEnum.absolute;

            c.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 0, 8 + (int)(uizoom * cubefacesize + 8) * 3);

            var pass = new CubeToEquirectangular.Library.ShaderToy.EffectPass(
                       null,
                       gl,
                       precission: CubeToEquirectangular.Library.ShaderToy.DetermineShaderPrecission(gl),
                       supportDerivatives: gl.getExtension("OES_standard_derivatives") != null,
                       callback: null,
                       obj: null,
                       forceMuted: false,
                       forcePaused: false,
                //quadVBO: Library.ShaderToy.createQuadVBO(gl, right: 0, top: 0),
                       outputGainNode: null
                   );

            // how shall we upload our textures?
            // can we reference GLSL.samplerCube yet?
            //pass.mInputs[0] = new samplerCube { };
            pass.mInputs[0] = new CubeToEquirectangular.Library.ShaderToy.samplerCube { };

            pass.MakeHeader_Image();
            var vs = new Shaders.ProgramFragmentShader();
            pass.NewShader_Image(vs);

            #endregion




            //var frame0 = new HTML.Images.FromAssets.tiles_regrid().AttachToDocument();
            var frame0 = new HTML.Images.FromAssets.anvil___spherical_hdri_panorama_skybox_by_macsix_d6vv4hs().AttachToDocument();
            //var xor = new HTML.Images.FromAssets.Orion360_test_image_8192x4096().AttachToDocument();
            //var xor = new HTML.Images.FromAssets._2_no_clouds_4k().AttachToDocument();
            //var frame0 = new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().AttachToDocument();


            // 270px
            //xor.style.height = "";
            frame0.style.height = "270px";
            frame0.style.width = "480px";
            frame0.style.SetLocation(
                8 + (int)(uizoom * cubefacesize + 8) * 0 + 480 + 16, 8 + (int)(uizoom * cubefacesize + 8) * 3);


            var mesh = new THREE.Mesh(new THREE.SphereGeometry(far / 2, 50, 50),
           new THREE.MeshBasicMaterial(new
           {
               map = THREE.ImageUtils.loadTexture(
                   //new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().src
                   //new HTML.Images.FromAssets._4008650304_7f837ccbb7_b().src
                  frame0.src
                   //new WebGLEquirectangularPanorama.HTML.Images.FromAssets.PANO_20130616_222058().src
                   //new WebGLEquirectangularPanorama.HTML.Images.FromAssets.PANO_20121225_210448().src

                   )
           }));
            mesh.scale.x = -1;

            #region fixup rotation

            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI / 2);
            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI / 2);
            mesh.rotateOnAxis(new THREE.Vector3(0, 1, 0), -Math.PI / 2);
            #endregion


            scene.add(mesh);


            //new IHTMLButton { }

            var dir = default(DirectoryEntry);

            new IHTMLButton { "openDirectory" }.AttachToDocument().onclick += async delegate
            {
                dir = (DirectoryEntry)await chrome.fileSystem.chooseEntry(new { type = "openDirectory" });
            };

            frame0.onclick += delegate
            {
                // http://paulbourke.net/papers/vsmm2006/vsmm2006.pdf
                //            A method of creating synthetic stereoscopic panoramic images that can be implemented
                //in most rendering packages has been presented. If single panoramic pairs can be created
                //then stereoscopic panoramic movies are equally possible giving rise to the prospect of
                //movies where the viewer can interact with, at least with regard to what they choose to look
                //at.These images can be projected so as to engage the two features of the human visual
                //system that assist is giving us a sense of immersion, the feeling of “being there”. That is,
                //imagery that contains parallax information as captured from two horizontally separated eye
                //positions (stereopsis)and imagery that fills our peripheral vision.The details that define
                //how the two panoramic images should be created in rendering packages are provided, in
                //particular, how to precisely configure the virtual cameras and control the distance to zero
                //parallax.

                // grab a frame


                var f0 = new IHTMLImage { src = gl.canvas.toDataURL() };

                //var f0 = (IHTMLImage)gl.canvas;
                //var f0 = (IHTMLImage)gl.canvas;
                //var base64 = gl.canvas.toDataURL();


                //frame0.src = base64;
                frame0.src = f0.src;

                // 7MB!

                if (dir == null)
                    return;

                //                // ---------------------------
                //IrfanView
                //---------------------------
                //Warning !
                //The file: "X:\vr\tape1\0001.jpg" is a PNG file with incorrect extension !
                //Rename ?
                //---------------------------
                //Yes   No   
                //---------------------------

                // haha this will render the thumbnail.
                //dir.WriteAllBytes("0000.png", frame0);

                dir.WriteAllBytes("0000.png", f0);
                // 3.7MB
                // 3840x2160

            };



            // "Z:\jsc.svn\examples\javascript\WebGL\WebGLColladaExperiment\WebGLColladaExperiment\WebGLColladaExperiment.csproj"

            #region WebGLRah66Comanche
            // why isnt it being found?
            // "Z:\jsc.svn\examples\javascript\WebGL\collada\WebGLRah66Comanche\WebGLRah66Comanche\WebGLRah66Comanche.csproj"
            new global::WebGLRah66Comanche.Comanche(
            ).Source.Task.ContinueWithResult(
                dae =>
                {

                    //dae.position.y = -40;
                    //dae.position.z = 280;
                    scene.add(dae);
                    //oo.Add(dae);

                    // wont do it
                    //dae.castShadow = true;

                    dae.children[0].children[0].children.WithEach(x => x.castShadow = true);


                    // the rotors?
                    dae.children[0].children[0].children.Last().children.WithEach(x => x.castShadow = true);


                    dae.scale.set(0.5, 0.5, 0.5);
                    dae.position.x = -900;
                    dae.position.z = +900;

                    // raise it up
                    dae.position.y = 400;

                    //var sw = Stopwatch.StartNew();

                    //Native.window.onframe += delegate
                    //{
                    //    //dae.children[0].children[0].children.Last().al
                    //    //dae.children[0].children[0].children.Last().rotation.z = sw.ElapsedMilliseconds * 0.01;
                    //    //dae.children[0].children[0].children.Last().rotation.x = sw.ElapsedMilliseconds * 0.01;
                    //    dae.children[0].children[0].children.Last().rotation.y = sw.ElapsedMilliseconds * 0.01;
                    //};
                }
            );
            #endregion



            #region tree
            // "Z:\jsc.svn\examples\javascript\WebGL\WebGLGodRay\WebGLGodRay\WebGLGodRay.csproj"

            var materialScene = new THREE.MeshBasicMaterial(new { color = 0x000000, shading = THREE.FlatShading });
            var tloader = new THREE.JSONLoader();

            // http://stackoverflow.com/questions/16539736/do-not-use-system-runtime-compilerservices-dynamicattribute-use-the-dynamic
            // https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.dynamicattribute%28v=vs.110%29.aspx
            //System.Runtime.CompilerServices.DynamicAttribute

            tloader.load(

                new WebGLGodRay.Models.tree().Content.src,

                new Action<THREE.Geometry>(
                xgeometry =>
                {

                    var treeMesh = new THREE.Mesh(xgeometry, materialScene);
                    treeMesh.position.set(0, -150, -150);
                    treeMesh.position.x = -900;
                    treeMesh.position.z = -900;

                    treeMesh.position.y = 25;

                    var tsc = 400;
                    treeMesh.scale.set(tsc, tsc, tsc);

                    treeMesh.matrixAutoUpdate = false;
                    treeMesh.updateMatrix();


                    treeMesh.AttachTo(scene);

                }
                )
                );
            #endregion

            #region create field

            // THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint.

            // could we get some film grain?
            var planeGeometry = new THREE.CubeGeometry(512, 512, 1);
            var plane = new THREE.Mesh(planeGeometry,
                    new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })

                );
            //plane.castShadow = false;
            plane.receiveShadow = true;


            {

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

                scene.add(parent);
            }

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

            for (var i = 3; i < 9; i++)
            {

                //THREE.MeshPhongMaterial
                var ii = new THREE.Mesh(geometry,


                    new THREE.MeshPhongMaterial(new { ambient = 0x000000, color = 0xA06040, specular = 0xA26D41, shininess = 1 })

                    //new THREE.MeshLambertMaterial(
                    //new
                    //{
                    //    color = (Convert.ToInt32(0xffffff * random.NextDouble())),
                    //    specular = 0xffaaaa,
                    //    ambient= 0x050505, 
                    //})

                    );
                ii.position.x = i % 7 * 200 - 2.5f;

                // raise it up
                ii.position.y = .5f * 100;
                ii.position.z = -1 * i * 100;
                ii.castShadow = true;
                ii.receiveShadow = true;
                //ii.scale.set(100, 100, 100 * i);
                ii.scale.set(100, 100 * i, 100);


                meshArray.Add(ii);

                scene.add(ii);

                if (i % 2 == 0)
                {
#if FWebGLHZBlendCharacter
                    #region SpeedBlendCharacter
					var _i = i;
					{ WebGLHZBlendCharacter.HTML.Pages.TexturesImages ref0; }

					var blendMesh = new THREE.SpeedBlendCharacter();
					blendMesh.load(
						new WebGLHZBlendCharacter.Models.marine_anims().Content.src,
						new Action(
							delegate
							{
								// buildScene
								//blendMesh.rotation.y = Math.PI * -135 / 180;
								blendMesh.castShadow = true;
								// we cannot scale down we want our shadows
								//blendMesh.scale.set(0.1, 0.1, 0.1);

								blendMesh.position.x = (_i + 2) % 7 * 200 - 2.5f;

								// raise it up
								//blendMesh.position.y = .5f * 100;
								blendMesh.position.z = -1 * _i * 100;


								var xtrue = true;
								// run
								blendMesh.setSpeed(1.0);

								// will in turn call THREE.AnimationHandler.play( this );
								//blendMesh.run.play();
								// this wont help. bokah does not see the animation it seems.
								//blendMesh.run.update(1);

								blendMesh.showSkeleton(!xtrue);

								scene.add(blendMesh);


								Native.window.onframe +=
								 delegate
								 {

									 blendMesh.rotation.y = Math.PI * 0.0002 * sw.ElapsedMilliseconds;



									 ii.rotation.y = Math.PI * 0.0002 * sw.ElapsedMilliseconds;

								 };

							}
						)
					);
                    #endregion
#endif
                }

            }
            #endregion


            #region HZCannon
            // "Z:\jsc.svn\examples\javascript\WebGL\HeatZeekerRTSOrto\HeatZeekerRTSOrto\HeatZeekerRTSOrto.csproj"
            new HeatZeekerRTSOrto.HZCannon().Source.Task.ContinueWithResult(
                async cube =>
                {
                    // https://github.com/mrdoob/three.js/issues/1285
                    //cube.children.WithEach(c => c.castShadow = true);

                    //cube.traverse(
                    //    new Action<THREE.Object3D>(
                    //        child =>
                    //        {
                    //            // does it work? do we need it?
                    //            //if (child is THREE.Mesh)

                    //            child.castShadow = true;
                    //            //child.receiveShadow = true;

                    //        }
                    //    )
                    //);

                    // um can edit and continue insert code going back in time?
                    cube.scale.x = 10.0;
                    cube.scale.y = 10.0;
                    cube.scale.z = 10.0;



                    //cube.castShadow = true;
                    //dae.receiveShadow = true;

                    //cube.position.x = -100;

                    ////cube.position.y = (cube.scale.y * 50) / 2;
                    //cube.position.z = Math.Floor((random() * 1000 - 500) / 50) * 50 + 25;



                    // if i want to rotate, how do I do it?
                    //cube.rotation.z = random() + Math.PI;
                    //cube.rotation.x = random() + Math.PI;
                    var sw2 = Stopwatch.StartNew();



                    scene.add(cube);
                    //interactiveObjects.Add(cube);

                    // offset is wrong
                    //while (true)
                    //{
                    //    await Native.window.async.onframe;

                    //    cube.rotation.y = Math.PI * 0.0002 * sw2.ElapsedMilliseconds;

                    //}
                }
            );
            #endregion


            #region HZCannon
            new HeatZeekerRTSOrto.HZCannon().Source.Task.ContinueWithResult(
                async cube =>
                {
                    // https://github.com/mrdoob/three.js/issues/1285
                    //cube.children.WithEach(c => c.castShadow = true);

                    //cube.traverse(
                    //    new Action<THREE.Object3D>(
                    //        child =>
                    //        {
                    //            // does it work? do we need it?
                    //            //if (child is THREE.Mesh)

                    //            child.castShadow = true;
                    //            //child.receiveShadow = true;

                    //        }
                    //    )
                    //);

                    // um can edit and continue insert code going back in time?
                    cube.scale.x = 10.0;
                    cube.scale.y = 10.0;
                    cube.scale.z = 10.0;



                    //cube.castShadow = true;
                    //dae.receiveShadow = true;


                    // jsc shat about out of band code patching?
                    cube.position.z = 600;
                    cube.position.x = -900;
                    //cube.position.y = -400;

                    //cube.position.x = -100;
                    //cube.position.y = -400;

                    ////cube.position.y = (cube.scale.y * 50) / 2;
                    //cube.position.z = Math.Floor((random() * 1000 - 500) / 50) * 50 + 25;



                    // if i want to rotate, how do I do it?
                    //cube.rotation.z = random() + Math.PI;
                    //cube.rotation.x = random() + Math.PI;
                    var sw2 = Stopwatch.StartNew();



                    scene.add(cube);
                    //interactiveObjects.Add(cube);

                    // offset is wrong
                    //while (true)
                    //{
                    //    await Native.window.async.onframe;

                    //    cube.rotation.y = Math.PI * 0.0002 * sw2.ElapsedMilliseconds;

                    //}
                }
            );
            #endregion


            #region HZBunker
            new HeatZeekerRTSOrto.HZBunker().Source.Task.ContinueWithResult(
                     cube =>
                     {
                         // https://github.com/mrdoob/three.js/issues/1285
                         //cube.children.WithEach(c => c.castShadow = true);
                         cube.castShadow = true;

                         //cube.traverse(
                         //    new Action<THREE.Object3D>(
                         //        child =>
                         //        {
                         //            // does it work? do we need it?
                         //            //if (child is THREE.Mesh)
                         //            child.castShadow = true;
                         //            //child.receiveShadow = true;

                         //        }
                         //    )
                         //);

                         // um can edit and continue insert code going back in time?
                         cube.scale.x = 10.0;
                         cube.scale.y = 10.0;
                         cube.scale.z = 10.0;

                         //cube.castShadow = true;
                         //dae.receiveShadow = true;

                         cube.position.x = -1000;
                         //cube.position.y = (cube.scale.y * 50) / 2;
                         cube.position.z = 0;

                         scene.add(cube);
                     }
                 );
            #endregion


            new Models.ColladaS6Edge().Source.Task.ContinueWithResult(
                   dae =>
                   {
                       // 90deg
                       dae.rotation.x = -Math.Cos(Math.PI);

                       //dae.scale.x = 30;
                       //dae.scale.y = 30;
                       //dae.scale.z = 30;
                       dae.position.z = -(65 - 200);





                       var scale = 0.9;

                       // jsc, do we have ILObserver available yet?
                       dae.scale.x = scale;
                       dae.scale.y = scale;
                       dae.scale.z = scale;


                       #region onmousewheel
                       Native.body.onmousewheel +=
                           e =>
                           {
                               e.preventDefault();

                               //camera.position.z = 1.5;

                               // min max. shall adjust speed also!
                               // max 4.0
                               // min 0.6
                               dae.position.z -= 10.0 * e.WheelDirection;

                               //camera.position.z = 400;
                               //dae.position.z = dae.position.z.Max(-200).Min(200);

                               //Native.document.title = new { z }.ToString();

                           };
                       #endregion


                       //dae.position.y = -80;

                       scene.add(dae);
                       oo.Add(dae);




                       // view-source:http://threejs.org/examples/webgl_multiple_canvases_circle.html
                       // https://threejsdoc.appspot.com/doc/three.js/src.source/extras/cameras/CubeCamera.js.html
                       Native.window.onframe +=
                           e =>
                           {
                               //if (pause) return;
                               //if ([email protected])
                               //    return;


                               // can we float out of frame?
                               // haha. a bit too flickery.
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.01) * 50.0;
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.001) * 190.0;
                               dae.position.x = Math.Sin(sw.ElapsedMilliseconds * 0.0001) * 190.0;
                               dae.position.y = Math.Cos(sw.ElapsedMilliseconds * 0.0001) * 90.0;
                               // manual rebuild?
                               // red compiler notifies laptop chrome of pending update
                               // app reloads


                               renderer0.clear();
                               //rendererPY.clear();

                               //cameraPX.aspect = canvasPX.aspect;
                               //cameraPX.updateProjectionMatrix();

                               // um what does this do?
                               //cameraPX.position.z += (z - cameraPX.position.z) * e.delay.ElapsedMilliseconds / 200.0;
                               // mousewheel allos the camera to move closer
                               // once we see the frame in vr, can we udp sync vr tracking back to laptop?


                               //this.targetPX.x += 1;
                               //this.targetNX.x -= 1;

                               //this.targetPY.y += 1;
                               //this.targetNY.y -= 1;

                               //this.targetPZ.z += 1;
                               //this.targetNZ.z -= 1;

                               // how does the 360 or shadertoy want our cubemaps?


                               // and then rotate right?

                               // how can we render cubemap?


                               #region x
                               // upside down?
                               renderer0.render(scene, cameraPX);
                               canvasPX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);

                               renderer0.render(scene, cameraNX);
                               canvasNX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               #endregion

                               #region z
                               renderer0.render(scene, cameraPZ);
                               canvasPZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);

                               renderer0.render(scene, cameraNZ);
                               canvasNZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               #endregion



                               #region y
                               renderer0.render(scene, cameraPY);

                               //canvasPY.save();
                               //canvasPY.translate(0, size);
                               //canvasPY.rotate((float)(-Math.PI / 2));
                               canvasPY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               //canvasPY.restore();


                               renderer0.render(scene, cameraNY);
                               //canvasNY.save();
                               //canvasNY.translate(size, 0);
                               //canvasNY.rotate((float)(Math.PI / 2));
                               canvasNY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               //canvasNY.restore();
                               // ?
                               #endregion


                               //renderer0.render(scene, cameraPX);


                               //rendererPY.render(scene, cameraPY);

                               // at this point we should be able to render the sphere texture

                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_X = 34069;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_X = 34070;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Y = 34071;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Z = 34073;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074;


                               //var cube0 = new IHTMLImage[] {
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_px(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nx(),

                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_py(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_ny(),


                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_pz(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nz()
                               //};

                               new[] {
                                   canvasPX, canvasNX,
                                   canvasPY, canvasNY,
                                   canvasPZ, canvasNZ
                               }.WithEachIndex(
                                   (img, index) =>
                                   {
                                       gl.bindTexture(gl.TEXTURE_CUBE_MAP, pass.tex);

                                       //gl.pixelStorei(gl.UNPACK_FLIP_X_WEBGL, false);
                                       gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);

                                       // http://stackoverflow.com/questions/15364517/pixelstoreigl-unpack-flip-y-webgl-true

                                       // https://msdn.microsoft.com/en-us/library/dn302429(v=vs.85).aspx
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

                                       gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + (uint)index, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img.canvas);

                                   }
                                );


                               pass.Paint_Image(
                                     0,

                                     0,
                                     0,
                                     0,
                                     0
                                   //,

                                // gl_FragCoord
                                   // cannot be scaled, and can be referenced directly.
                                   // need another way to scale
                                   //zoom: 0.3f
                                );

                               //paintsw.Stop();


                               // what does it do?
                               gl.flush();

                           };


                   }
               );


            #endregion



            Console.WriteLine("do you see it?");
        }
Example #28
0
        public SecureDecoration(IStore rulesStore, IStore decorated)
            : base(new EventingDecoration(decorated))
        {
            Condition.Requires(rulesStore).IsNotNull();
            this.RuleStore = rulesStore;

            #region Auth Token Intercepts
            this.InterceptCore.GetOperationIntercept.AddNextIntercept("auth",
                (tuple) =>
                {
                    //decorate with the current user
                    return new Tuple<Tuple<Type, IHasId>, object>(tuple.LastCore, CurrentUser.UserStore);
                },
                (tuple) =>
                {
                    //validate that we have a user
                    Condition.Requires(tuple.GetDecorationById("auth").Extension).IsNotNull();
                },
                null, null);

            this.InterceptCore.SearchOperationIntercept.AddNextIntercept("auth",
                (tuple) =>
                {
                    //decorate with the current user
                    return new Tuple<Tuple<Type, SearchFilter>, object>(tuple.LastCore, CurrentUser.UserStore);
                },
                (tuple) =>
                {
                    //validate that we have a user
                    Condition.Requires(tuple.GetDecorationById("auth").Extension).IsNotNull();
                },
                null, null);

            this.InterceptCore.CommitOperationIntercept.AddNextIntercept("auth",
                (tuple) =>
                {
                    //decorate with the current user
                    return new Tuple<CommitBag, object>(tuple.LastCore, CurrentUser.UserStore);
                },
                (tuple) =>
                {
                    //validate that we have a user
                    Condition.Requires(tuple.GetDecorationById("auth").Extension).IsNotNull();
                },
                null, null);
            #endregion

            #region Filtering Intercepts
            this.InterceptCore.GetOperationIntercept.AddNextIntercept("filter",
                null, null,
                (tuple) =>
                {
                    //set the core to null if the user doesn't have access
                    if (!this.HasAccessToItem(StoredItemAccessMode.Read, tuple.LastCore, tuple.GetDecorationById("auth").Extension as IUserInfoStore))
                    {
                        return new Tuple<IHasId, object>(null, null);
                    }
                    return null;//do nothing
                },
                null
                );

            this.InterceptCore.SearchOperationIntercept.AddNextIntercept("filter",
                null, null,
                (tuple) =>
                {
                    List<IHasId> itemsToRemove = new List<IHasId>();

                    tuple.LastCore.WithEach(item =>
                    {
                        //set the core to null if the user doesn't have access
                        if (!this.HasAccessToItem(StoredItemAccessMode.Read, item, tuple.GetDecorationById("auth").Extension as IUserInfoStore))
                        {
                            itemsToRemove.Add(item);
                        }
                    });

                    //remove those items from the returned list
                    List<IHasId> newItems = new List<IHasId>(tuple.LastCore);
                    itemsToRemove.WithEach(item =>
                    {
                        newItems.Remove(item);
                    });

                    return new Tuple<List<IHasId>, object>(newItems, null);
                },
                null
                );

            this.InterceptCore.CommitOperationIntercept.AddNextIntercept("filter",
                null,
                (tuple) =>
                {
                    //check access
                    tuple.LastCore.ItemsToDelete.WithEach(del =>
                    {
                        HasAccessToItemAndThrow(StoredItemAccessMode.Delete, del.Value, tuple.GetDecorationById("auth").Extension as IUserInfoStore);
                    });

                    tuple.LastCore.ItemsToSave.WithEach(save =>
                    {
                        HasAccessToItemAndThrow(StoredItemAccessMode.Save, save.Value, tuple.GetDecorationById("auth").Extension as IUserInfoStore);
                    });
                },
                null, null);
            #endregion
        }
Example #29
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)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                1000
                //2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            // WebGLRenderer preserveDrawingBuffer
            var renderer = new THREE.WebGLRenderer(

                new
            {
                preserveDrawingBuffer = true
            }
                );

            // https://github.com/mrdoob/three.js/issues/3836
            renderer.setClearColor(0xfffff, 1);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);

            this.canvas = (IHTMLCanvas)renderer.domElement;


            var mouseX = 0;
            var mouseY = 0;
            var st     = new Stopwatch();
            st.Start();

            Native.window.onframe +=
                delegate
            {
                renderer.clear();


                //camera.aspect = window.aspect;
                //camera.aspect = canvas.clientWidth / (double)canvas.clientHeight;
                //camera.aspect = canvas.aspect;
                camera.updateProjectionMatrix();


                oo.WithEach(
                    x =>
                    x.rotation.y = st.ElapsedMilliseconds * 0.0001
                    );


                camera.position.x += (mouseX - camera.position.x) * .05;
                camera.position.y += (-mouseY - camera.position.y) * .05;

                camera.lookAt(scene.position);

                renderer.render(scene, camera);
            };

            Native.window.onresize +=
                delegate
            {
                if (canvas.parentNode == Native.document.body)
                {
                    renderer.setSize(window.Width, window.Height);
                }
            };
            #endregion

            new Cisco().Source.Task.ContinueWithResult(
                dae =>
            {
                //dae.scale.x = 30;
                //dae.scale.y = 30;
                //dae.scale.z = 30;

                //dae.castShadow = true;
                //dae.receiveShadow = true;

                dae.scale.x = 5;
                dae.scale.y = 5;
                dae.scale.z = 5;

                dae.position.y = -80;

                scene.add(dae);
                oo.Add(dae);
            }
                );
        }
        /// <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)
        {
            // .obj nolonger works?


            // http://forums.newtek.com/showthread.php?139633-how-to-convert-sketchup-files-into-OBJ-without-the-PRO-version

            // http://www.gameartmarket.com/details?id=ag9zfmRhZGEtM2RtYXJrZXRyMgsSBFVzZXIiE3BpZXJ6YWtAcGllcnphay5jb20MCxIKVXNlclVwbG9hZBjc_5ik8ycM
            // http://www.gameartmarket.com/details?id=ag9zfmRhZGEtM2RtYXJrZXRyMgsSBFVzZXIiE3BpZXJ6YWtAcGllcnphay5jb20MCxIKVXNlclVwbG9hZBjXwOHe-icM
            // http://scfreak.0catch.com/dlindex.html
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131109-gold
            // view-source:file:///X:/opensource/github/three.js/examples/webgl_loader_obj.html

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new Scene();

            new AmbientLight(0x101030).AttachTo(scene);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);



            var controls = new THREE.OrbitControls(camera, renderer.domElement);

            var st = Stopwatch.StartNew();

            Native.window.onframe +=
                delegate
                {

                    oo.WithEach(
                        x =>
                            x.rotation.y = st.ElapsedMilliseconds * 0.001
                    );


                    controls.update();
                    camera.position = controls.center.clone();

                    renderer.render(scene, camera);


                };

            Native.window.onresize +=
                delegate
                {
                    camera.aspect = window.aspect;
                    camera.updateProjectionMatrix();

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

                };
            #endregion








            new THREE_OBJAsset(
                 new HTML.Images.FromAssets.texture_palm(),
                   "assets/WebGLOBJExperiment/palm.obj"
            ).Source.Task.ContinueWithResult(
                palm =>
                {
                    palm.position.y = -80;
                    //scene.add(palm);
                    palm.AttachTo(scene);

                    oo.Add(palm);

                    palm.position.x = -200;
                    palm.scale = new THREE.Vector3(5, 5, 5);
                }
            );

            new THREE_OBJAsset(
                  new HTML.Images.FromAssets.texture_palm(),
                    "assets/WebGLOBJExperiment/palm.obj"
             ).Source.Task.ContinueWithResult(
                 palm2 =>
                 {
                     palm2.position.y = -80;
                     palm2.AttachTo(scene);
                     oo.Add(palm2);

                     palm2.position.x = 200;
                     palm2.scale = new THREE.Vector3(5, 5, 5);
                 }
             );

            new THREE_OBJAsset(
                 new HTML.Images.FromAssets.Fence_texture3(),
                   "assets/WebGLOBJExperiment/fence.obj"
            ).Source.Task.ContinueWithResult(
                fence =>
                {
                    fence.position.y = -80;
                    fence.AttachTo(scene);
                    //scene.add(fence);
                    oo.Add(fence);

                    fence.position.x = -100;
                    fence.scale = new THREE.Vector3(0.2, 0.2, 0.2);
                }
            );

            new sack_of_gold2().Source.Task.ContinueWithResult(
               sack_of_gold2 =>
               {
                   sack_of_gold2.position.y = -80;
                   sack_of_gold2.AttachTo(scene);
                   oo.Add(sack_of_gold2);

                   sack_of_gold2.position.x = 70;
                   sack_of_gold2.position.z = 100;
                   sack_of_gold2.scale = new THREE.Vector3(0.5, 0.5, 0.5);
               }
           );

            new sack_of_gold2().Source.Task.ContinueWithResult(
          o =>
          {
              o.position.y = -80;
              scene.add(o);
              oo.Add(o);

              o.position.x = -70;
              o.position.z = 100;
              o.scale = new THREE.Vector3(0.5, 0.5, 0.5);
          }
      );

            new THREE_OBJAsset(
              new HTML.Images.FromAssets.ash_uvgrid01(),
                   "assets/WebGLOBJExperiment/male02.obj"
            ).Source.Task.ContinueWithResult(
                o =>
                {
                    o.position.y = -80;
                    scene.add(o);
                    oo.Add(o);

                    o.position.x = 50;
                    //o.scale = new THREE.Vector3(5, 5, 5);
                }
            );


            var ze = new ZeProperties
            {
                //() => renderer
            };

            ze.Show();

            ze.treeView1.Nodes.Clear();

            ze.Add(() => renderer);
            ze.Add(() => controls);
            ze.Add(() => scene);

            ze.Left = 0;
        }
Example #31
0
        public ApplicationCanvas()
        {
            c = new Base.ApplicationCanvas();

            c.Selection.GlassArea.Orphanize();
            c.Selection.Orphanize();



            c.AttachTo(this);
            c.MoveTo(8, 8);

            this.SizeChanged += (s, e) => c.SizeTo(this.Width - 16.0, this.Height - 16.0);

            r.Fill    = Brushes.Red;
            r.Opacity = 0;

            r.AttachTo(this);
            r.MoveTo(8, 8);

            this.SizeChanged += (s, e) => r.SizeTo(this.Width - 16.0, this.Height - 16.0);

            Rectangle h = null;
            AnimatedOpacity <Rectangle> hOpacity = null;


            Action <Action <double, double> > GetPosition = null;
            var Windows = new List <Base.ApplicationCanvas.WindowInfo>();


            #region GetSnapLocation
            Action <Func <UIElement, Point>, Action <bool, double, double, double, double> > GetSnapLocation =
                (e_GetPosition, SetLocation) =>
            {
                var p = e_GetPosition(r);

                var x = 0.0;
                var y = 0.0;

                GetPosition((_x, _y) => { x = _x; y = _y; });

                var cx = p.X - x;
                var cy = p.Y - y;

                if (cx < 0)
                {
                    x += cx;
                    cx = -cx;
                }

                if (cy < 0)
                {
                    y += cy;
                    cy = -cy;
                }

                var Snap     = 16;
                var SnapMode = false;

                Enumerable.FirstOrDefault(
                    from k in Windows
                    let dx0 = Math.Abs(k.WindowLocation.Left - x)
                              where dx0 < Snap
                              orderby dx0
                              select k
                    ).With(
                    ax =>
                {
                    SnapMode = true;
                    cx      += x - ax.WindowLocation.Left;
                    x        = ax.WindowLocation.Left;
                }
                    );


                Enumerable.FirstOrDefault(
                    from k in Windows
                    let dx0 = Math.Abs(k.WindowLocation.Top - y)
                              where dx0 < Snap
                              orderby dx0
                              select k
                    ).With(
                    ax =>
                {
                    SnapMode = true;
                    cy      += y - ax.WindowLocation.Top;
                    y        = ax.WindowLocation.Top;
                }
                    );


                SetLocation(SnapMode, x, y, cx, cy);
            };
            #endregion

            #region MouseLeftButtonDown
            r.MouseLeftButtonDown +=
                (s, e) =>
            {
                h = new Rectangle
                {
                    Fill = Brushes.Black,
                };
                hOpacity         = h.ToAnimatedOpacity();
                hOpacity.Opacity = 0.3;

                var p = e.GetPosition(r);

                //Console.WriteLine("MouseLeftButtonDown " + new { p.X, p.Y });

                GetPosition = y => y(p.X, p.Y);


                h.AttachTo(c).MoveTo(p).SizeTo(0, 0);

                c.Selection.Orphanize();

                c.Selection.WindowLocation.Left   = p.X;
                c.Selection.WindowLocation.Top    = p.Y;
                c.Selection.WindowLocation.Width  = 0;
                c.Selection.WindowLocation.Height = 0;
                c.Selection.WindowLocationChanged();
                c.Selection.Attach();


                Windows.WithEach(k => k.GlassOpacity.Opacity = 0);
            };
            #endregion



            #region MouseMove
            r.MouseMove +=
                (s, e) =>
            {
                if (GetPosition != null)
                {
                    GetSnapLocation(e.GetPosition,
                                    (SnapMode, x, y, cx, cy) =>
                    {
                        //Console.WriteLine("MouseMove " + new { x, y, cx, cy });

                        if (SnapMode)
                        {
                            hOpacity.Opacity = 0.9;
                        }
                        else
                        {
                            hOpacity.Opacity = 0.3;
                        }

                        c.Selection.WindowLocation.Left   = x;
                        c.Selection.WindowLocation.Top    = y;
                        c.Selection.WindowLocation.Width  = cx;
                        c.Selection.WindowLocation.Height = cy;
                        c.Selection.WindowLocationChanged();

                        h.MoveTo(x, y).SizeTo(cx, cy);
                    }
                                    );
                }
            };
            #endregion


            #region MouseLeftButtonUp
            r.MouseLeftButtonUp +=
                (s, e) =>
            {
                //Console.WriteLine("MouseLeftButtonUp");

                if (GetPosition == null)
                {
                    return;
                }


                GetSnapLocation(e.GetPosition,
                                (SnapMode, x, y, cx, cy) =>
                {
                    //Console.WriteLine("MouseLeftButtonUp " + new { x, y, cx, cy });

                    Windows.WithEach(k => k.GlassOpacity.Opacity = 1);

                    h.Orphanize();
                    c.Selection.Orphanize();

                    if (cx > 32)
                    {
                        if (cy > 32)
                        {
                            c.CreateWindow(
                                new Base.ApplicationCanvas.Position
                            {
                                Left   = x,
                                Top    = y,
                                Width  = cx,
                                Height = cy
                            },

                                Windows.Add
                                );
                        }
                    }
                }
                                );



                GetPosition = null;
            };
            #endregion



            #region TouchDown
            r.TouchDown +=
                (s, e) =>
            {
                h = new Rectangle
                {
                    Fill = Brushes.Black,
                };
                hOpacity         = h.ToAnimatedOpacity();
                hOpacity.Opacity = 0.3;

                var p = e.GetTouchPoint(r).Position;

                //Console.WriteLine("MouseLeftButtonDown " + new { p.X, p.Y });

                GetPosition = y => y(p.X, p.Y);


                h.AttachTo(c).MoveTo(p).SizeTo(0, 0);

                c.Selection.Orphanize();

                c.Selection.WindowLocation.Left   = p.X;
                c.Selection.WindowLocation.Top    = p.Y;
                c.Selection.WindowLocation.Width  = 0;
                c.Selection.WindowLocation.Height = 0;
                c.Selection.WindowLocationChanged();
                c.Selection.Attach();


                Windows.WithEach(k => k.GlassOpacity.Opacity = 0);
            };
            #endregion



            #region MouseMove
            r.TouchMove +=
                (s, e) =>
            {
                if (GetPosition != null)
                {
                    Func <UIElement, Point> e_GetPosition = x => e.GetTouchPoint(x).Position;

                    GetSnapLocation(e_GetPosition,
                                    (SnapMode, x, y, cx, cy) =>
                    {
                        //Console.WriteLine("MouseMove " + new { x, y, cx, cy });

                        if (SnapMode)
                        {
                            hOpacity.Opacity = 0.9;
                        }
                        else
                        {
                            hOpacity.Opacity = 0.3;
                        }

                        c.Selection.WindowLocation.Left   = x;
                        c.Selection.WindowLocation.Top    = y;
                        c.Selection.WindowLocation.Width  = cx;
                        c.Selection.WindowLocation.Height = cy;
                        c.Selection.WindowLocationChanged();

                        h.MoveTo(x, y).SizeTo(cx, cy);
                    }
                                    );
                }
            };
            #endregion


            #region TouchUp
            r.TouchUp +=
                (s, e) =>
            {
                //Console.WriteLine("MouseLeftButtonUp");

                if (GetPosition == null)
                {
                    return;
                }

                Func <UIElement, Point> e_GetPosition = x => e.GetTouchPoint(x).Position;

                GetSnapLocation(e_GetPosition,
                                (SnapMode, x, y, cx, cy) =>
                {
                    //Console.WriteLine("MouseLeftButtonUp " + new { x, y, cx, cy });

                    Windows.WithEach(k => k.GlassOpacity.Opacity = 1);

                    h.Orphanize();
                    c.Selection.Orphanize();

                    if (cx > 32)
                    {
                        if (cy > 32)
                        {
                            c.CreateWindow(
                                new Base.ApplicationCanvas.Position
                            {
                                Left   = x,
                                Top    = y,
                                Width  = cx,
                                Height = cy
                            },

                                Windows.Add
                                );
                        }
                    }
                }
                                );



                GetPosition = null;
            };
            #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)
        {
            // why are the trucks black?
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae
            // what will happen if we resync THREE version from 70 to?
            Native.document.title = new { THREE.REVISION }.ToString();

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            //var ambient = new THREE.AmbientLight(0x101030);
            var ambient = new THREE.AmbientLight(0x808080);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd, 0.7);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            // WebGLRenderer preserveDrawingBuffer 
            var renderer = new THREE.WebGLRenderer(

                new
                {
                    preserveDrawingBuffer = true
                }
            );

            // https://github.com/mrdoob/three.js/issues/3836
            renderer.setClearColor(0xfffff, 1);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);

            this.canvas = (IHTMLCanvas)renderer.domElement;


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();


            var controls = new THREE.OrbitControls(camera, renderer.domElement);

            Native.window.onframe +=
                delegate
                {
                    renderer.clear();


                    //camera.aspect = window.aspect;
                    //camera.aspect = canvas.clientWidth / (double)canvas.clientHeight;
                    //camera.aspect = canvas.aspect;


                    oo.WithEach(
                        x =>
                            x.rotation.y = st.ElapsedMilliseconds * 0.0001
                    );


                    controls.update();
                    camera.position = controls.center.clone();

                    renderer.render(scene, camera);


                };

            Native.window.onresize +=
                delegate
                {
                    if (canvas.parentNode == Native.document.body)
                    {
                        renderer.setSize(window.Width, window.Height);
                    }

                };
            #endregion

            new truck().Source.Task.ContinueWithResult(
                   dae =>
                    {
                        //dae.scale.x = 30;
                        //dae.scale.y = 30;
                        //dae.scale.z = 30;
                        dae.position.z = 65;

                        dae.scale.x = 10;
                        dae.scale.y = 10;
                        dae.scale.z = 10;

                        dae.position.y = -80;

                        scene.add(dae);
                        oo.Add(dae);


                    }
               );

            //var ref0 = "assets/WebGLColladaExperiment/HZCannon_capture_009_04032013_192834.png";

            //new HZCannon().Source.Task.ContinueWithResult(
            //    dae =>
            //    {
            //        //dae.scale.x = 30;
            //        //dae.scale.y = 30;
            //        //dae.scale.z = 30;

            //        dae.castShadow = true;
            //        dae.receiveShadow = true;

            //        dae.scale.x = 3;
            //        dae.scale.y = 3;
            //        dae.scale.z = 3;

            //        dae.position.y = -80;

            //        scene.add(dae);
            //        oo.Add(dae);


            //    }
            //);
        }
        /// <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)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                1000
                //2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            // WebGLRenderer preserveDrawingBuffer 
            var renderer = new THREE.WebGLRenderer(

                new
                {
                    preserveDrawingBuffer = true
                }
            );

            // https://github.com/mrdoob/three.js/issues/3836
            renderer.setClearColor(0xfffff, 1);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);

            this.canvas = (IHTMLCanvas)renderer.domElement;


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();

            Native.window.onframe +=
                delegate
                {
                    renderer.clear();


                    //camera.aspect = window.aspect;
                    //camera.aspect = canvas.clientWidth / (double)canvas.clientHeight;
                    //camera.aspect = canvas.aspect;
                    camera.updateProjectionMatrix();


                    oo.WithEach(
                        x =>
                            x.rotation.y = st.ElapsedMilliseconds * 0.0001
                    );


                    camera.position.x += (mouseX - camera.position.x) * .05;
                    camera.position.y += (-mouseY - camera.position.y) * .05;

                    camera.lookAt(scene.position);

                    renderer.render(scene, camera);


                };

            Native.window.onresize +=
                delegate
                {
                    if (canvas.parentNode == Native.document.body)
                    {
                        renderer.setSize(window.Width, window.Height);
                    }

                };
            #endregion

            new Cisco().Source.Task.ContinueWithResult(
                dae =>
                {
                    //dae.scale.x = 30;
                    //dae.scale.y = 30;
                    //dae.scale.z = 30;

                    //dae.castShadow = true;
                    //dae.receiveShadow = true;

                    dae.scale.x = 5;
                    dae.scale.y = 5;
                    dae.scale.z = 5;

                    dae.position.y = -80;

                    scene.add(dae);
                    oo.Add(dae);


                }
            );
        }
Example #34
0
        /// <summary>
        /// serializes the list of nodes by dehydrating each node and adding to a delimited string
        /// </summary>
        /// <param name="nodes"></param>
        /// <returns></returns>
        public static string DehydrateNodeList(List<GraphNode> nodes)
        {
            if (nodes == null)
                return null;

            List<string> lines = new List<string>();
            nodes.WithEach(node =>
            {
                lines.Add(node.GetValue());
            });
            var rv = LengthEncoder.LengthEncodeList(lines.ToArray());
            return rv;
        }
        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150809

        // the eye nor the display will be able to do any stereo
        // until tech is near matrix capability. 2019?

        // cubemap can be used for all long range scenes
        // http://www.imdb.com/title/tt0112111/?ref_=nv_sr_1


        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150808/cubemapcamera
        // subst a: s:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeEquirectangularCameraExperiment\ChromeEquirectangularCameraExperiment\bin\Debug\staging\ChromeEquirectangularCameraExperiment.Application\web
        // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeEquirectangularCameraExperiment\ChromeEquirectangularCameraExperiment\bin\Debug\staging\ChromeEquirectangularCameraExperiment.Application\web

        // ColladaLoader: Empty or non-existing file (assets/ChromeEquirectangularCameraExperiment/S6Edge.dae)

        /// <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 =
            //s =>
            //{
            //    s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

            //    //var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
            //    var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDragWithShadow().AttachTo(s.Context.GetHTMLTarget());



            //    s.Context.GetHTMLTarget().style.backgroundColor = "#efefef";
            //    //s.Context.GetHTMLTarget().style.backgroundColor = "#A26D41";

            //};

#if AsWEBSERVER
            #region += Launched chrome.app.window
            // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

            if (self_chrome_socket != null)
            {
                // if we run as a server. we can open up on android.

                //chrome.Notification.DefaultTitle = "Nexus7";
                //chrome.Notification.DefaultIconUrl = new x128().src;
                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                     AppSource.Text
                //, AtFormCreated: FormStyler.AtFormCreated

                //AtFormConstructor:
                //    f =>
                //    {
                //        //arg[0] is typeof System.Int32
                //        //script: error JSC1000: No implementation found for this native method, please implement [static System.Drawing.Color.FromArgb(System.Int32)]

                //        // X:\jsc.svn\examples\javascript\forms\Test\TestFromArgb\TestFromArgb\ApplicationControl.cs

                //        f.BackColor = System.Drawing.Color.FromArgb(0xA26D41);
                //    }
                );
                return;
            }
            #endregion
#else

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

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

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

                    //};

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

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

                        // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions
                        var xappwindow = await chrome.app.window.create(
                               Native.document.location.pathname, options: new
                               {
                                   alwaysOnTop = true,
                                   visibleOnAllWorkspaces = true
                               }
                        );

                        //xappwindow.setAlwaysOnTop

                        xappwindow.show();

                        await xappwindow.contentWindow.async.onload;

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


                    return;
                }
            }
            #endregion


#endif


            Native.css.style.backgroundColor = "blue";
            Native.css.style.overflow = IStyle.OverflowEnum.hidden;

            Native.body.Clear();

            new IHTMLPre { "can we stream it into VR, shadertoy, youtube 360, youtube stereo yet?" }.AttachToDocument();


            var sw = Stopwatch.StartNew();

            var pause = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox, title = "pause" }.AttachToDocument();


            pause.onchange += delegate
            {

                if ([email protected])
                    sw.Stop();
                else
                    sw.Start();


            };

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

            #region scene
            var window = Native.window;


            // what about physics and that portal rendering?

            // if we are running as a chrome web server, we may also be opened as android ndk webview app
            //var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: window.aspect, near: 1, far: 2000);
            // once we update source
            // save the source
            // manually recompile 
            //cameraPX.position.z = 400;

            //// the camera should be close enough for the object to float off the FOV of PX
            //cameraPX.position.z = 200;

            // scene
            // can we make the 3D object orbit around us ?
            // and
            // stream it to vr?
            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x303030);
            scene.add(ambient);

            // should we fix jsc to do a more correct IDL?
            var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);



            // whats WebGLRenderTargetCube do?

            // WebGLRenderer preserveDrawingBuffer 

            //const int size = 128;
            //const int size = 256; // 6 faces, 12KB
            //const int size = 512; // 6 faces, ?

            // WebGL: drawArrays: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.

            //const int size = 720; // 6 faces, ?
            const int size = 1024; // 6 faces, ?

            var renderer0 = new THREE.WebGLRenderer(

                new
                {
                    antialias = true,
                    alpha = true,
                    preserveDrawingBuffer = true
                }
            );

            // https://github.com/mrdoob/three.js/issues/3836

            // the construct. white bg
            renderer0.setClearColor(0xfffff, 1);

            //renderer.setSize(window.Width, window.Height);
            renderer0.setSize(size, size);

            //renderer0.domElement.AttachToDocument();
            //rendererPX.domElement.style.SetLocation(0, 0);
            //renderer0.domElement.style.SetLocation(4, 4);


            // top

            // http://stackoverflow.com/questions/27612524/can-multiple-webglrenderers-render-the-same-scene


            // need a place to show the cubemap face to GUI 
            // how does the stereo OTOY do it?
            // https://www.opengl.org/wiki/Sampler_(GLSL)

            // http://www.richardssoftware.net/Home/Post/25

            // [+X, –X, +Y, –Y, +Z, –Z] fa

            var uizoom = 0.1;

            var far = 0xffff;

            #region y
            // need to rotate90?
            var cameraNY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraNY.lookAt(new THREE.Vector3(0, -1, 0));
            //cameraNY.lookAt(new THREE.Vector3(0, 1, 0));
            var canvasNY = new CanvasRenderingContext2D(size, size);
            canvasNY.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 1, 8 + (int)(uizoom * size + 8) * 2);
            canvasNY.canvas.title = "NY";
            canvasNY.canvas.AttachToDocument();
            canvasNY.canvas.style.transformOrigin = "0 0";
            canvasNY.canvas.style.transform = $"scale({uizoom})";

            var cameraPY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraPY.lookAt(new THREE.Vector3(0, 1, 0));
            //cameraPY.lookAt(new THREE.Vector3(0, -1, 0));
            var canvasPY = new CanvasRenderingContext2D(size, size);
            canvasPY.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 1, 8 + (int)(uizoom * size + 8) * 0);
            canvasPY.canvas.title = "PY";
            canvasPY.canvas.AttachToDocument();
            canvasPY.canvas.style.transformOrigin = "0 0";
            canvasPY.canvas.style.transform = $"scale({uizoom})";
            #endregion

            // transpose xz?

            #region x
            var cameraNX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraNX.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraNX.lookAt(new THREE.Vector3(0, 0, -1));
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNX.lookAt(new THREE.Vector3(1, 0, 0));
            var canvasNX = new CanvasRenderingContext2D(size, size);
            canvasNX.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 2, 8 + (int)(uizoom * size + 8) * 1);
            canvasNX.canvas.title = "NX";
            canvasNX.canvas.AttachToDocument();
            canvasNX.canvas.style.transformOrigin = "0 0";
            canvasNX.canvas.style.transform = $"scale({uizoom})";

            var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            cameraPX.lookAt(new THREE.Vector3(0, 0, -1));
            //cameraPX.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPX.lookAt(new THREE.Vector3(1, 0, 0));
            //cameraPX.lookAt(new THREE.Vector3(-1, 0, 0));
            var canvasPX = new CanvasRenderingContext2D(size, size);
            canvasPX.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 0, 8 + (int)(uizoom * size + 8) * 1);
            canvasPX.canvas.title = "PX";
            canvasPX.canvas.AttachToDocument();
            canvasPX.canvas.style.transformOrigin = "0 0";
            canvasPX.canvas.style.transform = $"scale({uizoom})";
            #endregion



            #region z
            var cameraNZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, -1));
            cameraNZ.lookAt(new THREE.Vector3(1, 0, 0));
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, 1));
            var canvasNZ = new CanvasRenderingContext2D(size, size);
            canvasNZ.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 3, 8 + (int)(uizoom * size + 8) * 1);
            canvasNZ.canvas.title = "NZ";
            canvasNZ.canvas.AttachToDocument();
            canvasNZ.canvas.style.transformOrigin = "0 0";
            canvasNZ.canvas.style.transform = $"scale({uizoom})";

            var cameraPZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraPZ.lookAt(new THREE.Vector3(1, 0, 0));
            cameraPZ.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, -1));
            var canvasPZ = new CanvasRenderingContext2D(size, size);
            canvasPZ.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 1, 8 + (int)(uizoom * size + 8) * 1);
            canvasPZ.canvas.title = "PZ";
            canvasPZ.canvas.AttachToDocument();
            canvasPZ.canvas.style.transformOrigin = "0 0";
            canvasPZ.canvas.style.transform = $"scale({uizoom})";
            #endregion




            // c++ alias locals would be nice..
            var canvas0 = (IHTMLCanvas)renderer0.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


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

            //canvas0.css.active.style.cursor = IStyle.CursorEnum.move;

            #region onmousedown
            Native.body.onmousedown +=
                async e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                        return;

                    // movementX no longer works
                    old = new
                    {


                        e.CursorX,
                        e.CursorY
                    };


                    //e.CaptureMouse();
                    var release = e.Element.CaptureMouse();
                    await e.Element.async.onmouseup;

                    release();


                };
            #endregion



            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            Native.body.onmousemove +=
                e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                    {
                        Native.body.style.cursor = [email protected];
                        return;
                    }

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


                    Native.body.style.cursor = IStyle.CursorEnum.move;

                    var pointerLock = canvas0 == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion

            // THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(78,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll
            // THREE.WebGLProgram: gl.getProgramInfoLog() (79,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll

            // http://www.roadtovr.com/youtube-confirms-stereo-3d-360-video-support-coming-soon/
            // https://www.youtube.com/watch?v=D-Wl9jAB45Q



            #region spherical
            var gl = new WebGLRenderingContext(alpha: true, preserveDrawingBuffer: true);
            var c = gl.canvas.AttachToDocument();

            //  3840x2160

            //c.style.SetSize(3840, 2160);

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


            c.width = 3840;
            c.height = 2160;

            // wont work
            //c.width = 8192;
            //c.height = 4096;


            // this has the wrong aspect?
            //c.width = 6466;
            //c.height = 3232;

            new IHTMLPre { new { c.width, c.height } }.AttachToDocument();

            //6466x3232

            //var suizoom = 720f / c.height;
            //var suizoom = 360f / c.height;
            var suizoom = 480f / c.width;

            c.style.transformOrigin = "0 0";
            c.style.transform = $"scale({suizoom})";
            c.style.backgroundColor = "yellow";
            c.style.position = IStyle.PositionEnum.absolute;

            c.style.SetLocation(8 + (int)(uizoom * size + 8) * 0, 8 + (int)(uizoom * size + 8) * 3);

            var pass = new CubeToEquirectangular.Library.ShaderToy.EffectPass(
                       null,
                       gl,
                       precission: CubeToEquirectangular.Library.ShaderToy.DetermineShaderPrecission(gl),
                       supportDerivatives: gl.getExtension("OES_standard_derivatives") != null,
                       callback: null,
                       obj: null,
                       forceMuted: false,
                       forcePaused: false,
                       //quadVBO: Library.ShaderToy.createQuadVBO(gl, right: 0, top: 0),
                       outputGainNode: null
                   );

            // how shall we upload our textures?
            // can we reference GLSL.samplerCube yet?
            //pass.mInputs[0] = new samplerCube { };
            pass.mInputs[0] = new CubeToEquirectangular.Library.ShaderToy.samplerCube { };

            pass.MakeHeader_Image();
            var vs = new Shaders.ProgramFragmentShader();
            pass.NewShader_Image(vs);

            #endregion




            //var xor = new HTML.Images.FromAssets.tiles_regrid().AttachToDocument();
            //var xor = new HTML.Images.FromAssets.Orion360_test_image_8192x4096().AttachToDocument();
            //var xor = new HTML.Images.FromAssets._2_no_clouds_4k().AttachToDocument();
            var frame0 = new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().AttachToDocument();


            // 270px
            //xor.style.height = "";
            frame0.style.height = "270px";
            frame0.style.width = "480px";
            frame0.style.SetLocation(
                8 + (int)(uizoom * size + 8) * 0 + 480 + 16, 8 + (int)(uizoom * size + 8) * 3);


            var mesh = new THREE.Mesh(new THREE.SphereGeometry(0xFFF, 50, 50),
           new THREE.MeshBasicMaterial(new
           {
               map = THREE.ImageUtils.loadTexture(
                  //new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().src
                  //new HTML.Images.FromAssets._4008650304_7f837ccbb7_b().src
                  frame0.src
                   //new WebGLEquirectangularPanorama.HTML.Images.FromAssets.PANO_20130616_222058().src
                   //new WebGLEquirectangularPanorama.HTML.Images.FromAssets.PANO_20121225_210448().src

                   )
           }));
            mesh.scale.x = -1;

            #region fixup rotation

            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI / 2);
            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI / 2);
            mesh.rotateOnAxis(new THREE.Vector3(0, 1, 0), -Math.PI / 2);
            #endregion


            scene.add(mesh);



            frame0.onclick += delegate
            {
                // http://paulbourke.net/papers/vsmm2006/vsmm2006.pdf
                //            A method of creating synthetic stereoscopic panoramic images that can be implemented
                //in most rendering packages has been presented. If single panoramic pairs can be created
                //then stereoscopic panoramic movies are equally possible giving rise to the prospect of
                //movies where the viewer can interact with, at least with regard to what they choose to look
                //at.These images can be projected so as to engage the two features of the human visual
                //system that assist is giving us a sense of immersion, the feeling of “being there”. That is,
                //imagery that contains parallax information as captured from two horizontally separated eye
                //positions (stereopsis)and imagery that fills our peripheral vision.The details that define
                //how the two panoramic images should be created in rendering packages are provided, in
                //particular, how to precisely configure the virtual cameras and control the distance to zero
                //parallax.

                // grab a frame

                var base64 = gl.canvas.toDataURL();

                frame0.src = base64;
                // 7MB!

            };

            new Models.ColladaS6Edge().Source.Task.ContinueWithResult(
                   dae =>
                   {
                       // 90deg
                       dae.rotation.x = -Math.Cos(Math.PI);

                       //dae.scale.x = 30;
                       //dae.scale.y = 30;
                       //dae.scale.z = 30;
                       dae.position.z = -(65 - 200);





                       var scale = 0.9;

                       // jsc, do we have ILObserver available yet?
                       dae.scale.x = scale;
                       dae.scale.y = scale;
                       dae.scale.z = scale;


                       #region onmousewheel
                       Native.body.onmousewheel +=
                           e =>
                           {
                               e.preventDefault();

                               //camera.position.z = 1.5;

                               // min max. shall adjust speed also!
                               // max 4.0
                               // min 0.6
                               dae.position.z -= 10.0 * e.WheelDirection;

                               //camera.position.z = 400;
                               //dae.position.z = dae.position.z.Max(-200).Min(200);

                               //Native.document.title = new { z }.ToString();

                           };
                       #endregion


                       //dae.position.y = -80;

                       scene.add(dae);
                       oo.Add(dae);




                       // view-source:http://threejs.org/examples/webgl_multiple_canvases_circle.html
                       // https://threejsdoc.appspot.com/doc/three.js/src.source/extras/cameras/CubeCamera.js.html
                       Native.window.onframe +=
                           e =>
                           {
                               //if (pause) return;
                               //if ([email protected])
                               //    return;


                               // can we float out of frame?
                               // haha. a bit too flickery.
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.01) * 50.0;
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.001) * 190.0;
                               dae.position.x = Math.Sin(sw.ElapsedMilliseconds * 0.0001) * 190.0;
                               dae.position.y = Math.Cos(sw.ElapsedMilliseconds * 0.0001) * 90.0;
                               // manual rebuild?
                               // red compiler notifies laptop chrome of pending update
                               // app reloads


                               renderer0.clear();
                               //rendererPY.clear();

                               //cameraPX.aspect = canvasPX.aspect;
                               //cameraPX.updateProjectionMatrix();

                               // um what does this do?
                               //cameraPX.position.z += (z - cameraPX.position.z) * e.delay.ElapsedMilliseconds / 200.0;
                               // mousewheel allos the camera to move closer
                               // once we see the frame in vr, can we udp sync vr tracking back to laptop?


                               //this.targetPX.x += 1;
                               //this.targetNX.x -= 1;

                               //this.targetPY.y += 1;
                               //this.targetNY.y -= 1;

                               //this.targetPZ.z += 1;
                               //this.targetNZ.z -= 1;

                               // how does the 360 or shadertoy want our cubemaps?


                               // and then rotate right?

                               // how can we render cubemap?


                               #region x
                               // upside down?
                               renderer0.render(scene, cameraPX);
                               canvasPX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);

                               renderer0.render(scene, cameraNX);
                               canvasNX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               #endregion

                               #region z
                               renderer0.render(scene, cameraPZ);
                               canvasPZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);

                               renderer0.render(scene, cameraNZ);
                               canvasNZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               #endregion



                               #region y
                               renderer0.render(scene, cameraPY);

                               //canvasPY.save();
                               //canvasPY.translate(0, size);
                               //canvasPY.rotate((float)(-Math.PI / 2));
                               canvasPY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               //canvasPY.restore();


                               renderer0.render(scene, cameraNY);
                               //canvasNY.save();
                               //canvasNY.translate(size, 0);
                               //canvasNY.rotate((float)(Math.PI / 2));
                               canvasNY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               //canvasNY.restore();
                               // ?
                               #endregion


                               //renderer0.render(scene, cameraPX);


                               //rendererPY.render(scene, cameraPY);

                               // at this point we should be able to render the sphere texture

                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_X = 34069;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_X = 34070;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Y = 34071;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Z = 34073;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074;


                               //var cube0 = new IHTMLImage[] {
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_px(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nx(),

                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_py(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_ny(),


                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_pz(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nz()
                               //};

                               new[] {
                                   canvasPX, canvasNX,
                                   canvasPY, canvasNY,
                                   canvasPZ, canvasNZ
                               }.WithEachIndex(
                                   (img, index) =>
                                   {
                                       gl.bindTexture(gl.TEXTURE_CUBE_MAP, pass.tex);

                                       //gl.pixelStorei(gl.UNPACK_FLIP_X_WEBGL, false);
                                       gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);

                                       // http://stackoverflow.com/questions/15364517/pixelstoreigl-unpack-flip-y-webgl-true

                                       // https://msdn.microsoft.com/en-us/library/dn302429(v=vs.85).aspx
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

                                       gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + (uint)index, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img.canvas);

                                   }
                                );


                               pass.Paint_Image(
                                     0,

                                     0,
                                     0,
                                     0,
                                     0
                                //,

                                // gl_FragCoord
                                // cannot be scaled, and can be referenced directly.
                                // need another way to scale
                                //zoom: 0.3f
                                );

                               //paintsw.Stop();


                               // what does it do?
                               gl.flush();

                           };


                   }
               );


            #endregion



            Console.WriteLine("do you see it?");
        }
        /// <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 oo = new List<THREE.Object3D>();

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();

            Native.window.onframe +=
                delegate
                {

                    oo.WithEach(
                        x =>
                            x.rotation.y = st.ElapsedMilliseconds * 0.001
                    );


                    camera.position.x += (mouseX - camera.position.x) * .05;
                    camera.position.y += (-mouseY - camera.position.y) * .05;

                    camera.lookAt(scene.position);

                    renderer.render(scene, camera);


                };

            Native.window.onresize +=
                delegate
                {
                    camera.aspect = window.aspect;
                    camera.updateProjectionMatrix();

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

                };
            #endregion


            var ref0 = new TexturesImages();

            //var texture = new THREE.Texture(
            //    //new HTML.Images.FromAssets.ash_uvgrid01()
            //    //new HTML.Images.FromAssets.texture_palm()
            //           new TLC200_Side_89pc()
            //      );
            //texture.needsUpdate = true;

            // X:\jsc.svn\examples\javascript\WebGL\WebGLMTLExperiment\WebGLMTLExperiment\Application.cs

            var loader = new THREE.OBJMTLLoader();
            loader.load(
                "assets/WebGLOBJToyota/LX570_2008.obj",
                "assets/WebGLOBJToyota/LX570_2008.mtl",
                     new Action<THREE.Object3D>(
                    o =>
                    {
                        Console.WriteLine("onload " + new { o });

                        // need to use
                        // Toyota Land Cruiser 200 Series aka Lexus LX 570_2008.mtl
                        // http://pages.cs.wisc.edu/~lizy/mrdoob-three.js-ef5f05d/examples/webgl_loader_obj_mtl.html

                        
                        o.scale = new THREE.Vector3(40, 40, 40);

                        o.position.y = -80;
                        scene.add(o);
                        oo.Add(o);
                    }
                ),
                new Action<object>(
                    o =>
                    {
                        Console.WriteLine("progress " + new { o });
                    }
                ),

                 new Action<object>(
                    o =>
                    {
                        Console.WriteLine("error " + new { o });
                    }
                 )
            );


        }
Example #37
0
        public SecureDecoration(IStore rulesStore, IStore decorated)
            : base(new EventingDecoration(decorated))
        {
            Condition.Requires(rulesStore).IsNotNull();
            this.RuleStore = rulesStore;

            #region Auth Token Intercepts
            this.InterceptCore.GetOperationIntercept.AddNextIntercept("auth",
                                                                      (tuple) =>
            {
                //decorate with the current user
                return(new Tuple <Tuple <Type, IHasId>, object>(tuple.LastCore, CurrentUser.UserStore));
            },
                                                                      (tuple) =>
            {
                //validate that we have a user
                Condition.Requires(tuple.GetDecorationById("auth").Extension).IsNotNull();
            },
                                                                      null, null);

            this.InterceptCore.SearchOperationIntercept.AddNextIntercept("auth",
                                                                         (tuple) =>
            {
                //decorate with the current user
                return(new Tuple <Tuple <Type, SearchFilter>, object>(tuple.LastCore, CurrentUser.UserStore));
            },
                                                                         (tuple) =>
            {
                //validate that we have a user
                Condition.Requires(tuple.GetDecorationById("auth").Extension).IsNotNull();
            },
                                                                         null, null);

            this.InterceptCore.CommitOperationIntercept.AddNextIntercept("auth",
                                                                         (tuple) =>
            {
                //decorate with the current user
                return(new Tuple <CommitBag, object>(tuple.LastCore, CurrentUser.UserStore));
            },
                                                                         (tuple) =>
            {
                //validate that we have a user
                Condition.Requires(tuple.GetDecorationById("auth").Extension).IsNotNull();
            },
                                                                         null, null);
            #endregion

            #region Filtering Intercepts
            this.InterceptCore.GetOperationIntercept.AddNextIntercept("filter",
                                                                      null, null,
                                                                      (tuple) =>
            {
                //set the core to null if the user doesn't have access
                if (!this.HasAccessToItem(StoredItemAccessMode.Read, tuple.LastCore, tuple.GetDecorationById("auth").Extension as IUserInfoStore))
                {
                    return(new Tuple <IHasId, object>(null, null));
                }
                return(null);   //do nothing
            },
                                                                      null
                                                                      );

            this.InterceptCore.SearchOperationIntercept.AddNextIntercept("filter",
                                                                         null, null,
                                                                         (tuple) =>
            {
                List <IHasId> itemsToRemove = new List <IHasId>();

                tuple.LastCore.WithEach(item =>
                {
                    //set the core to null if the user doesn't have access
                    if (!this.HasAccessToItem(StoredItemAccessMode.Read, item, tuple.GetDecorationById("auth").Extension as IUserInfoStore))
                    {
                        itemsToRemove.Add(item);
                    }
                });

                //remove those items from the returned list
                List <IHasId> newItems = new List <IHasId>(tuple.LastCore);
                itemsToRemove.WithEach(item =>
                {
                    newItems.Remove(item);
                });

                return(new Tuple <List <IHasId>, object>(newItems, null));
            },
                                                                         null
                                                                         );

            this.InterceptCore.CommitOperationIntercept.AddNextIntercept("filter",
                                                                         null,
                                                                         (tuple) =>
            {
                //check access
                tuple.LastCore.ItemsToDelete.WithEach(del =>
                {
                    HasAccessToItemAndThrow(StoredItemAccessMode.Delete, del.Value, tuple.GetDecorationById("auth").Extension as IUserInfoStore);
                });

                tuple.LastCore.ItemsToSave.WithEach(save =>
                {
                    HasAccessToItemAndThrow(StoredItemAccessMode.Save, save.Value, tuple.GetDecorationById("auth").Extension as IUserInfoStore);
                });
            },
                                                                         null, null);
            #endregion
        }
        public Application(IApp page)
        {
            // jsc does not yet pre package chrome apps nor extensions
            // thus we do it manually.
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/20140705/20140712
            // X:\jsc.svn\examples\javascript\chrome\extensions\ChromeTabsExperiment\ChromeTabsExperiment\Application.cs

            // A single extension can override only one page. For example, an extension can't override both the Bookmark Manager and History pages.


            // we could provide special API for scriptcorelib runtime on the tab being loaded
            // http://blog.chromium.org/

            // what else can we override besides options?
            // "options_page": "Application.htm",
            // https://code.google.com/p/chromium/issues/detail?id=171752
            // https://developer.chrome.com/extensions/options

            // can we provide an API about available android devices?

            #region self_chrome_tabs
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_tabs = self_chrome.tabs;

            if (self_chrome_tabs != null)
            {
                #region Suspend
                chrome.runtime.Suspend += delegate
                  {
                      // dispose all injection done so far?
                      Console.WriteLine("chrome.runtime.Suspend");
                  };
                #endregion


                // jsc, add chrome nuget
                #region Installed
                chrome.runtime.Installed += delegate
                {
                    // our API does not have a Show
                    new chrome.Notification
                    {
                        Message = "Extension Installed!"
                    };
                };
                #endregion

                Action<string> AtMessageFromTabToExtensionForApplication = delegate { };

                Action<string> AtUDPString = delegate { };

                var IgnoreSecondaryUpdatesFor = new List<TabIdInteger>();

                #region Updated
                chrome.tabs.Updated +=
                    async (i, x, tab) =>
                    {
                        // chrome://newtab/

                        if (tab.url.StartsWith("chrome-devtools://"))
                            return;

                        if (tab.url.StartsWith("chrome://"))
                            return;

                        if (tab.status != "complete")
                            return;


                        if (IgnoreSecondaryUpdatesFor.Contains(tab.id))
                            return;

                        // inject?

                        // what if we sent the uri to our android tab?
                        var n = new Notification
                        {
                            Message = "Updated! " + new { tab.id, tab.url }
                        };

                        IgnoreSecondaryUpdatesFor.Add(tab.id);



                        // X:\jsc.svn\core\ScriptCoreLib\JavaScript\BCLImplementation\System\Net\WebClient.cs

                        //var aFileParts = new[] { code };
                        //var oMyBlob = new Blob(aFileParts, new { type = "text/javascript" }); // the blob
                        //var url = oMyBlob.ToObjectURL();

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


                        // when will roslyn learn to expose events as async?
                        await tab.pageAction.async.onclick;

                        var nn = new Notification
                        {
                            Message = "Clicked " + new { tab.id, tab.url }
                        };



                        var code = await new WebClient().DownloadStringTaskAsync(
                             new Uri(Worker.ScriptApplicationSource, UriKind.Relative)
                        );


                        //Console.WriteLine("before insertCSS");

                        // https://developer.chrome.com/extensions/tabs#type-Tab
                        // http://stackoverflow.com/questions/9795058/how-to-run-chrome-tabs-insertcss-from-the-background-page-on-each-page
                        // chrome::
                        tab.id.insertCSS(
                            new
                            {
                                // .css do we have a CSS parser/builder available yet?

                                //code = "body { border: 1em solid red; }"
                                code = "body { border-left: 1em solid yellow; }"
                            },
                            null
                        );

                        // await tab.id.Run(async delegate {});
                        //};


                        // Unchecked runtime.lastError while running tabs.executeScript: No source code or file specified.
                        // https://developer.chrome.com/extensions/tabs#method-executeScript
                        // https://developer.chrome.com/extensions/tabs#type-InjectDetails
                        // https://developer.chrome.com/extensions/content_scripts#pi

                        // Content scripts execute in a special environment called an isolated world. 
                        // They have access to the DOM of the page they are injected into, but not to any JavaScript variables or 
                        // functions created by the page. It looks to each content script as if there is no other JavaScript executing
                        // on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any 
                        // functions or access any variables defined by content scripts.

                        var result = await tab.id.executeScript(
                            //new { file = url }
                            new { code }
                        );




                        // how to use connect?
                        var p = tab.id.connect();
                        var p_disconnected = false;

                        p.onDisconnect.addListener(
                            new Action(
                                delegate
                                {
                                    p_disconnected = true;
                                }
                            )
                        );


                        p.onMessage.addListener(
                            new Action<string>(
                                data =>
                                {
                                    AtMessageFromTabToExtensionForApplication(data);

                                    //Console.WriteLine("extension: onMessage " + new { data });
                                    //new Notification
                                    //{
                                    //    Message = "extension onMessage: " + new { tab.id, data }
                                    //};
                                }
                            )
                        );


                        //p.postMessage("hello executeScript");


                        // lets enable workers within tab
                        p.postMessage(new { code });

                        AtUDPString +=
                            xml =>
                            {
                                //Console.WriteLine("extension: " + new { xml });

                                if (p_disconnected)
                                    return;

                                if (tab.active)
                                {
                                    // only if active tab?
                                    p.postMessage(new { xml });
                                }
                            };
                    };
                #endregion





                #region __MulticastListenExperiment

                // can this chrome.extension connect to a chrome app?
                var __MulticastListenExperiment = "aemlnmcokphbneegoefdckonejmknohh";

                Console.WriteLine("chrome.runtime.connect " + new { __MulticastListenExperiment });

                // what if the app is not loaded, or is inactive?

                chrome.runtime.connect(__MulticastListenExperiment).With(
                      port =>
                      {
                          // Uncaught TypeError: Cannot read property 'id' of undefined
                          Console.WriteLine("chrome.runtime.connect OK " + new { __MulticastListenExperiment, chrome.runtime.lastError });
                          // 0:60ms chrome.runtime.connect OK { __MulticastListenExperiment = aemlnmcokphbneegoefdckonejmknohh, lastError =  } 
                          //Console.WriteLine("chrome.runtime.connect OK " + new { __MulticastListenExperiment, chrome.runtime.lastError, port.sender.id });


                          port.onDisconnect.addListener(
                              new Action(
                                  delegate
                                  {
                                      Console.WriteLine("chrome.runtime.connect onDisconnect " + new { __MulticastListenExperiment });
                                  }
                              )
                          );

                          // we wont know if we got the connection...
                          port.onMessage.addListener(
                                new Action<object>(
                                    message =>
                                    {
                                        // %c0:182ms app to extension { message = hello from app }

                                        //Console.WriteLine("app to extension " + new { message, port.sender.id });
                                        Console.WriteLine("app to extension " + new { message });

                                        //var nn = new chrome.Notification
                                        //{
                                        //    Title = "app to extension",
                                        //    Message = new { message }.ToString(),
                                        //};

                                        AtUDPString((string)message);
                                    }
                                )
                            );

                          AtMessageFromTabToExtensionForApplication +=
                              message =>
                              {
                                  port.postMessage(message);
                              };
                      }
                  );
                #endregion


                //Console.WriteLine("chrome.runtime.connect exit " + new { __MulticastListenExperiment });

                return;
            }
            #endregion

            Native.body.style.borderTop = "1em solid yellow";

            // if we were injected by executeScript, how would we launch a worker now?

            // VM608:41423


            // https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
            //getFileName: if this function was defined in a script returns the name of the script

            //var xx = new Exception();

            //Console.WriteLine(new { xx.StackTrace });
            //0:46ms { StackTrace = Error
            //    at AgsABmfn8j_aa_bqCu59PrPg (http://192.168.43.252:12879/view-source:27498:56)


            //0:25ms { StackTrace = Error
            //    at AgsABmfn8j_aa_bqCu59PrPg (<anonymous>:27498:56)
            //    at mV1GtUeaNze1ZFoeDPNoHQ.type$mV1GtUeaNze1ZFoeDPNoHQ.AwAABkeaNze1ZFoeDPNoHQ (<anonymous>:59652:9)


            // can we atleast try to ask for the source?


            Action<string> Notify = delegate { };

            new xxAvatar().Create();



            #region go worker
            new IHTMLButton { 
                "go worker: ",
               (

                    // we can read our own data, and any other browser extension can too, encrypt it?
                    from x in new xxAvatar()
                    orderby x.Key descending
                    //select x.Tag
                    //select new  {x.Tag}
                    select new xxAvatarRow { Tag = x.Tag}
                ).FirstOrDefaultAsync()
            }.AttachToDocument().With(
            button =>
            {
                button.style.position = [email protected];
                button.style.left = "1em";
                button.style.bottom = "1em";
                //button.style.zIndex = 1000;
                button.style.zIndex = 10000;




                button.onclick +=
                    async e =>
                    {
                        e.Element.disabled = true;


                        button.innerText = "working... ";


                        // live updates from worker via DB.
                        button.Add(

                             () => (

                                // we can read our own data, and any other browser extension can too, encrypt it?
                                from xx in new xxAvatar()
                                orderby xx.Key descending
                                //select x.Tag
                                //select new  {x.Tag}
                                select new xxAvatarRow { Tag = xx.Tag }
                            ).FirstOrDefaultAsync()

                        );


                        Native.body.style.borderTop = "1em solid blue";


                        var scopedata1 = "enter";
                        var scopedata2 = "exit";

                        var x = await Task.Run(
                            async delegate
                            {
                                var s = Stopwatch.StartNew();



                                for (int index = 0; index < 10; index++)
                                {

                                    // does it show up?
                                    await new xxAvatar().InsertAsync(
                                        new xxAvatarRow
                                        {
                                            Tag = "tab worker! " + scopedata1 + new { index, s.ElapsedMilliseconds, Thread.CurrentThread.ManagedThreadId },
                                        }
                                    );

                                    Console.WriteLine(new { Thread.CurrentThread.ManagedThreadId });
                                    await Task.Delay(99);
                                }


                                // does it show up?
                                await new xxAvatar().InsertAsync(
                                    new xxAvatarRow
                                    {
                                        Tag = "tab worker! " + scopedata2 + new { s.ElapsedMilliseconds, Thread.CurrentThread.ManagedThreadId },
                                    }
                                );

                                return "webview worker calling extension " + new { s.ElapsedMilliseconds, Thread.CurrentThread.ManagedThreadId };
                            }
                        );


                        button.innerText = "go worker: ";


                        // live updates from worker via DB.
                        button.Add(

                            // show a static field, so we wont spam console
                             (

                                // we can read our own data, and any other browser extension can too, encrypt it?
                                from xx in new xxAvatar()
                                orderby xx.Key descending
                                //select x.Tag
                                //select new  {x.Tag}
                                select new xxAvatarRow { Tag = xx.Tag }
                            ).FirstOrDefaultAsync()

                        );

                        Notify(x);

                        Native.body.style.borderTop = "1em solid pink";
                        e.Element.disabled = false;
                    };




            }
            );
            #endregion



            var forms = new List<Form>();



            #region onxmlmessage
            Action<XElement> onxmlmessage = null;

            onxmlmessage =
                xml =>
                {
                    // we are working within another webapp
                    // the tab was told by the extension
                    // the extension was told by the app
                    // the app was told by udp broadcast
                    // that a jsc app is now running.

                    // cool.

                    // can we load it into here?

                    if (xml.Value.StartsWith("Visit me at "))
                    {
                        // what about android apps runnning on SSL?
                        // what about preview images?
                        // do we get localhost events too?

                        var uri = "http://" + xml.Value.SkipUntilOrEmpty("Visit me at ");

                        if (forms.Any(x => x.Text == uri))
                        {
                            // look already opened!
                            return;
                        }

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

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




                        // can we pop ourselves out of here too?
                        // can chrome>extensions do AppWindows?


                        // on some pages they style our div. shall we use a non div to get nonstyled element?
                        // or do we need shadow DOM? is it even available yet for us?
                        var f = new Form { Text = uri, ShowIcon = false };
                        forms.Add(f);

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

                        f.Controls.Add(w);

                        w.Navigate(uri);
                        f.Show();

                        f.FormClosed +=
                            delegate
                            {
                                Console.WriteLine("FormClosed " + new { uri });

                                forms.Remove(f);

                            };

                        // if we close it we want it to be gone for good.
                        // the extension cannot detatch our frame. it may need to ask the app to reopen this virtual tab...
                        f.PopupInsteadOfClosing(HandleFormClosing: false,

                            SpecialCloseOnLeft:
                                delegate
                                {
                                    // shall we ask app:: to reopen uri in AppWindow?
                                    Notify(xml.ToString());

                                    f.Close();
                                }
                        );


                    }

                };
            #endregion


            #region Connect
            object self_chrome_runtime = self_chrome.runtime;
            Console.WriteLine(new { self_chrome_runtime });
            // 0:39ms { self_chrome_runtime = [object Object] }
            if (self_chrome_runtime != null)
            {
                chrome.runtime.Connect +=
                        e =>
                        {
                            // port
                            // extension connects to injected tab?
                            Console.WriteLine("chrome.runtime.Connect " + new { Native.document.domain });
                            //Console.WriteLine("chrome.runtime.Connect " + new { Native.document.domain, e.sender.id });

                            //0:123ms chrome.runtime.Connect
                            //0:126ms webview: onMessage { data = hello executeScript }


                            //http://stackoverflow.com/questions/15798516/is-there-an-event-for-when-a-chrome-extension-popup-is-closed


                            e.onDisconnect.addListener(
                                new Action(
                                    delegate
                                    {
                                        // extension unloaded
                                        Native.body.style.borderTop = "0em solid red";
                                        Native.body.style.borderLeft = "0em solid red";

                                        forms.WithEach(f => f.Close());

                                    }
                                )
                            );



                            e.onMessage.addListener(
                                new Action<dynamic>(
                                    data =>
                                    {
                                        string xml = data.xml;
                                        if (xml != null)
                                        {
                                            // tab injection was notified by extension, by app, by udp android?
                                            Native.body.style.borderLeft = "1em solid red";

                                            // 0:40394ms { xml = <string c="1">Visit me at 192.168.1.67:6169</string> }
                                            Console.WriteLine(new { xml });


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

                                            onxmlmessage(
                                                XElement.Parse(xml)
                                                );

                                        }

                                        string code = data.code;
                                        if (code != null)
                                        {

                                            //Console.WriteLine("webview: onMessage " + new { data });

                                            // %c0:41906ms extension: onMessage { data = connected! }
                                            //e.postMessage("got code! " + new { code.Length });

                                            Native.body.style.borderTop = "1em solid red";

                                            // InternalInlineWorker

                                            // http://stackoverflow.com/questions/21408510/chrome-cant-load-web-worker
                                            // this wont work for file:// tabs

                                            // message: "Failed to construct 'Worker': Script at 'blob:null/f544915f-b855-480b-8db8-bd6c686829b9#worker' cannot be accessed from origin 'null'."
                                            var aFileParts = new[] { code };
                                            var oMyBlob = new Blob(aFileParts, new { type = "text/javascript" }); // the blob
                                            var url = oMyBlob.ToObjectURL();

                                            InternalInlineWorker.ScriptApplicationSourceForInlineWorker = url;

                                            Notify = x =>
                                            {
                                                // Error in event handler for (unknown): Attempting to use a disconnected port object Stack trace: Error: Attempting to use a disconnected port object
                                                e.postMessage(x);
                                            };
                                        }
                                    }
                                )
                            );


                        };

                //chrome.runtime.Message +=
                //    delegate
                //    {
                //        Console.WriteLine("chrome.runtime.Message");
                //    };
            }
            #endregion





            // 0:168ms chrome.runtime.Connect
            // https://developer.chrome.com/extensions/tabs#method-sendMessage
            // chrome extension wont call here?
            //Native.window.onmessage +=
            //    e =>
            //    {
            //        Console.WriteLine(
            //            "onmessage: " +
            //            new { e.data }
            //        );




            //        e.postMessage("ok");

            //    };
        }
        // http://youtu.be/Lo1IU8UAutE
        // 60hz 2160 4K!

        // The equirectangular projection was used in map creation since it was invented around 100 A.D. by Marinus of Tyre. 

        //        C:\Users\Arvo> "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hzsky.png" "/sdcard/oculus/360photos/"
        //1533 KB/s(3865902 bytes in 2.461s)

        //C:\Users\Arvo> "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hznosky.png" "/sdcard/oculus/360photos/"
        //1556 KB/s(2714294 bytes in 1.703s)

        //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hz2048c3840x2160.png" "/sdcard/oculus/360photos/"

        // "X:\vr\tape360hzlights\0000.png"
        //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "r:\vr\tape360hzlights\0000.png" "/sdcard/oculus/360photos/hzlights.png"
        // 1421 KB/s (2516443 bytes in 1.729s)



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

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

        // the eye nor the display will be able to do any stereo
        // until tech is near matrix capability. 2019?

        // cubemap can be used for all long range scenes
        // http://www.imdb.com/title/tt0112111/?ref_=nv_sr_1


        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150808/cubemapcamera
        // subst /D a:
        // subst a:  s:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360LightAnimation\Chrome360LightAnimation\bin\Debug\staging\Chrome360LightAnimation.Application\web
        // subst a: z:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360LightAnimation\Chrome360LightAnimation\bin\Debug\staging\Chrome360LightAnimation.Application\web
        // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360LightAnimation\Chrome360LightAnimation\bin\Debug\staging\Chrome360LightAnimation.Application\web
        // what if we want to do subst in another winstat or session?

        // ColladaLoader: Empty or non-existing file (assets/Chrome360LightAnimation/S6Edge.dae)

        /// <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 =
            //s =>
            //{
            //    s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

            //    //var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
            //    var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDragWithShadow().AttachTo(s.Context.GetHTMLTarget());



            //    s.Context.GetHTMLTarget().style.backgroundColor = "#efefef";
            //    //s.Context.GetHTMLTarget().style.backgroundColor = "#A26D41";

            //};

#if AsWEBSERVER
            #region += Launched chrome.app.window
            // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

            if (self_chrome_socket != null)
            {
                // if we run as a server. we can open up on android.

                //chrome.Notification.DefaultTitle = "Nexus7";
                //chrome.Notification.DefaultIconUrl = new x128().src;
                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                     AppSource.Text
                //, AtFormCreated: FormStyler.AtFormCreated

                //AtFormConstructor:
                //    f =>
                //    {
                //        //arg[0] is typeof System.Int32
                //        //script: error JSC1000: No implementation found for this native method, please implement [static System.Drawing.Color.FromArgb(System.Int32)]

                //        // X:\jsc.svn\examples\javascript\forms\Test\TestFromArgb\TestFromArgb\ApplicationControl.cs

                //        f.BackColor = System.Drawing.Color.FromArgb(0xA26D41);
                //    }
                );
                return;
            }
            #endregion
#else

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

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

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

                    //};

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

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

                        // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions
                        var xappwindow = await chrome.app.window.create(
                               Native.document.location.pathname, options: new
                               {
                                   alwaysOnTop = true,
                                   visibleOnAllWorkspaces = true
                               }
                        );

                        //xappwindow.setAlwaysOnTop

                        xappwindow.show();

                        await xappwindow.contentWindow.async.onload;

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


                    return;
                }
            }
            #endregion


#endif



            //const int size = 128;
            //const int size = 256; // 6 faces, 12KB
            //const int size = 512; // 6 faces, ?

            // WebGL: drawArrays: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.

            //const int size = 720; // 6 faces, ?
            //const int size = 1024; // 6 faces, ?
            //const int cubefacesize = 1024; // 6 faces, ?

            // THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( chrome-extension://aemlnmcokphbneegoefdckonejmknohh/assets/Chrome360LightAnimation/anvil___spherical_hdri_panorama_skybox_by_macsix_d6vv4hs.jpg )
            int cubefacesize = 2048; // 6 faces, ?
                                     // "X:\vr\tape1\0000x2048.png"
                                     // for 60hz render we may want to use float camera percision, not available for ui.
                                     //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\tape1\0000x2048.png" "/sdcard/oculus/360photos/"
                                     //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\tape1\0000x128.png" "/sdcard/oculus/360photos/"

            //if (Environment.ProcessorCount < 8)
            //    //cubefacesize = 64; // 6 faces, ?
            //    cubefacesize = 128; // 6 faces, ?

            new IHTMLPre { new { Environment.ProcessorCount, cubefacesize } }.AttachToDocument();

            // can we keep fast fps yet highp?

            // can we choose this on runtime? designtime wants fast fps, yet for end product we want highdef on our render farm?
            //const int cubefacesize = 128; // 6 faces, ?

            //var cubecameraoffsetx = 256;
            var cubecameraoffsetx = 400;


            //var uizoom = 0.1;
            //var uizoom = cubefacesize / 128f;
            var uizoom = 128f / cubefacesize;

            var far = 0xffffff;

            Native.css.style.backgroundColor = "blue";
            Native.css.style.overflow = IStyle.OverflowEnum.hidden;

            Native.body.Clear();
            (Native.body.style as dynamic).webkitUserSelect = "text";

            //new IHTMLPre { "can we stream it into VR, shadertoy, youtube 360, youtube stereo yet?" }.AttachToDocument();


            var sw = Stopwatch.StartNew();



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

            var window = Native.window;


            // what about physics and that portal rendering?

            // if we are running as a chrome web server, we may also be opened as android ndk webview app
            //var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: window.aspect, near: 1, far: 2000);
            // once we update source
            // save the source
            // manually recompile 
            //cameraPX.position.z = 400;

            //// the camera should be close enough for the object to float off the FOV of PX
            //cameraPX.position.z = 200;

            // scene
            // can we make the 3D object orbit around us ?
            // and
            // stream it to vr?
            var scene = new THREE.Scene();

            // since our cube camera is somewhat a fixed thing
            // would it be easier to move mountains to come to us?
            // once we change code would chrome app be able to let VR know that a new view is available?
            var sceneg = new THREE.Group();
            sceneg.AttachTo(scene);


            // fly up?
            //sceneg.translateZ(-1024);
            // rotate the world, as the skybox then matches what we have on filesystem
            scene.rotateOnAxis(new THREE.Vector3(0, 1, 0), -Math.PI / 2);
            // yet for headtracking we shall rotate camera


            //sceneg.position.set(0, 0, -1024);
            //sceneg.position.set(0, -1024, 0);

            var ambient = new THREE.AmbientLight(0x303030).AttachTo(sceneg);
            //scene.add(ambient);

            // should we fix jsc to do a more correct IDL?
            //var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
            //directionalLight.position.set(0, 0, 1);
            //scene.add(directionalLight);

            #region light
            //var light = new THREE.DirectionalLight(0xffffff, 1.0);
            var light = new THREE.DirectionalLight(0xffffff, 2.5);
            //var light = new THREE.DirectionalLight(0xffffff, 2.5);
            //var light = new THREE.DirectionalLight(0xffffff, 1.5);
            //var lightOffset = new THREE.Vector3(0, 1000, 2500.0);
            var lightOffset = new THREE.Vector3(
                2000,
                700,

                // lower makes longer shadows 
                700.0
                );
            light.position.copy(lightOffset);
            light.castShadow = true;

            var xlight = light as dynamic;
            xlight.shadowMapWidth = 4096;
            xlight.shadowMapHeight = 2048;

            xlight.shadowDarkness = 0.1;
            //xlight.shadowDarkness = 0.5;

            xlight.shadowCameraNear = 10;
            xlight.shadowCameraFar = 10000;
            xlight.shadowBias = 0.00001;
            xlight.shadowCameraRight = 4000;
            xlight.shadowCameraLeft = -4000;
            xlight.shadowCameraTop = 4000;
            xlight.shadowCameraBottom = -4000;

            // wont show if we add skybox?
            xlight.shadowCameraVisible = true;

            //scene.add(light);
            //light.AttachTo(sceneg);
            #endregion




            // whats WebGLRenderTargetCube do?

            // WebGLRenderer preserveDrawingBuffer 



            var renderer0 = new THREE.WebGLRenderer(

                new
                {
                    antialias = true,
                    alpha = true,
                    preserveDrawingBuffer = true
                }
            );


            // must enable shadows on the renderer 
            renderer0.shadowMapEnabled = true;

            // https://github.com/mrdoob/three.js/issues/3836

            // the construct. white bg
            //renderer0.setClearColor(0xfffff, 1);

            //renderer.setSize(window.Width, window.Height);
            renderer0.setSize(cubefacesize, cubefacesize);

            //renderer0.domElement.AttachToDocument();
            //rendererPX.domElement.style.SetLocation(0, 0);
            //renderer0.domElement.style.SetLocation(4, 4);


            // top

            // http://stackoverflow.com/questions/27612524/can-multiple-webglrenderers-render-the-same-scene


            // need a place to show the cubemap face to GUI 
            // how does the stereo OTOY do it?
            // https://www.opengl.org/wiki/Sampler_(GLSL)

            // http://www.richardssoftware.net/Home/Post/25

            // [+X, –X, +Y, –Y, +Z, –Z] fa



            // move up
            //camera.position.set(-1200, 800, 1200);
            //var cameraoffset = new THREE.Vector3(0, 15, 0);

            // can we aniamte it?
            //var cameraoffset = new THREE.Vector3(0, 800, 1200);
            // can we have linear animation fromcenter of the map to the edge and back?
            // then do the flat earth sun orbit?
            var cameraoffset = new THREE.Vector3(
                // left?
                -512,
                // height?
                //0,
                //1600,
                //1024,

                // if the camera is in the center, would we need to move the scene?
                // we have to move the camera. as we move the scene the lights are messed up
                //2014,
                1024,

                //1200
                0
                // can we hover top of the map?
                );

            // original vieworigin
            //var cameraoffset = new THREE.Vector3(-1200, 800, 1200);



            var camerax = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = 0 - 2048, max = 0 + 2048, valueAsNumber = -512, title = "camerax" }.AttachToDocument();
            // up. whats the most high a rocket can go 120km?
            new IHTMLHorizontalRule { }.AttachToDocument();


            // how high is the bunker?
            var cameray = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = 64, max = 2048, valueAsNumber = 1024, title = "cameray" }.AttachToDocument();
            new IHTMLBreak { }.AttachToDocument();
            var camerayHigh = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = cameray.max, max = 1024 * 256, valueAsNumber = cameray.max, title = "cameray" }.AttachToDocument();
            new IHTMLHorizontalRule { }.AttachToDocument();
            var cameraz = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = 0 - 2048, max = 0 + 2048, valueAsNumber = 0, title = "cameraz" }.AttachToDocument();

            // for render server
            var fcamerax = 0.0;
            var fcameray = 0.0;
            var fcameraz = 0.0;

            //while (await camerax.async.onchange)

            //cameray.onchange += delegate
            //{
            //    if (cameray.valueAsNumber < cameray.max)
            //        camerayHigh.valueAsNumber = camerayHigh.min;
            //};

            camerayHigh.onmousedown += delegate
            {
                //if (camerayHigh.valueAsNumber > camerayHigh.min)
                cameray.valueAsNumber = cameray.max;
            };


            Action applycameraoffset = delegate
            {
                // make sure UI and gpu sync up

                var cy = cameray;

                if (cameray.valueAsNumber < cameray.max)
                    camerayHigh.valueAsNumber = camerayHigh.min;

                if (camerayHigh.valueAsNumber > camerayHigh.min)
                    cameray.valueAsNumber = cameray.max;

                if (cameray.valueAsNumber == cameray.max)
                    cy = camerayHigh;



                cameraoffset = new THREE.Vector3(
                  // left?
                  camerax + fcamerax,
                   // height?
                   //0,
                   //1600,
                   //1024,

                   // if the camera is in the center, would we need to move the scene?
                   // we have to move the camera. as we move the scene the lights are messed up
                   //2014,
                   cy + fcameray,

                   //1200
                   cameraz + fcameraz
                   // can we hover top of the map?
                   );
            };


            #region y
            // need to rotate90?
            var cameraNY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraNY.position.copy(new THREE.Vector3(0, 0, 0));
                cameraNY.lookAt(new THREE.Vector3(0, -1, 0));
                cameraNY.position.add(cameraoffset);
            };

            //cameraNY.lookAt(new THREE.Vector3(0, 1, 0));
            var canvasNY = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNY.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 2);
            canvasNY.canvas.title = "NY";
            canvasNY.canvas.AttachToDocument();
            canvasNY.canvas.style.transformOrigin = "0 0";
            canvasNY.canvas.style.transform = $"scale({uizoom})";

            var cameraPY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraPY.position.copy(new THREE.Vector3(0, 0, 0));
                cameraPY.lookAt(new THREE.Vector3(0, 1, 0));
                cameraPY.position.add(cameraoffset);
            };
            //cameraPY.lookAt(new THREE.Vector3(0, -1, 0));
            var canvasPY = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPY.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 0);
            canvasPY.canvas.title = "PY";
            canvasPY.canvas.AttachToDocument();
            canvasPY.canvas.style.transformOrigin = "0 0";
            canvasPY.canvas.style.transform = $"scale({uizoom})";
            #endregion

            // transpose xz?

            #region x
            var cameraNX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraNX.position.copy(new THREE.Vector3(0, 0, 0));
                cameraNX.lookAt(new THREE.Vector3(0, 0, 1));
                cameraNX.position.add(cameraoffset);
            };
            //cameraNX.lookAt(new THREE.Vector3(0, 0, -1));
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNX.lookAt(new THREE.Vector3(1, 0, 0));
            var canvasNX = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNX.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 2, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasNX.canvas.title = "NX";
            canvasNX.canvas.AttachToDocument();
            canvasNX.canvas.style.transformOrigin = "0 0";
            canvasNX.canvas.style.transform = $"scale({uizoom})";

            var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraPX.position.copy(new THREE.Vector3(0, 0, 0));
                cameraPX.lookAt(new THREE.Vector3(0, 0, -1));
                cameraPX.position.add(cameraoffset);
            };
            //cameraPX.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPX.lookAt(new THREE.Vector3(1, 0, 0));
            //cameraPX.lookAt(new THREE.Vector3(-1, 0, 0));
            var canvasPX = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPX.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 0, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasPX.canvas.title = "PX";
            canvasPX.canvas.AttachToDocument();
            canvasPX.canvas.style.transformOrigin = "0 0";
            canvasPX.canvas.style.transform = $"scale({uizoom})";
            #endregion



            #region z
            var cameraNZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, -1));
            applycameraoffset += delegate
            {
                cameraNZ.position.copy(new THREE.Vector3(0, 0, 0));
                cameraNZ.lookAt(new THREE.Vector3(1, 0, 0));
                cameraNZ.position.add(cameraoffset);
            };
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, 1));
            var canvasNZ = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNZ.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 3, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasNZ.canvas.title = "NZ";
            canvasNZ.canvas.AttachToDocument();
            canvasNZ.canvas.style.transformOrigin = "0 0";
            canvasNZ.canvas.style.transform = $"scale({uizoom})";

            var cameraPZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraPZ.lookAt(new THREE.Vector3(1, 0, 0));
            applycameraoffset += delegate
            {
                cameraPZ.position.copy(new THREE.Vector3(0, 0, 0));
                cameraPZ.lookAt(new THREE.Vector3(-1, 0, 0));
                cameraPZ.position.add(cameraoffset);
            };
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, -1));
            var canvasPZ = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPZ.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasPZ.canvas.title = "PZ";
            canvasPZ.canvas.AttachToDocument();
            canvasPZ.canvas.style.transformOrigin = "0 0";
            canvasPZ.canvas.style.transform = $"scale({uizoom})";
            #endregion




            // c++ alias locals would be nice..
            var canvas0 = (IHTMLCanvas)renderer0.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


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

            //canvas0.css.active.style.cursor = IStyle.CursorEnum.move;

            #region onmousedown
            Native.body.onmousedown +=
                async e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                        return;

                    // movementX no longer works
                    old = new
                    {


                        e.CursorX,
                        e.CursorY
                    };


                    //e.CaptureMouse();
                    var release = e.Element.CaptureMouse();
                    await e.Element.async.onmouseup;

                    release();


                };
            #endregion



            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            Native.body.onmousemove +=
                e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                    {
                        Native.body.style.cursor = [email protected];
                        return;
                    }

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


                    Native.body.style.cursor = IStyle.CursorEnum.move;

                    var pointerLock = canvas0 == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion

            // THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(78,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll
            // THREE.WebGLProgram: gl.getProgramInfoLog() (79,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll

            // http://www.roadtovr.com/youtube-confirms-stereo-3d-360-video-support-coming-soon/
            // https://www.youtube.com/watch?v=D-Wl9jAB45Q



            #region spherical
            var gl = new WebGLRenderingContext(alpha: true, preserveDrawingBuffer: true);
            var c = gl.canvas.AttachToDocument();

            //  3840x2160

            //c.style.SetSize(3840, 2160);

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


            c.width = 3840;
            c.height = 2160;


            //c.width = 3840 * 2;
            //c.height = 2160 * 2;


            //c.width = 3840;
            //c.height = 2160;
            // 1,777777777777778

            // https://www.youtube.com/watch?v=fTfJwzRsE-w
            //c.width = 7580;
            //c.height = 3840;
            //1,973958333333333

            //7580
            //    3840

            // wont work
            //c.width = 8192;
            //c.height = 4096;


            // this has the wrong aspect?
            //c.width = 6466;
            //c.height = 3232;

            new IHTMLPre { new { c.width, c.height } }.AttachToDocument();

            //6466x3232

            //var suizoom = 720f / c.height;
            //var suizoom = 360f / c.height;
            var suizoom = 480f / c.width;

            c.style.transformOrigin = "0 0";
            c.style.transform = $"scale({suizoom})";
            //c.style.backgroundColor = "yellow";
            c.style.position = IStyle.PositionEnum.absolute;

            c.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 0, 8 + (int)(uizoom * cubefacesize + 8) * 3);

            var pass = new CubeToEquirectangular.Library.ShaderToy.EffectPass(
                       null,
                       gl,
                       precission: CubeToEquirectangular.Library.ShaderToy.DetermineShaderPrecission(gl),
                       supportDerivatives: gl.getExtension("OES_standard_derivatives") != null,
                       callback: null,
                       obj: null,
                       forceMuted: false,
                       forcePaused: false,
                       //quadVBO: Library.ShaderToy.createQuadVBO(gl, right: 0, top: 0),
                       outputGainNode: null
                   );

            // how shall we upload our textures?
            // can we reference GLSL.samplerCube yet?
            //pass.mInputs[0] = new samplerCube { };
            pass.mInputs[0] = new CubeToEquirectangular.Library.ShaderToy.samplerCube { };

            pass.MakeHeader_Image();
            var vs = new Shaders.ProgramFragmentShader();
            pass.NewShader_Image(vs);

            #endregion




            var frame0 = new HTML.Images.FromAssets.galaxy_starfield().AttachToDocument();
            //var frame0 = new HTML.Images.FromAssets.tiles_regrid().AttachToDocument();
            //var frame0 = new HTML.Images.FromAssets.anvil___spherical_hdri_panorama_skybox_by_macsix_d6vv4hs().AttachToDocument();
            //var xor = new HTML.Images.FromAssets.Orion360_test_image_8192x4096().AttachToDocument();
            //var xor = new HTML.Images.FromAssets._2_no_clouds_4k().AttachToDocument();
            //var frame0 = new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().AttachToDocument();


            // 270px
            //xor.style.height = "";
            frame0.style.height = "270px";
            frame0.style.width = "480px";
            frame0.style.SetLocation(
                8 + (int)(uizoom * cubefacesize + 8) * 0 + 480 + 16, 8 + (int)(uizoom * cubefacesize + 8) * 3);



            #region  skybox
            // what shall the skybox do if we reach upper altitude?
            // fade into space skybox ?
            var skybox = new THREE.Mesh(new THREE.SphereGeometry(far * 0.9, 50, 50),
           new THREE.MeshBasicMaterial(new
           {
               map = THREE.ImageUtils.loadTexture(
                  //new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().src
                  //new HTML.Images.FromAssets._4008650304_7f837ccbb7_b().src
                  frame0.src
                   //new WebGLEquirectangularPanorama.HTML.Images.FromAssets.PANO_20130616_222058().src
                   //new WebGLEquirectangularPanorama.HTML.Images.FromAssets.PANO_20121225_210448().src

                   )
           }));
            skybox.scale.x = -1;
            skybox.AttachTo(sceneg);
            #endregion



            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI / 2);
            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI / 2);

            // dont need the fixup. unless we want to animate the sky rotate?
            //mesh.rotateOnAxis(new THREE.Vector3(0, 1, 0), -Math.PI / 2);


            // hide the sky to see camera lines?
            //  can we show this as HUD on VR in webview?
            //skybox.visible = false;
            //scene.add(skybox);




            //new IHTMLButton { }

            #region DirectoryEntry
            var dir = default(DirectoryEntry);

            new IHTMLButton { "openDirectory" }.AttachToDocument().onclick += async delegate
            {
                dir = (DirectoryEntry)await chrome.fileSystem.chooseEntry(new { type = "openDirectory" });
            };

            frame0.onclick += delegate
            {
                // http://paulbourke.net/papers/vsmm2006/vsmm2006.pdf
                //            A method of creating synthetic stereoscopic panoramic images that can be implemented
                //in most rendering packages has been presented. If single panoramic pairs can be created
                //then stereoscopic panoramic movies are equally possible giving rise to the prospect of
                //movies where the viewer can interact with, at least with regard to what they choose to look
                //at.These images can be projected so as to engage the two features of the human visual
                //system that assist is giving us a sense of immersion, the feeling of “being there”. That is,
                //imagery that contains parallax information as captured from two horizontally separated eye
                //positions (stereopsis)and imagery that fills our peripheral vision.The details that define
                //how the two panoramic images should be created in rendering packages are provided, in
                //particular, how to precisely configure the virtual cameras and control the distance to zero
                //parallax.

                // grab a frame

                if (dir == null)
                {
                    // not exporting to file system?
                    var f0 = new IHTMLImage { src = gl.canvas.toDataURL() };

                    //var f0 = (IHTMLImage)gl.canvas;
                    //var f0 = (IHTMLImage)gl.canvas;
                    //var base64 = gl.canvas.toDataURL();


                    //frame0.src = base64;
                    frame0.src = f0.src;

                    // 7MB!

                    return;
                }

                //                // ---------------------------
                //IrfanView
                //---------------------------
                //Warning !
                //The file: "X:\vr\tape1\0001.jpg" is a PNG file with incorrect extension !
                //Rename ?
                //---------------------------
                //Yes   No   
                //---------------------------

                // haha this will render the thumbnail.
                //dir.WriteAllBytes("0000.png", frame0);

                //dir.WriteAllBytes("0000.png", gl.canvas);

                var glsw = Stopwatch.StartNew();
                dir.WriteAllBytes("0000.png", gl);

                new IHTMLPre { new { glsw.ElapsedMilliseconds } }.AttachToDocument();

                // {{ ElapsedMilliseconds = 1548 }}

                // 3.7MB
                // 3840x2160

            };

            #endregion

            var vsync = default(TaskCompletionSource<object>);

            new IHTMLButton {
                "render 60hz 30sec"
            }.AttachToDocument().onclick += async e =>
            {
                e.Element.disabled = true;


                var total = Stopwatch.StartNew();
                var status = "rendering... " + new { dir };

                new IHTMLPre { () => status }.AttachToDocument();

                if (dir == null)
                {
                    //dir = (DirectoryEntry)await chrome.fileSystem.chooseEntry(new { type = "openDirectory" });
                }

                total.Restart();



                vsync = new TaskCompletionSource<object>();
                await vsync.Task;

                status = "rendering... vsync";

                var frameid = -1;

                goto beforeframe;
                //fcamerax = -15.0;

                // parallax offset?

                await_nextframe:


                var filename = frameid.ToString().PadLeft(4, '0') + ".png";
                status = "rendering... " + new { frameid, filename };


                vsync = new TaskCompletionSource<object>();
                await vsync.Task;

                // frame0 has been rendered

                var swcapture = Stopwatch.StartNew();
                status = "WriteAllBytes... " + new { filename };
                //await Native.window.async.onframe;

                if (dir != null)
                    // https://code.google.com/p/chromium/issues/detail?id=404301
                    await dir.WriteAllBytes(filename, gl);

                //await dir.WriteAllBytes(filename, gl.canvas);

                status = "WriteAllBytes... done " + new { fcamerax, filename, swcapture.ElapsedMilliseconds };
                status = "rdy " + new { filename, fcamerax };
                //await Native.window.async.onframe;



                beforeframe:

                // speed? S6 slow motion?
                // this is really slow. if we do x4x2 =x8 
                // https://www.youtube.com/watch?v=r76ULW16Ib8
                //fcamerax += 16 * (1.0 / 60.0);
                fcamerax = 128 * Math.Sin(Math.PI * (frameid - (60 * 30 / 2f)) / (60 * 30 / 2f));
                fcameraz = 256 * Math.Cos(Math.PI * (frameid - (60 * 30 / 2f)) / (60 * 30 / 2f));


                // up
                fcameray = 16 * Math.Cos(Math.PI * (frameid - (60 * 30 / 2f)) / (60 * 30 / 2f));

                //fcamerax += (1.0 / 60.0);

                //fcamerax += (1.0 / 60.0) * 120;

                if (Environment.ProcessorCount < 8)
                    frameid += 30;
                else
                    frameid++;

                // 60hz 30sec
                if (frameid < 60 * 30)
                {
                    // Blob GC? either this helms or the that we made a Blob static. 
                    await Task.Delay(11);

                    goto await_nextframe;
                }

                total.Stop();
                status = "all done " + new { frameid, total.ElapsedMilliseconds };
                vsync = default(TaskCompletionSource<object>);
                // http://stackoverflow.com/questions/22899333/delete-javascript-blobs

                e.Element.disabled = false;
            };

            // "Z:\jsc.svn\examples\javascript\WebGL\WebGLColladaExperiment\WebGLColladaExperiment\WebGLColladaExperiment.csproj"

            #region WebGLRah66Comanche
            // why isnt it being found?
            // "Z:\jsc.svn\examples\javascript\WebGL\collada\WebGLRah66Comanche\WebGLRah66Comanche\WebGLRah66Comanche.csproj"
            new global::WebGLRah66Comanche.Comanche(
            ).Source.Task.ContinueWithResult(
                dae =>
                {
                    dae.AttachTo(sceneg);
                    //dae.position.y = -40;
                    //dae.position.z = 280;
                    //scene.add(dae);
                    //oo.Add(dae);

                    // wont do it
                    //dae.castShadow = true;

                    dae.children[0].children[0].children.WithEach(x => x.castShadow = true);


                    // the rotors?
                    dae.children[0].children[0].children.Last().children.WithEach(x => x.castShadow = true);


                    dae.scale.set(0.5, 0.5, 0.5);
                    dae.position.x = -900;
                    dae.position.z = +900;

                    // raise it up
                    dae.position.y = 400;

                    //var sw = Stopwatch.StartNew();

                    //Native.window.onframe += delegate
                    //{
                    //    //dae.children[0].children[0].children.Last().al
                    //    //dae.children[0].children[0].children.Last().rotation.z = sw.ElapsedMilliseconds * 0.01;
                    //    //dae.children[0].children[0].children.Last().rotation.x = sw.ElapsedMilliseconds * 0.01;
                    //    dae.children[0].children[0].children.Last().rotation.y = sw.ElapsedMilliseconds * 0.01;
                    //};
                }
            );
            #endregion



            #region tree
            // "Z:\jsc.svn\examples\javascript\WebGL\WebGLGodRay\WebGLGodRay\WebGLGodRay.csproj"

            var materialScene = new THREE.MeshBasicMaterial(new { color = 0x000000, shading = THREE.FlatShading });
            var tloader = new THREE.JSONLoader();

            // http://stackoverflow.com/questions/16539736/do-not-use-system-runtime-compilerservices-dynamicattribute-use-the-dynamic
            // https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.dynamicattribute%28v=vs.110%29.aspx
            //System.Runtime.CompilerServices.DynamicAttribute

            tloader.load(

                new WebGLGodRay.Models.tree().Content.src,

                new Action<THREE.Geometry>(
                xgeometry =>
                {

                    var treeMesh = new THREE.Mesh(xgeometry, materialScene);
                    treeMesh.position.set(0, -150, -150);
                    treeMesh.position.x = -900;
                    treeMesh.position.z = -900;

                    treeMesh.position.y = 25;

                    var tsc = 400;
                    treeMesh.scale.set(tsc, tsc, tsc);

                    treeMesh.matrixAutoUpdate = false;
                    treeMesh.updateMatrix();


                    //treeMesh.AttachTo(scene);
                    treeMesh.AttachTo(sceneg);

                }
                )
                );
            #endregion


            // http://learningthreejs.com/blog/2013/09/16/how-to-make-the-earth-in-webgl/

            #region create floor

            // THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint.
            // can we have our checkerboard?

            var floorColors = new[] {
                0xA26D41,
                0xA06040,
                0xAF6F4F,
                // marker to detect horizon
                0xAF0000,



                0xA26D41,
                0xA06040,
                0xAF6F4F,
                // marker to detect horizon
                0x006D00,



                0xA26D41,
                0xA06040,
                0xAF6F4F,
                // marker to detect horizon
                0x0000FF
            };


            // human eye can see up to 10miles, then horizion flattens out.
            var planeGeometry = new THREE.CubeGeometry(2048, 1, 2048);
            var planeGeometryMarkerH = new THREE.CubeGeometry(2048, 1, 2048 * 5);


            var planeGeometryMarkerV = new THREE.CubeGeometry(2048 * 5 * 4, 1, 2048 * 4);
            var planeGeometryV = new THREE.CubeGeometry(2048 * 4, 1, 2048 * 4);
            ////var floor0 = new THREE.Mesh(planeGeometry,
            ////        new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })

            ////    );
            //////plane.castShadow = false;
            ////floor0.receiveShadow = true;
            ////floor0.AttachTo(sceneg);

            ////var floor1 = new THREE.Mesh(planeGeometry,
            ////       //new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })
            ////       new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA06040, specular = 0xA26D41, shininess = 1 })

            ////   );
            //////plane.castShadow = false;
            ////floor1.receiveShadow = true;
            ////floor1.position.set(2048, 0, 1024);
            ////floor1.AttachTo(sceneg);

            // can we see horizon?
            for (int i = 0; i < 3 * 256; i++)
            {
                var planeGeometry0 = planeGeometry;

                if (i % 4 == 3)
                {
                    planeGeometry0 = planeGeometryMarkerH;

                    // for high altitude zoom level

                    var i4 = (i / 4);


                    var planeGeometryV0 = planeGeometryV;

                    if (i4 % 4 == 3)
                        planeGeometryV0 = planeGeometryMarkerV;

                    {
                        var floor2 = new THREE.Mesh(planeGeometryV0,
                            //new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })
                            new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = floorColors[i4 % floorColors.Length], specular = 0xA26D41, shininess = 1 })

                        );
                        //plane.castShadow = false;
                        floor2.receiveShadow = true;
                        floor2.position.set(1024 * -i, 0, 2048 * i);
                        floor2.AttachTo(scene);
                    }


                    {
                        var floor2 = new THREE.Mesh(planeGeometryV0,
                            //new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })
                            new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = floorColors[(i / 4) % floorColors.Length], specular = 0xA26D41, shininess = 1 })

                        );
                        //plane.castShadow = false;
                        floor2.receiveShadow = true;
                        floor2.position.set(-1024 * -i, 0, -2048 * i);
                        floor2.AttachTo(scene);
                    }
                }

                {
                    var floor2 = new THREE.Mesh(planeGeometry0,
                        //new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })
                        new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = floorColors[i % floorColors.Length], specular = 0xA26D41, shininess = 1 })

                    );
                    //plane.castShadow = false;
                    floor2.receiveShadow = true;
                    floor2.position.set(2048 * i, 0, 1024 * i);
                    floor2.AttachTo(scene);
                }

                // flipz
                {
                    var floor2 = new THREE.Mesh(planeGeometry0,
                        //new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = 0xA26D41, specular = 0xA26D41, shininess = 1 })
                        new THREE.MeshPhongMaterial(new { ambient = 0x101010, color = floorColors[i % floorColors.Length], specular = 0xA26D41, shininess = 1 })

                    );
                    //plane.castShadow = false;
                    floor2.receiveShadow = true;
                    floor2.position.set(2048 * -i, 0, 1024 * -i);
                    floor2.AttachTo(scene);
                }
            }

            #endregion



            // "shadow cameras" show the light source and direction

            // spotlight #1 -- yellow, dark shadow
            var spotlight = new THREE.SpotLight(0xffff00);
            spotlight.position.set(-60, 150, -30);
            //spotlight.shadowCameraVisible = true;
            spotlight.shadowDarkness = 0.95;
            spotlight.intensity = 2;
            // must enable shadow casting ability for the light
            spotlight.castShadow = true;
            scene.add(spotlight);

            // spotlight #2 -- red, light shadow
            var spotlight2 = new THREE.SpotLight(0xff0000);
            //var spotlight2 = new THREE.SpotLight(0xffff00);
            spotlight2.position.set(60, 150, -60);
            scene.add(spotlight2);
            //spotlight2.shadowCameraVisible = true;
            spotlight2.shadowDarkness = 0.70;
            spotlight2.intensity = 2;
            spotlight2.castShadow = true;


            // THREE.WebGLProgram: gl.getProgramInfoLog() Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (16).
            for (int i = 0; i < 8; i++)
            {

                // spotlight #3 blue
                var spotlight3 = new THREE.SpotLight(0x0000ff);
                //var spotlight3 = new THREE.SpotLight(0x00ffff);
                spotlight3.position.set(150 * i, 80, -100);
                //spotlight3.shadowCameraVisible = true;
                spotlight3.shadowDarkness = 0.95;
                spotlight3.intensity = 2;
                spotlight3.castShadow = true;
                scene.add(spotlight3);
                // change the direction this spotlight is facing
                var lightTarget = new THREE.Object3D();
                lightTarget.position.set(150 * i, 10, -100);
                scene.add(lightTarget);
                spotlight3.target = lightTarget;



            }





            // cube: mesh to cast shadows
            #region castShadow
            var cubeGeometry = new THREE.CubeGeometry(50, 50, 50);
            var cubeMaterial = new THREE.MeshLambertMaterial(new { color = 0x888888 });

            var cube0 = new THREE.Mesh(cubeGeometry, cubeMaterial);
            //cube.position.set(0, 50, 0);
            cube0.position.set(0, 100, 0);
            // Note that the mesh is flagged to cast shadows
            cube0.castShadow = true;
            scene.add(cube0);

            // floor: mesh to receive shadows

            #endregion






            #region create walls

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

            for (var i = 3; i < 9; i++)
            {

                //THREE.MeshPhongMaterial
                var ii = new THREE.Mesh(geometry,


                    new THREE.MeshPhongMaterial(new { ambient = 0x000000, color = 0xA06040, specular = 0xA26D41, shininess = 1 })

                    //new THREE.MeshLambertMaterial(
                    //new
                    //{
                    //    color = (Convert.ToInt32(0xffffff * random.NextDouble())),
                    //    specular = 0xffaaaa,
                    //    ambient= 0x050505, 
                    //})

                    );
                ii.position.x = i % 7 * 200 - 2.5f;

                // raise it up
                ii.position.y = .5f * 100 * i;
                ii.position.z = -1 * i * 100;

                ii.castShadow = true;
                ii.receiveShadow = true;
                //ii.scale.set(100, 100, 100 * i);
                ii.scale.set(100, 100 * i, 100);


                meshArray.Add(ii);

                //scene.add(ii);
                ii.AttachTo(sceneg);

                if (i % 2 == 0)
                {

                    // Z:\jsc.svn\examples\javascript\WebGL\WebGLHZBlendCharacter\WebGLHZBlendCharacter\Application.cs
#if FWebGLHZBlendCharacter
                    #region SpeedBlendCharacter
                    var _i = i;
                    { WebGLHZBlendCharacter.HTML.Pages.TexturesImages ref0; }

                    var blendMesh = new THREE.SpeedBlendCharacter();
                    blendMesh.load(
                        new WebGLHZBlendCharacter.Models.marine_anims().Content.src,
                        new Action(
                            delegate
                            {
                                // buildScene
                                //blendMesh.rotation.y = Math.PI * -135 / 180;
                                blendMesh.castShadow = true;
                                // we cannot scale down we want our shadows
                                //blendMesh.scale.set(0.1, 0.1, 0.1);

                                blendMesh.position.x = (_i + 2) % 7 * 200 - 2.5f;

                                // raise it up
                                //blendMesh.position.y = .5f * 100;
                                blendMesh.position.z = -1 * _i * 100;


                                var xtrue = true;
                                // run
                                blendMesh.setSpeed(1.0);

                                // will in turn call THREE.AnimationHandler.play( this );
                                blendMesh.run.play();
                                // this wont help. bokah does not see the animation it seems.
                                blendMesh.run.update(1);

                                blendMesh.showSkeleton(!xtrue);

                                //scene.add(blendMesh);
                                blendMesh.AttachTo(sceneg);


                                //Native.window.onframe +=
                                // delegate
                                // {

                                //     blendMesh.rotation.y = Math.PI * 0.0002 * sw.ElapsedMilliseconds;



                                //     ii.rotation.y = Math.PI * 0.0002 * sw.ElapsedMilliseconds;

                                // };

                            }
                        )
                    );
                    #endregion
#endif
                }

            }
            #endregion


            //#region HZCannon
            //// "Z:\jsc.svn\examples\javascript\WebGL\HeatZeekerRTSOrto\HeatZeekerRTSOrto\HeatZeekerRTSOrto.csproj"
            //new HeatZeekerRTSOrto.HZCannon().Source.Task.ContinueWithResult(
            //    async cube =>
            //    {
            //        // https://github.com/mrdoob/three.js/issues/1285
            //        //cube.children.WithEach(c => c.castShadow = true);

            //        //cube.traverse(
            //        //    new Action<THREE.Object3D>(
            //        //        child =>
            //        //        {
            //        //            // does it work? do we need it?
            //        //            //if (child is THREE.Mesh)

            //        //            child.castShadow = true;
            //        //            //child.receiveShadow = true;

            //        //        }
            //        //    )
            //        //);

            //        // um can edit and continue insert code going back in time?
            //        cube.scale.x = 10.0;
            //        cube.scale.y = 10.0;
            //        cube.scale.z = 10.0;



            //        //cube.castShadow = true;
            //        //dae.receiveShadow = true;

            //        //cube.position.x = -100;

            //        ////cube.position.y = (cube.scale.y * 50) / 2;
            //        //cube.position.z = Math.Floor((random() * 1000 - 500) / 50) * 50 + 25;



            //        // if i want to rotate, how do I do it?
            //        //cube.rotation.z = random() + Math.PI;
            //        //cube.rotation.x = random() + Math.PI;
            //        //var sw2 = Stopwatch.StartNew();



            //        cube.AttachTo(sceneg);
            //        //scene.add(cube);
            //        //interactiveObjects.Add(cube);

            //        // offset is wrong
            //        //while (true)
            //        //{
            //        //    await Native.window.async.onframe;

            //        //    cube.rotation.y = Math.PI * 0.0002 * sw2.ElapsedMilliseconds;

            //        //}
            //    }
            //);
            //#endregion


            #region HZCannon
            new HeatZeekerRTSOrto.HZCannon().Source.Task.ContinueWithResult(
                async cube =>
                {
                    // https://github.com/mrdoob/three.js/issues/1285
                    //cube.children.WithEach(c => c.castShadow = true);

                    //cube.traverse(
                    //    new Action<THREE.Object3D>(
                    //        child =>
                    //        {
                    //            // does it work? do we need it?
                    //            //if (child is THREE.Mesh)

                    //            child.castShadow = true;
                    //            //child.receiveShadow = true;

                    //        }
                    //    )
                    //);

                    // um can edit and continue insert code going back in time?
                    cube.scale.x = 10.0;
                    cube.scale.y = 10.0;
                    cube.scale.z = 10.0;



                    //cube.castShadow = true;
                    //dae.receiveShadow = true;


                    // jsc shat about out of band code patching?
                    cube.position.z = 600;
                    cube.position.x = -900;
                    //cube.position.y = -400;

                    //cube.position.x = -100;
                    //cube.position.y = -400;

                    ////cube.position.y = (cube.scale.y * 50) / 2;
                    //cube.position.z = Math.Floor((random() * 1000 - 500) / 50) * 50 + 25;



                    // if i want to rotate, how do I do it?
                    //cube.rotation.z = random() + Math.PI;
                    //cube.rotation.x = random() + Math.PI;
                    var sw2 = Stopwatch.StartNew();



                    //scene.add(cube);
                    cube.AttachTo(sceneg);
                    //interactiveObjects.Add(cube);

                    // offset is wrong
                    //while (true)
                    //{
                    //    await Native.window.async.onframe;

                    //    cube.rotation.y = Math.PI * 0.0002 * sw2.ElapsedMilliseconds;

                    //}
                }
            );
            #endregion


            #region HZBunker
            new HeatZeekerRTSOrto.HZBunker().Source.Task.ContinueWithResult(
                     cube =>
                     {
                         // https://github.com/mrdoob/three.js/issues/1285
                         //cube.children.WithEach(c => c.castShadow = true);
                         cube.castShadow = true;

                         //cube.traverse(
                         //    new Action<THREE.Object3D>(
                         //        child =>
                         //        {
                         //            // does it work? do we need it?
                         //            //if (child is THREE.Mesh)
                         //            child.castShadow = true;
                         //            //child.receiveShadow = true;

                         //        }
                         //    )
                         //);

                         // um can edit and continue insert code going back in time?
                         cube.scale.x = 10.0;
                         cube.scale.y = 10.0;
                         cube.scale.z = 10.0;

                         //cube.castShadow = true;
                         //dae.receiveShadow = true;

                         cube.position.x = -1000;
                         //cube.position.y = (cube.scale.y * 50) / 2;
                         cube.position.z = 0;

                         cube.AttachTo(sceneg);
                         //scene.add(cube);
                     }
                 );
            #endregion


            new Models.ColladaS6Edge().Source.Task.ContinueWithResult(
                   dae =>
                   {
                       // 90deg
                       dae.rotation.x = -Math.Cos(Math.PI);

                       //dae.scale.x = 30;
                       //dae.scale.y = 30;
                       //dae.scale.z = 30;
                       dae.position.z = -(65 - 200);





                       var scale = 0.9;

                       // jsc, do we have ILObserver available yet?
                       dae.scale.x = scale;
                       dae.scale.y = scale;
                       dae.scale.z = scale;


                       //#region onmousewheel
                       //Native.body.onmousewheel +=
                       //    e =>
                       //    {
                       //        e.preventDefault();

                       //        //camera.position.z = 1.5;

                       //        // min max. shall adjust speed also!
                       //        // max 4.0
                       //        // min 0.6
                       //        dae.position.z -= 10.0 * e.WheelDirection;

                       //        //camera.position.z = 400;
                       //        //dae.position.z = dae.position.z.Max(-200).Min(200);

                       //        //Native.document.title = new { z }.ToString();

                       //    };
                       //#endregion


                       ////dae.position.y = -80;

                       //dae.AttachTo(sceneg);
                       ////scene.add(dae);
                       //oo.Add(dae);




                       // view-source:http://threejs.org/examples/webgl_multiple_canvases_circle.html
                       // https://threejsdoc.appspot.com/doc/three.js/src.source/extras/cameras/CubeCamera.js.html
                       Native.window.onframe +=
                           e =>
                           {
                               // let render man know..
                               if (vsync != null)
                                   if (vsync.Task.IsCompleted)
                                       return;


                               //if (pause) return;
                               //if ([email protected])
                               //    return;


                               // can we float out of frame?
                               // haha. a bit too flickery.
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.01) * 50.0;
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.001) * 190.0;
                               dae.position.x = Math.Sin(fcamerax * 0.001) * 190.0;
                               dae.position.y = Math.Cos(fcamerax * 0.001) * 90.0;
                               // manual rebuild?
                               // red compiler notifies laptop chrome of pending update
                               // app reloads

                               applycameraoffset();
                               renderer0.clear();
                               //rendererPY.clear();

                               //cameraPX.aspect = canvasPX.aspect;
                               //cameraPX.updateProjectionMatrix();

                               // um what does this do?
                               //cameraPX.position.z += (z - cameraPX.position.z) * e.delay.ElapsedMilliseconds / 200.0;
                               // mousewheel allos the camera to move closer
                               // once we see the frame in vr, can we udp sync vr tracking back to laptop?


                               //this.targetPX.x += 1;
                               //this.targetNX.x -= 1;

                               //this.targetPY.y += 1;
                               //this.targetNY.y -= 1;

                               //this.targetPZ.z += 1;
                               //this.targetNZ.z -= 1;

                               // how does the 360 or shadertoy want our cubemaps?


                               // and then rotate right?

                               // how can we render cubemap?


                               #region x
                               // upside down?
                               renderer0.render(scene, cameraPX);
                               canvasPX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);

                               renderer0.render(scene, cameraNX);
                               canvasNX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               #endregion

                               #region z
                               renderer0.render(scene, cameraPZ);
                               canvasPZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);

                               renderer0.render(scene, cameraNZ);
                               canvasNZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               #endregion



                               #region y
                               renderer0.render(scene, cameraPY);

                               //canvasPY.save();
                               //canvasPY.translate(0, size);
                               //canvasPY.rotate((float)(-Math.PI / 2));
                               canvasPY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               //canvasPY.restore();


                               renderer0.render(scene, cameraNY);
                               //canvasNY.save();
                               //canvasNY.translate(size, 0);
                               //canvasNY.rotate((float)(Math.PI / 2));
                               canvasNY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               //canvasNY.restore();
                               // ?
                               #endregion


                               //renderer0.render(scene, cameraPX);


                               //rendererPY.render(scene, cameraPY);

                               // at this point we should be able to render the sphere texture

                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_X = 34069;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_X = 34070;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Y = 34071;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Z = 34073;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074;


                               //var cube0 = new IHTMLImage[] {
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_px(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nx(),

                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_py(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_ny(),


                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_pz(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nz()
                               //};

                               new[] {
                                   canvasPX, canvasNX,
                                   canvasPY, canvasNY,
                                   canvasPZ, canvasNZ
                               }.WithEachIndex(
                                   (img, index) =>
                                   {
                                       gl.bindTexture(gl.TEXTURE_CUBE_MAP, pass.tex);

                                       //gl.pixelStorei(gl.UNPACK_FLIP_X_WEBGL, false);
                                       gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);

                                       // http://stackoverflow.com/questions/15364517/pixelstoreigl-unpack-flip-y-webgl-true

                                       // https://msdn.microsoft.com/en-us/library/dn302429(v=vs.85).aspx
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

                                       gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + (uint)index, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img.canvas);

                                   }
                                );

                               // could do dynamic resolution- fog of war or fog of FOV. where up to 150deg field of vision is encouragedm, not 360
                               pass.Paint_Image(
                                     0,

                                     0,
                                     0,
                                     0,
                                     0
                                //,

                                // gl_FragCoord
                                // cannot be scaled, and can be referenced directly.
                                // need another way to scale
                                //zoom: 0.3f
                                );

                               //paintsw.Stop();


                               // what does it do?
                               gl.flush();

                               // let render man know..
                               if (vsync != null)
                                   if (!vsync.Task.IsCompleted)
                                       vsync.SetResult(null);
                           };


                   }
               );





            Console.WriteLine("do you see it?");
        }
        /// <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)
        {
            // http://blog.cuartodejuegos.es/wp-content/uploads/2011/06/Story-cubes-caras.jpg
            // http://css-eblog.com/3d/box.html

            var w = Native.window.Width;
            var h = Native.window.Height;

            //      var world, ground, 
            var timeStep = 1 / 60.0;

            //diceRigid, dice,
            //camera, scene, renderer, floorObj,
            //startDiceNum = 3,
            var cubeSize = 3.0;

            #region Cannonの世界を生成
            var world = new CANNON.World();

            //重力を設定
            world.gravity.set(0, -90.82, 0);
            world.broadphase = new CANNON.NaiveBroadphase();
            world.solver.iterations = 10;
            world.solver.tolerance = 0.001;

            //地面用にPlaneを生成
            var plane = new CANNON.Plane();

            //Planeの剛体を質量0で生成する
            var ground = new CANNON.RigidBody(0, plane);

            //X軸に90度(つまり地面)に回転
            ground.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
            ground.position.set(
                50, 0, 50);

            world.add(ground);
            #endregion


            #region initThree() {


            //var camera = new THREE.OrthographicCamera(-w / 2, w / 2, h / 2, -h / 2, 1, 1000);
            var camera = new THREE.PerspectiveCamera(60, w / (double)h, 0.1, 1000);


            camera.lookAt(new THREE.Vector3(0, 0, 0));

            var scene = new THREE.Scene();
            var renderer = new THREE.CSS3DRenderer();
            renderer.setSize(w, h);

            var textureSize = 800;
            var floorEle = new IHTMLDiv();
            //floorEle.style.width = textureSize + "px";
            //floorEle.style.height = textureSize + "px";

            floorEle.style.width = 100 + "px";
            floorEle.style.height = 100 + "px";

            new WebGLDiceByEBLOG.HTML.Images.FromAssets.background().ToBackground(floorEle.style, true);

            //floorEle.style.background = 'url(http://jsrun.it/assets/d/x/0/w/dx0wl.png) left top repeat';
            //floorEle.style.backgroundSize = textureSize / 20 + "px " + textureSize / 20 + "px";
            (floorEle.style as dynamic).backgroundSize = textureSize / 20 + "px " + textureSize / 20 + "px";

            var floorObj = new THREE.CSS3DObject(floorEle);
            //floorObj.position.fromArray(new double[] { 100, 0, 0 });
            //floorObj.rotation.fromArray(new double[] { Math.PI / 2.0, 0, 0 });
            scene.add(floorObj);

            scene.add(camera);

            renderer.domElement.AttachToDocument();

            renderer.render(scene, camera);
            #endregion }



            #region createDice
            Func<xdice> createDice = delegate
            {


                Console.WriteLine("before array");


                //t = new Array(3);
                //p.rotation = t;

                var zero = 0.0;


                #region boxInfo
                var boxInfo = new[] 
                {
                         new xdiceface {
                        img = (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num4(),
                        position= new double [] { 0, 0, -cubeSize },

                        // jsc, please allow 
                        rotation= new double [] { 0, 0, zero }
                    },


                    new  xdiceface{
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num2(),
                        position = new double [] { -cubeSize, 0, 0 },
                        rotation =  new double [] { 0, Math.PI / 2, 0 }
                    },
                    new xdiceface{
                        img = (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num5(),
                        position = new double [] { cubeSize, 0, 0 },
                        rotation= new double [] { 0, -Math.PI / 2, 0 }
                    },
                    new xdiceface{
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num1(),
                        position= new double [] { 0,  cubeSize, 0 },
                        rotation= new double [] { Math.PI / 2, 0, Math.PI }
                    },
                    new xdiceface {
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num6(),
                        position= new double [] { 0, -cubeSize, 0 },
                        rotation= new double [] { - Math.PI / 2, 0, Math.PI }
                    },
                    new xdiceface{
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num3(),
                        position= new double [] { 0, 0,  cubeSize },
                        rotation= new double [] { 0, Math.PI, 0 }
                    },
               
                };
                #endregion
                Console.WriteLine("after array");

                //for three.js
                //var el, dice,
                //    info, img, face;

                var el = new IHTMLDiv();
                el.style.width = cubeSize * 2 + "px";
                el.style.height = cubeSize * 2 + "px";
                var dice = new THREE.CSS3DObject(el);

                for (var j = 0; j < boxInfo.Length; j++)
                {
                    Console.WriteLine("after array " + new { j });

                    var info = boxInfo[j];

                    info.img.style.SetSize(
                        (int)(cubeSize * 2),
                        (int)(cubeSize * 2)
                    );


                    var face = new THREE.CSS3DObject(info.img);

                    face.position.fromArray(info.position);
                    face.rotation.fromArray(info.rotation);
                    dice.add(face);
                }

                //Create physics.
                var mass = 1;
                var box = new CANNON.Box(new CANNON.Vec3(cubeSize, cubeSize, cubeSize));
                var body = new CANNON.RigidBody(mass, box);

                //body.position.set(x, y, z);
                //body.velocity.set(0, 0, Math.random() * -50 - 30);

                //body.angularVelocity.set(10, 10, 10);
                //body.angularDamping = 0.001;

                return new xdice
                {
                    dice = dice,
                    rigid = body
                };
            };
            #endregion


            //world.allowSleep = true;
            var stopped = false;

            Func<double> random = new Random().NextDouble;

            #region initAnimation
            Action<xdice> initAnimation = y =>
            {
                var position = new
                {
                    x = 5 + random() * 50.0,
                    y = 5 + random() * 50.0,
                    z = 5 + random() * 5.0,
                };

                Console.WriteLine(new { position });
                y.rigid.position.set(position.x, position.y, position.z);

                y.rigid.velocity.set(
                    random() * 20 + 0,
                    random() * 20 + 10,
                    random() * 20 + 10
                    );


                y.rigid.angularVelocity.set(10, 10, 10);
                y.rigid.angularDamping = 0.001;
            };
            #endregion

            //create a dice.

            var AllDice = new List<xdice>();

            for (int i = 0; i < 9; i++)
            {

                var y = createDice();

                initAnimation(y);

                scene.add(y.dice);
                world.add(y.rigid);

                AllDice.Add(y);

            }





            var target = new THREE.Vector3();

            var lon = 50.0;
            var lat = -72.0;





            var drag = false;

            #region onframe
            Native.window.onframe +=
                delegate
                {
                    if (Native.document.pointerLockElement == Native.document.body)
                        lon += 0.00;
                    else
                        lon += 0.01;

                    lat = Math.Max(-85, Math.Min(85, lat));

                    Native.document.title = new { lon = (int)lon, lat = (int)lat }.ToString();


                    var phi = THREE.Math.degToRad(90.0 - lat);
                    var theta = THREE.Math.degToRad(lon);

                    target.x = Math.Sin(phi) * Math.Cos(theta);
                    target.y = Math.Cos(phi);
                    target.z = Math.Sin(phi) * Math.Sin(theta);

                    //XInteractiveInt32Form.ToInteractiveInt32Form(
                    camera.position.set(
                        x: 0,
                        y: 50.ToInteractiveInt32Form(),
                        z: 0
                   );

                    #region updatePhysics();
                    //物理エンジンの時間を進める
                    world.step(timeStep);

                    //物理エンジンで計算されたbody(RigidBody)の位置をThree.jsのMeshにコピー
                    AllDice.WithEach(
                        y =>
                        {
                            y.rigid.position.copy(y.dice.position);
                            y.rigid.quaternion.copy(y.dice.quaternion);

                            //y.rigid.position.copy(camera.position);
                        }
                    );

                    if (!drag)
                    {
                        camera.lookAt(
                            new THREE.Vector3(
                                AllDice.Average(i => i.rigid.position.x),
                                AllDice.Average(i => i.rigid.position.y),
                                AllDice.Average(i => i.rigid.position.z)
                            )
                        );



                    }
                    else
                    {
                        camera.lookAt(
                            new THREE.Vector3(
                                target.x + camera.position.x,
                                target.y + camera.position.y,
                                target.z + camera.position.z
                            )
                        );
                    }

                    ground.position.copy(floorObj.position);
                    ground.quaternion.copy(floorObj.quaternion);
                    #endregion

                    renderer.render(scene, camera);
                };
            #endregion




            #region sleepy
            AllDice.Last().With(
                x =>
                {

                    x.rigid.addEventListener("sleepy",

                        IFunction.OfDelegate(
                            new Action(
                                delegate
                                {

                                    var px = new THREE.Vector4(1, 0, 0, 0);
                                    var nx = new THREE.Vector4(-1, 0, 0, 0);
                                    var py = new THREE.Vector4(0, 1, 0, 0);
                                    var ny = new THREE.Vector4(0, -1, 0, 0);
                                    var pz = new THREE.Vector4(0, 0, 1, 0);
                                    var nz = new THREE.Vector4(0, 0, -1, 0);
                                    var UP = 0.99;
                                    //tmp;

                                    #region showNum
                                    Action<int> showNum = num =>
                                    {
                                        new { num }.ToString().ToDocumentTitle();
                                    };

                                    if (px.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(5);
                                    }
                                    else if (nx.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(2);
                                    }
                                    else if (py.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(1);
                                    }
                                    else if (ny.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(6);
                                    }
                                    else if (pz.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(3);
                                    }
                                    else if (nz.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(4);
                                    }
                                    #endregion

                                    stopped = true;
                                }
                            )
                        )
                    );
                }
            );

            #endregion

            #region onresize
            Action AtResize = delegate
            {
                camera.aspect = Native.window.Width / Native.window.Height;
                camera.updateProjectionMatrix();
                renderer.setSize(Native.window.Width, Native.window.Height);
            };
            Native.window.onresize +=
              delegate
              {
                  AtResize();
              };
            #endregion


            #region onclick
            var button = new IHTMLDiv();

            button.style.position = IStyle.PositionEnum.absolute;
            button.style.left = "0px";
            button.style.right = "0px";
            button.style.bottom = "0px";
            button.style.height = "3em";
            button.style.backgroundColor = "rgba(0,0,0,0.5)";

            button.AttachToDocument();



            button.onmousedown +=
                e =>
                {
                    e.stopPropagation();
                };

            button.ontouchstart +=
                e =>
                {
                    e.stopPropagation();
                };

            button.ontouchmove +=
                 e =>
                 {
                     e.stopPropagation();
                 };

            button.onclick +=
                delegate
                {
                    stopped = false;

                    AllDice.WithEach(
                       y =>
                       {
                           initAnimation(y);
                       }
                    );

                };
            #endregion

            #region ontouchmove
            var touchX = 0;
            var touchY = 0;

            Native.document.body.ontouchend +=
               e =>
               {
                   drag = false;
               };


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

                    var touch = e.touches[0];

                    touchX = touch.screenX;
                    touchY = touch.screenY;

                };


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

                  var touch = e.touches[0];

                  lon -= (touch.screenX - touchX) * 0.1;
                  lat += (touch.screenY - touchY) * 0.1;

                  touchX = touch.screenX;
                  touchY = touch.screenY;

              };
            #endregion






            #region camera rotation
            renderer.domElement.onmousemove +=
                e =>
                {
                    e.preventDefault();

                    if (Native.document.pointerLockElement == renderer.domElement)
                    {
                        drag = true;
                        lon += e.movementX * 0.1;
                        lat -= e.movementY * 0.1;

                        //Console.WriteLine(new { lon, lat, e.movementX, e.movementY });
                    }
                };


            renderer.domElement.onmouseup +=
              e =>
              {
                  drag = Native.document.pointerLockElement != null;
                  e.preventDefault();
              };

            renderer.domElement.onmousedown +=
                e =>
                {
                    //e.CaptureMouse();

                    drag = true;
                    e.preventDefault();
                    renderer.domElement.requestPointerLock();

                };


            renderer.domElement.ondblclick +=
                e =>
                {
                    e.preventDefault();

                    Console.WriteLine("requestPointerLock");
                };

            #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)
        {
            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;
        }
        /// <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)
        {
            // X:\jsc.svn\examples\actionscript\synergy\Flare3DMeetsStarlingExperiment\Flare3DMeetsStarlingExperiment\ApplicationSprite.cs
            // X:\jsc.svn\examples\javascript\WebGL\WebGLGalaxyS\WebGLGalaxyS\Application.cs

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201408/20140801
            // jsc, when can we have compiled collada asssets?
            // svg we have why not collada..
            // https://3dwarehouse.sketchup.com/model.html?id=b3bdb20081c023accbd2ad75d6ff6a24
            // https://3dwarehouse.sketchup.com/collection.html?id=982aafab70c9aba140c287facf4f3262


            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x303030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            // WebGLRenderer preserveDrawingBuffer 
            var renderer = new THREE.WebGLRenderer(

                new
            {
                antialias = true,
                alpha = true,
                preserveDrawingBuffer = true
            }
            );

            // https://github.com/mrdoob/three.js/issues/3836
            //renderer.setClearColor(0xfffff, 1);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);

            var canvas = (IHTMLCanvas)renderer.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();


            #region onmousedown
            canvas.onmousedown +=
                e =>
                {

                    if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
                    {
                        canvas.requestFullscreen();
                    }
                    else
                    {
                        // movementX no longer works
                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };


                        e.CaptureMouse();
                    }

                };
            #endregion

            canvas.css.active.style.cursor = IStyle.CursorEnum.move;


            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            canvas.onmousemove +=
                e =>
                {
                    var pointerLock = canvas == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion
            var z = camera.position.z;

            #region onmousewheel
            canvas.onmousewheel +=
                e =>
                {
                    //camera.position.z = 1.5;

                    // min max. shall adjust speed also!
                    // max 4.0
                    // min 0.6
                    z -= 10.0 * e.WheelDirection;

                    //camera.position.z = 400;
                    z = z.Max(200).Min(500);

                    //Native.document.title = new { z }.ToString();

                };
            #endregion


            Native.window.onframe +=
                e =>
            {
                renderer.clear();

                camera.aspect = canvas.aspect;
                camera.updateProjectionMatrix();

                camera.position.z += (z - camera.position.z) * e.delay.ElapsedMilliseconds / 200;


                camera.lookAt(scene.position);

                renderer.render(scene, camera);


            };

            Native.window.onresize +=
                delegate
            {
                if (canvas.parentNode == Native.document.body)
                {
                    renderer.setSize(window.Width, window.Height);
                }

            };
            #endregion

            new galaxyS().Source.Task.ContinueWithResult(
                   dae =>
                    {
                        //dae.scale.x = 30;
                        //dae.scale.y = 30;
                        //dae.scale.z = 30;
                        dae.position.z = 65;

                        dae.scale.x = 0.5;
                        dae.scale.y = 0.5;
                        dae.scale.z = 0.5;

                        //dae.position.y = -80;

                        scene.add(dae);
                        oo.Add(dae);


                    }
               );



        }
Example #43
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)
        {
            var oo = new List <THREE.Object3D>();

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);


            var mouseX = 0;
            var mouseY = 0;
            var st     = new Stopwatch();
            st.Start();

            Native.window.onframe +=
                delegate
            {
                oo.WithEach(
                    x =>
                    x.rotation.y = st.ElapsedMilliseconds * 0.001
                    );


                camera.position.x += (mouseX - camera.position.x) * .05;
                camera.position.y += (-mouseY - camera.position.y) * .05;

                camera.lookAt(scene.position);

                renderer.render(scene, camera);
            };

            Native.window.onresize +=
                delegate
            {
                camera.aspect = window.aspect;
                camera.updateProjectionMatrix();

                renderer.setSize(window.Width, window.Height);
            };
            #endregion


            var ref0 = new TexturesImages();

            //var texture = new THREE.Texture(
            //    //new HTML.Images.FromAssets.ash_uvgrid01()
            //    //new HTML.Images.FromAssets.texture_palm()
            //           new TLC200_Side_89pc()
            //      );
            //texture.needsUpdate = true;

            // X:\jsc.svn\examples\javascript\WebGL\WebGLMTLExperiment\WebGLMTLExperiment\Application.cs

            var loader = new THREE.OBJMTLLoader();
            loader.load(
                "assets/WebGLOBJToyota/LX570_2008.obj",
                "assets/WebGLOBJToyota/LX570_2008.mtl",
                new Action <THREE.Object3D>(
                    o =>
            {
                Console.WriteLine("onload " + new { o });

                // need to use
                // Toyota Land Cruiser 200 Series aka Lexus LX 570_2008.mtl
                // http://pages.cs.wisc.edu/~lizy/mrdoob-three.js-ef5f05d/examples/webgl_loader_obj_mtl.html


                o.scale = new THREE.Vector3(40, 40, 40);

                o.position.y = -80;
                scene.add(o);
                oo.Add(o);
            }
                    ),
                new Action <object>(
                    o =>
            {
                Console.WriteLine("progress " + new { o });
            }
                    ),

                new Action <object>(
                    o =>
            {
                Console.WriteLine("error " + new { o });
            }
                    )
                );
        }
        /// <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)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                10000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();


            Native.window.document.onmousemove +=
                e =>
                {
                    mouseX = e.CursorX - Native.window.Width / 2;
                    mouseY = e.CursorY - Native.window.Height / 2;
                };


            Native.window.onframe +=
                delegate
            {

                oo.WithEach(
                    x =>
                        x.rotation.y = (st.ElapsedMilliseconds + mouseX * 100) * 0.00001
                );


                camera.position.x += (mouseX - camera.position.x) * .05;
                camera.position.y += (-mouseY - camera.position.y) * .05;

                camera.lookAt(scene.position);

                renderer.render(scene, camera);


            };

            Native.window.onresize +=
                delegate
            {
                camera.aspect = window.aspect;
                camera.updateProjectionMatrix();

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

            };
            #endregion

            // why isnt it being found?
            new global::WebGLColladaExperiment.THREE_ColladaAsset(

                // we get purple small thingy
                "assets/WebGLHeatZeekerColladaExperiment/Promotion3D_daytime.dae"

            // maybe sketchup doesnt know how to export colors?
            //"assets/WebGLHeatZeekerColladaExperiment/sam_site.dae"
            ).Source.Task.ContinueWithResult(
                dae =>
                {

                    dae.position.y = -40;
                    //dae.position.z = 280;
                    scene.add(dae);
                    oo.Add(dae);

                    dae.scale = new THREE.Vector3(2, 2, 2);

                }
            );
        }
Example #45
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)
        {
            // why are the trucks black?
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae
            // what will happen if we resync THREE version from 70 to?
            Native.document.title = new { THREE.REVISION }.ToString();

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            //var ambient = new THREE.AmbientLight(0x101030);
            var ambient = new THREE.AmbientLight(0x808080);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd, 0.7);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            // WebGLRenderer preserveDrawingBuffer
            var renderer = new THREE.WebGLRenderer(

                new
            {
                preserveDrawingBuffer = true
            }
                );

            // https://github.com/mrdoob/three.js/issues/3836
            renderer.setClearColor(0xfffff, 1);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);

            this.canvas = (IHTMLCanvas)renderer.domElement;


            var mouseX = 0;
            var mouseY = 0;
            var st     = new Stopwatch();
            st.Start();


            var controls = new THREE.OrbitControls(camera, renderer.domElement);

            Native.window.onframe +=
                delegate
            {
                renderer.clear();


                //camera.aspect = window.aspect;
                //camera.aspect = canvas.clientWidth / (double)canvas.clientHeight;
                //camera.aspect = canvas.aspect;


                oo.WithEach(
                    x =>
                    x.rotation.y = st.ElapsedMilliseconds * 0.0001
                    );


                controls.update();
                camera.position = controls.center.clone();

                renderer.render(scene, camera);
            };

            Native.window.onresize +=
                delegate
            {
                if (canvas.parentNode == Native.document.body)
                {
                    renderer.setSize(window.Width, window.Height);
                }
            };
            #endregion

            new truck().Source.Task.ContinueWithResult(
                dae =>
            {
                //dae.scale.x = 30;
                //dae.scale.y = 30;
                //dae.scale.z = 30;
                dae.position.z = 65;

                dae.scale.x = 10;
                dae.scale.y = 10;
                dae.scale.z = 10;

                dae.position.y = -80;

                scene.add(dae);
                oo.Add(dae);
            }
                );

            //var ref0 = "assets/WebGLColladaExperiment/HZCannon_capture_009_04032013_192834.png";

            //new HZCannon().Source.Task.ContinueWithResult(
            //    dae =>
            //    {
            //        //dae.scale.x = 30;
            //        //dae.scale.y = 30;
            //        //dae.scale.z = 30;

            //        dae.castShadow = true;
            //        dae.receiveShadow = true;

            //        dae.scale.x = 3;
            //        dae.scale.y = 3;
            //        dae.scale.z = 3;

            //        dae.position.y = -80;

            //        scene.add(dae);
            //        oo.Add(dae);


            //    }
            //);
        }
        /// <summary>
        /// sorts types that are decorated with DependencyAttribute.  If the type does not have a DependencyAttribute
        /// with the provided classification, it is returned at the beginning (least dependent) of the list with a null dependency.
        /// </summary>
        /// <param name="types"></param>
        /// <returns></returns>
        public static List<Tuple<Type, NamedDependency>> GetAttributeAndSort(List<Type> types, string dependencyName)
        {
            //build type map and dep list
            List<Tuple<Type, NamedDependency>> returnValue = new List<Tuple<Type, NamedDependency>>();

            Dictionary<string, Type> depName2Type = new Dictionary<string, Type>();
            Dictionary<Type, NamedDependency> type2dep = new Dictionary<Type, NamedDependency>();
            List<NamedDependency> deps = new List<NamedDependency>();

            types.WithEach(type =>
            {
                //build it
                var dep = BuildNamedDependencyFromTypeAttributes(type, dependencyName);

                //add to type2dep
                type2dep[type] = dep;

                //add to depName2Type if there is a dep
                if (dep != null)
                {
                    deps.Add(dep);

                    //register the type's dependency by self name
                    depName2Type[dep.Self] = type;
                }
            });

            //sort the deps, get the names back
            var stringDeps = NamedDependency.Sort(deps);

            stringDeps.WithEach(depName =>
            {
                //with the dep name, look in the map to get the type
                var type = depName2Type[depName.Self];
                //using the type, get the dep itself
                var dep = type2dep[type];

                returnValue.Add(new Tuple<Type, NamedDependency>(type, dep));
            });

            //now prepend list with types that have no dependency
            var depTypes = depName2Type.Values.ToList();
            var noDepTypes = types.Where(type=> depTypes.Contains(type) == false);

            noDepTypes.WithEach(type =>
            {
                returnValue.Insert(0, new Tuple<Type, NamedDependency>(type, null));
            });
            return returnValue;
        }
        /// <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)
        {
            // https://3dwarehouse.sketchup.com/model.html?id=3afce20492cb901a4fc117e4bba6a423



            // http://blogs.msdn.com/b/dotnet/archive/2014/05/09/the-net-native-tool-chain.aspx

            // http://stackoverflow.com/questions/23771022/plinq-c-net-4-5-1-vs-stream-jdk-java-8-performance
            // http://blogs.msdn.com/b/dotnet/archive/2014/04/21/sharing-code-across-platforms.aspx

            // Uncaught TypeError: Cannot read property 'nodes' of null
            // sketchup creates empty nodes
            // .//dae:scene/dae:instance_visual_scene

            // .dae download missing?
            //<scene>
            //    <instance_visual_scene url="#ID1" />

            // https://3dwarehouse.sketchup.com/model.html?id=7bf6249a031b5095ddd41159baaa3ad5
            // jsc, how to show dae?

            // Uncaught TypeError: Cannot read property 'input' of null
            // geometry: "ID690"
            //<geometry id="ID979">
            //        <mesh />
            //    </geometry>
            //    <geometry id="ID980">
            //        <mesh />
            //    </geometry>

            // X:\jsc.svn\examples\javascript\WebGL\WebGLNexus7\WebGLNexus7\Application.cs

            // X:\jsc.svn\examples\javascript\WebGL\WebGLGalaxyS\WebGLGalaxyS\Application.cs

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201408/20140801
            // jsc, when can we have compiled collada asssets?
            // svg we have why not collada..
            // https://3dwarehouse.sketchup.com/model.html?id=b3bdb20081c023accbd2ad75d6ff6a24
            // https://3dwarehouse.sketchup.com/collection.html?id=982aafab70c9aba140c287facf4f3262


            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131110-dae

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x303030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            // WebGLRenderer preserveDrawingBuffer 
            var renderer = new THREE.WebGLRenderer(

                new
            {
                antialias = true,
                alpha = true,
                preserveDrawingBuffer = true
            }
            );

            // https://github.com/mrdoob/three.js/issues/3836
            //renderer.setClearColor(0xfffff, 1);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);

            var canvas = (IHTMLCanvas)renderer.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();


            canvas.css.active.style.cursor = IStyle.CursorEnum.move;

            #region onmousedown
            canvas.onmousedown +=
                e =>
                {

                    if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
                    {
                        canvas.requestFullscreen();
                    }
                    else
                    {
                        // movementX no longer works
                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };


                        e.CaptureMouse();
                    }

                };
            #endregion



            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            canvas.onmousemove +=
                e =>
                {
                    var pointerLock = canvas == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion
            var z = camera.position.z;

            #region onmousewheel
            canvas.onmousewheel +=
                e =>
                {
                    //camera.position.z = 1.5;

                    // min max. shall adjust speed also!
                    // max 4.0
                    // min 0.6
                    z -= 10.0 * e.WheelDirection;

                    //camera.position.z = 400;
                    z = z.Max(200).Min(500);

                    //Native.document.title = new { z }.ToString();

                };
            #endregion


            Native.window.onframe +=
                e =>
                {
                    renderer.clear();

                    camera.aspect = canvas.aspect;
                    camera.updateProjectionMatrix();

                    camera.position.z += (z - camera.position.z) * e.delay.ElapsedMilliseconds / 200;


                    camera.lookAt(scene.position);

                    renderer.render(scene, camera);


                };

            Native.window.onresize +=
                delegate
                {
                    if (canvas.parentNode == Native.document.body)
                    {
                        renderer.setSize(window.Width, window.Height);
                    }

                };
            #endregion

            new __AssetsLibrary__.ColladaISS().Source.Task.ContinueWithResult(
                   dae =>
                   {
                       // 90deg
                       dae.rotation.x = -Math.Cos(Math.PI);

                       //dae.scale.x = 30;
                       //dae.scale.y = 30;
                       //dae.scale.z = 30;
                       dae.position.z = 65;


                       // jsc, do we have ILObserver available yet?
                       dae.scale.x = 1.0;
                       dae.scale.y = 1.0;
                       dae.scale.z = 1.0;

                       //dae.position.y = -80;

                       scene.add(dae);
                       oo.Add(dae);


                   }
               );


            // no! why?
            Console.WriteLine("do you see it?");
            // slow to load
            // then too small!
        }
        public StudioView(Action<IHTMLElement, Action<ISaveAction>> AddSaveButton = null)
        {
            Content.style.position = IStyle.PositionEnum.absolute;
            Content.style.left = "0px";
            Content.style.right = "0px";
            Content.style.top = "0px";
            Content.style.bottom = "0px";

            new TwentyTenWorkspace().ToBackground(Content.style, true);

            var WorkspaceHeaderTab0 = new IHTMLDiv().With(
                div =>
                {
                    div.style.position = IStyle.PositionEnum.absolute;
                    div.style.top = "0px";
                    div.style.left = "0px";
                    div.style.width = "14em";
                    div.style.height = "6em";

                    div.style.padding = "0.5em";

                    new Glow1().ToBackground(div.style, false);
                }
            ).AttachTo(Content);

            var WorkspaceHeaderTab1 = new IHTMLDiv().With(
                div =>
                {
                    div.style.position = IStyle.PositionEnum.absolute;
                    div.style.top = "0px";
                    div.style.left = "14em";
                    div.style.width = "20em";
                    div.style.height = "6em";

                    div.style.padding = "0.5em";

                    new Glow1().ToBackground(div.style, false);
                }
            ).AttachTo(Content);

            var WorkspaceHeaderTab2 = new IHTMLDiv().With(
                div =>
                {
                    div.style.position = IStyle.PositionEnum.absolute;
                    div.style.top = "0px";
                    div.style.left = "34em";
                    div.style.right = "6em";
                    div.style.height = "6em";

                    div.style.padding = "0.5em";

                    new Glow1().ToBackground(div.style, false);
                }
            ).AttachTo(Content);

            var WorkspaceHeaderTab7 = new IHTMLDiv().With(
                 div =>
                 {
                     div.style.position = IStyle.PositionEnum.absolute;
                     div.style.top = "0px";
                     div.style.width = "6em";
                     div.style.right = "0px";
                     div.style.height = "6em";

                     //div.style.padding = "0.5em";

                     new Glow1().ToBackground(div.style, false);
                 }
             ).AttachTo(Content);

            var WorkspaceHeaderTab0Text = default(IHTMLSpan);



            new DownloadSDK
            {

            }.AttachTo(
                 new IHTMLAnchor
                 {
                     title = "Download JSC SDK!",
                     href = "http://download.jsc-solutions.net"
                 }.AttachTo(WorkspaceHeaderTab7)
            );

            @"studio.jsc-solutions.net".ToDocumentTitle().With(
                title =>
                {
                    WorkspaceHeaderTab0Text = new IHTMLSpan { innerText = title };

                    WorkspaceHeaderTab0Text.AttachTo(WorkspaceHeaderTab0);
                    //WorkspaceHeaderTab0Text.style.SetLocation(16, 8);
                    WorkspaceHeaderTab0Text.style.fontFamily = IStyle.FontFamilyEnum.Tahoma;
                    WorkspaceHeaderTab0Text.style.color = Color.White;
                    WorkspaceHeaderTab0Text.style.display = IStyle.DisplayEnum.block;

                    // http://www.quirksmode.org/css/textshadow.html
                    WorkspaceHeaderTab0Text.style.textShadow = "#808080 4px 2px 2px";

                }
            );


            if (AddSaveButton != null)
                AddSaveButton(WorkspaceHeaderTab0Text, i => Save = i);

            // em + px :)
            var Workspace0 = new IHTMLDiv().With(
                div =>
                {
                    div.style.position = IStyle.PositionEnum.absolute;
                    div.style.left = "0px";
                    div.style.right = "0px";
                    div.style.bottom = "0px";
                    div.style.top = "6em";
                }
            ).AttachTo(Content);

            // workspace contains the split views
            var Workspace = new IHTMLDiv().With(
                div =>
                {
                    div.style.position = IStyle.PositionEnum.absolute;
                    div.style.left = "6px";
                    div.style.right = "6px";
                    div.style.bottom = "6px";
                    div.style.top = "6px";
                }
            ).AttachTo(Workspace0);

            // in this project we wont be having toolbox or toolbar yet

            Action<HorizontalSplit> ApplyStyle =
                t =>
                {
                    t.Split.Splitter.style.backgroundColor = Color.None;
                    t.SplitImageContainer.Orphanize();
                    t.SplitArea.Target.style.borderLeft = "0";
                    t.SplitArea.Target.style.borderRight = "0";
                    t.SplitArea.Target.style.width = "6px";
                    t.SplitArea.Target.style.Opacity = 0.7;

                    // should we obselete JSColor already?
                    t.SelectionColor = JSColor.Black;
                };

            var EditorTreeSplit = new HorizontalSplit
            {
                Minimum = 0,
                Maximum = 1,
                Value = 0.7,
            };

            EditorTreeSplit.With(ApplyStyle);

            EditorTreeSplit.Split.Splitter.style.backgroundColor = Color.None;


            EditorTreeSplit.Container.AttachTo(Workspace);



            var Split = new HorizontalSplit
            {
                Minimum = 0,
                Maximum = 1,
                Value = 0.3,
            };

            Split.With(ApplyStyle);

            Split.Split.Splitter.style.backgroundColor = Color.None;

            EditorTreeSplit.LeftContainer = Split.Container;



            var SolutionToolbox = new SolutionDockWindowPage();

            SolutionToolbox.HeaderText.innerText = "Toolbox";
            SolutionToolbox.Content.style.backgroundColor = Color.White;
            SolutionToolbox.Content.style.padding = "2px";
            SolutionToolbox.Content.style.overflow = IStyle.OverflowEnum.auto;
            SolutionToolbox.Content.Clear();


            var vv = new SolutionToolboxListView();

            vv.Container.style.color = Color.Black;
            //vv.Container.AttachTo(SolutionToolbox.Content);

            var items = new StockToolboxTabsForHTMLDocument();

            // jsc market components

            vv.Add(
             new SolutionToolboxListViewTab
             {
                 DataType = "DataTable",

                 Name = "DataTable",
                 Title = "DataTable",
                 Text = "DataTable",
                 Icon = new DataTableImage()
             }
          );

            vv.Add(
                new SolutionToolboxListViewTab
                {
                    DataType = "SpiralDataType",

                    Name = "Spiral1",
                    Title = "Spiral",
                    Text = "Spiral",
                    Icon = new Spiral()
                }
             );

            // can we drag this into 
            // code ?
            // msvs gets the image link
            //http://192.168.43.252:11924/assets/ScriptCoreLib.Ultra.Components/StockToolboxImageTransparent64.png?data-jsc-type=DAETruck
            vv.Add(
                  new SolutionToolboxListViewTab
                  {
                      DataType = "DAETruck",

                      Name = "DAETruck",
                      Title = "DAETruck",
                      Text = "DAETruck",
                      Icon = new DAETruck()
                  }
               );

            vv.Add(
                new SolutionToolboxListViewTab
                {
                    DataType = "WebGLEarthByBjorn",

                    Name = "WebGLEarthByBjorn",
                    Title = "WebGLEarthByBjorn",
                    Text = "WebGLEarthByBjorn",
                    Icon = new WebGLEarthByBjorn()
                }
                );


            items.WithEach(vv.Add);




            var Viewer = new SolutionDocumentViewer();
            SolutionDocumentViewerTab File7Tab = "Design/App.htm";
            Viewer.Add(File7Tab);

            #region OutputFile
            var OutputFile = new SolutionFile();
            var OutputFileViewer = new SolutionFileView();

            // fullscreen! :)
            OutputFileViewer.Container.style.height = "100%";

            OutputFile.IndentStack.Push(
                delegate
                {
                    OutputFile.Write(SolutionFileTextFragment.Comment, "" + DateTime.Now);
                    OutputFile.WriteSpace();
                }
            );

            Action<string> OutputWriteLine =
                n =>
                {
                    // Would we want to rewire System.Out? Console.WriteLine?
                    OutputFile.WriteIndent();
                    OutputFile.WriteLine(n);

                    // we could have a resume feature? now we just go and clear...
                    OutputFileViewer.File = OutputFile;
                };


            OutputWriteLine("studio.jsc-solutions.net ready!");
            #endregion

            SolutionDocumentViewerTab OutputTab = "Output";
            Viewer.Add(OutputTab);
            OutputTab.TabElement.style.Float = IStyle.FloatEnum.right;


            SolutionDocumentViewerTab AboutTab = "Project";
            Viewer.Add(AboutTab);
            AboutTab.TabElement.style.Float = IStyle.FloatEnum.right;


            var CurrentDesigner = new SolutionFileDesigner();




            var HTMLDesigner = new SolutionFileDesignerHTMLElementTabs();

            CurrentDesigner.Add(HTMLDesigner);


            // undoable?
            var sln = new SolutionBuilder();




            #region CodeSourceA
            var CodeSourceATab =
                new SolutionFileDesignerTab
                {
                    Image = new RTA_mode_html(),
                    Text = "Generated Code"
                };

            var CodeSourceAView = new SolutionFileView();

            CodeSourceAView.Container.style.position = IStyle.PositionEnum.absolute;
            CodeSourceAView.Container.style.left = "0px";
            CodeSourceAView.Container.style.right = "0px";
            CodeSourceAView.Container.style.top = "0px";
            CodeSourceAView.Container.style.bottom = "0px";

            CodeSourceAView.Container.style.display = IStyle.DisplayEnum.none;
            CodeSourceAView.Container.AttachTo(CurrentDesigner.Content);

            CodeSourceATab.Deactivated +=
                delegate
                {
                    CodeSourceAView.Container.style.display = IStyle.DisplayEnum.none;
                };

            CodeSourceATab.Activated +=
                delegate
                {
                    HTMLDesigner.HTMLDesignerContent.WhenContentReady(
                        body =>
                        {
                            var CodeSourceFile = new SolutionFile
                            {

                                Name = "Default.htm"
                            };

                            var Type = new SolutionProjectLanguageType
                            {
                                Comments = new SolutionFileComment[] { "This type was generated from the HTML file." },
                                Namespace = sln.Name + ".HTML.Pages",
                                Name = "IDefaultPage",
                                IsInterface = true,
                            };

                            (from n in body.AsXElement().DescendantsAndSelf()
                             let id = n.Attribute("id")
                             where id != null
                             select new { n, id }
                            ).WithEach(
                                k =>
                                {
                                    Type.Properties.Add(
                                        new KnownStockTypes.ScriptCoreLib.JavaScript.DOM.HTML.IHTMLElement().ToAutoProperty(k.id.Value)
                                    );
                                }
                            );

                            sln.Language.WriteType(CodeSourceFile, Type, null);

                            CodeSourceAView.File = CodeSourceFile;

                            CodeSourceAView.Container.style.display = IStyle.DisplayEnum.empty;
                        }
                    );
                };


            #endregion


            #region CodeSourceB
            var CodeSourceBTab =
                new SolutionFileDesignerTab
                {
                    Image = new RTA_mode_html(),
                    // all source code, not just html?
                    Text = "Source"
                };

            var CodeSourceBView = new SolutionFileView();

            CodeSourceBView.Container.style.position = IStyle.PositionEnum.absolute;
            CodeSourceBView.Container.style.left = "0px";
            CodeSourceBView.Container.style.right = "0px";
            CodeSourceBView.Container.style.top = "0px";
            CodeSourceBView.Container.style.bottom = "0px";

            CodeSourceBView.Container.style.display = IStyle.DisplayEnum.none;
            CodeSourceBView.Container.AttachTo(CurrentDesigner.Content);

            CodeSourceBTab.Deactivated +=
                delegate
                {
                    CodeSourceBView.Container.style.display = IStyle.DisplayEnum.none;
                };

            CodeSourceBTab.Activated +=
                delegate
                {

                    CodeSourceBView.Container.style.display = IStyle.DisplayEnum.empty;
                };


            #endregion

            #region CodeSourceFormsDesignerTab
            var CodeSourceFormsDesignerTab =
                new SolutionFileDesignerTab
                {
                    Image = new RTA_mode_design(),
                    // all source code, not just html?
                    Text = "Designer"
                };


            var CodeSourceFormsDesignerTabView = new SolutionFileView();

            CodeSourceFormsDesignerTabView.Container.style.With(
                style =>
                {
                    style.position = IStyle.PositionEnum.absolute;
                    style.left = "0px";
                    style.right = "0px";
                    style.top = "0px";
                    style.bottom = "0px";

                    style.display = IStyle.DisplayEnum.none;
                }
            );

            new IHTMLDiv().With(
                div =>
                {
                    div.style.position = IStyle.PositionEnum.absolute;
                    div.style.left = "16px";
                    div.style.top = "16px";
                    div.style.width = "400px";
                    div.style.height = "300px";
                    div.style.backgroundColor = Color.FromGray(0xe0);
                    div.style.border = "1px solid gray";
                    div.AttachTo(CodeSourceFormsDesignerTabView.Container);
                }
            );


            CodeSourceFormsDesignerTabView.Container.AttachTo(CurrentDesigner.Content);

            CodeSourceFormsDesignerTab.Deactivated +=
                delegate
                {
                    CodeSourceFormsDesignerTabView.Container.style.display = IStyle.DisplayEnum.none;
                };

            CodeSourceFormsDesignerTab.Activated +=
                delegate
                {

                    CodeSourceFormsDesignerTabView.Container.style.display = IStyle.DisplayEnum.empty;
                };


            #endregion

            CurrentDesigner.Add(CodeSourceFormsDesignerTab);
            CurrentDesigner.Add(CodeSourceBTab);
            CurrentDesigner.Add(CodeSourceATab);




            var wLeftScrollable = new System.Windows.Forms.Form
            {
                BackColor = global::System.Drawing.Color.White,
                Text = "Toolbox",
                ControlBox = false,
                ShowIcon = false,
                AutoScroll = true
            };

            vv.Container.AttachTo(
                wLeftScrollable.GetHTMLTargetContainer()
            );

            //wLeftScrollable.Show();

            Split.Split.LeftScrollable.style.zIndex = 0;
            wLeftScrollable.AttachFormTo(Split.Split.LeftScrollable);


            //wLeftScrollable.PopupInsteadOfClosing();

            //Split.Split.LeftScrollable = (IHTMLDiv)(object)SolutionToolbox.body;
            Split.Split.RightScrollable = Viewer.Container;

            // ...





            #region dynamic content
            Func<IEnumerable<XElement>> GetPages = delegate
            {
                return from n in sln.ApplicationPage.DescendantsAndSelf()
                       let type = n.Attribute(SolutionBuilderInteractive.DataTypeAttribute)
                       where type != null
                       let id = n.Attribute("id")
                       where id != null
                       select n;
            };

            sln.Interactive.GenerateApplicationExpressions +=
                Add =>
                {


                    // page.PageContainer.ReplaceWith(
                    GetPages().WithEach(
                        k =>
                        {
                            var id = k.Attribute("id").Value;

                            if (id == "Page1")
                            {
                                Add(
                                    new StockReplaceWithNewPageExpression(id)
                                );
                            }

                            if (id == "UserControl1")
                            {
                                Add(
                                    new StockReplaceWithNewUserControlExpression(sln.Name + ".Components", id)
                                );
                            }

                            if (id == "Applet1")
                            {
                                Add(
                                    new StockReplaceWithNewAppletExpression(sln.Name + ".Components", id)
                                );
                            }

                            if (id == "Sprite1")
                            {
                                Add(
                                    new StockReplaceWithNewSpriteExpression(sln.Name + ".Components", id)
                                );
                            }

                            if (id == "AppletUserControl1")
                            {
                                Add(
                                    new StockReplaceWithNewAppletExpression(sln.Name + ".Components", id)
                                );
                            }
                        }
                    );
                };

            sln.Interactive.GenerateHTMLFiles +=
                Add =>
                {

                    GetPages().WithEach(
                        k =>
                        {
                            var id = k.Attribute("id").Value;

                            if (id == "Page1")
                            {
                                var __Content = new XElement(StockPageDefault.Page);


                                __Content.Element("head").Element("title").Value = id;

                                Add(
                                    new SolutionProjectHTMLFile
                                    {
                                        Name = "Design/" + id + ".htm",
                                        Content = __Content
                                    }
                                );
                            }
                        }
                     );
                };

            sln.Interactive.GenerateTypes +=
                Add =>
                {
                    GetPages().WithEach(
                        k =>
                        {
                            var id = k.Attribute("id").Value;

                            if (id == "UserControl1")
                            {
                                Add(
                                    new StockUserControlType(sln.Name + ".Components", id)
                                );
                            }

                            if (id == "Applet1")
                            {
                                Add(
                                    new StockAppletType(sln.Name + ".Components", id)
                                );
                            }

                            if (id == "Sprite1")
                            {
                                Add(
                                    new StockSpriteType(sln.Name + ".Components", id)
                                );
                            }

                            if (id == "AppletUserControl1")
                            {
                                var UserControl2 = new StockUserControlType(sln.Name + ".Components", "UserControl2");

                                Add(
                                    UserControl2
                                );

                                Add(
                                    new StockUserControlAppletType(sln.Name + ".Components", id, UserControl2)
                                );
                            }
                        }
                     );
                };
            #endregion


            var _Solution = new TreeNode(VistaTreeNodePage.Create);


            var _Project = _Solution.Add();

            var About = new About();

            #region UpdateFile1Text
            Action UpdateFile1Text =
                delegate
                {

                    if (CodeSourceBView.File != null)
                    {
                        File7Tab.Text = CodeSourceBView.File.Name.SkipUntilLastIfAny("/");
                    }
                    else
                    {
                        File7Tab.Text = sln.Name;
                    }


                };
            #endregion



            #region Update
            Action Update =
                delegate
                {
                    sln.Name = About.ProjectName.value;

                    UpdateFile1Text();

                    _Project.Clear();
                    UpdateTree(sln, CodeSourceBView, _Solution, _Project);
                };
            #endregion


            var PreviousVersion = default(string);

            #region HTMLDesigner.HTMLDesignerContent
            HTMLDesigner.HTMLDesignerContent.WhenContentReady(
                body =>
                {
                    if (PreviousVersion == null)
                    {
                        var x = new XElement(body.AsXElement());
                        var y = x.ToString();
                        PreviousVersion = y;
                    }

                    Action<bool> HTMLDesignerContentCheck =
                        DoUpdate =>
                        {
                            var x = new XElement(body.AsXElement());
                            var y = x.ToString();

                            if (PreviousVersion != y)
                            {
                                PreviousVersion = y;


                                sln.ApplicationPage = x;

                                // allow any blur causing action to complete first
                                // we get reselected for some odd reason, why?
                                new Timer(
                                    delegate
                                    {
                                        if (DoUpdate)
                                        {
                                            OutputWriteLine("Designer has caused an update.");
                                            Update();
                                        }
                                        else
                                        {
                                            OutputWriteLine("Designer will cause an update.");
                                        }

                                    }
                                ).StartTimeout(700);
                            }
                        };

                    var HTMLDesignerContentDirty = new Timer(
                        delegate
                        {
                            HTMLDesignerContentCheck(false);
                        }
                    );

                    HTMLDesigner.HTMLDesignerContent.contentWindow.onfocus +=
                        delegate
                        {
                            OutputWriteLine("Designer activated.");
                            //"focus".ToDocumentTitle();

                            //HTMLDesignerContentDirty.StartInterval(700);
                        };

                    HTMLDesigner.HTMLDesignerContent.contentWindow.onblur +=
                        delegate
                        {
                            //HTMLDesignerContentDirty.Stop();

                            OutputWriteLine("Designer deactivated.");
                            //"blur".ToDocumentTitle();
                            HTMLDesignerContentCheck(true);

                        };
                }
            );
            #endregion

            #region CodeSourceBView.FileChanged
            CodeSourceBView.FileChanged +=
                delegate
                {
                    UpdateFile1Text();


                    OutputWriteLine("Select: " + CodeSourceBView.File.Name);

                    CodeSourceFormsDesignerTab.TabElement.Hide();

                    // hack :)
                    if (CodeSourceBView.File.Name.EndsWith("/App.htm"))
                    {
                        // currently we only have one element :)

                        HTMLDesigner.HTMLDesignerTab.RaiseActivated();

                        HTMLDesigner.HTMLDesignerTab.TabElement.style.display = IStyle.DisplayEnum.inline_block;
                        HTMLDesigner.HTMLSourceTab.TabElement.style.display = IStyle.DisplayEnum.none;
                        CodeSourceATab.TabElement.style.display = IStyle.DisplayEnum.inline_block;
                        CodeSourceBTab.TabElement.style.display = IStyle.DisplayEnum.inline_block;

                        HTMLDesigner.HTMLDesignerContent.WhenContentReady(
                            body =>
                            {
                                HTMLDesigner.HTMLDesignerContent.contentWindow.focus();
                            }
                        );

                        // show the design/source buttons
                    }
                    else if (CodeSourceBView.File.Name.EndsWith(".sln"))
                    {
                        AboutTab.Activate();
                    }
                    else if (CodeSourceBView.File.Name.EndsWith(sln.Language.ProjectFileExtension))
                    {
                        AboutTab.Activate();
                    }
                    else if (CodeSourceBView.File.Name.EndsWith(sln.Language.CodeFileExtension))
                    {
                        // show type outline / member
                        CodeSourceBTab.RaiseActivated();

                        HTMLDesigner.HTMLDesignerTab.TabElement.style.display = IStyle.DisplayEnum.none;
                        HTMLDesigner.HTMLSourceTab.TabElement.style.display = IStyle.DisplayEnum.none;
                        CodeSourceATab.TabElement.style.display = IStyle.DisplayEnum.none;
                        CodeSourceBTab.TabElement.style.display = IStyle.DisplayEnum.inline_block;

                        CodeSourceBView.File.ContextType.BaseType.With(
                            BaseType =>
                            {
                                if (BaseType is KnownStockTypes.System.Windows.Forms.UserControl)
                                {
                                    CodeSourceFormsDesignerTab.TabElement.Show();
                                    CodeSourceFormsDesignerTab.RaiseActivated();

                                }

                                if (BaseType is KnownStockTypes.System.ComponentModel.Component)
                                {
                                    CodeSourceFormsDesignerTab.TabElement.Show();
                                    CodeSourceFormsDesignerTab.RaiseActivated();

                                }
                            }
                        );

                    }


                };
            #endregion


            //AddSaveButton(WorkspaceHeader, i => Save = i);

            About.ProjectName.value = sln.Name;
            About.ProjectName.onchange +=
                delegate
                {
                    OutputWriteLine("Project name has changed.");
                    Update();
                };



            Viewer.Content.Clear();
            Viewer.Content.Add(About.Container);
            Viewer.Content.Add(CurrentDesigner.Container);
            Viewer.Content.Add(OutputFileViewer.Container);

            AboutTab.WhenActivated(About.Container);
            File7Tab.WhenActivated(CurrentDesigner.Container);
            OutputTab.WhenActivated(OutputFileViewer.Container);



            Viewer.First().Activate();

            //var SolutionExplorer = new SolutionDockWindowPage();

            //SolutionExplorer.HeaderText.innerText = "Solution Explorer";
            //SolutionExplorer.Content.style.backgroundColor = Color.White;
            //SolutionExplorer.Content.style.padding = "2px";
            //SolutionExplorer.Content.ReplaceContentWith(_Solution.Container);


            var fSolutionExplorer = new System.Windows.Forms.Form
            {
                BackColor = global::System.Drawing.Color.White,
                Text = "Solution Explorer",
                ControlBox = false,
                ShowIcon = false

            };

            EditorTreeSplit.Split.RightScrollable.style.zIndex = 0;
            EditorTreeSplit.Split.RightScrollable.style.position = IStyle.PositionEnum.relative;

            fSolutionExplorer.AttachFormTo(EditorTreeSplit.Split.RightScrollable);

            _Solution.Container.AttachTo(fSolutionExplorer.GetHTMLTargetContainer());

            _Solution.Container.style.overflow = IStyle.OverflowEnum.auto;
            _Solution.Container.style.height = "100%";
            _Solution.Container.style.backgroundColor = Color.White;

            //EditorTreeSplit.Split.RightContainer = (IHTMLDiv)(object)SolutionExplorer.Container;

            EditorTreeSplit.Container.AttachTo(Workspace);

            //CurrentDesigner.First().RaiseActivated();

            Update();

            #region CreateLanguageButton
            Action<IHTMLImage, string, SolutionProjectLanguage, string> CreateLanguageButton =
                (Icon, Text, Language, Name) =>
                {
                    var span = new IHTMLSpan(Text);

                    span.style.marginLeft = "0.7em";
                    span.style.marginRight = "0.7em";

                    new IHTMLButton { Icon /*, span */ }.AttachTo(WorkspaceHeaderTab1).With(
                        btn =>
                        {
                            btn.onclick +=
                                delegate
                                {
                                    sln.Language = Language;
                                    sln.Name = Language.LanguageSpelledName.Replace(" ", "") + "Project1";
                                    Update();
                                };

                            //btn.style.display = IStyle.DisplayEnum.block;
                        }
                    );
                };
            #endregion


            CreateLanguageButton(new VisualCSharpProject(), "C#", KnownLanguages.VisualCSharp, "VisualCSharpProject1");
            CreateLanguageButton(new VisualFSharpProject(), "F#", KnownLanguages.VisualFSharp, "VisualFSharpProject1");
            CreateLanguageButton(new VisualBasicProject(), "Visual Basic", KnownLanguages.VisualBasic, "VisualBasicProject1");

            var ListOfCreateProjectTypeButton = new List<IHTMLButton>();

            #region CreateProjectTypeButton
            Action<string, Action> CreateProjectTypeButton =
              (Text, Handler) =>
              {
                  var span = new IHTMLSpan(Text);

                  span.style.marginLeft = "0.7em";
                  span.style.marginRight = "0.7em";

                  new IHTMLButton { span }.AttachTo(WorkspaceHeaderTab2).With(
                      btn =>
                      {
                          ListOfCreateProjectTypeButton.Add(btn);

                          btn.onclick +=
                              delegate
                              {
                                  ListOfCreateProjectTypeButton.WithEach(n => n.disabled = true);

                                  Handler();
                              };

                          //btn.style.display = IStyle.DisplayEnum.block;
                      }
                  );
              };
            #endregion

            #region ToSpecificProjectType
            Action<string, Action> ToSpecificProjectType =
                (Text, Handler) =>
                {
                    CreateProjectTypeButton(Text,
                        delegate
                        {
                            Handler();


                            HTMLDesigner.HTMLDesignerContent.WhenDocumentReady(
                                document =>
                                {
                                    document.WithContent(sln.ApplicationPage);
                                    // we should now also lock the designer!
                                    document.DesignMode = false;
                                }
                            );

                            Update();
                        }
                    );
                };
            #endregion

            #region Avalon, Forms
            ToSpecificProjectType("Avalon App",
                delegate
                {
                    sln.WithCanvas();
                }
            );


            ToSpecificProjectType("Avalon Flash App",
               delegate
               {
                   sln.WithCanvasAdobeFlash();

               }
            );

            ToSpecificProjectType("Forms App",
                delegate
                {
                    sln.WithForms();
                }
            );


            ToSpecificProjectType("Forms Applet App",
               delegate
               {
                   sln.WithFormsApplet();

               }
            );
            #endregion

            ToSpecificProjectType("Flash App",
              delegate
              {
                  sln.WithAdobeFlash();
              }
            );

            ToSpecificProjectType("Flash Camera App",
                delegate
                {
                    sln.WithAdobeFlashCamera();
                }
              );

            ToSpecificProjectType("Flash Flare3D App",
               delegate
               {
                   sln.WithAdobeFlashWithFlare3D();
               }
             );

            ToSpecificProjectType("Applet App",
              delegate
              {
                  sln.WithJavaApplet();
              }
            );
        }
        // http://youtu.be/Lo1IU8UAutE
        // 60hz 2160 4K!

        // The equirectangular projection was used in map creation since it was invented around 100 A.D. by Marinus of Tyre. 

        //        C:\Users\Arvo> "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hzsky.png" "/sdcard/oculus/360photos/"
        //1533 KB/s(3865902 bytes in 2.461s)

        //C:\Users\Arvo> "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\tape360globe1\0000.png" "/sdcard/oculus/360photos/tape360globe1.png"
        //1556 KB/s(2714294 bytes in 1.703s)

        //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\hz2048c3840x2160.png" "/sdcard/oculus/360photos/"
        //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push   "X:\vr\tape360globe1\0000.png" "/sdcard/oculus/360photos/tape360globe2.png"
        //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push   "X:\vr\tape360globe1\0000.png" "/sdcard/oculus/360photos/tape360globenight.png"



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

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

        // the eye nor the display will be able to do any stereo
        // until tech is near matrix capability. 2019?

        // cubemap can be used for all long range scenes
        // http://www.imdb.com/title/tt0112111/?ref_=nv_sr_1


        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150808/cubemapcamera
        // subst /D b:
        // subst b: s:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360GlobeAnimation\Chrome360GlobeAnimation\bin\Debug\staging\Chrome360GlobeAnimation.Application\web
        // subst a: z:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360GlobeAnimation\Chrome360GlobeAnimation\bin\Debug\staging\Chrome360GlobeAnimation.Application\web
        // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\Chrome360GlobeAnimation\Chrome360GlobeAnimation\bin\Debug\staging\Chrome360GlobeAnimation.Application\web
        // what if we want to do subst in another winstat or session?

        // ColladaLoader: Empty or non-existing file (assets/Chrome360GlobeAnimation/S6Edge.dae)

        /// <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 =
            //s =>
            //{
            //    s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

            //    //var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
            //    var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDragWithShadow().AttachTo(s.Context.GetHTMLTarget());



            //    s.Context.GetHTMLTarget().style.backgroundColor = "#efefef";
            //    //s.Context.GetHTMLTarget().style.backgroundColor = "#A26D41";

            //};

#if AsWEBSERVER
            #region += Launched chrome.app.window
            // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

            if (self_chrome_socket != null)
            {
                // if we run as a server. we can open up on android.

                //chrome.Notification.DefaultTitle = "Nexus7";
                //chrome.Notification.DefaultIconUrl = new x128().src;
                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                     AppSource.Text
                //, AtFormCreated: FormStyler.AtFormCreated

                //AtFormConstructor:
                //    f =>
                //    {
                //        //arg[0] is typeof System.Int32
                //        //script: error JSC1000: No implementation found for this native method, please implement [static System.Drawing.Color.FromArgb(System.Int32)]

                //        // X:\jsc.svn\examples\javascript\forms\Test\TestFromArgb\TestFromArgb\ApplicationControl.cs

                //        f.BackColor = System.Drawing.Color.FromArgb(0xA26D41);
                //    }
                );
                return;
            }
            #endregion
#else

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

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

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

                    //};

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

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

                        // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions
                        var xappwindow = await chrome.app.window.create(
                               Native.document.location.pathname, options: new
                               {
                                   alwaysOnTop = true,
                                   visibleOnAllWorkspaces = true
                               }
                        );

                        //xappwindow.setAlwaysOnTop

                        xappwindow.show();

                        await xappwindow.contentWindow.async.onload;

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


                    return;
                }
            }
            #endregion


#endif

            // Earth params
            //var radius = 0.5;
            //var radius = 1024;
            //var radius = 2048;
            //var radius = 512;
            //var radius = 256;
            //var radius = 400;

            // can we have not fly beyond moon too much?
            //var radius = 500;
            var radius = 480;

            //var segments = 32;
            var segments = 128;
            //var rotation = 6;


            //const int size = 128;
            //const int size = 256; // 6 faces, 12KB
            //const int size = 512; // 6 faces, ?

            // WebGL: drawArrays: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.

            //const int size = 720; // 6 faces, ?
            //const int size = 1024; // 6 faces, ?
            //const int cubefacesize = 1024; // 6 faces, ?

            // THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( chrome-extension://aemlnmcokphbneegoefdckonejmknohh/assets/Chrome360GlobeAnimation/anvil___spherical_hdri_panorama_skybox_by_macsix_d6vv4hs.jpg )
            int cubefacesize = 2048; // 6 faces, ?
                                     //int cubefacesize = 1024; // 6 faces, ?
                                     // "X:\vr\tape1\0000x2048.png"
                                     // for 60hz render we may want to use float camera percision, not available for ui.
                                     //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\tape1\0000x2048.png" "/sdcard/oculus/360photos/"
                                     //  "x:\util\android-sdk-windows\platform-tools\adb.exe" push "X:\vr\tape1\0000x128.png" "/sdcard/oculus/360photos/"

            //if (Environment.ProcessorCount < 8)
            //    //cubefacesize = 64; // 6 faces, ?
            //    cubefacesize = 1024; // 6 faces, ?

            new IHTMLPre { new { Environment.ProcessorCount, cubefacesize } }.AttachToDocument();

            // can we keep fast fps yet highp?

            // can we choose this on runtime? designtime wants fast fps, yet for end product we want highdef on our render farm?
            //const int cubefacesize = 128; // 6 faces, ?

            //var cubecameraoffsetx = 256;
            var cubecameraoffsetx = 400;


            //var uizoom = 0.1;
            //var uizoom = cubefacesize / 128f;
            var uizoom = 128f / cubefacesize;

            var far = 0xffffff;

            Native.css.style.backgroundColor = "blue";
            Native.css.style.overflow = IStyle.OverflowEnum.hidden;

            Native.body.Clear();
            (Native.body.style as dynamic).webkitUserSelect = "text";

            //new IHTMLPre { "can we stream it into VR, shadertoy, youtube 360, youtube stereo yet?" }.AttachToDocument();


            var sw = Stopwatch.StartNew();



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

            var window = Native.window;


            // what about physics and that portal rendering?

            // if we are running as a chrome web server, we may also be opened as android ndk webview app
            //var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: window.aspect, near: 1, far: 2000);
            // once we update source
            // save the source
            // manually recompile 
            //cameraPX.position.z = 400;

            //// the camera should be close enough for the object to float off the FOV of PX
            //cameraPX.position.z = 200;

            // scene
            // can we make the 3D object orbit around us ?
            // and
            // stream it to vr?
            var scene = new THREE.Scene();

            // since our cube camera is somewhat a fixed thing
            // would it be easier to move mountains to come to us?
            // once we change code would chrome app be able to let VR know that a new view is available?
            var sceneg = new THREE.Group();
            sceneg.AttachTo(scene);


            // fly up?
            //sceneg.translateZ(-1024);
            // rotate the world, as the skybox then matches what we have on filesystem
            scene.rotateOnAxis(new THREE.Vector3(0, 1, 0), -Math.PI / 2);
            // yet for headtracking we shall rotate camera


            //sceneg.position.set(0, 0, -1024);
            //sceneg.position.set(0, -1024, 0);

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


            //384,400 km

            var distanceKM = 384400f;
            var earthdiameterKM = 12742f;
            var moondiameterKM = 3475f;
            var virtualDistance = radius / earthdiameterKM * distanceKM;
            // 12,742 km

            // 2,159.2 miles (3,475 km).


            var light = new THREE.DirectionalLight(0xffffff, 1);
            // sun should be beyond moon
            //light.position.set(-5 * virtualDistance, -3 * virtualDistance, -5 * virtualDistance);
            light.position.set(-15 * virtualDistance, -1 * virtualDistance, -15 * virtualDistance);
            scene.add(light);





            // whats WebGLRenderTargetCube do?

            // WebGLRenderer preserveDrawingBuffer 



            var renderer0 = new THREE.WebGLRenderer(

                new
                {
                    antialias = true,
                    alpha = true,
                    preserveDrawingBuffer = true
                }
            );

            // https://github.com/mrdoob/three.js/issues/3836

            // the construct. white bg
            //renderer0.setClearColor(0xfffff, 1);
            renderer0.setClearColor(0x0, 1);

            //renderer.setSize(window.Width, window.Height);
            renderer0.setSize(cubefacesize, cubefacesize);

            //renderer0.domElement.AttachToDocument();
            //rendererPX.domElement.style.SetLocation(0, 0);
            //renderer0.domElement.style.SetLocation(4, 4);


            // top

            // http://stackoverflow.com/questions/27612524/can-multiple-webglrenderers-render-the-same-scene


            // need a place to show the cubemap face to GUI 
            // how does the stereo OTOY do it?
            // https://www.opengl.org/wiki/Sampler_(GLSL)

            // http://www.richardssoftware.net/Home/Post/25

            // [+X, –X, +Y, –Y, +Z, –Z] fa



            // move up
            //camera.position.set(-1200, 800, 1200);
            //var cameraoffset = new THREE.Vector3(0, 15, 0);

            // can we aniamte it?
            //var cameraoffset = new THREE.Vector3(0, 800, 1200);
            // can we have linear animation fromcenter of the map to the edge and back?
            // then do the flat earth sun orbit?
            var cameraoffset = new THREE.Vector3(
                // left?
                -512,
                // height?
                //0,
                //1600,
                //1024,

                // if the camera is in the center, would we need to move the scene?
                // we have to move the camera. as we move the scene the lights are messed up
                //2014,
                1024,

                //1200
                0
                // can we hover top of the map?
                );

            // original vieworigin
            //var cameraoffset = new THREE.Vector3(-1200, 800, 1200);



            var camerax = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = 0 - 2048 * 4, max = 0 + 2048 * 4, valueAsNumber = 0, title = "camerax" }.AttachToDocument();
            // up. whats the most high a rocket can go 120km?
            new IHTMLHorizontalRule { }.AttachToDocument();


            // how high is the bunker?
            var cameray = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = 0 - 2048 * 4, max = 2048 * 4, valueAsNumber = 0, title = "cameray" }.AttachToDocument();
            new IHTMLBreak { }.AttachToDocument();
            var camerayHigh = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = cameray.max, max = 1024 * 256, valueAsNumber = cameray.max, title = "cameray" }.AttachToDocument();
            new IHTMLHorizontalRule { }.AttachToDocument();
            var cameraz = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, min = 0 - 2048 * 4, max = 0 + 2048 * 4, valueAsNumber = 0, title = "cameraz" }.AttachToDocument();

            // for render server
            var fcamerax = 0.0;
            var fcameray = 0.0;
            var fcameraz = 0.0;

            //while (await camerax.async.onchange)

            //cameray.onchange += delegate
            //{
            //    if (cameray.valueAsNumber < cameray.max)
            //        camerayHigh.valueAsNumber = camerayHigh.min;
            //};

            camerayHigh.onmousedown += delegate
            {
                //if (camerayHigh.valueAsNumber > camerayHigh.min)
                cameray.valueAsNumber = cameray.max;
            };


            Action applycameraoffset = delegate
            {
                // make sure UI and gpu sync up

                var cy = cameray;

                if (cameray.valueAsNumber < cameray.max)
                    camerayHigh.valueAsNumber = camerayHigh.min;

                if (camerayHigh.valueAsNumber > camerayHigh.min)
                    cameray.valueAsNumber = cameray.max;

                if (cameray.valueAsNumber == cameray.max)
                    cy = camerayHigh;



                cameraoffset = new THREE.Vector3(
                  // left?
                  camerax + fcamerax,
                   // height?
                   //0,
                   //1600,
                   //1024,

                   // if the camera is in the center, would we need to move the scene?
                   // we have to move the camera. as we move the scene the lights are messed up
                   //2014,
                   cy + fcameray,

                   //1200
                   cameraz + fcameraz
                   // can we hover top of the map?
                   );
            };


            #region y
            // need to rotate90?
            var cameraNY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraNY.position.copy(new THREE.Vector3(0, 0, 0));
                cameraNY.lookAt(new THREE.Vector3(0, -1, 0));
                cameraNY.position.add(cameraoffset);
            };

            //cameraNY.lookAt(new THREE.Vector3(0, 1, 0));
            var canvasNY = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNY.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 2);
            canvasNY.canvas.title = "NY";
            canvasNY.canvas.AttachToDocument();
            canvasNY.canvas.style.transformOrigin = "0 0";
            canvasNY.canvas.style.transform = "scale(" + uizoom + ")";

            var cameraPY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraPY.position.copy(new THREE.Vector3(0, 0, 0));
                cameraPY.lookAt(new THREE.Vector3(0, 1, 0));
                cameraPY.position.add(cameraoffset);
            };
            //cameraPY.lookAt(new THREE.Vector3(0, -1, 0));
            var canvasPY = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPY.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 0);
            canvasPY.canvas.title = "PY";
            canvasPY.canvas.AttachToDocument();
            canvasPY.canvas.style.transformOrigin = "0 0";
            canvasPY.canvas.style.transform = "scale(" + uizoom + ")";
            #endregion

            // transpose xz?

            #region x
            var cameraNX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraNX.position.copy(new THREE.Vector3(0, 0, 0));
                cameraNX.lookAt(new THREE.Vector3(0, 0, 1));
                cameraNX.position.add(cameraoffset);
            };
            //cameraNX.lookAt(new THREE.Vector3(0, 0, -1));
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNX.lookAt(new THREE.Vector3(1, 0, 0));
            var canvasNX = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNX.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 2, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasNX.canvas.title = "NX";
            canvasNX.canvas.AttachToDocument();
            canvasNX.canvas.style.transformOrigin = "0 0";
            canvasNX.canvas.style.transform = "scale(" + uizoom + ")";

            var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            applycameraoffset += delegate
            {
                cameraPX.position.copy(new THREE.Vector3(0, 0, 0));
                cameraPX.lookAt(new THREE.Vector3(0, 0, -1));
                cameraPX.position.add(cameraoffset);
            };
            //cameraPX.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPX.lookAt(new THREE.Vector3(1, 0, 0));
            //cameraPX.lookAt(new THREE.Vector3(-1, 0, 0));
            var canvasPX = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPX.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 0, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasPX.canvas.title = "PX";
            canvasPX.canvas.AttachToDocument();
            canvasPX.canvas.style.transformOrigin = "0 0";
            canvasPX.canvas.style.transform = "scale(" + uizoom + ")";
            #endregion



            #region z
            var cameraNZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, -1));
            applycameraoffset += delegate
            {
                cameraNZ.position.copy(new THREE.Vector3(0, 0, 0));
                cameraNZ.lookAt(new THREE.Vector3(1, 0, 0));
                cameraNZ.position.add(cameraoffset);
            };
            //cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            //cameraNZ.lookAt(new THREE.Vector3(0, 0, 1));
            var canvasNZ = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasNZ.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 3, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasNZ.canvas.title = "NZ";
            canvasNZ.canvas.AttachToDocument();
            canvasNZ.canvas.style.transformOrigin = "0 0";
            canvasNZ.canvas.style.transform ="scale(" + uizoom + ")";

            var cameraPZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: far);
            //cameraPZ.lookAt(new THREE.Vector3(1, 0, 0));
            applycameraoffset += delegate
            {
                cameraPZ.position.copy(new THREE.Vector3(0, 0, 0));
                cameraPZ.lookAt(new THREE.Vector3(-1, 0, 0));
                cameraPZ.position.add(cameraoffset);
            };
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, 1));
            //cameraPZ.lookAt(new THREE.Vector3(0, 0, -1));
            var canvasPZ = new CanvasRenderingContext2D(cubefacesize, cubefacesize);
            canvasPZ.canvas.style.SetLocation(cubecameraoffsetx + (int)(uizoom * cubefacesize + 8) * 1, 8 + (int)(uizoom * cubefacesize + 8) * 1);
            canvasPZ.canvas.title = "PZ";
            canvasPZ.canvas.AttachToDocument();
            canvasPZ.canvas.style.transformOrigin = "0 0";
            canvasPZ.canvas.style.transform = "scale(" + uizoom + ")";
            #endregion




            // c++ alias locals would be nice..
            var canvas0 = (IHTMLCanvas)renderer0.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


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

            //canvas0.css.active.style.cursor = IStyle.CursorEnum.move;

            #region onmousedown
            Native.body.onmousedown +=
                async e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                        return;

                    // movementX no longer works
                    old = new
                    {


                        e.CursorX,
                        e.CursorY
                    };


                    //e.CaptureMouse();
                    var release = e.Element.CaptureMouse();
                    await e.Element.async.onmouseup;

                    release();


                };
            #endregion



            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            Native.body.onmousemove +=
                e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                    {
                        Native.body.style.cursor = [email protected];
                        return;
                    }

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


                    Native.body.style.cursor = IStyle.CursorEnum.move;

                    var pointerLock = canvas0 == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion

            // THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(78,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll
            // THREE.WebGLProgram: gl.getProgramInfoLog() (79,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll

            // http://www.roadtovr.com/youtube-confirms-stereo-3d-360-video-support-coming-soon/
            // https://www.youtube.com/watch?v=D-Wl9jAB45Q



            #region spherical
            var gl = new WebGLRenderingContext(alpha: true, preserveDrawingBuffer: true);
            var c = gl.canvas.AttachToDocument();

            //  3840x2160

            //c.style.SetSize(3840, 2160);

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


            c.width = 3840;
            c.height = 2160;


            //c.width = 3840 * 2;
            //c.height = 2160 * 2;


            //c.width = 3840;
            //c.height = 2160;
            // 1,777777777777778

            // https://www.youtube.com/watch?v=fTfJwzRsE-w
            //c.width = 7580;
            //c.height = 3840;
            //1,973958333333333

            //7580
            //    3840

            // wont work
            //c.width = 8192;
            //c.height = 4096;


            // this has the wrong aspect?
            //c.width = 6466;
            //c.height = 3232;

            new IHTMLPre { new { c.width, c.height } }.AttachToDocument();

            //6466x3232

            //var suizoom = 720f / c.height;
            //var suizoom = 360f / c.height;
            var suizoom = 480f / c.width;

            c.style.transformOrigin = "0 0";
            c.style.transform = "scale(" + suizoom + ")";
            //c.style.backgroundColor = "yellow";
            c.style.position = IStyle.PositionEnum.absolute;

            c.style.SetLocation(8 + (int)(uizoom * cubefacesize + 8) * 0, 8 + (int)(uizoom * cubefacesize + 8) * 3);

            var pass = new CubeToEquirectangular.Library.ShaderToy.EffectPass(
                       null,
                       gl,
                       precission: CubeToEquirectangular.Library.ShaderToy.DetermineShaderPrecission(gl),
                       supportDerivatives: gl.getExtension("OES_standard_derivatives") != null,
                       callback: null,
                       obj: null,
                       forceMuted: false,
                       forcePaused: false,
                       //quadVBO: Library.ShaderToy.createQuadVBO(gl, right: 0, top: 0),
                       outputGainNode: null
                   );

            // how shall we upload our textures?
            // can we reference GLSL.samplerCube yet?
            //pass.mInputs[0] = new samplerCube { };
            pass.mInputs[0] = new CubeToEquirectangular.Library.ShaderToy.samplerCube { };

            pass.MakeHeader_Image();
            var vs = new Shaders.ProgramFragmentShader();
            pass.NewShader_Image(vs);

            #endregion




            //var frame0 = new HTML.Images.FromAssets.tiles_regrid().AttachToDocument();
            //var frame0 = new HTML.Images.FromAssets.galaxy_starfield().AttachToDocument();
            var frame0 = new HTML.Images.FromAssets.galaxy_starfield150FOV().AttachToDocument();
            //var xor = new HTML.Images.FromAssets.Orion360_test_image_8192x4096().AttachToDocument();
            //var xor = new HTML.Images.FromAssets._2_no_clouds_4k().AttachToDocument();
            //var frame0 = new HTML.Images.FromAssets._2294472375_24a3b8ef46_o().AttachToDocument();


            // 270px
            //xor.style.height = "";
            frame0.style.height = "270px";
            frame0.style.width = "480px";
            frame0.style.SetLocation(
                8 + (int)(uizoom * cubefacesize + 8) * 0 + 480 + 16, 8 + (int)(uizoom * cubefacesize + 8) * 3);





            #region fixup rotation

            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI / 2);
            //mesh.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI / 2);

            // dont need the fixup. unless we want to animate the sky rotate?
            //mesh.rotateOnAxis(new THREE.Vector3(0, 1, 0), -Math.PI / 2);
            #endregion


            // hide the sky to see camera lines?
            //  can we show this as HUD on VR in webview?
            //skybox.visible = false;
            //scene.add(skybox);




            //new IHTMLButton { }

            #region DirectoryEntry
            var dir = default(DirectoryEntry);

            new IHTMLButton { "openDirectory" }.AttachToDocument().onclick += async delegate
            {
                dir = (DirectoryEntry)await chrome.fileSystem.chooseEntry(new { type = "openDirectory" });
            };

            frame0.onclick += delegate
            {
                // http://paulbourke.net/papers/vsmm2006/vsmm2006.pdf
                //            A method of creating synthetic stereoscopic panoramic images that can be implemented
                //in most rendering packages has been presented. If single panoramic pairs can be created
                //then stereoscopic panoramic movies are equally possible giving rise to the prospect of
                //movies where the viewer can interact with, at least with regard to what they choose to look
                //at.These images can be projected so as to engage the two features of the human visual
                //system that assist is giving us a sense of immersion, the feeling of “being there”. That is,
                //imagery that contains parallax information as captured from two horizontally separated eye
                //positions (stereopsis)and imagery that fills our peripheral vision.The details that define
                //how the two panoramic images should be created in rendering packages are provided, in
                //particular, how to precisely configure the virtual cameras and control the distance to zero
                //parallax.

                // grab a frame

                if (dir == null)
                {
                    // not exporting to file system?
                    var f0 = new IHTMLImage { src = gl.canvas.toDataURL() };

                    //var f0 = (IHTMLImage)gl.canvas;
                    //var f0 = (IHTMLImage)gl.canvas;
                    //var base64 = gl.canvas.toDataURL();


                    //frame0.src = base64;
                    frame0.src = f0.src;

                    // 7MB!

                    return;
                }

                //                // ---------------------------
                //IrfanView
                //---------------------------
                //Warning !
                //The file: "X:\vr\tape1\0001.jpg" is a PNG file with incorrect extension !
                //Rename ?
                //---------------------------
                //Yes   No   
                //---------------------------

                // haha this will render the thumbnail.
                //dir.WriteAllBytes("0000.png", frame0);

                //dir.WriteAllBytes("0000.png", gl.canvas);

                var glsw = Stopwatch.StartNew();
                dir.WriteAllBytes("0000.png", gl);

                new IHTMLPre { new { glsw.ElapsedMilliseconds } }.AttachToDocument();

                // {{ ElapsedMilliseconds = 1548 }}

                // 3.7MB
                // 3840x2160

            };

            #endregion

            var vsync = default(TaskCompletionSource<object>);

            new IHTMLButton {
                "render 60hz 30sec"
            }.AttachToDocument().onclick += async e =>
            {
                e.Element.disabled = true;


                var total = Stopwatch.StartNew();
                var status = "rendering... " + new { dir };

                new IHTMLPre { () => status }.AttachToDocument();

                if (dir == null)
                {
                    //dir = (DirectoryEntry)await chrome.fileSystem.chooseEntry(new { type = "openDirectory" });
                }

                total.Restart();



                vsync = new TaskCompletionSource<object>();
                await vsync.Task;

                status = "rendering... vsync";

                var frameid = 0;

                goto beforeframe;


                // parallax offset?

                await_nextframe:


                var filename = frameid.ToString().PadLeft(4, '0') + ".png";
                status = "rendering... " + new { frameid, filename };


                vsync = new TaskCompletionSource<object>();
                await vsync.Task;

                // frame0 has been rendered

                var swcapture = Stopwatch.StartNew();
                status = "WriteAllBytes... " + new { filename };
                //await Native.window.async.onframe;

                // https://code.google.com/p/chromium/issues/detail?id=404301
                if (dir != null)
                    await dir.WriteAllBytes(filename, gl);
                //await dir.WriteAllBytes(filename, gl.canvas);

                status = "WriteAllBytes... done " + new { fcamerax, filename, swcapture.ElapsedMilliseconds };
                status = "rdy " + new { filename, fcamerax };
                //await Native.window.async.onframe;


                beforeframe:

                // speed? S6 slow motion?
                // this is really slow. if we do x4x2 =x8 
                // https://www.youtube.com/watch?v=r76ULW16Ib8
                //fcamerax += 16 * (1.0 / 60.0);
                fcamerax = radius * Math.Cos(Math.PI * (frameid - (60 * 30 / 2f)) / (60 * 30 / 2f));

                cameraz.valueAsNumber = (int)(cameraz.max * Math.Sin(Math.PI * (frameid - (60 * 30 / 2f)) / (60 * 30 / 2f)));


                // up
                //fcameray = 128 * Math.Cos(Math.PI * (frameid - (60 * 30 / 2f)) / (60 * 30 / 2f));

                //fcamerax += (1.0 / 60.0);

                //fcamerax += (1.0 / 60.0) * 120;

                if (Environment.ProcessorCount < 8)
                    frameid += 15;
                else
                    frameid++;

                // 60hz 30sec
                if (frameid < 60 * 30)
                {
                    // Blob GC? either this helms or the that we made a Blob static. 
                    await Task.Delay(11);

                    goto await_nextframe;
                }

                total.Stop();
                status = "all done " + new { frameid, total.ElapsedMilliseconds };
                vsync = default(TaskCompletionSource<object>);
                // http://stackoverflow.com/questions/22899333/delete-javascript-blobs

                e.Element.disabled = false;
            };

            // "Z:\jsc.svn\examples\javascript\WebGL\WebGLColladaExperiment\WebGLColladaExperiment\WebGLColladaExperiment.csproj"


            #region moonsphere
            var moonsphere = new THREE.Mesh(
                    new THREE.SphereGeometry(radius / earthdiameterKM * moondiameterKM, segments, segments),
                    new THREE.MeshPhongMaterial(
                            new
                            {
                                map = new THREE.Texture().With(

                                    async s =>
                                    {
                                        //0:75ms event: _2_no_clouds_4k_low view-source:36543
                                        //Application Cache Progress event (1 of 2) http://192.168.1.72:22248/view-source 192.168.1.72/:1
                                        //Application Cache Progress event (2 of 2)  192.168.1.72/:1
                                        //Application Cache Cached event 192.168.1.72/:1
                                        //1:1018ms event: _2_no_clouds_4k_low done view-source:36543
                                        //1:1019ms event: _2_no_clouds_4k view-source:36543
                                        //event.returnValue is deprecated. Please use the standard event.preventDefault() instead. view-source:2995
                                        //1:16445ms event: _2_no_clouds_4k done 

                                        // ~ tilde to open css editor?


                                        //await 20000;

                                        //Console.WriteLine("event: _2_no_clouds_4k");
                                        s.image = await new moon();
                                        s.needsUpdate = true;
                                        //Console.WriteLine("event: _2_no_clouds_4k done");
                                    }
                                ),


                                //bumpMap = THREE.ImageUtils.loadTexture(
                                //    new elev_bump_4k().src
                                ////new elev_bump_4k_low().src
                                //),


                                //// applies onyl to shaders to create the shadow
                                //bumpScale = 0.005,

                                //specularMap = new THREE.Texture().With(
                                //    async s =>
                                //    {

                                //        Console.WriteLine("event: water_4k");
                                //        s.image = await new water_4k().async.oncomplete;
                                //        s.needsUpdate = true;
                                //        Console.WriteLine("event: water_4k done");
                                //    }
                                //),


                                ////specular =    new THREE.Color("grey")								
                                //specular = new THREE.Color(0xa0a0a0)
                            })
                );
            #endregion


            //moonsphere.position.set(radius * 4, 0, 0);
            //moonsphere.position.set(0, 0, -radius * 4);

            scene.add(moonsphere);


            #region globesphere
            var globesphere = new THREE.Mesh(
                    new THREE.SphereGeometry(radius, segments, segments),
                    new THREE.MeshPhongMaterial(
                            new
                            {
                                map = new THREE.Texture().With(

                                    async s =>
                                    {
                                        //0:75ms event: _2_no_clouds_4k_low view-source:36543
                                        //Application Cache Progress event (1 of 2) http://192.168.1.72:22248/view-source 192.168.1.72/:1
                                        //Application Cache Progress event (2 of 2)  192.168.1.72/:1
                                        //Application Cache Cached event 192.168.1.72/:1
                                        //1:1018ms event: _2_no_clouds_4k_low done view-source:36543
                                        //1:1019ms event: _2_no_clouds_4k view-source:36543
                                        //event.returnValue is deprecated. Please use the standard event.preventDefault() instead. view-source:2995
                                        //1:16445ms event: _2_no_clouds_4k done 

                                        // ~ tilde to open css editor?


                                        //await 20000;

                                        //Console.WriteLine("event: _2_no_clouds_4k");
                                        s.image = await new _2_no_clouds_4k();
                                        s.needsUpdate = true;
                                        //Console.WriteLine("event: _2_no_clouds_4k done");
                                    }
                                ),


                                bumpMap = THREE.ImageUtils.loadTexture(
                                    new elev_bump_4k().src
                                //new elev_bump_4k_low().src
                                ),


                                // applies onyl to shaders to create the shadow
                                bumpScale = 0.005,

                                specularMap = new THREE.Texture().With(
                                    async s =>
                                    {

                                        Console.WriteLine("event: water_4k");
                                        s.image = await new water_4k().async.oncomplete;
                                        s.needsUpdate = true;
                                        Console.WriteLine("event: water_4k done");
                                    }
                                ),


                                //specular =    new THREE.Color("grey")								
                                specular = new THREE.Color(0xa0a0a0)
                            })
                );
            #endregion



            // http://stackoverflow.com/questions/12447734/three-js-updateing-texture-on-plane


            //globesphere.rotation.y = rotation;
            scene.add(globesphere);


            #region clouds
            var clouds = new THREE.Mesh(
                    new THREE.SphereGeometry(
                        //radius + 0.003,
                        radius + radius * 0.01,
                        segments, segments),
                    new THREE.MeshPhongMaterial(
                        new
                        {
                            //map = THREE.ImageUtils.loadTexture(
                            //    //new fair_clouds_4k().src
                            //    new fair_clouds_4k_low().src
                            //    ),


                            map = new THREE.Texture().With(
                                async s =>
                                {


                                    Console.WriteLine("event: fair_clouds_4k");
                                    s.image = await new fair_clouds_4k().async.oncomplete;
                                    s.needsUpdate = true;
                                    Console.WriteLine("event: fair_clouds_4k done");
                                }
                            ),


                            transparent = true
                        })
                );
            //clouds.rotation.y = rotation;
            scene.add(clouds);
            #endregion



            //clouds.position.set(0, virtualDistance / -2, 0);
            //globesphere.position.set(0, virtualDistance / -2, 0);

            //moonsphere.position.set(0, virtualDistance / 2, 0);


            //clouds.position.set(virtualDistance / -2, 0, 0);
            //globesphere.position.set(virtualDistance / -2, 0, 0);

            //moonsphere.position.set(virtualDistance / 2, 0, 0);

            clouds.position.set(virtualDistance / 2, (int)(-radius * 1.06), 0);
            globesphere.position.set(virtualDistance / 2, (int)(-radius * 1.06), 0);

            // moon dark side away from earth?
            //moonsphere.position.set(virtualDistance / -2, -radius, 0);
            moonsphere.position.set(virtualDistance / -2, radius / earthdiameterKM * moondiameterKM, 0);

            applycameraoffset += delegate
            {
                globesphere.rotation.y = Math.Sin((cameraz.max * 0.5 + cameraz.valueAsNumber) * 0.0005);
                clouds.rotation.y = Math.Sin((cameraz.max * 0.5 + cameraz.valueAsNumber) * 0.0006);
            };

            //globesphere.position.set(0, radius / earthdiameterKM * distanceKM, 0);

            //clouds.rotateOnAxis(new THREE.Vector3(0, 1, 0), Math.PI / 2);
            //globesphere.rotateOnAxis(new THREE.Vector3(0, 1, 0), Math.PI / 2);



            // X:\jsc.svn\examples\javascript\chrome\apps\ChromeEarth\ChromeEarth\Application.cs
            // X:\jsc.svn\examples\javascript\canvas\ConvertBlackToAlpha\ConvertBlackToAlpha\Application.cs
            // hidden for alpha AppWindows
            //#if FBACKGROUND

            #region galaxy_starfield
            new THREE.Texture().With(
                async s =>
                {
                    //var i = new HTML.Images.FromAssets.galaxy_starfield();
                    var i = new HTML.Images.FromAssets.galaxy_starfield150FOV();

                    var bytes = await i.async.bytes;

                    //for (int ii = 0; ii < bytes.Length; ii += 4)
                    //{

                    //    bytes[ii + 3] = (byte)(bytes[ii + 0]);

                    //    bytes[ii + 0] = 0xff;
                    //    bytes[ii + 1] = 0xff;
                    //    bytes[ii + 2] = 0xff;
                    //}

                    var cc = new CanvasRenderingContext2D(i.width, i.height);

                    cc.bytes = bytes;

                    s.image = cc;
                    s.needsUpdate = true;

                    var stars_material = new THREE.MeshBasicMaterial(
                            new
                            {
                                //map = THREE.ImageUtils.loadTexture(new galaxy_starfield().src),
                                map = s,
                                side = THREE.BackSide,
                                transparent = true
                            });


                    var stars = new THREE.Mesh(
                            new THREE.SphereGeometry(far * 0.9, 64, 64),
                           stars_material
                        );

                    // http://stackoverflow.com/questions/8502150/three-js-how-can-i-dynamically-change-objects-opacity
                    //(stars_material as dynamic).opacity = 0.5;


                    scene.add(stars);
                }
           );
            #endregion




            new Models.ColladaS6Edge().Source.Task.ContinueWithResult(
                   dae =>
                   {
                       // 90deg
                       dae.rotation.x = -Math.Cos(Math.PI);

                       //dae.scale.x = 30;
                       //dae.scale.y = 30;
                       //dae.scale.z = 30;
                       dae.position.z = -(65 - 200);





                       var scale = 0.9;

                       // jsc, do we have ILObserver available yet?
                       dae.scale.x = scale;
                       dae.scale.y = scale;
                       dae.scale.z = scale;


                       #region onmousewheel
                       Native.body.onmousewheel +=
                           e =>
                           {
                               e.preventDefault();

                               //camera.position.z = 1.5;

                               // min max. shall adjust speed also!
                               // max 4.0
                               // min 0.6
                               dae.position.z -= 10.0 * e.WheelDirection;

                               //camera.position.z = 400;
                               //dae.position.z = dae.position.z.Max(-200).Min(200);

                               //Native.document.title = new { z }.ToString();

                           };
                       #endregion


                       //dae.position.y = -80;

                       //dae.AttachTo(sceneg);
                       //scene.add(dae);
                       //oo.Add(dae);




                       // view-source:http://threejs.org/examples/webgl_multiple_canvases_circle.html
                       // https://threejsdoc.appspot.com/doc/three.js/src.source/extras/cameras/CubeCamera.js.html
                       Native.window.onframe +=
                           e =>
                           {
                               // let render man know..
                               if (vsync != null)
                                   if (vsync.Task.IsCompleted)
                                       return;


                               //if (pause) return;
                               //if ([email protected])
                               //    return;


                               // can we float out of frame?
                               // haha. a bit too flickery.
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.01) * 50.0;
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.001) * 190.0;
                               //globesphere.position.y = Math.Sin(fcamerax * 0.001) * 90.0;
                               //clouds.position.y = Math.Cos(fcamerax * 0.001) * 90.0;

                               //sphere.rotation.y += speed;
                               //clouds.rotation.y += speed;

                               // manual rebuild?
                               // red compiler notifies laptop chrome of pending update
                               // app reloads

                               applycameraoffset();
                               renderer0.clear();
                               //rendererPY.clear();

                               //cameraPX.aspect = canvasPX.aspect;
                               //cameraPX.updateProjectionMatrix();

                               // um what does this do?
                               //cameraPX.position.z += (z - cameraPX.position.z) * e.delay.ElapsedMilliseconds / 200.0;
                               // mousewheel allos the camera to move closer
                               // once we see the frame in vr, can we udp sync vr tracking back to laptop?


                               //this.targetPX.x += 1;
                               //this.targetNX.x -= 1;

                               //this.targetPY.y += 1;
                               //this.targetNY.y -= 1;

                               //this.targetPZ.z += 1;
                               //this.targetNZ.z -= 1;

                               // how does the 360 or shadertoy want our cubemaps?


                               // and then rotate right?

                               // how can we render cubemap?


                               #region x
                               // upside down?
                               renderer0.render(scene, cameraPX);
                               canvasPX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);

                               renderer0.render(scene, cameraNX);
                               canvasNX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               #endregion

                               #region z
                               renderer0.render(scene, cameraPZ);
                               canvasPZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);

                               renderer0.render(scene, cameraNZ);
                               canvasNZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               #endregion



                               #region y
                               renderer0.render(scene, cameraPY);

                               //canvasPY.save();
                               //canvasPY.translate(0, size);
                               //canvasPY.rotate((float)(-Math.PI / 2));
                               canvasPY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               //canvasPY.restore();


                               renderer0.render(scene, cameraNY);
                               //canvasNY.save();
                               //canvasNY.translate(size, 0);
                               //canvasNY.rotate((float)(Math.PI / 2));
                               canvasNY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, cubefacesize, cubefacesize);
                               //canvasNY.restore();
                               // ?
                               #endregion


                               //renderer0.render(scene, cameraPX);


                               //rendererPY.render(scene, cameraPY);

                               // at this point we should be able to render the sphere texture

                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_X = 34069;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_X = 34070;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Y = 34071;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072;
                               //public const uint TEXTURE_CUBE_MAP_POSITIVE_Z = 34073;
                               //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074;


                               //var cube0 = new IHTMLImage[] {
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_px(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nx(),

                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_py(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_ny(),


                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_pz(),
                               //        new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nz()
                               //};

                               new[] {
                                   canvasPX, canvasNX,
                                   canvasPY, canvasNY,
                                   canvasPZ, canvasNZ
                               }.WithEachIndex(
                                   (img, index) =>
                                   {
                                       gl.bindTexture(gl.TEXTURE_CUBE_MAP, pass.tex);

                                       //gl.pixelStorei(gl.UNPACK_FLIP_X_WEBGL, false);
                                       gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);

                                       // http://stackoverflow.com/questions/15364517/pixelstoreigl-unpack-flip-y-webgl-true

                                       // https://msdn.microsoft.com/en-us/library/dn302429(v=vs.85).aspx
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
                                       //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

                                       gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + (uint)index, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img.canvas);

                                   }
                                );

                               // could do dynamic resolution- fog of war or fog of FOV. where up to 150deg field of vision is encouragedm, not 360
                               pass.Paint_Image(
                                     0,

                                     0,
                                     0,
                                     0,
                                     0
                                //,

                                // gl_FragCoord
                                // cannot be scaled, and can be referenced directly.
                                // need another way to scale
                                //zoom: 0.3f
                                );

                               //paintsw.Stop();


                               // what does it do?
                               gl.flush();

                               // let render man know..
                               if (vsync != null)
                                   if (!vsync.Task.IsCompleted)
                                       vsync.SetResult(null);
                           };


                   }
               );





            Console.WriteLine("do you see it?");
        }
        /// <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);

        }
Example #51
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)
        {
            // .obj nolonger works?


            // http://forums.newtek.com/showthread.php?139633-how-to-convert-sketchup-files-into-OBJ-without-the-PRO-version

            // http://www.gameartmarket.com/details?id=ag9zfmRhZGEtM2RtYXJrZXRyMgsSBFVzZXIiE3BpZXJ6YWtAcGllcnphay5jb20MCxIKVXNlclVwbG9hZBjc_5ik8ycM
            // http://www.gameartmarket.com/details?id=ag9zfmRhZGEtM2RtYXJrZXRyMgsSBFVzZXIiE3BpZXJ6YWtAcGllcnphay5jb20MCxIKVXNlclVwbG9hZBjXwOHe-icM
            // http://scfreak.0catch.com/dlindex.html
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201311/20131109-gold
            // view-source:file:///X:/opensource/github/three.js/examples/webgl_loader_obj.html

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

            #region scene
            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                window.aspect,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new Scene();

            new AmbientLight(0x101030).AttachTo(scene);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

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

            renderer.domElement.AttachToDocument();
            renderer.domElement.style.SetLocation(0, 0);



            var controls = new THREE.OrbitControls(camera, renderer.domElement);

            var st = Stopwatch.StartNew();

            Native.window.onframe +=
                delegate
            {
                oo.WithEach(
                    x =>
                    x.rotation.y = st.ElapsedMilliseconds * 0.001
                    );


                controls.update();
                camera.position = controls.center.clone();

                renderer.render(scene, camera);
            };

            Native.window.onresize +=
                delegate
            {
                camera.aspect = window.aspect;
                camera.updateProjectionMatrix();

                renderer.setSize(window.Width, window.Height);
            };
            #endregion



            new THREE_OBJAsset(
                new HTML.Images.FromAssets.texture_palm(),
                "assets/WebGLOBJExperiment/palm.obj"
                ).Source.Task.ContinueWithResult(
                palm =>
            {
                palm.position.y = -80;
                //scene.add(palm);
                palm.AttachTo(scene);

                oo.Add(palm);

                palm.position.x = -200;
                palm.scale      = new THREE.Vector3(5, 5, 5);
            }
                );

            new THREE_OBJAsset(
                new HTML.Images.FromAssets.texture_palm(),
                "assets/WebGLOBJExperiment/palm.obj"
                ).Source.Task.ContinueWithResult(
                palm2 =>
            {
                palm2.position.y = -80;
                palm2.AttachTo(scene);
                oo.Add(palm2);

                palm2.position.x = 200;
                palm2.scale      = new THREE.Vector3(5, 5, 5);
            }
                );

            new THREE_OBJAsset(
                new HTML.Images.FromAssets.Fence_texture3(),
                "assets/WebGLOBJExperiment/fence.obj"
                ).Source.Task.ContinueWithResult(
                fence =>
            {
                fence.position.y = -80;
                fence.AttachTo(scene);
                //scene.add(fence);
                oo.Add(fence);

                fence.position.x = -100;
                fence.scale      = new THREE.Vector3(0.2, 0.2, 0.2);
            }
                );

            new sack_of_gold2().Source.Task.ContinueWithResult(
                sack_of_gold2 =>
            {
                sack_of_gold2.position.y = -80;
                sack_of_gold2.AttachTo(scene);
                oo.Add(sack_of_gold2);

                sack_of_gold2.position.x = 70;
                sack_of_gold2.position.z = 100;
                sack_of_gold2.scale      = new THREE.Vector3(0.5, 0.5, 0.5);
            }
                );

            new sack_of_gold2().Source.Task.ContinueWithResult(
                o =>
            {
                o.position.y = -80;
                scene.add(o);
                oo.Add(o);

                o.position.x = -70;
                o.position.z = 100;
                o.scale      = new THREE.Vector3(0.5, 0.5, 0.5);
            }
                );

            new THREE_OBJAsset(
                new HTML.Images.FromAssets.ash_uvgrid01(),
                "assets/WebGLOBJExperiment/male02.obj"
                ).Source.Task.ContinueWithResult(
                o =>
            {
                o.position.y = -80;
                scene.add(o);
                oo.Add(o);

                o.position.x = 50;
                //o.scale = new THREE.Vector3(5, 5, 5);
            }
                );


            var ze = new ZeProperties
            {
                //() => renderer
            };

            ze.Show();

            ze.treeView1.Nodes.Clear();

            ze.Add(() => renderer);
            ze.Add(() => controls);
            ze.Add(() => scene);

            ze.Left = 0;
        }
        // subst a: s:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeGalaxyS6Edge\ChromeGalaxyS6Edge\bin\Debug\staging\ChromeGalaxyS6Edge.Application\web
        // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeGalaxyS6Edge\ChromeGalaxyS6Edge\bin\Debug\staging\ChromeGalaxyS6Edge.Application\web

		/// <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 =
            s =>
            {
                s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

                //var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
                var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDragWithShadow().AttachTo(s.Context.GetHTMLTarget());



                s.Context.GetHTMLTarget().style.backgroundColor = "#efefef";
                //s.Context.GetHTMLTarget().style.backgroundColor = "#A26D41";

            };

			#region += Launched chrome.app.window
			// X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs
			dynamic self = Native.self;
			dynamic self_chrome = self.chrome;
			object self_chrome_socket = self_chrome.socket;

			if (self_chrome_socket != null)
			{
				//chrome.Notification.DefaultTitle = "Nexus7";
				//chrome.Notification.DefaultIconUrl = new x128().src;
                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                     AppSource.Text,
                    AtFormCreated: FormStyler.AtFormCreated

                    //AtFormConstructor:
                    //    f =>
                    //    {
                    //        //arg[0] is typeof System.Int32
                    //        //script: error JSC1000: No implementation found for this native method, please implement [static System.Drawing.Color.FromArgb(System.Int32)]

                    //        // X:\jsc.svn\examples\javascript\forms\Test\TestFromArgb\TestFromArgb\ApplicationControl.cs

                    //        f.BackColor = System.Drawing.Color.FromArgb(0xA26D41);
                    //    }
                );
				return;
			}
			#endregion

			Native.body.Clear();

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

			#region scene
			var window = Native.window;

			var camera = new THREE.PerspectiveCamera(
				45,
				window.aspect,
				1,
				2000
				);
			camera.position.z = 400;

			// scene

			var scene = new THREE.Scene();

			var ambient = new THREE.AmbientLight(0x303030);
			scene.add(ambient);

			var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
			directionalLight.position.set(0, 0, 1);
			scene.add(directionalLight);

			// WebGLRenderer preserveDrawingBuffer 
			var renderer = new THREE.WebGLRenderer(

				new
				{
					antialias = true,
					alpha = true,
					preserveDrawingBuffer = true
				}
			);

			// https://github.com/mrdoob/three.js/issues/3836
			//renderer.setClearColor(0xfffff, 1);

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

			renderer.domElement.AttachToDocument();
			renderer.domElement.style.SetLocation(0, 0);

			var canvas = (IHTMLCanvas)renderer.domElement;


			var old = new
			{



				CursorX = 0,
				CursorY = 0
			};


			var mouseX = 0;
			var mouseY = 0;
			var st = new Stopwatch();
			st.Start();


			canvas.css.active.style.cursor = IStyle.CursorEnum.move;

			#region onmousedown
			canvas.onmousedown +=
				e =>
				{

					if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
					{
						canvas.requestFullscreen();
					}
					else
					{
						// movementX no longer works
						old = new
						{


							e.CursorX,
							e.CursorY
						};


						e.CaptureMouse();
					}

				};
			#endregion



			// X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
			#region onmousemove
			canvas.onmousemove +=
				e =>
				{
					var pointerLock = canvas == Native.document.pointerLockElement;


					//Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

					if (e.MouseButton == IEvent.MouseButtonEnum.Left)
					{

						oo.WithEach(
							x =>
							{
								x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
								x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
							}
						);

						old = new
						{


							e.CursorX,
							e.CursorY
						};



					}

				};
			#endregion
			var z = camera.position.z;

			#region onmousewheel
			canvas.onmousewheel +=
				e =>
				{
					//camera.position.z = 1.5;

					// min max. shall adjust speed also!
					// max 4.0
					// min 0.6
					z -= 10.0 * e.WheelDirection;

					//camera.position.z = 400;
					z = z.Max(200).Min(500);

					//Native.document.title = new { z }.ToString();

				};
			#endregion


			Native.window.onframe +=
				e =>
				{
					renderer.clear();

					camera.aspect = canvas.aspect;
					camera.updateProjectionMatrix();

					camera.position.z += (z - camera.position.z) * e.delay.ElapsedMilliseconds / 200;


					camera.lookAt(scene.position);

					renderer.render(scene, camera);


				};

			Native.window.onresize +=
				delegate
				{
					if (canvas.parentNode == Native.document.body)
					{
						renderer.setSize(window.Width, window.Height);
					}

				};
			#endregion

			// THREE.WebGLProgram: gl.getProgramInfoLog() (79,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll

			new Models.ColladaS6Edge().Source.Task.ContinueWithResult(
				   dae =>
				   {
					   // 90deg
					   dae.rotation.x = -Math.Cos(Math.PI);

					   //dae.scale.x = 30;
					   //dae.scale.y = 30;
					   //dae.scale.z = 30;
					   dae.position.z = 65;

                       var scale = 0.7;

					   // jsc, do we have ILObserver available yet?
                       dae.scale.x = scale;
                       dae.scale.y = scale;
                       dae.scale.z = scale;

					   //dae.position.y = -80;

					   scene.add(dae);
					   oo.Add(dae);


				   }
			   );

			Console.WriteLine("do you see it?");
		}
Example #53
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)
        {
            // 1e40:01:01 RewriteToAssembly error: System.MissingMethodException: Method not found: 'Void ScriptCoreLib.JavaScript.DOM.IWindow.add_onframe(System.Action`1<Int32>)'.

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

                var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
            };
            #endregion


            // chrome 31 wont load view-source
            // chrome 33 shows black window. nice.
            #region ChromeTCPServer
            dynamic self               = Native.self;
            dynamic self_chrome        = self.chrome;
            object  self_chrome_socket = self_chrome.socket;

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

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

                return;
            }
            #endregion
#endif


            #region clouds
            new WebGLClouds.HTML.Pages.Default().With(
                layout =>
            {
                layout.body.AttachTo(page.clouds);

                new WebGLClouds.Application(layout);
            }
                );
            #endregion



            page.header.style.backgroundColor = "";

            page.header.css.style.transition      = "background-color 200ms linear";
            page.header.css.style.backgroundColor = "rgba(255, 255, 0, 0)";
            //page.header.css.style.backgroundColor = "rgba(255, 255, 0, 0.2)";

            page.header.css.hover.style.backgroundColor = "rgba(255, 255, 0, 1.0)";

            Native.window.onframe +=
                delegate
            {
                if (Native.document.body.scrollTop == 0)
                {
                    page.header.css.style.backgroundColor = "rgba(255, 255, 0, 0)";
                }
                else
                {
                    page.header.css.style.backgroundColor = "rgba(0, 0, 0, 0.3)";
                }
            };

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

            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                page.header.clientWidth / (double)page.header.clientHeight,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            var renderer = new THREE.WebGLRenderer();

            //renderer.domElement.AttachToDocument();
            renderer.domElement.AttachTo(page.header);
            renderer.setSize(page.header.clientWidth, page.header.clientHeight);
            //renderer.setSize(window.Width, window.Height);
            //renderer.domElement.style.SetLocation(0, 0);


            var mouseX = 0;
            var mouseY = 0;
            var st     = new Stopwatch();
            st.Start();

            Native.window.onframe +=
                delegate
            {
                oo.WithEach(
                    x =>
                    x.rotation.y = st.ElapsedMilliseconds * 0.001
                    );


                camera.position.x += (mouseX - camera.position.x) * .05;
                camera.position.y += (-mouseY - camera.position.y) * .05;

                camera.lookAt(scene.position);

                renderer.render(scene, camera);
            };

            Native.window.onresize +=
                delegate
            {
                camera.aspect = page.header.clientWidth / (double)page.header.clientHeight;

                camera.updateProjectionMatrix();

                //renderer.setSize(window.Width, window.Height);
                renderer.setSize(page.header.clientWidth, page.header.clientHeight);
            };



            var data = Book1.GetDataSet();

            #region bind
            Func <string, IHTMLElement, DataGridView> bind =
                (DataMember, c) =>
            {
                var g = new DataGridView
                {
                    BackgroundColor = Color.Transparent,


                    // does this work?
                    DefaultCellStyle = new DataGridViewCellStyle
                    {
                        SelectionBackColor = Color.Black,
                        SelectionForeColor = Color.Yellow,

                        //BackColor = Color.Transparent
                        //BackColor = Color.FromArgb(0x05, 0, 0, 0)
                        BackColor = Color.FromArgb(0x3f, 255, 255, 255)
                    },

                    ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle
                    {
                        BackColor = Color.FromArgb(0x8f, 255, 255, 255)
                    },


                    SelectionMode       = DataGridViewSelectionMode.FullRowSelect,
                    AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,

                    // do we have a test for this?
                    AllowUserToAddRows = false,

                    //AllowUserToDeleteRows = false,

                    RowHeadersVisible = false,


                    // cannot hide column headers yet
                    // script: error JSC1000: No implementation found for this native method, please implement [System.Windows.Forms.DataGridView.set_ColumnHeadersVisible(System.Boolean)]
                    //ColumnHeadersVisible = false,

                    DataSource = data,
                    DataMember = DataMember,
                };

                // this should be the one that maximizes itself onto the parent which is supposed to be absolute in size
                //g.GetHTMLTarget().With(
                //    div =>
                //    {
                //        //div.style.reset();

                //        // no scrollbars, thanks
                //        div.style.overflow = IStyle.OverflowEnum.hidden;
                //        (div.style as dynamic).zIndex = "";

                //        div.style.position = IStyle.PositionEnum.relative;
                //        div.style.left = "";
                //        div.style.top = "";
                //        div.style.right = "";
                //    }
                //);

                c.style.position = IStyle.PositionEnum.relative;
                c.style.height   = "20em";

                c.Clear();
                g.AttachControlTo(c);

                return(g);
            };
            #endregion


            bind("Assets", page.assets);
            bind("Transactions", page.transactions).ReadOnly = true;

            // script: error JSC1000: No implementation found for this native method, please implement [System.Data.DataTableCollection.get_Item(System.String)]
            var data_Assets       = data.Tables["Assets"];
            var data_Transactions = data.Tables["Transactions"];


            #region data_Assets_NewRow
            Action <DataRow> data_Assets_NewRow =
                SourceRow =>
            {
                var r = new Random();

                new sack_of_gold2().Source.Task.ContinueWithResult(
                    o =>
                {
                    o.position.y = -80;
                    scene.add(o);
                    oo.Add(o);

                    o.position.x         = r.Next(-250, 250);
                    o.position.z         = r.Next(-400, 200);
                    (o as dynamic).scale = new THREE.Vector3(0.5, 0.5, 0.5);

                    data_Assets.RowDeleting +=
                        (sender, e) =>
                    {
                        if (SourceRow != e.Row)
                        {
                            return;
                        }

                        scene.remove(o);
                        oo.Remove(o);

                        data_Transactions.Rows.Add(
                            "now", "item removed -" + SourceRow["Net worth"]
                            );
                    };
                }
                    );
            };
            #endregion


            data_Assets.Rows.AsEnumerable().WithEach(data_Assets_NewRow);

            // "X:\jsc.svn\examples\javascript\DropFileIntoSQLite\DropFileIntoSQLite.sln"
            // X:\jsc.svn\examples\javascript\DragDataTableIntoCSVFile\DragDataTableIntoCSVFile\Application.cs
            #region ondragstart
            page.header.ondragstart +=
                e =>
            {
                data_Assets.Rows.AsEnumerable().FirstOrDefault().With(
                    SourceRow =>
                {
                    // x:\jsc.svn\examples\javascript\dropfileintosqlite\dropfileintosqlite\application.cs

                    data_Assets.Rows.Remove(SourceRow);
                    //data_Assets.Rows.RemoveAt(0);


                    var clipboard = new DataTable();

                    clipboard.Columns.AddRange(
                        Enumerable.ToArray(
                            from x in data_Assets.Columns.AsEnumerable()
                            select new DataColumn {
                        ColumnName = x.ColumnName
                    }
                            )
                        );

                    clipboard.Rows.Add(
                        Enumerable.ToArray(
                            from x in data_Assets.Columns.AsEnumerable()
                            select SourceRow[x]
                            )
                        );

                    e.dataTransfer.effectAllowed = "copy";

                    var clipboard_string = StringConversionsForDataTable.ConvertToString(clipboard);
                    e.dataTransfer.setData(typeof(DataTable).Name, clipboard_string);
                }
                    );
            };
            #endregion


            // X:\jsc.svn\market\javascript\Abstractatech.JavaScript.FileStorage\Abstractatech.JavaScript.FileStorage\Application.cs
            var dz = new DropZone();


            var TimerHide = new ScriptCoreLib.JavaScript.Runtime.Timer(
                delegate
            {
                dz.body.Orphanize();
            }
                );

            #region ondragover
            Action <DragEvent> ondragover =
                evt =>
            {
                evt.stopPropagation();
                evt.preventDefault();


                if (evt.dataTransfer.types.Contains(typeof(DataTable).Name.ToLower()))
                {
                    evt.dataTransfer.dropEffect = "copy";     // Explicitly show this is a copy.

                    dz.body.AttachTo(Native.document.documentElement);
                    dz.bglayer.style.transition      = "background-color 500ms linear";
                    dz.bglayer.style.backgroundColor = "rgba(0,0,0, 0.7)";

                    TimerHide.Stop();
                }
            };

            Native.Document.body.ondragover += ondragover;
            dz.Container.ondragover         += ondragover;
            #endregion



            dz.Container.ondragleave +=
                evt =>
            {
                //Console.WriteLine("ondragleave");

                //Console.WriteLine(" dz.Container.ondragleave");
                TimerHide.StartTimeout(90);

                evt.stopPropagation();
                evt.preventDefault();
            };

            Native.window.onblur +=
                delegate
            {
                data_Transactions.Rows.Add(
                    //"now", "item added +" + SourceRow["Net worth"]
                    "now", "blur"
                    );
            };

            Native.window.onfocus +=
                delegate
            {
                data_Transactions.Rows.Add(
                    //"now", "item added +" + SourceRow["Net worth"]
                    "now", "focus"
                    );
            };

            data_Assets_NewRow +=
                SourceRow =>
            {
                data_Transactions.Rows.Add(
                    //"now", "item added +" + SourceRow["Net worth"]
                    "now", "item added"
                    );
            };

            data_Assets.TableNewRow +=
                (sender, e) =>
            {
                data_Assets_NewRow(e.Row);
            };


            #region ondrop
            dz.Container.ondrop +=
                evt =>
            {
                //Console.WriteLine("ondrop");

                TimerHide.StartTimeout(90);

                evt.stopPropagation();
                evt.preventDefault();

                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 xx =>
                    {
                        // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dfnReturnLink-0
                        var DataTable_xml = await xx.getAsString();

                        var DataTable = StringConversionsForDataTable.ConvertFromString(DataTable_xml);

                        DataTable.Rows.AsEnumerable().WithEach(
                            SourceRow =>
                        {
                            data_Assets.Rows.Add(
                                Enumerable.ToArray(
                                    from x in data_Assets.Columns.AsEnumerable()
                                    select SourceRow[x]
                                    )
                                );
                        }
                            );
                    }
                        );
                }
            };
            #endregion
        }
        public ApplicationCanvas()
        {
            c = new Base.ApplicationCanvas();

            c.Selection.GlassArea.Orphanize();
            c.Selection.Orphanize();



            c.AttachTo(this);
            c.MoveTo(8, 8);

            this.SizeChanged += (s, e) => c.SizeTo(this.Width - 16.0, this.Height - 16.0);

            r.Fill = Brushes.Red;
            r.Opacity = 0;

            r.AttachTo(this);
            r.MoveTo(8, 8);

            this.SizeChanged += (s, e) => r.SizeTo(this.Width - 16.0, this.Height - 16.0);

            Rectangle h = null;
            AnimatedOpacity<Rectangle> hOpacity = null;


            Action<Action<double, double>> GetPosition = null;
            var Windows = new List<Base.ApplicationCanvas.WindowInfo>();

         
            #region GetSnapLocation
            Action<Func<UIElement, Point>, Action<bool, double, double, double, double>> GetSnapLocation =
                (e_GetPosition, SetLocation) =>
                {
                    var p = e_GetPosition(r);

                    var x = 0.0;
                    var y = 0.0;

                    GetPosition((_x, _y) => { x = _x; y = _y; });

                    var cx = p.X - x;
                    var cy = p.Y - y;

                    if (cx < 0)
                    {
                        x += cx;
                        cx = -cx;
                    }

                    if (cy < 0)
                    {
                        y += cy;
                        cy = -cy;
                    }

                    var Snap = 16;
                    var SnapMode = false;

                    Enumerable.FirstOrDefault(
                        from k in Windows
                        let dx0 = Math.Abs(k.WindowLocation.Left - x)
                        where dx0 < Snap
                        orderby dx0
                        select k
                    ).With(
                     ax =>
                     {
                         SnapMode = true;
                         cx += x - ax.WindowLocation.Left;
                         x = ax.WindowLocation.Left;
                     }
                   );


                    Enumerable.FirstOrDefault(
                         from k in Windows
                         let dx0 = Math.Abs(k.WindowLocation.Top - y)
                         where dx0 < Snap
                         orderby dx0
                         select k
                     ).With(
                      ax =>
                      {
                          SnapMode = true;
                          cy += y - ax.WindowLocation.Top;
                          y = ax.WindowLocation.Top;
                      }
                    );


                    SetLocation(SnapMode, x, y, cx, cy);
                };
            #endregion

            #region MouseLeftButtonDown
            r.MouseLeftButtonDown +=
               (s, e) =>
               {

                   h = new Rectangle
                   {
                       Fill = Brushes.Black,
                   };
                   hOpacity = h.ToAnimatedOpacity();
                   hOpacity.Opacity = 0.3;

                   var p = e.GetPosition(r);

                   //Console.WriteLine("MouseLeftButtonDown " + new { p.X, p.Y });

                   GetPosition = y => y(p.X, p.Y);


                   h.AttachTo(c).MoveTo(p).SizeTo(0, 0);

                   c.Selection.Orphanize();

                   c.Selection.WindowLocation.Left = p.X;
                   c.Selection.WindowLocation.Top = p.Y;
                   c.Selection.WindowLocation.Width = 0;
                   c.Selection.WindowLocation.Height = 0;
                   c.Selection.WindowLocationChanged();
                   c.Selection.Attach();


                   Windows.WithEach(k => k.GlassOpacity.Opacity = 0);
               };
            #endregion



            #region MouseMove
            r.MouseMove +=
               (s, e) =>
               {
                   if (GetPosition != null)
                   {



                       GetSnapLocation(e.GetPosition,
                           (SnapMode, x, y, cx, cy) =>
                           {
                               //Console.WriteLine("MouseMove " + new { x, y, cx, cy });

                               if (SnapMode)
                                   hOpacity.Opacity = 0.9;
                               else
                                   hOpacity.Opacity = 0.3;

                               c.Selection.WindowLocation.Left = x;
                               c.Selection.WindowLocation.Top = y;
                               c.Selection.WindowLocation.Width = cx;
                               c.Selection.WindowLocation.Height = cy;
                               c.Selection.WindowLocationChanged();

                               h.MoveTo(x, y).SizeTo(cx, cy);
                           }
                       );
                   }
               };
            #endregion


            #region MouseLeftButtonUp
            r.MouseLeftButtonUp +=
                 (s, e) =>
                 {
                     //Console.WriteLine("MouseLeftButtonUp");

                     if (GetPosition == null)
                         return;


                     GetSnapLocation(e.GetPosition,
                        (SnapMode, x, y, cx, cy) =>
                        {
                            //Console.WriteLine("MouseLeftButtonUp " + new { x, y, cx, cy });

                            Windows.WithEach(k => k.GlassOpacity.Opacity = 1);

                            h.Orphanize();
                            c.Selection.Orphanize();

                            if (cx > 32)
                                if (cy > 32)
                                    c.CreateWindow(
                                        new Base.ApplicationCanvas.Position
                                        {
                                            Left = x,
                                            Top = y,
                                            Width = cx,
                                            Height = cy
                                        },

                                       Windows.Add
                                     );


                        }
                    );



                     GetPosition = null;


                 };
            #endregion



            #region TouchDown
            r.TouchDown +=
               (s, e) =>
               {
                   
                   h = new Rectangle
                   {
                       Fill = Brushes.Black,
                   };
                   hOpacity = h.ToAnimatedOpacity();
                   hOpacity.Opacity = 0.3;

                   var p = e.GetTouchPoint(r).Position;

                   //Console.WriteLine("MouseLeftButtonDown " + new { p.X, p.Y });

                   GetPosition = y => y(p.X, p.Y);


                   h.AttachTo(c).MoveTo(p).SizeTo(0, 0);

                   c.Selection.Orphanize();

                   c.Selection.WindowLocation.Left = p.X;
                   c.Selection.WindowLocation.Top = p.Y;
                   c.Selection.WindowLocation.Width = 0;
                   c.Selection.WindowLocation.Height = 0;
                   c.Selection.WindowLocationChanged();
                   c.Selection.Attach();


                   Windows.WithEach(k => k.GlassOpacity.Opacity = 0);
               };
            #endregion



            #region MouseMove
            r.TouchMove +=
               (s, e) =>
               {
                   if (GetPosition != null)
                   {

                       Func<UIElement, Point> e_GetPosition = x => e.GetTouchPoint(x).Position;

                       GetSnapLocation(e_GetPosition,
                           (SnapMode, x, y, cx, cy) =>
                           {
                               //Console.WriteLine("MouseMove " + new { x, y, cx, cy });

                               if (SnapMode)
                                   hOpacity.Opacity = 0.9;
                               else
                                   hOpacity.Opacity = 0.3;

                               c.Selection.WindowLocation.Left = x;
                               c.Selection.WindowLocation.Top = y;
                               c.Selection.WindowLocation.Width = cx;
                               c.Selection.WindowLocation.Height = cy;
                               c.Selection.WindowLocationChanged();

                               h.MoveTo(x, y).SizeTo(cx, cy);
                           }
                       );
                   }
               };
            #endregion


            #region TouchUp
            r.TouchUp +=
                 (s, e) =>
                 {
                     //Console.WriteLine("MouseLeftButtonUp");

                     if (GetPosition == null)
                         return;

                     Func<UIElement, Point> e_GetPosition = x => e.GetTouchPoint(x).Position;

                     GetSnapLocation(e_GetPosition,
                        (SnapMode, x, y, cx, cy) =>
                        {
                            //Console.WriteLine("MouseLeftButtonUp " + new { x, y, cx, cy });

                            Windows.WithEach(k => k.GlassOpacity.Opacity = 1);

                            h.Orphanize();
                            c.Selection.Orphanize();

                            if (cx > 32)
                                if (cy > 32)
                                    c.CreateWindow(
                                        new Base.ApplicationCanvas.Position
                                        {
                                            Left = x,
                                            Top = y,
                                            Width = cx,
                                            Height = cy
                                        },

                                       Windows.Add
                                     );


                        }
                    );



                     GetPosition = null;


                 };
            #endregion

        }
        // the eye nor the display will be able to do any stereo
        // until tech is near matrix capability. 2019?

        // cubemap can be used for all long range scenes
        // http://www.imdb.com/title/tt0112111/?ref_=nv_sr_1


        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150808/cubemapcamera
        // subst a: s:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeCubeCameraExperiment\ChromeCubeCameraExperiment\bin\Debug\staging\ChromeCubeCameraExperiment.Application\web
        // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeCubeCameraExperiment\ChromeCubeCameraExperiment\bin\Debug\staging\ChromeCubeCameraExperiment.Application\web

        // ColladaLoader: Empty or non-existing file (assets/ChromeCubeCameraExperiment/S6Edge.dae)

        /// <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 =
            //s =>
            //{
            //    s.Context.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

            //    //var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
            //    var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDragWithShadow().AttachTo(s.Context.GetHTMLTarget());



            //    s.Context.GetHTMLTarget().style.backgroundColor = "#efefef";
            //    //s.Context.GetHTMLTarget().style.backgroundColor = "#A26D41";

            //};

#if AsWEBSERVER
            #region += Launched chrome.app.window
            // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

            if (self_chrome_socket != null)
            {
                // if we run as a server. we can open up on android.

                //chrome.Notification.DefaultTitle = "Nexus7";
                //chrome.Notification.DefaultIconUrl = new x128().src;
                ChromeTCPServer.TheServerWithStyledForm.Invoke(
                     AppSource.Text
                //, AtFormCreated: FormStyler.AtFormCreated

                //AtFormConstructor:
                //    f =>
                //    {
                //        //arg[0] is typeof System.Int32
                //        //script: error JSC1000: No implementation found for this native method, please implement [static System.Drawing.Color.FromArgb(System.Int32)]

                //        // X:\jsc.svn\examples\javascript\forms\Test\TestFromArgb\TestFromArgb\ApplicationControl.cs

                //        f.BackColor = System.Drawing.Color.FromArgb(0xA26D41);
                //    }
                );
                return;
            }
            #endregion
#else

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

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

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

                    //};

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

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

                        // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions
                        var xappwindow = await chrome.app.window.create(
                               Native.document.location.pathname, options: new
                               {
                                   alwaysOnTop = true,
                                   visibleOnAllWorkspaces = true
                               }
                        );

                        //xappwindow.setAlwaysOnTop

                        xappwindow.show();

                        await xappwindow.contentWindow.async.onload;

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


                    return;
                }
            }
            #endregion


#endif


            Native.css.style.backgroundColor = "blue";
            Native.css.style.overflow = IStyle.OverflowEnum.hidden;

            Native.body.Clear();

            new IHTMLPre { "can we stream it into VR, shadertoy, youtube 360, youtube stereo yet?" }.AttachToDocument();


            var pause = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox, title = "pause" }.AttachToDocument();

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

            #region scene
            var window = Native.window;


            // what about physics and that portal rendering?

            // if we are running as a chrome web server, we may also be opened as android ndk webview app
            //var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: window.aspect, near: 1, far: 2000);
            // once we update source
            // save the source
            // manually recompile 
            //cameraPX.position.z = 400;

            //// the camera should be close enough for the object to float off the FOV of PX
            //cameraPX.position.z = 200;

            // scene
            // can we make the 3D object orbit around us ?
            // and
            // stream it to vr?
            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x303030);
            scene.add(ambient);

            // should we fix jsc to do a more correct IDL?
            var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);



            // whats WebGLRenderTargetCube do?

            // WebGLRenderer preserveDrawingBuffer 

            //const int size = 128;
            //const int size = 256; // 6 faces, 12KB
            const int size = 512; // 6 faces, ?
            //const int size = 1024; // 6 faces, ?

            var renderer0 = new THREE.WebGLRenderer(

                new
                {
                    antialias = true,
                    alpha = true,
                    preserveDrawingBuffer = true
                }
            );

            // https://github.com/mrdoob/three.js/issues/3836

            // the construct. white bg
            renderer0.setClearColor(0xfffff, 1);

            //renderer.setSize(window.Width, window.Height);
            renderer0.setSize(size, size);

            //renderer0.domElement.AttachToDocument();
            //rendererPX.domElement.style.SetLocation(0, 0);
            //renderer0.domElement.style.SetLocation(4, 4);


            // top

            // http://stackoverflow.com/questions/27612524/can-multiple-webglrenderers-render-the-same-scene


            // need a place to show the cubemap face to GUI 
            // how does the stereo OTOY do it?
            // https://www.opengl.org/wiki/Sampler_(GLSL)

            // http://www.richardssoftware.net/Home/Post/25

            // [+X, –X, +Y, –Y, +Z, –Z] fa

            var uizoom = 0.25;


            #region x
            var cameraNX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: 2000);
            cameraNX.lookAt(new THREE.Vector3(-1, 0, 0));
            var canvasNX = new CanvasRenderingContext2D(size, size);
            canvasNX.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 2, 8 + (int)(uizoom * size + 8) * 1);
            canvasNX.canvas.title = "NX";
            canvasNX.canvas.AttachToDocument();
            canvasNX.canvas.style.transformOrigin = "0 0";
            canvasNX.canvas.style.transform = $"scale({uizoom})";

            var cameraPX = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: 2000);
            cameraPX.lookAt(new THREE.Vector3(1, 0, 0));
            var canvasPX = new CanvasRenderingContext2D(size, size);
            canvasPX.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 0, 8 + (int)(uizoom * size + 8) * 1);
            canvasPX.canvas.title = "PX";
            canvasPX.canvas.AttachToDocument();
            canvasPX.canvas.style.transformOrigin = "0 0";
            canvasPX.canvas.style.transform = $"scale({uizoom})";
            #endregion


            #region y
            // need to rotate90?
            var cameraNY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: 2000);
            cameraNY.lookAt(new THREE.Vector3(0, -1, 0));
            var canvasNY = new CanvasRenderingContext2D(size, size);
            canvasNY.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 1, 8 + (int)(uizoom * size + 8) * 2);
            canvasNY.canvas.title = "NY";
            canvasNY.canvas.AttachToDocument();
            canvasNY.canvas.style.transformOrigin = "0 0";
            canvasNY.canvas.style.transform = $"scale({uizoom})";

            var cameraPY = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: 2000);
            cameraPY.lookAt(new THREE.Vector3(0, 1, 0));
            var canvasPY = new CanvasRenderingContext2D(size, size);
            canvasPY.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 1, 8 + (int)(uizoom * size + 8) * 0);
            canvasPY.canvas.title = "PY";
            canvasPY.canvas.AttachToDocument();
            canvasPY.canvas.style.transformOrigin = "0 0";
            canvasPY.canvas.style.transform = $"scale({uizoom})";
            #endregion

            #region z
            var cameraNZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: 2000);
            cameraNZ.lookAt(new THREE.Vector3(0, 0, -1));
            var canvasNZ = new CanvasRenderingContext2D(size, size);
            canvasNZ.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 3, 8 + (int)(uizoom * size + 8) * 1);
            canvasNZ.canvas.title = "NZ";
            canvasNZ.canvas.AttachToDocument();
            canvasNZ.canvas.style.transformOrigin = "0 0";
            canvasNZ.canvas.style.transform = $"scale({uizoom})";

            var cameraPZ = new THREE.PerspectiveCamera(fov: 90, aspect: 1.0, near: 1, far: 2000);
            cameraPZ.lookAt(new THREE.Vector3(0, 0, 1));
            var canvasPZ = new CanvasRenderingContext2D(size, size);
            canvasPZ.canvas.style.SetLocation(8 + (int)(uizoom * size + 8) * 1, 8 + (int)(uizoom * size + 8) * 1);
            canvasPZ.canvas.title = "PZ";
            canvasPZ.canvas.AttachToDocument();
            canvasPZ.canvas.style.transformOrigin = "0 0";
            canvasPZ.canvas.style.transform = $"scale({uizoom})";
            #endregion




            // c++ alias locals would be nice..
            var canvas0 = (IHTMLCanvas)renderer0.domElement;


            var old = new
            {



                CursorX = 0,
                CursorY = 0
            };


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

            //canvas0.css.active.style.cursor = IStyle.CursorEnum.move;

            #region onmousedown
            Native.body.onmousedown +=
                async e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                        return;

                    // movementX no longer works
                    old = new
                    {


                        e.CursorX,
                        e.CursorY
                    };


                    //e.CaptureMouse();
                    var release = e.Element.CaptureMouse();
                    await e.Element.async.onmouseup;

                    release();


                };
            #endregion



            // X:\jsc.svn\examples\javascript\Test\TestMouseMovement\TestMouseMovement\Application.cs
            #region onmousemove
            Native.body.onmousemove +=
                e =>
                {
                    if (e.Element.nodeName.ToLower() != "canvas")
                    {
                        Native.body.style.cursor = [email protected];
                        return;
                    }

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


                    Native.body.style.cursor = IStyle.CursorEnum.move;

                    var pointerLock = canvas0 == Native.document.pointerLockElement;


                    //Console.WriteLine(new { e.MouseButton, pointerLock, e.movementX });

                    if (e.MouseButton == IEvent.MouseButtonEnum.Left)
                    {

                        oo.WithEach(
                            x =>
                            {
                                x.rotation.y += 0.006 * (e.CursorX - old.CursorX);
                                x.rotation.x += 0.006 * (e.CursorY - old.CursorY);
                            }
                        );

                        old = new
                        {


                            e.CursorX,
                            e.CursorY
                        };



                    }

                };
            #endregion

            // THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(78,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll
            // THREE.WebGLProgram: gl.getProgramInfoLog() (79,3-98): warning X3557: loop only executes for 1 iteration(s), forcing loop to unroll

            // http://www.roadtovr.com/youtube-confirms-stereo-3d-360-video-support-coming-soon/
            // https://www.youtube.com/watch?v=D-Wl9jAB45Q

            new Models.ColladaS6Edge().Source.Task.ContinueWithResult(
                   dae =>
                   {
                       // 90deg
                       dae.rotation.x = -Math.Cos(Math.PI);

                       //dae.scale.x = 30;
                       //dae.scale.y = 30;
                       //dae.scale.z = 30;
                       dae.position.z = -(65 - 200);





                       var scale = 0.9;

                       // jsc, do we have ILObserver available yet?
                       dae.scale.x = scale;
                       dae.scale.y = scale;
                       dae.scale.z = scale;


                       #region onmousewheel
                       Native.body.onmousewheel +=
                           e =>
                           {
                               e.preventDefault();

                               //camera.position.z = 1.5;

                               // min max. shall adjust speed also!
                               // max 4.0
                               // min 0.6
                               dae.position.z -= 10.0 * e.WheelDirection;

                               //camera.position.z = 400;
                               //dae.position.z = dae.position.z.Max(-200).Min(200);

                               //Native.document.title = new { z }.ToString();

                           };
                       #endregion


                       //dae.position.y = -80;

                       scene.add(dae);
                       oo.Add(dae);


                       var sw = Stopwatch.StartNew();


                       // view-source:http://threejs.org/examples/webgl_multiple_canvases_circle.html
                       // https://threejsdoc.appspot.com/doc/three.js/src.source/extras/cameras/CubeCamera.js.html
                       Native.window.onframe +=
                           e =>
                           {
                               //if (pause) return;
                               if ([email protected])
                                   return;


                               // can we float out of frame?
                               // haha. a bit too flickery.
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.01) * 50.0;
                               //dae.position.x = Math.Sin(e.delay.ElapsedMilliseconds * 0.001) * 190.0;
                               dae.position.x = Math.Sin(sw.ElapsedMilliseconds * 0.0001) * 190.0;
                               dae.position.y = Math.Cos(sw.ElapsedMilliseconds * 0.0001) * 90.0;
                               // manual rebuild?
                               // red compiler notifies laptop chrome of pending update
                               // app reloads


                               renderer0.clear();
                               //rendererPY.clear();

                               //cameraPX.aspect = canvasPX.aspect;
                               //cameraPX.updateProjectionMatrix();

                               // um what does this do?
                               //cameraPX.position.z += (z - cameraPX.position.z) * e.delay.ElapsedMilliseconds / 200.0;
                               // mousewheel allos the camera to move closer
                               // once we see the frame in vr, can we udp sync vr tracking back to laptop?


                               //this.targetPX.x += 1;
                               //this.targetNX.x -= 1;

                               //this.targetPY.y += 1;
                               //this.targetNY.y -= 1;

                               //this.targetPZ.z += 1;
                               //this.targetNZ.z -= 1;

                               // how does the 360 or shadertoy want our cubemaps?


                               // and then rotate right?

                               // how can we render cubemap?


                               #region x
                               // upside down?
                               renderer0.render(scene, cameraPX);
                               canvasPX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);

                               renderer0.render(scene, cameraNX);
                               canvasNX.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               #endregion

                               #region z
                               renderer0.render(scene, cameraPZ);
                               canvasPZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);

                               renderer0.render(scene, cameraNZ);
                               canvasNZ.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               #endregion



                               #region y
                               renderer0.render(scene, cameraPY);

                               canvasPY.save();
                               canvasPY.translate(0, size);
                               canvasPY.rotate((float)(-Math.PI / 2));
                               canvasPY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               canvasPY.restore();

                               // ?

                               renderer0.render(scene, cameraNY);
                               canvasNY.save();
                               canvasNY.translate(size, 0);
                               canvasNY.rotate((float)(Math.PI / 2));
                               canvasNY.drawImage((IHTMLCanvas)renderer0.domElement, 0, 0, size, size);
                               canvasNY.restore();
                               // ?
                               #endregion


                               //renderer0.render(scene, cameraPX);


                               //rendererPY.render(scene, cameraPY);


                           };


                   }
               );


            #endregion



            Console.WriteLine("do you see it?");
        }
Example #56
0
 public ICommitBag MarkItemsDeleted(List<StoredObjectId> objs)
 {
     objs.WithEach(x =>
     {
         this.MarkItemDeleted(x);
     });
     return this;
 }
Example #57
0
        public StudioView(Action <IHTMLElement, Action <ISaveAction> > AddSaveButton = null)
        {
            Content.style.position = IStyle.PositionEnum.absolute;
            Content.style.left     = "0px";
            Content.style.right    = "0px";
            Content.style.top      = "0px";
            Content.style.bottom   = "0px";

            new TwentyTenWorkspace().ToBackground(Content.style, true);

            var WorkspaceHeaderTab0 = new IHTMLDiv().With(
                div =>
            {
                div.style.position = IStyle.PositionEnum.absolute;
                div.style.top      = "0px";
                div.style.left     = "0px";
                div.style.width    = "14em";
                div.style.height   = "6em";

                div.style.padding = "0.5em";

                new Glow1().ToBackground(div.style, false);
            }
                ).AttachTo(Content);

            var WorkspaceHeaderTab1 = new IHTMLDiv().With(
                div =>
            {
                div.style.position = IStyle.PositionEnum.absolute;
                div.style.top      = "0px";
                div.style.left     = "14em";
                div.style.width    = "20em";
                div.style.height   = "6em";

                div.style.padding = "0.5em";

                new Glow1().ToBackground(div.style, false);
            }
                ).AttachTo(Content);

            var WorkspaceHeaderTab2 = new IHTMLDiv().With(
                div =>
            {
                div.style.position = IStyle.PositionEnum.absolute;
                div.style.top      = "0px";
                div.style.left     = "34em";
                div.style.right    = "6em";
                div.style.height   = "6em";

                div.style.padding = "0.5em";

                new Glow1().ToBackground(div.style, false);
            }
                ).AttachTo(Content);

            var WorkspaceHeaderTab7 = new IHTMLDiv().With(
                div =>
            {
                div.style.position = IStyle.PositionEnum.absolute;
                div.style.top      = "0px";
                div.style.width    = "6em";
                div.style.right    = "0px";
                div.style.height   = "6em";

                //div.style.padding = "0.5em";

                new Glow1().ToBackground(div.style, false);
            }
                ).AttachTo(Content);

            var WorkspaceHeaderTab0Text = default(IHTMLSpan);



            new DownloadSDK
            {
            }.AttachTo(
                new IHTMLAnchor
            {
                title = "Download JSC SDK!",
                href  = "http://download.jsc-solutions.net"
            }.AttachTo(WorkspaceHeaderTab7)
                );

            @"studio.jsc-solutions.net".ToDocumentTitle().With(
                title =>
            {
                WorkspaceHeaderTab0Text = new IHTMLSpan {
                    innerText = title
                };

                WorkspaceHeaderTab0Text.AttachTo(WorkspaceHeaderTab0);
                //WorkspaceHeaderTab0Text.style.SetLocation(16, 8);
                WorkspaceHeaderTab0Text.style.fontFamily = IStyle.FontFamilyEnum.Tahoma;
                WorkspaceHeaderTab0Text.style.color      = Color.White;
                WorkspaceHeaderTab0Text.style.display    = IStyle.DisplayEnum.block;

                // http://www.quirksmode.org/css/textshadow.html
                WorkspaceHeaderTab0Text.style.textShadow = "#808080 4px 2px 2px";
            }
                );


            if (AddSaveButton != null)
            {
                AddSaveButton(WorkspaceHeaderTab0Text, i => Save = i);
            }

            // em + px :)
            var Workspace0 = new IHTMLDiv().With(
                div =>
            {
                div.style.position = IStyle.PositionEnum.absolute;
                div.style.left     = "0px";
                div.style.right    = "0px";
                div.style.bottom   = "0px";
                div.style.top      = "6em";
            }
                ).AttachTo(Content);

            // workspace contains the split views
            var Workspace = new IHTMLDiv().With(
                div =>
            {
                div.style.position = IStyle.PositionEnum.absolute;
                div.style.left     = "6px";
                div.style.right    = "6px";
                div.style.bottom   = "6px";
                div.style.top      = "6px";
            }
                ).AttachTo(Workspace0);

            // in this project we wont be having toolbox or toolbar yet

            Action <HorizontalSplit> ApplyStyle =
                t =>
            {
                t.Split.Splitter.style.backgroundColor = Color.None;
                t.SplitImageContainer.Orphanize();
                t.SplitArea.Target.style.borderLeft  = "0";
                t.SplitArea.Target.style.borderRight = "0";
                t.SplitArea.Target.style.width       = "6px";
                t.SplitArea.Target.style.Opacity     = 0.7;

                // should we obselete JSColor already?
                t.SelectionColor = JSColor.Black;
            };

            var EditorTreeSplit = new HorizontalSplit
            {
                Minimum = 0,
                Maximum = 1,
                Value   = 0.7,
            };

            EditorTreeSplit.With(ApplyStyle);

            EditorTreeSplit.Split.Splitter.style.backgroundColor = Color.None;


            EditorTreeSplit.Container.AttachTo(Workspace);



            var Split = new HorizontalSplit
            {
                Minimum = 0,
                Maximum = 1,
                Value   = 0.3,
            };

            Split.With(ApplyStyle);

            Split.Split.Splitter.style.backgroundColor = Color.None;

            EditorTreeSplit.LeftContainer = Split.Container;



            var SolutionToolbox = new SolutionDockWindowPage();

            SolutionToolbox.HeaderText.innerText          = "Toolbox";
            SolutionToolbox.Content.style.backgroundColor = Color.White;
            SolutionToolbox.Content.style.padding         = "2px";
            SolutionToolbox.Content.style.overflow        = IStyle.OverflowEnum.auto;
            SolutionToolbox.Content.Clear();


            var vv = new SolutionToolboxListView();

            vv.Container.style.color = Color.Black;
            //vv.Container.AttachTo(SolutionToolbox.Content);

            var items = new StockToolboxTabsForHTMLDocument();

            // jsc market components

            vv.Add(
                new SolutionToolboxListViewTab
            {
                DataType = "DataTable",

                Name  = "DataTable",
                Title = "DataTable",
                Text  = "DataTable",
                Icon  = new DataTableImage()
            }
                );

            vv.Add(
                new SolutionToolboxListViewTab
            {
                DataType = "SpiralDataType",

                Name  = "Spiral1",
                Title = "Spiral",
                Text  = "Spiral",
                Icon  = new Spiral()
            }
                );

            // can we drag this into
            // code ?
            // msvs gets the image link
            //http://192.168.43.252:11924/assets/ScriptCoreLib.Ultra.Components/StockToolboxImageTransparent64.png?data-jsc-type=DAETruck
            vv.Add(
                new SolutionToolboxListViewTab
            {
                DataType = "DAETruck",

                Name  = "DAETruck",
                Title = "DAETruck",
                Text  = "DAETruck",
                Icon  = new DAETruck()
            }
                );

            vv.Add(
                new SolutionToolboxListViewTab
            {
                DataType = "WebGLEarthByBjorn",

                Name  = "WebGLEarthByBjorn",
                Title = "WebGLEarthByBjorn",
                Text  = "WebGLEarthByBjorn",
                Icon  = new WebGLEarthByBjorn()
            }
                );


            items.WithEach(vv.Add);



            var Viewer = new SolutionDocumentViewer();
            SolutionDocumentViewerTab File7Tab = "Design/App.htm";

            Viewer.Add(File7Tab);

            #region OutputFile
            var OutputFile       = new SolutionFile();
            var OutputFileViewer = new SolutionFileView();

            // fullscreen! :)
            OutputFileViewer.Container.style.height = "100%";

            OutputFile.IndentStack.Push(
                delegate
            {
                OutputFile.Write(SolutionFileTextFragment.Comment, "" + DateTime.Now);
                OutputFile.WriteSpace();
            }
                );

            Action <string> OutputWriteLine =
                n =>
            {
                // Would we want to rewire System.Out? Console.WriteLine?
                OutputFile.WriteIndent();
                OutputFile.WriteLine(n);

                // we could have a resume feature? now we just go and clear...
                OutputFileViewer.File = OutputFile;
            };


            OutputWriteLine("studio.jsc-solutions.net ready!");
            #endregion

            SolutionDocumentViewerTab OutputTab = "Output";
            Viewer.Add(OutputTab);
            OutputTab.TabElement.style.Float = IStyle.FloatEnum.right;


            SolutionDocumentViewerTab AboutTab = "Project";
            Viewer.Add(AboutTab);
            AboutTab.TabElement.style.Float = IStyle.FloatEnum.right;


            var CurrentDesigner = new SolutionFileDesigner();



            var HTMLDesigner = new SolutionFileDesignerHTMLElementTabs();

            CurrentDesigner.Add(HTMLDesigner);


            // undoable?
            var sln = new SolutionBuilder();



            #region CodeSourceA
            var CodeSourceATab =
                new SolutionFileDesignerTab
            {
                Image = new RTA_mode_html(),
                Text  = "Generated Code"
            };

            var CodeSourceAView = new SolutionFileView();

            CodeSourceAView.Container.style.position = IStyle.PositionEnum.absolute;
            CodeSourceAView.Container.style.left     = "0px";
            CodeSourceAView.Container.style.right    = "0px";
            CodeSourceAView.Container.style.top      = "0px";
            CodeSourceAView.Container.style.bottom   = "0px";

            CodeSourceAView.Container.style.display = IStyle.DisplayEnum.none;
            CodeSourceAView.Container.AttachTo(CurrentDesigner.Content);

            CodeSourceATab.Deactivated +=
                delegate
            {
                CodeSourceAView.Container.style.display = IStyle.DisplayEnum.none;
            };

            CodeSourceATab.Activated +=
                delegate
            {
                HTMLDesigner.HTMLDesignerContent.WhenContentReady(
                    body =>
                {
                    var CodeSourceFile = new SolutionFile
                    {
                        Name = "Default.htm"
                    };

                    var Type = new SolutionProjectLanguageType
                    {
                        Comments    = new SolutionFileComment[] { "This type was generated from the HTML file." },
                        Namespace   = sln.Name + ".HTML.Pages",
                        Name        = "IDefaultPage",
                        IsInterface = true,
                    };

                    (from n in body.AsXElement().DescendantsAndSelf()
                     let id = n.Attribute("id")
                              where id != null
                              select new { n, id }
                    ).WithEach(
                        k =>
                    {
                        Type.Properties.Add(
                            new KnownStockTypes.ScriptCoreLib.JavaScript.DOM.HTML.IHTMLElement().ToAutoProperty(k.id.Value)
                            );
                    }
                        );

                    sln.Language.WriteType(CodeSourceFile, Type, null);

                    CodeSourceAView.File = CodeSourceFile;

                    CodeSourceAView.Container.style.display = IStyle.DisplayEnum.empty;
                }
                    );
            };


            #endregion


            #region CodeSourceB
            var CodeSourceBTab =
                new SolutionFileDesignerTab
            {
                Image = new RTA_mode_html(),
                // all source code, not just html?
                Text = "Source"
            };

            var CodeSourceBView = new SolutionFileView();

            CodeSourceBView.Container.style.position = IStyle.PositionEnum.absolute;
            CodeSourceBView.Container.style.left     = "0px";
            CodeSourceBView.Container.style.right    = "0px";
            CodeSourceBView.Container.style.top      = "0px";
            CodeSourceBView.Container.style.bottom   = "0px";

            CodeSourceBView.Container.style.display = IStyle.DisplayEnum.none;
            CodeSourceBView.Container.AttachTo(CurrentDesigner.Content);

            CodeSourceBTab.Deactivated +=
                delegate
            {
                CodeSourceBView.Container.style.display = IStyle.DisplayEnum.none;
            };

            CodeSourceBTab.Activated +=
                delegate
            {
                CodeSourceBView.Container.style.display = IStyle.DisplayEnum.empty;
            };


            #endregion

            #region CodeSourceFormsDesignerTab
            var CodeSourceFormsDesignerTab =
                new SolutionFileDesignerTab
            {
                Image = new RTA_mode_design(),
                // all source code, not just html?
                Text = "Designer"
            };


            var CodeSourceFormsDesignerTabView = new SolutionFileView();

            CodeSourceFormsDesignerTabView.Container.style.With(
                style =>
            {
                style.position = IStyle.PositionEnum.absolute;
                style.left     = "0px";
                style.right    = "0px";
                style.top      = "0px";
                style.bottom   = "0px";

                style.display = IStyle.DisplayEnum.none;
            }
                );

            new IHTMLDiv().With(
                div =>
            {
                div.style.position        = IStyle.PositionEnum.absolute;
                div.style.left            = "16px";
                div.style.top             = "16px";
                div.style.width           = "400px";
                div.style.height          = "300px";
                div.style.backgroundColor = Color.FromGray(0xe0);
                div.style.border          = "1px solid gray";
                div.AttachTo(CodeSourceFormsDesignerTabView.Container);
            }
                );


            CodeSourceFormsDesignerTabView.Container.AttachTo(CurrentDesigner.Content);

            CodeSourceFormsDesignerTab.Deactivated +=
                delegate
            {
                CodeSourceFormsDesignerTabView.Container.style.display = IStyle.DisplayEnum.none;
            };

            CodeSourceFormsDesignerTab.Activated +=
                delegate
            {
                CodeSourceFormsDesignerTabView.Container.style.display = IStyle.DisplayEnum.empty;
            };


            #endregion

            CurrentDesigner.Add(CodeSourceFormsDesignerTab);
            CurrentDesigner.Add(CodeSourceBTab);
            CurrentDesigner.Add(CodeSourceATab);



            var wLeftScrollable = new System.Windows.Forms.Form
            {
                BackColor  = global::System.Drawing.Color.White,
                Text       = "Toolbox",
                ControlBox = false,
                ShowIcon   = false,
                AutoScroll = true
            };

            vv.Container.AttachTo(
                wLeftScrollable.GetHTMLTargetContainer()
                );

            //wLeftScrollable.Show();

            Split.Split.LeftScrollable.style.zIndex = 0;
            wLeftScrollable.AttachFormTo(Split.Split.LeftScrollable);


            //wLeftScrollable.PopupInsteadOfClosing();

            //Split.Split.LeftScrollable = (IHTMLDiv)(object)SolutionToolbox.body;
            Split.Split.RightScrollable = Viewer.Container;

            // ...



            #region dynamic content
            Func <IEnumerable <XElement> > GetPages = delegate
            {
                return(from n in sln.ApplicationPage.DescendantsAndSelf()
                       let type = n.Attribute(SolutionBuilderInteractive.DataTypeAttribute)
                                  where type != null
                                  let id = n.Attribute("id")
                                           where id != null
                                           select n);
            };

            sln.Interactive.GenerateApplicationExpressions +=
                Add =>
            {
                // page.PageContainer.ReplaceWith(
                GetPages().WithEach(
                    k =>
                {
                    var id = k.Attribute("id").Value;

                    if (id == "Page1")
                    {
                        Add(
                            new StockReplaceWithNewPageExpression(id)
                            );
                    }

                    if (id == "UserControl1")
                    {
                        Add(
                            new StockReplaceWithNewUserControlExpression(sln.Name + ".Components", id)
                            );
                    }

                    if (id == "Applet1")
                    {
                        Add(
                            new StockReplaceWithNewAppletExpression(sln.Name + ".Components", id)
                            );
                    }

                    if (id == "Sprite1")
                    {
                        Add(
                            new StockReplaceWithNewSpriteExpression(sln.Name + ".Components", id)
                            );
                    }

                    if (id == "AppletUserControl1")
                    {
                        Add(
                            new StockReplaceWithNewAppletExpression(sln.Name + ".Components", id)
                            );
                    }
                }
                    );
            };

            sln.Interactive.GenerateHTMLFiles +=
                Add =>
            {
                GetPages().WithEach(
                    k =>
                {
                    var id = k.Attribute("id").Value;

                    if (id == "Page1")
                    {
                        var __Content = new XElement(StockPageDefault.Page);


                        __Content.Element("head").Element("title").Value = id;

                        Add(
                            new SolutionProjectHTMLFile
                        {
                            Name    = "Design/" + id + ".htm",
                            Content = __Content
                        }
                            );
                    }
                }
                    );
            };

            sln.Interactive.GenerateTypes +=
                Add =>
            {
                GetPages().WithEach(
                    k =>
                {
                    var id = k.Attribute("id").Value;

                    if (id == "UserControl1")
                    {
                        Add(
                            new StockUserControlType(sln.Name + ".Components", id)
                            );
                    }

                    if (id == "Applet1")
                    {
                        Add(
                            new StockAppletType(sln.Name + ".Components", id)
                            );
                    }

                    if (id == "Sprite1")
                    {
                        Add(
                            new StockSpriteType(sln.Name + ".Components", id)
                            );
                    }

                    if (id == "AppletUserControl1")
                    {
                        var UserControl2 = new StockUserControlType(sln.Name + ".Components", "UserControl2");

                        Add(
                            UserControl2
                            );

                        Add(
                            new StockUserControlAppletType(sln.Name + ".Components", id, UserControl2)
                            );
                    }
                }
                    );
            };
            #endregion


            var _Solution = new TreeNode(VistaTreeNodePage.Create);


            var _Project = _Solution.Add();

            var About = new About();

            #region UpdateFile1Text
            Action UpdateFile1Text =
                delegate
            {
                if (CodeSourceBView.File != null)
                {
                    File7Tab.Text = CodeSourceBView.File.Name.SkipUntilLastIfAny("/");
                }
                else
                {
                    File7Tab.Text = sln.Name;
                }
            };
            #endregion



            #region Update
            Action Update =
                delegate
            {
                sln.Name = About.ProjectName.value;

                UpdateFile1Text();

                _Project.Clear();
                UpdateTree(sln, CodeSourceBView, _Solution, _Project);
            };
            #endregion


            var PreviousVersion = default(string);

            #region HTMLDesigner.HTMLDesignerContent
            HTMLDesigner.HTMLDesignerContent.WhenContentReady(
                body =>
            {
                if (PreviousVersion == null)
                {
                    var x           = new XElement(body.AsXElement());
                    var y           = x.ToString();
                    PreviousVersion = y;
                }

                Action <bool> HTMLDesignerContentCheck =
                    DoUpdate =>
                {
                    var x = new XElement(body.AsXElement());
                    var y = x.ToString();

                    if (PreviousVersion != y)
                    {
                        PreviousVersion = y;


                        sln.ApplicationPage = x;

                        // allow any blur causing action to complete first
                        // we get reselected for some odd reason, why?
                        new Timer(
                            delegate
                        {
                            if (DoUpdate)
                            {
                                OutputWriteLine("Designer has caused an update.");
                                Update();
                            }
                            else
                            {
                                OutputWriteLine("Designer will cause an update.");
                            }
                        }
                            ).StartTimeout(700);
                    }
                };

                var HTMLDesignerContentDirty = new Timer(
                    delegate
                {
                    HTMLDesignerContentCheck(false);
                }
                    );

                HTMLDesigner.HTMLDesignerContent.contentWindow.onfocus +=
                    delegate
                {
                    OutputWriteLine("Designer activated.");
                    //"focus".ToDocumentTitle();

                    //HTMLDesignerContentDirty.StartInterval(700);
                };

                HTMLDesigner.HTMLDesignerContent.contentWindow.onblur +=
                    delegate
                {
                    //HTMLDesignerContentDirty.Stop();

                    OutputWriteLine("Designer deactivated.");
                    //"blur".ToDocumentTitle();
                    HTMLDesignerContentCheck(true);
                };
            }
                );
            #endregion

            #region CodeSourceBView.FileChanged
            CodeSourceBView.FileChanged +=
                delegate
            {
                UpdateFile1Text();


                OutputWriteLine("Select: " + CodeSourceBView.File.Name);

                CodeSourceFormsDesignerTab.TabElement.Hide();

                // hack :)
                if (CodeSourceBView.File.Name.EndsWith("/App.htm"))
                {
                    // currently we only have one element :)

                    HTMLDesigner.HTMLDesignerTab.RaiseActivated();

                    HTMLDesigner.HTMLDesignerTab.TabElement.style.display = IStyle.DisplayEnum.inline_block;
                    HTMLDesigner.HTMLSourceTab.TabElement.style.display   = IStyle.DisplayEnum.none;
                    CodeSourceATab.TabElement.style.display = IStyle.DisplayEnum.inline_block;
                    CodeSourceBTab.TabElement.style.display = IStyle.DisplayEnum.inline_block;

                    HTMLDesigner.HTMLDesignerContent.WhenContentReady(
                        body =>
                    {
                        HTMLDesigner.HTMLDesignerContent.contentWindow.focus();
                    }
                        );

                    // show the design/source buttons
                }
                else if (CodeSourceBView.File.Name.EndsWith(".sln"))
                {
                    AboutTab.Activate();
                }
                else if (CodeSourceBView.File.Name.EndsWith(sln.Language.ProjectFileExtension))
                {
                    AboutTab.Activate();
                }
                else if (CodeSourceBView.File.Name.EndsWith(sln.Language.CodeFileExtension))
                {
                    // show type outline / member
                    CodeSourceBTab.RaiseActivated();

                    HTMLDesigner.HTMLDesignerTab.TabElement.style.display = IStyle.DisplayEnum.none;
                    HTMLDesigner.HTMLSourceTab.TabElement.style.display   = IStyle.DisplayEnum.none;
                    CodeSourceATab.TabElement.style.display = IStyle.DisplayEnum.none;
                    CodeSourceBTab.TabElement.style.display = IStyle.DisplayEnum.inline_block;

                    CodeSourceBView.File.ContextType.BaseType.With(
                        BaseType =>
                    {
                        if (BaseType is KnownStockTypes.System.Windows.Forms.UserControl)
                        {
                            CodeSourceFormsDesignerTab.TabElement.Show();
                            CodeSourceFormsDesignerTab.RaiseActivated();
                        }

                        if (BaseType is KnownStockTypes.System.ComponentModel.Component)
                        {
                            CodeSourceFormsDesignerTab.TabElement.Show();
                            CodeSourceFormsDesignerTab.RaiseActivated();
                        }
                    }
                        );
                }
            };
            #endregion


            //AddSaveButton(WorkspaceHeader, i => Save = i);

            About.ProjectName.value     = sln.Name;
            About.ProjectName.onchange +=
                delegate
            {
                OutputWriteLine("Project name has changed.");
                Update();
            };



            Viewer.Content.Clear();
            Viewer.Content.Add(About.Container);
            Viewer.Content.Add(CurrentDesigner.Container);
            Viewer.Content.Add(OutputFileViewer.Container);

            AboutTab.WhenActivated(About.Container);
            File7Tab.WhenActivated(CurrentDesigner.Container);
            OutputTab.WhenActivated(OutputFileViewer.Container);



            Viewer.First().Activate();

            //var SolutionExplorer = new SolutionDockWindowPage();

            //SolutionExplorer.HeaderText.innerText = "Solution Explorer";
            //SolutionExplorer.Content.style.backgroundColor = Color.White;
            //SolutionExplorer.Content.style.padding = "2px";
            //SolutionExplorer.Content.ReplaceContentWith(_Solution.Container);


            var fSolutionExplorer = new System.Windows.Forms.Form
            {
                BackColor  = global::System.Drawing.Color.White,
                Text       = "Solution Explorer",
                ControlBox = false,
                ShowIcon   = false
            };

            EditorTreeSplit.Split.RightScrollable.style.zIndex   = 0;
            EditorTreeSplit.Split.RightScrollable.style.position = IStyle.PositionEnum.relative;

            fSolutionExplorer.AttachFormTo(EditorTreeSplit.Split.RightScrollable);

            _Solution.Container.AttachTo(fSolutionExplorer.GetHTMLTargetContainer());

            _Solution.Container.style.overflow        = IStyle.OverflowEnum.auto;
            _Solution.Container.style.height          = "100%";
            _Solution.Container.style.backgroundColor = Color.White;

            //EditorTreeSplit.Split.RightContainer = (IHTMLDiv)(object)SolutionExplorer.Container;

            EditorTreeSplit.Container.AttachTo(Workspace);

            //CurrentDesigner.First().RaiseActivated();

            Update();

            #region CreateLanguageButton
            Action <IHTMLImage, string, SolutionProjectLanguage, string> CreateLanguageButton =
                (Icon, Text, Language, Name) =>
            {
                var span = new IHTMLSpan(Text);

                span.style.marginLeft  = "0.7em";
                span.style.marginRight = "0.7em";

                new IHTMLButton {
                    Icon                   /*, span */
                }.AttachTo(WorkspaceHeaderTab1).With(
                    btn =>
                {
                    btn.onclick +=
                        delegate
                    {
                        sln.Language = Language;
                        sln.Name     = Language.LanguageSpelledName.Replace(" ", "") + "Project1";
                        Update();
                    };

                    //btn.style.display = IStyle.DisplayEnum.block;
                }
                    );
            };
            #endregion


            CreateLanguageButton(new VisualCSharpProject(), "C#", KnownLanguages.VisualCSharp, "VisualCSharpProject1");
            CreateLanguageButton(new VisualFSharpProject(), "F#", KnownLanguages.VisualFSharp, "VisualFSharpProject1");
            CreateLanguageButton(new VisualBasicProject(), "Visual Basic", KnownLanguages.VisualBasic, "VisualBasicProject1");

            var ListOfCreateProjectTypeButton = new List <IHTMLButton>();

            #region CreateProjectTypeButton
            Action <string, Action> CreateProjectTypeButton =
                (Text, Handler) =>
            {
                var span = new IHTMLSpan(Text);

                span.style.marginLeft  = "0.7em";
                span.style.marginRight = "0.7em";

                new IHTMLButton {
                    span
                }.AttachTo(WorkspaceHeaderTab2).With(
                    btn =>
                {
                    ListOfCreateProjectTypeButton.Add(btn);

                    btn.onclick +=
                        delegate
                    {
                        ListOfCreateProjectTypeButton.WithEach(n => n.disabled = true);

                        Handler();
                    };

                    //btn.style.display = IStyle.DisplayEnum.block;
                }
                    );
            };
            #endregion

            #region ToSpecificProjectType
            Action <string, Action> ToSpecificProjectType =
                (Text, Handler) =>
            {
                CreateProjectTypeButton(Text,
                                        delegate
                {
                    Handler();


                    HTMLDesigner.HTMLDesignerContent.WhenDocumentReady(
                        document =>
                    {
                        document.WithContent(sln.ApplicationPage);
                        // we should now also lock the designer!
                        document.DesignMode = false;
                    }
                        );

                    Update();
                }
                                        );
            };
            #endregion

            #region Avalon, Forms
            ToSpecificProjectType("Avalon App",
                                  delegate
            {
                sln.WithCanvas();
            }
                                  );


            ToSpecificProjectType("Avalon Flash App",
                                  delegate
            {
                sln.WithCanvasAdobeFlash();
            }
                                  );

            ToSpecificProjectType("Forms App",
                                  delegate
            {
                sln.WithForms();
            }
                                  );


            ToSpecificProjectType("Forms Applet App",
                                  delegate
            {
                sln.WithFormsApplet();
            }
                                  );
            #endregion

            ToSpecificProjectType("Flash App",
                                  delegate
            {
                sln.WithAdobeFlash();
            }
                                  );

            ToSpecificProjectType("Flash Camera App",
                                  delegate
            {
                sln.WithAdobeFlashCamera();
            }
                                  );

            ToSpecificProjectType("Flash Flare3D App",
                                  delegate
            {
                sln.WithAdobeFlashWithFlare3D();
            }
                                  );

            ToSpecificProjectType("Applet App",
                                  delegate
            {
                sln.WithJavaApplet();
            }
                                  );
        }
Example #58
0
        /// <summary>
        /// splits items out from a store and creates a new store for them 
        /// </summary>
        /// <param name="store"></param>
        /// <param name="itemsToRemove"></param>
        public static NaturalInMemoryStore SplitFromStore(this IStore store, List<StoredObjectId> itemsToRemove)
        {
            if (store == null)
                return null;

            if (itemsToRemove == null || itemsToRemove.Count == 0)
                return null;

            NaturalInMemoryStore returnValue = new NaturalInMemoryStore();

            itemsToRemove.WithEach(x =>
            {
                var item = store.Get(x);
                if (item != null)
                {
                    //move the item from one store to the other
                    returnValue.SaveItem(item);
                    store.DeleteItem(item.GetStoredObjectId());
                }
            });

            return returnValue;
        }
        /// <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(IDefaultPage page)
        {

            var r = new Random();
            var id = "" + r.Next();
            var x = r.Next(400);
            var y = r.Next(400);
            var btn = new IHTMLButton { innerText = "this is id " + id + " at " + x + ", " + y };

            btn.AttachToDocument();
            btn.style.SetLocation(x, y);

            btn.onclick +=
                delegate
                {
                    btn.disabled = true;
                    service.UpdateLobby(id, x + "", y + "",
                        delegate
                        {
                            btn.disabled = false;

                        }
                    );
                };

            page.ClearLobby.onclick +=
                delegate
                {
                    page.ClearLobby.disabled = true;
                    service.ClearLobby(
                        delegate
                        {
                            page.ClearLobby.disabled = false;

                        }
                    );
                };


            var a = new List<IHTMLButton>();

            page.RefreshLobby.onclick +=
                delegate
                {
                    a.WithEach(
                        k =>
                        {
                            k.Orphanize();
                        }
                    );
                    a.Clear();

                    page.RefreshLobby.disabled = true;
                    service.EnumerateLobby(
                        (_id, _x, _y) =>
                        {
                            if (_id == "")
                            {
                                page.RefreshLobby.disabled = false;
                                return;
                            }

                            if (_id == id)
                                return;

                            var shadow = new IHTMLButton
                            {
                                innerText = "id " + _id + " at " + _x + ", " + _y
                            };

                            shadow.AttachToDocument();
                            shadow.style.SetLocation(Convert.ToInt32(_x), Convert.ToInt32(_y));

                            a.Add(shadow);
                        }
                    );

                };

            @"Hello world".ToDocumentTitle();
            // Send data from JavaScript to the server tier
            service.WebMethod2(
                @"A string from JavaScript.",
                value => value.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)
        {

            // 1e40:01:01 RewriteToAssembly error: System.MissingMethodException: Method not found: 'Void ScriptCoreLib.JavaScript.DOM.IWindow.add_onframe(System.Action`1<Int32>)'.

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

                     var x = new ChromeTCPServerWithFrameNone.HTML.Pages.AppWindowDrag().AttachTo(s.Context.GetHTMLTarget());
                 };
            #endregion


            // chrome 31 wont load view-source
            // chrome 33 shows black window. nice.
            #region ChromeTCPServer
            dynamic self = Native.self;
            dynamic self_chrome = self.chrome;
            object self_chrome_socket = self_chrome.socket;

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

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

                return;
            }
            #endregion
#endif


            #region clouds
            new WebGLClouds.HTML.Pages.Default().With(
                layout =>
                {
                    layout.body.AttachTo(page.clouds);

                    new WebGLClouds.Application(layout);
                }
            );
            #endregion



            page.header.style.backgroundColor = "";

            page.header.css.style.transition = "background-color 200ms linear";
            page.header.css.style.backgroundColor = "rgba(255, 255, 0, 0)";
            //page.header.css.style.backgroundColor = "rgba(255, 255, 0, 0.2)";

            page.header.css.hover.style.backgroundColor = "rgba(255, 255, 0, 1.0)";

            Native.window.onframe +=
                delegate
                {
                    if (Native.document.body.scrollTop == 0)
                        page.header.css.style.backgroundColor = "rgba(255, 255, 0, 0)";
                    else
                        page.header.css.style.backgroundColor = "rgba(0, 0, 0, 0.3)";

                };

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

            var window = Native.window;

            var camera = new THREE.PerspectiveCamera(
                45,
                page.header.clientWidth / (double)page.header.clientHeight,
                1,
                2000
                );
            camera.position.z = 400;

            // scene

            var scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight(0x101030);
            scene.add(ambient);

            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0, 0, 1);
            scene.add(directionalLight);

            var renderer = new THREE.WebGLRenderer();

            //renderer.domElement.AttachToDocument();
            renderer.domElement.AttachTo(page.header);
            renderer.setSize(page.header.clientWidth, page.header.clientHeight);
            //renderer.setSize(window.Width, window.Height);
            //renderer.domElement.style.SetLocation(0, 0);


            var mouseX = 0;
            var mouseY = 0;
            var st = new Stopwatch();
            st.Start();

            Native.window.onframe +=
                delegate
                {

                    oo.WithEach(
                        x =>
                            x.rotation.y = st.ElapsedMilliseconds * 0.001
                    );


                    camera.position.x += (mouseX - camera.position.x) * .05;
                    camera.position.y += (-mouseY - camera.position.y) * .05;

                    camera.lookAt(scene.position);

                    renderer.render(scene, camera);


                };

            Native.window.onresize +=
                delegate
                {
                    camera.aspect = page.header.clientWidth / (double)page.header.clientHeight;

                    camera.updateProjectionMatrix();

                    //renderer.setSize(window.Width, window.Height);
                    renderer.setSize(page.header.clientWidth, page.header.clientHeight);

                };




            var data = Book1.GetDataSet();

            #region bind
            Func<string, IHTMLElement, DataGridView> bind =
                (DataMember, c) =>
                {
                    var g = new DataGridView
                    {
                        BackgroundColor = Color.Transparent,


                        // does this work?
                        DefaultCellStyle = new DataGridViewCellStyle
                        {

                            SelectionBackColor = Color.Black,
                            SelectionForeColor = Color.Yellow,

                            //BackColor = Color.Transparent
                            //BackColor = Color.FromArgb(0x05, 0, 0, 0)
                            BackColor = Color.FromArgb(0x3f, 255, 255, 255)
                        },

                        ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle
                        {

                            BackColor = Color.FromArgb(0x8f, 255, 255, 255)
                        },


                        SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                        AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,

                        // do we have a test for this?
                        AllowUserToAddRows = false,

                        //AllowUserToDeleteRows = false,

                        RowHeadersVisible = false,


                        // cannot hide column headers yet
                        // script: error JSC1000: No implementation found for this native method, please implement [System.Windows.Forms.DataGridView.set_ColumnHeadersVisible(System.Boolean)]
                        //ColumnHeadersVisible = false,

                        DataSource = data,
                        DataMember = DataMember,
                    };

                    // this should be the one that maximizes itself onto the parent which is supposed to be absolute in size
                    //g.GetHTMLTarget().With(
                    //    div =>
                    //    {
                    //        //div.style.reset();

                    //        // no scrollbars, thanks
                    //        div.style.overflow = IStyle.OverflowEnum.hidden;
                    //        (div.style as dynamic).zIndex = "";

                    //        div.style.position = IStyle.PositionEnum.relative;
                    //        div.style.left = "";
                    //        div.style.top = "";
                    //        div.style.right = "";
                    //    }
                    //);

                   c.style.position = IStyle.PositionEnum.relative;
                    c.style.height = "20em";

                    c.Clear();
                    g.AttachControlTo(c);

                    return g;
                };
            #endregion


            bind("Assets", page.assets);
            bind("Transactions", page.transactions).ReadOnly = true;

            // script: error JSC1000: No implementation found for this native method, please implement [System.Data.DataTableCollection.get_Item(System.String)]
            var data_Assets = data.Tables["Assets"];
            var data_Transactions = data.Tables["Transactions"];


            #region data_Assets_NewRow
            Action<DataRow> data_Assets_NewRow =
                 SourceRow =>
                 {

                     var r = new Random();

                     new sack_of_gold2().Source.Task.ContinueWithResult(
                        o =>
                        {
                            o.position.y = -80;
                            scene.add(o);
                            oo.Add(o);

                            o.position.x = r.Next(-250, 250);
                            o.position.z = r.Next(-400, 200);
                            (o as dynamic).scale = new THREE.Vector3(0.5, 0.5, 0.5);

                            data_Assets.RowDeleting +=
                                (sender, e) =>
                                {
                                    if (SourceRow != e.Row)
                                        return;

                                    scene.remove(o);
                                    oo.Remove(o);

                                    data_Transactions.Rows.Add(
                                        "now", "item removed -" + SourceRow["Net worth"]
                                    );

                                };


                        }
                    );

                 };
            #endregion


            data_Assets.Rows.AsEnumerable().WithEach(data_Assets_NewRow);

            // "X:\jsc.svn\examples\javascript\DropFileIntoSQLite\DropFileIntoSQLite.sln"
            // X:\jsc.svn\examples\javascript\DragDataTableIntoCSVFile\DragDataTableIntoCSVFile\Application.cs
            #region ondragstart
            page.header.ondragstart +=
                e =>
                {
                    data_Assets.Rows.AsEnumerable().FirstOrDefault().With(
                        SourceRow =>
                        {
                            // x:\jsc.svn\examples\javascript\dropfileintosqlite\dropfileintosqlite\application.cs

                            data_Assets.Rows.Remove(SourceRow);
                            //data_Assets.Rows.RemoveAt(0);


                            var clipboard = new DataTable();

                            clipboard.Columns.AddRange(
                                Enumerable.ToArray(
                                    from x in data_Assets.Columns.AsEnumerable()
                                    select new DataColumn { ColumnName = x.ColumnName }
                                )
                            );

                            clipboard.Rows.Add(
                                Enumerable.ToArray(
                                    from x in data_Assets.Columns.AsEnumerable()
                                    select SourceRow[x]
                                )
                            );

                            e.dataTransfer.effectAllowed = "copy";

                            var clipboard_string = StringConversionsForDataTable.ConvertToString(clipboard);
                            e.dataTransfer.setData(typeof(DataTable).Name, clipboard_string);
                        }
                    );

                };
            #endregion


            // X:\jsc.svn\market\javascript\Abstractatech.JavaScript.FileStorage\Abstractatech.JavaScript.FileStorage\Application.cs
            var dz = new DropZone();


            var TimerHide = new ScriptCoreLib.JavaScript.Runtime.Timer(
                  delegate
                  {
                      dz.body.Orphanize();
                  }
              );

            #region ondragover
            Action<DragEvent> ondragover =
                evt =>
                {


                    evt.stopPropagation();
                    evt.preventDefault();


                    if (evt.dataTransfer.types.Contains(typeof(DataTable).Name.ToLower()))
                    {


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

                        dz.body.AttachTo(Native.document.documentElement);
                        dz.bglayer.style.transition = "background-color 500ms linear";
                        dz.bglayer.style.backgroundColor = "rgba(0,0,0, 0.7)";

                        TimerHide.Stop();
                    }

                };

            Native.Document.body.ondragover += ondragover;
            dz.Container.ondragover += ondragover;
            #endregion



            dz.Container.ondragleave +=
                 evt =>
                 {
                     //Console.WriteLine("ondragleave");

                     //Console.WriteLine(" dz.Container.ondragleave");
                     TimerHide.StartTimeout(90);

                     evt.stopPropagation();
                     evt.preventDefault();

                 };

            Native.window.onblur +=
                delegate
                {
                    data_Transactions.Rows.Add(
                        //"now", "item added +" + SourceRow["Net worth"]
                        "now", "blur"
                    );

                };

            Native.window.onfocus +=
                delegate
                {
                    data_Transactions.Rows.Add(
                        //"now", "item added +" + SourceRow["Net worth"]
                        "now", "focus"
                    );

                };

            data_Assets_NewRow +=
                SourceRow =>
                {
                    data_Transactions.Rows.Add(
                        //"now", "item added +" + SourceRow["Net worth"]
                        "now", "item added"
                    );
                };

            data_Assets.TableNewRow +=
                (sender, e) =>
                {
                    data_Assets_NewRow(e.Row);
                };


            #region ondrop
            dz.Container.ondrop +=
                evt =>
                {
                    //Console.WriteLine("ondrop");

                    TimerHide.StartTimeout(90);

                    evt.stopPropagation();
                    evt.preventDefault();

                    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 xx =>
                            {
                                // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dfnReturnLink-0
                                var DataTable_xml = await xx.getAsString();

                                var DataTable = StringConversionsForDataTable.ConvertFromString(DataTable_xml);

                                DataTable.Rows.AsEnumerable().WithEach(
                                    SourceRow =>
                                    {

                                        data_Assets.Rows.Add(
                                            Enumerable.ToArray(
                                                from x in data_Assets.Columns.AsEnumerable()
                                                select SourceRow[x]
                                            )
                                        );
                                    }
                                );
                            }
                        );
                    }
                };
            #endregion


        }