public OrcasAvalonApplicationCanvas()
        {
            Width = DefaultWidth;
            Height = DefaultHeight;
            //Background = 0xffc0c0c0.ToSolidColorBrush();
            Background = Brushes.Black;

            var InfoOverlay = new Canvas
            {
                Width = DefaultWidth,
                Height = DefaultHeight,
            };


            var InfoOverlayShadow = new Rectangle
            {
                Width = DefaultWidth,
                Height = DefaultHeight,
                Fill = Brushes.Black
            }.AttachTo(InfoOverlay);

            var InfoOverlayShadowOpacity = InfoOverlay.ToAnimatedOpacity();
            InfoOverlayShadowOpacity.Opacity = 1;

            var InfoOverlayText = new TextBox
            {
                AcceptsReturn = true,
                IsReadOnly = true,
                Background = Brushes.Transparent,
                BorderThickness = new Thickness(0),
                Width = DefaultWidth,
                Height = 180,
                TextAlignment = TextAlignment.Center,
                FontSize = 30,
                Foreground = Brushes.White,
                Text = "The winner is\n the first player\n to get an unbroken row\n of five stones",
                FontFamily = new FontFamily("Verdana")

            }.MoveTo(0, (DefaultHeight - 180) / 2).AttachTo(InfoOverlay);



            var TouchOverlay = new Canvas
            {
                Width = DefaultWidth,
                Height = DefaultHeight,
                Background = Brushes.Yellow,
                Opacity = 0,
            };



            var Tiles = new Tile[Intersections * Intersections];

            #region WhereUnderAttack
            Func<int, int, IEnumerable<Tile>> WhereUnderAttack =
                (length, value) =>
                    Tiles.Where(
                        k =>
                        {
                            if (k.Value != 0)
                                return false;


                            return k.IsUnderAttack(value, length);
                        }
                    );
            #endregion

            #region AI
            Action AI =
                delegate
                {
                    // defensive rule:

                    var AttackWith4 = WhereUnderAttack(4, -1).FirstOrDefault();
                    if (AttackWith4 != null)
                    {
                        Console.WriteLine("AttackWith4");
                        AttackWith4.Value = -1;
                        return;
                    }

                    var AttackedBy4 = WhereUnderAttack(4, 1).FirstOrDefault();
                    if (AttackedBy4 != null)
                    {
                        Console.WriteLine("AttackedBy4");
                        AttackedBy4.Value = -1;
                        return;
                    }

                    var AttackWith3 = WhereUnderAttack(3, -1).FirstOrDefault();
                    if (AttackWith3 != null)
                    {
                        Console.WriteLine("AttackWith3");
                        AttackWith3.Value = -1;
                        return;
                    }

                    var AttackedBy3 = WhereUnderAttack(3, 1).FirstOrDefault();
                    if (AttackedBy3 != null)
                    {
                        Console.WriteLine("AttackedBy3");
                        AttackedBy3.Value = -1;
                        return;
                    }

                    var AttackWith2 = WhereUnderAttack(2, -1).FirstOrDefault();
                    if (AttackWith2 != null)
                    {
                        Console.WriteLine("AttackWith2");
                        AttackWith2.Value = -1;
                        return;
                    }

                    var AttackedBy2 = WhereUnderAttack(2, 1).FirstOrDefault();
                    if (AttackedBy2 != null)
                    {
                        Console.WriteLine("AttackedBy2");
                        AttackedBy2.Value = -1;
                        return;
                    }

                    var AttackedBy1 = WhereUnderAttack(1, 1).FirstOrDefault();
                    if (AttackedBy1 != null)
                    {
                        Console.WriteLine("AttackedBy1");
                        AttackedBy1.Value = -1;
                        return;
                    }



                    Console.WriteLine("Random");
                    Tiles.Where(k => k.Value == 0).Random().Value = -1;
                };
            #endregion

            var ResetOverlay = new Rectangle
            {
                Fill = Brushes.Yellow,
                Width = DefaultWidth,
                Height = DefaultHeight,
                Cursor = Cursors.Hand,
            };

            //9000.AtDelay(
            //    delegate
            //    {
            //        ResetOverlay.Orphanize();
            //        InfoOverlayShadowOpacity.Opacity = 0;
            //    }
            //);

            ResetOverlay.MouseLeftButtonUp +=
                delegate
                {
                    Tiles.ForEach(k => k.Value = 0);
                    ResetOverlay.Orphanize();
                    InfoOverlayShadowOpacity.Opacity = 0;
                };

            Action<Tile> Tiles_WithEvents =
                t =>
                {
                    #region add 2d awareness
                    t.ByOffset =
                        (ox, oy) =>
                        {
                            var x = t.X + ox;
                            var y = t.Y + oy;

                            if (x < 0)
                                return null;
                            if (y < 0)
                                return null;
                            if (x >= Intersections)
                                return null;
                            if (y >= Intersections)
                                return null;
                            return Tiles[x + y * Intersections];
                        };
                    #endregion

                    t.TouchOverlay.MouseLeftButtonUp +=
                        delegate
                        {
                            if (t.Value != 0)
                                return;

                            t.Value = 1;

                            if (AtClick != null)
                                AtClick();

                            // did we win?
                            if (Tiles.Any(
                                k =>
                                {
                                    if (k.Value != 1)
                                        return false;

                                    return k.IsUnderAttack(1, 4);
                                }
                            ))
                            {
                                InfoOverlayShadowOpacity.Opacity = 0.8;
                                InfoOverlayText.Text = "You won!\n\n:)";
                                ResetOverlay.AttachTo(TouchOverlay);


                                if (AtWin != null)
                                    AtWin();

                                return;
                            }

                            t.TouchOverlay.Hide();
                            100.AtDelay(
                                delegate
                                {
                                    AI();
                                    t.TouchOverlay.Show();


                                    if (Tiles.Any(
                                        k =>
                                        {
                                            if (k.Value != -1)
                                                return false;

                                            return k.IsUnderAttack(-1, 4);
                                        }
                                    ))
                                    {
                                        InfoOverlayShadowOpacity.Opacity = 0.8;
                                        InfoOverlayText.Text = "You lost!\n\n:(";
                                        ResetOverlay.AttachTo(TouchOverlay);


                                        if (AtLoss != null)
                                            AtLoss();

                                        return;
                                    }
                                }
                            );
                        };


                };

            var TileContainer = new Canvas().AttachTo(this);

            #region build board
            for (int x = 0; x < Intersections; x++)
                for (int y = 0; y < Intersections; y++)
                {

                    var t = new Tile(x, y);



                    t.Container.AttachTo(TileContainer);
                    t.TouchOverlay.AttachTo(TouchOverlay);

                    Tiles[x + y * Intersections] = t;
                    Tiles_WithEvents(t);
                }
            #endregion

            #region add logo
            var img = new com.abstractatech.gomoku.Avalon.Images.jsc
            {
            }.MoveTo(DefaultWidth - 96, DefaultHeight - 96).AttachTo(TileContainer);
            #endregion

            ResetOverlay.AttachTo(TouchOverlay);
            InfoOverlay.AttachTo(this);
            TouchOverlay.AttachTo(this);

            this.SizeChanged +=
                delegate
                {
                    TileContainer.MoveTo(
                        (this.Width - DefaultWidth) /2,
                        (this.Height - DefaultHeight) /2
                        );
                    TouchOverlay.MoveTo(
                     (this.Width - DefaultWidth) / 2,
                     (this.Height - DefaultHeight) / 2
                     );

                    ResetOverlay.SizeTo(this.Width, this.Height);
                    InfoOverlay.SizeTo(this.Width, this.Height);
                    InfoOverlayShadow.SizeTo(this.Width, this.Height);
                    //TouchOverlay.SizeTo(this.Width, this.Height);

                    InfoOverlayText.MoveTo(0, (this.Height - 180) / 2);
                    InfoOverlayText.SizeTo(this.Width, 180);


                };
        }
        public void CreateWindow(Position WindowLocation, Action<WindowInfo> Yield = null)
        {
            var GlassArea = new Canvas();

            GlassArea.AttachTo(this);
            GlassArea.MoveTo(WindowLocation.Left, WindowLocation.Top);
            GlassArea.SizeTo(WindowLocation.Width, WindowLocation.Height);
            GlassArea.ClipToBounds = true;

            for (int i = 0; i < WindowLocation.Width; i += 456)
                for (int j = 0; j < WindowLocation.Height; j += 696)
                {
                    var i2 = new Avalon.Images.s_bg().SizeTo(456, 696);

                    i2.MoveTo(i, j);
                    i2.Opacity = 0.8;

                    i2.AttachTo(GlassArea);
                }

            var GlassOpacity = GlassArea.ToAnimatedOpacity();

            GlassOpacity.Opacity = 1;
            var w = new WindowInfo { GlassArea = GlassArea, GlassOpacity = GlassOpacity, WindowLocation = WindowLocation };


            var Left = new Avalon.Images.s_l
            {
                Stretch = Stretch.Fill
            }
            .AttachTo(this);


            var Top = new Avalon.Images.s_t
            {
                Stretch = Stretch.Fill
            }
            .AttachTo(this);




            var Right = new Avalon.Images.s_r
            {
                Stretch = Stretch.Fill
            }.AttachTo(this);




            var Bottom = new Avalon.Images.s_b
            {
                Stretch = Stretch.Fill
            }
             .AttachTo(this);


            var TopLeft = new Avalon.Images.s_tl
            {
                Stretch = Stretch.Fill
            }
           .AttachTo(this);


            var BottomRight = new Avalon.Images.s_br
            {
                Stretch = Stretch.Fill
            }
             .AttachTo(this);



            var TopRight = new Avalon.Images.s_tr
            {
                Stretch = Stretch.Fill
            }
           .AttachTo(this);


            var BottomLeft = new Avalon.Images.s_bl
            {
                Stretch = Stretch.Fill
            }
           .AttachTo(this);


            w.WindowLocationChanged +=
               delegate
               {
                   Left.MoveTo(WindowLocation.Left - 16, WindowLocation.Top + 6)
                   .SizeTo(16, WindowLocation.Height - 6 - 4);

                   Top.MoveTo(WindowLocation.Left + 6, WindowLocation.Top - 16)
          .SizeTo(WindowLocation.Width - 6 - 4, 22);

                   Right.MoveTo(WindowLocation.Left + WindowLocation.Width, WindowLocation.Top + 6)
               .SizeTo(20, WindowLocation.Height - 4 - 6);


                   Bottom.MoveTo(WindowLocation.Left + 5, WindowLocation.Top + WindowLocation.Height)
                    .SizeTo(WindowLocation.Width - 4 - 5, 20);


                   TopLeft.MoveTo(WindowLocation.Left - 22 + 6, WindowLocation.Top - 22 + 6)
                   .SizeTo(22, 22);
                   BottomRight.MoveTo(WindowLocation.Left + WindowLocation.Width - 4, WindowLocation.Top + WindowLocation.Height - 4)
                .SizeTo(22, 22);
                   TopRight.MoveTo(WindowLocation.Left + WindowLocation.Width - 4, WindowLocation.Top - 22 + 6)
                  .SizeTo(22, 22);
                   BottomLeft.MoveTo(WindowLocation.Left - 22 + 5, WindowLocation.Top + WindowLocation.Height - 4)
                  .SizeTo(22, 22);

               };

            w.WindowLocationChanged();

            w.Orphanize +=
                delegate
                {
                    new FrameworkElement[]
                    {
                        Left,
                        Top,
                        Right,
                        Bottom,
                        TopLeft,
                        BottomRight,
                        TopRight,
                        BottomLeft
                    }.WithEach(k => k.Orphanize());
                };

            w.Attach +=
               delegate
               {
                   new FrameworkElement[]
                    {
                        Left,
                        Top,
                        Right,
                        Bottom,
                        TopLeft,
                        BottomRight,
                        TopRight,
                        BottomLeft
                    }.WithEach(k => k.AttachTo(this));
               };

            if (Yield != null)
            {

                Yield(
                   w
                );
            }
        }
        private void XInitialize()
        {

            //this.Background = Brushes.Black;
            this.Background = Brushes.White;

            var b = new JSCSolutionsNETCarouselCanvas();

            b.CloseOnClick = false;
            b.Container.AttachTo(this);

            var bg_black = new Canvas
            {
                Background = Brushes.Black
            }.AttachTo(this);

            var bg_black_opacity = bg_black.ToAnimatedOpacity();

            bg_black_opacity.Opacity = 0;

            var w = new JSCSolutionsNETWhiteCarouselCanvas();

            w.CloseOnClick = false;
            w.Container.AttachTo(bg_black);

            bool OtherView = false;

            //new { b.step }.With(
            //    x =>
            //    {
            //        var counter = 0;

            //        (1000 / 60).AtIntervalWithTimer(
            //            speedboost =>
            //            {
            //                counter++;

            //                b.step = x.step * (1 + counter * 0.1);

            //                if (counter == 60 * 2)
            //                    speedboost.Stop();

            //            }
            //        );

            //    }
            //);



            Action ChooseView =
                delegate
                {

                    //V:\web\AvalonBrowserLogos\ApplicationCanvas___c__DisplayClass5.as(35): col: 36 Error: Implicit coercion of a value of type Boolean to an unrelated type Number.

                    //            if (!(((this.__4__this.Width > this.__4__this.Height) ^ this.OtherView) == 0))
                    //                                   ^

                    //V:\web\AvalonBrowserLogos\ApplicationCanvas___c__DisplayClass5.as(35): col: 74 Error: Implicit coercion of a value of type Boolean to an unrelated type Number.

                    //            if (!(((this.__4__this.Width > this.__4__this.Height) ^ this.OtherView) == 0))
                    //                                                                         ^


                    // X:\jsc.svn\examples\actionscript\Test\TestBooleanXor\TestBooleanXor\Class1.cs
                    // actionscript thinks this operator results in int?
                    //var flag = (Width > Height) ^ OtherView;
                    var flag = (Width > Height);

                    if (OtherView)
                        flag = !flag;

                    if (flag)
                        bg_black_opacity.Opacity = 0;
                    else
                        bg_black_opacity.Opacity = 1;
                };

            w.AtLogoClick +=
                delegate
                {
                    OtherView = !OtherView;

                    ChooseView();
                };

            b.AtLogoClick +=
                delegate
                {
                    OtherView = !OtherView;

                    ChooseView();

                };

            this.SizeChanged += (s, e) =>
            {
                ChooseView();

                w.Container.MoveTo(
                    (this.Width - 400) / 2, (this.Height - 400) / 2
                );

                b.Container.MoveTo(
                      (this.Width - 400) / 2, (this.Height - 400) / 2
                  );

                bg_black.SizeTo(this.Width, this.Height);
            };


        }
        public ApplicationCanvas()
        {
            var c = new CheckBox
            {
                Content = new TextBlock { Text = "Print to Console  " }
            }.MoveTo(8, 96);


            var t = new TextBlock { Text = "?" }.AttachTo(this);

            var redblockcontainer = new Canvas();

            redblockcontainer.Opacity = 0.8;
            redblockcontainer.Background = Brushes.Red;
            redblockcontainer.AttachTo(this);
            redblockcontainer.MoveTo(8, 8);
            this.SizeChanged += (s, e) => redblockcontainer.MoveTo(64 - 16, this.Height / 3 - 16).SizeTo(this.Width - 96, this.Height / 3 - 8);

            var redblockoverlay = new Canvas();

            redblockoverlay.Opacity = 0.1;
            redblockoverlay.Background = Brushes.Red;
            redblockoverlay.AttachTo(this);
            redblockoverlay.MoveTo(8, 8);
            this.SizeChanged += (s, e) => redblockoverlay.MoveTo(64 + 64, this.Height / 3).SizeTo(this.Width - 96 - 64, this.Height / 3 - 8);

            var yellowblock = new Canvas();
            yellowblock.Opacity = 0.7;
            yellowblock.Background = Brushes.Yellow;
            yellowblock.AttachTo(this);
            yellowblock.SizeTo(400, 200);


            var a_case1 = Enumerable.Range(0, 64).Select(
              i =>
              {
                  var rr = new Rectangle();
                  rr.Fill = Brushes.Blue;
                  rr.AttachTo(yellowblock);
                  rr.SizeTo(32, 32);
                  rr.MoveTo(-32, -32);
                  return rr;
              }
          ).ToArray();


            var a_case2 = Enumerable.Range(0, 64).Select(
              i =>
              {
                  var rr = new Rectangle();
                  rr.Fill = Brushes.Green;
                  rr.AttachTo(this);
                  rr.SizeTo(32, 32);
                  rr.MoveTo(-32, -32);
                  return rr;
              }
          ).ToArray();


            var greenblock = new Canvas();
            greenblock.Opacity = 0.5;
            greenblock.Background = Brushes.Green;
            greenblock.AttachTo(this);
            greenblock.SizeTo(400, 200);
            greenblock.MoveTo(200 - 12, 12);

            var a_case3 = Enumerable.Range(0, 64).Select(
              i =>
              {
                  var rr = new Rectangle();
                  rr.Fill = Brushes.Black;
                  rr.AttachTo(redblockcontainer);
                  rr.SizeTo(32, 32);
                  rr.MoveTo(-32, -32);
                  return rr;
              }
          ).ToArray();



            var case1 = yellowblock;
            var case2 = greenblock;
            var case3 = redblockoverlay;

            #region case1
            case1.TouchDown +=
                (s, e) =>
                {
                    e.Handled = true;
                    // is called implicitly on Android Chrome
                    e.TouchDevice.Capture(case1);

                    Console.WriteLine("TouchDown");
                };

            case1.MouseMove +=
            (s, e) =>
            {
                // case 1
                var p = e.GetPosition(case1);

                a_case1.Last().MoveTo(p);

                if ((bool)c.IsChecked)
                    Console.WriteLine("MouseMove " + p);
            };

            case1.TouchUp +=
          (s, e) =>
          {
              Console.WriteLine("TouchUp");
          };
            #endregion

            case1.TouchMove +=
                (s, e) =>
                {
                    // case 1
                    var p = e.GetTouchPoint(case1).Position;

                    a_case1[e.TouchDevice.Id].MoveTo(p);

                    if ((bool)c.IsChecked)
                        Console.WriteLine("TouchMove " + e.TouchDevice.Id + " " + p);
                };




            #region case2
            case2.TouchDown +=
            (s, e) =>
            {
                e.Handled = true;
                // is called implicitly on Android Chrome
                e.TouchDevice.Capture(case2);

                Console.WriteLine("TouchDown");
            };

            case2.MouseMove +=
             (s, e) =>
             {
                 // case 1
                 var p = e.GetPosition(this);

                 a_case2.Last().MoveTo(p);

                 if ((bool)c.IsChecked)
                     Console.WriteLine("MouseMove " + p);
             };
            case2.TouchUp +=
          (s, e) =>
          {
              Console.WriteLine("TouchUp");
          };
            #endregion
            case2.TouchMove +=
                (s, e) =>
                {
                    var p = e.GetTouchPoint(this).Position;

                    t.Text = new { case2 = p }.ToString();

                    //// case 2
                    //var a = ((object)e as __TouchEventArgs);
                    //if (a != null)
                    //{



                    //    var pp = new Point(
                    //       a.InternalValue.pageX,
                    //       a.InternalValue.pageY
                    //    );


                    //    var b = GetPositionData.Of(a.InternalElement);

                    //    var item = b.Last();

                    //    pp.X -= item.X;
                    //    pp.Y -= item.Y;


                    //    t.Text = new
                    //    {
                    //        case2 = new
                    //        {
                    //            pp,

                    //            a.InternalValue.screenX,
                    //            a.InternalValue.screenY,
                    //            a.InternalValue.clientX,
                    //            a.InternalValue.clientY,
                    //            a.InternalValue.pageX,
                    //            a.InternalValue.pageY
                    //        }
                    //    }.ToString();
                    //}



                    a_case2[e.TouchDevice.Id].MoveTo(p);


                    if ((bool)c.IsChecked)
                        Console.WriteLine("TouchMove " + e.TouchDevice.Id + " " + p);
                };



            #region case3
            case3.TouchDown +=
            (s, e) =>
            {
                e.Handled = true;
                // is called implicitly on Android Chrome
                e.TouchDevice.Capture(case3);

                Console.WriteLine("TouchDown");
            };

            case3.MouseMove +=
                (s, e) =>
                {
                    // case 1
                    var p = e.GetPosition(redblockcontainer);

                    a_case3.Last().MoveTo(p);

                    if ((bool)c.IsChecked)
                        Console.WriteLine("MouseMove " + p);
                };
            case3.TouchUp +=
                  (s, e) =>
                  {
                      Console.WriteLine("TouchUp");
                  };
            #endregion
            case3.TouchMove +=
                (s, e) =>
                {
                    // case 3
                    var p = e.GetTouchPoint(redblockcontainer).Position;

                    t.Text = new { case3 = p }.ToString();

                    //var args = ((object)e as __TouchEventArgs);
                    //if (args != null)
                    //{

                    //    var pp = new Point(
                    //       args.InternalValue.pageX,
                    //       args.InternalValue.pageY
                    //    );


                    //    var a = GetPositionData.Of(((object)redblockcontainer as __Canvas).InternalContent);
                    //    var b = GetPositionData.Of(args.InternalElement);


                    //    if (b.Count > 0)
                    //    {
                    //        var item = b.Last();

                    //        pp.X -= item.X;
                    //        pp.Y -= item.Y;
                    //    }


                    //    // top elements might be the same so we remove them
                    //    var loop = true;

                    //    while (loop)
                    //    {
                    //        loop = false;

                    //        if (a.Count > 0)
                    //            if (b.Count > 0)
                    //                if (a[a.Count - 1].Element == b[b.Count - 1].Element)
                    //                {
                    //                    a.RemoveAt(a.Count - 1);
                    //                    b.RemoveAt(b.Count - 1);

                    //                    loop = true;
                    //                }
                    //    }

                    //    if (a.Count > 0)
                    //    {
                    //        var itembb = a.Last();

                    //        pp.X -= itembb.X;
                    //        pp.Y -= itembb.Y;
                    //    }

                    //    if (b.Count > 0)
                    //    {
                    //        var item = b.Last();

                    //        pp.X += item.X;
                    //        pp.Y += item.Y;
                    //    }

                    //    t.Text = new
                    //    {
                    //        case2 = new
                    //        {
                    //            p,
                    //            pp,

                    //            //a.InternalValue.screenX,
                    //            //a.InternalValue.screenY,
                    //            //a.InternalValue.clientX,
                    //            //a.InternalValue.clientY,
                    //            args.InternalValue.pageX,
                    //            args.InternalValue.pageY
                    //        }
                    //    }.ToString();

                    //    a_case3[e.TouchDevice.Id].MoveTo(pp);

                    //    Console.WriteLine("TouchMove " + e.TouchDevice.Id + " " + pp);
                    //    return;
                    //}


                    a_case3[e.TouchDevice.Id].MoveTo(p);

                    if ((bool)c.IsChecked)
                        Console.WriteLine("TouchMove " + e.TouchDevice.Id + " " + p);
                };

            c.AttachTo(this);

        }