public static void Main(string[] e)
        {
            var w = new Window { Title = "JSC - Android Project" }.SizeTo(400 + 48, 300);

            var c = new Canvas();

            c.AttachTo(w);


            new global::AndroidVortexLesson1.Avalon.Images.jsc().AttachTo(c).MoveTo(300, 16);

            var button1 = new Button { Content = "Debug in Android Emulator" };

            button1.MoveTo(16, 128).SizeTo(400, 32);
            button1.AttachTo(c);

            var button2 = new Button { Content = "Debug on Device" };

            button2.MoveTo(16, 128 + 48).SizeTo(400, 32);
            button2.AttachTo(c);

            w.ShowDialog();
        }
        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
                );
            }
        }
        public ApplicationCanvas()
        {
            Width = DefaultWidth;
            Height = DefaultHeight;


            this.Background = Brushes.Blue;

            var left = new PartialView(Colors.Blue, true).AttachTo(this);
            var right = new PartialView(Colors.Green).AttachTo(this).MoveTo(DefaultWidth / 2, 0);

            this.InfoOverlay = new Canvas().AttachTo(this);

            this.About = new TextBox
            {
                BorderThickness = new Thickness(0),
                Background = Brushes.Transparent,
                Foreground = Brushes.Black,
                AcceptsReturn = true,

                Text =

@"Windows Presentation Foundation Touch demo
- Debuggable under .NET (fullscreen when maximized and touch events)
- Adobe Flash 10.1 version via jsc
     No touch events in fullscreen
     Browser fullscreen feature shall be used instead
     Tested for IE, Firefox, Chrome

- Javascript version for Firefox4 via jsc
- Tested with 4 touch points on Dell Latitude XT
- Galaxy S/ Galaxy Tab within browser have only 1 touchpoint
- 2012.09 flash no longer available on android
- multitouch seems to work in firefox/ flash (11.0)
- multitouch seems to work in ie/flash (10.0)
- p2p LAN no longer works?
- Works on AIR for Android! :) 2013-03-05
- Works on AIR for iPad! :) 2014-03-01
"


            }.AttachTo(InfoOverlay).MoveTo(128, 32);

            var c1 = new cloud_mid().AttachTo(InfoOverlay);
            var c2 = new cloud_mid().AttachTo(InfoOverlay);


            this.TouchOverlay = new Canvas
            {



            }.AttachTo(this); //.SizeTo(DefaultWidth, DefaultHeight);

            var TouchArea = new Rectangle
            {
                Width = DefaultWidth,
                Height = DefaultHeight,
                Fill = Brushes.White,
                Opacity = 0
            }.AttachTo(TouchOverlay);


            var t = TouchOverlay.ToTouchEvents(
                m =>
                {
                    // a new reusable finger introduced by the system!
                    var Content = new Canvas();

                    new Avalon.Images.white_jsc().AttachTo(Content).MoveTo(
                        Avalon.Images.white_jsc.ImageDefaultWidth / -2,
                        Avalon.Images.white_jsc.ImageDefaultHeight / -2
                    );

                    var CurrentTouchPoint = default(Tuple<double, double>);

                    Func<Tuple<double, double>> GetTouchPoint = () => CurrentTouchPoint;

                    m.TouchDown += e =>
                    {
                        var p = e.GetTouchPoint(TouchOverlay).Position;

                        CurrentTouchPoint = Tuple.Create(p.X, p.Y);
                        Content.AttachTo(InfoOverlay);
                    };

                    m.TouchUp += e =>
                    {
                        CurrentTouchPoint = null;
                        Content.Orphanize();
                    };

                    m.TouchMove += e =>
                    {
                        var p = e.GetTouchPoint(TouchOverlay).Position;

                        CurrentTouchPoint = Tuple.Create(p.X, p.Y);



                        Content.MoveTo(e, TouchOverlay);
                    };


                    // this is what will be visible for the rest.
                    return new
                    {
                        Content,
                        GetTouchPoint,
                    };
                }
            );




            var touches = from k in t.Touches
                          let p = k.GetTouchPoint()
                          where p != null
                          let x = p.Item1
                          let y = p.Item2
                          select new { x, y, touch = k };

            var left_touch = from k in touches
                             let x = k.x
                             let y = k.y
                             where x < 64
                             where y > Height - 64
                             select k;




            var RocketsPending = new Dictionary<object, Canvas>();

            var buildmode_touches =
                from c in left_touch.Take(1)
                from k in touches
                where k.y < Height - 64

                // um, this finger already seems to have a pending rocket...
                where !RocketsPending.ContainsKey(k.touch)

                select k;

            var RocketsPendingToUpdate =
                from c in touches
                where RocketsPending.ContainsKey(c.touch)
                let rocket = RocketsPending[c.touch]
                let Update = new Action(() => rocket.MoveTo(c.x, c.y))
                select new { rocket, c, Update };

            var __left_buildmode = false;


            #region NotifyBuildRocket
            this.NotifyBuildRocket =
                (x, y) =>
                {
                    #region create a pending rocket
                    var n = new { Content = new Canvas().AttachTo(InfoOverlay) };

                    //Tuple

                    var i = new Avalon.Images.rocket
                    {

                    }.AttachTo(n.Content).MoveTo(
                       Avalon.Images.rocket.ImageDefaultWidth / -4,
                       Avalon.Images.rocket.ImageDefaultHeight / -4
                   ).SizeTo(
                       Avalon.Images.rocket.ImageDefaultWidth / 2,
                       Avalon.Images.rocket.ImageDefaultHeight / 2
                   );


                    // hold/build!
                    //i.Opacity = 0.5;
                    n.Content.MoveTo(x, y);
                    MultitouchExample.Sounds.launch.Source.PlaySound();
                    n.Content.AccelerateAndFade();
                    #endregion
                };
            #endregion




            #region VisualizeTouch
            Action<double, double> VisualizeTouch = (x, y) =>
            {
                var n = new { Content = new Canvas().AttachTo(InfoOverlay) };

                //Tuple

                new Avalon.Images.white_jsc
                {

                }.AttachTo(n.Content).MoveTo(
                   Avalon.Images.white_jsc.ImageDefaultWidth / -4,
                   Avalon.Images.white_jsc.ImageDefaultHeight / -4
               ).SizeTo(
                   Avalon.Images.white_jsc.ImageDefaultWidth / 2,
                   Avalon.Images.white_jsc.ImageDefaultHeight / 2
               );

                n.Content.FadeOut();

                n.Content.MoveTo(x, y);
            };

            this.NotifyVisualizeTouch = VisualizeTouch;
            #endregion



            #region MouseLeftButtonUp
            TouchOverlay.MouseLeftButtonUp +=
                (sender, args) =>
                {
                    // um this device has no finger support?
                    // 2014! less tech?

                    var p = args.GetPosition(TouchOverlay);
                    var item = new { x = p.X, y = p.Y };


                    #region create a pending rocket
                    var n = new { Content = new Canvas().AttachTo(InfoOverlay) };

                    //Tuple

                    var rocket = new Avalon.Images.rocket
                    {

                    }.AttachTo(n.Content).MoveTo(
                       Avalon.Images.rocket.ImageDefaultWidth / -4,
                       Avalon.Images.rocket.ImageDefaultHeight / -4
                   ).SizeTo(
                       Avalon.Images.rocket.ImageDefaultWidth / 2,
                       Avalon.Images.rocket.ImageDefaultHeight / 2
                   );


                    // hold/build!
                    //i.Opacity = 0.5;
                    n.Content.Opacity = 0.5;
                    n.Content.MoveTo(item.x, item.y);
                    #endregion

                    MultitouchExample.Sounds.launch.Source.PlaySound();

                    rocket.Opacity = 1;
                    rocket.AccelerateAndFade();

                    //RocketsPending.Remove(item.touch);

                    if (AtNotifyBuildRocket != null)
                        AtNotifyBuildRocket(item.x, item.y);

                };
            #endregion

            (1000 / 15).AtInterval(
                delegate
                {


                    #region visualize all touches
                    foreach (var item in touches)
                    {
                        VisualizeTouch(item.x, item.y);

                        if (this.AtNotifyVisualizeTouch != null)
                            this.AtNotifyVisualizeTouch(item.x, item.y);
                    }
                    #endregion

                    foreach (var item in
                        from k in t.Touches
                        where k.GetTouchPoint() == null
                        where RocketsPending.ContainsKey(k)
                        select new { rocket = RocketsPending[k], touch = k }
                        )
                    {
                        // finger was lifted and rocked should be launched
                        // no sound in .net
                        // and NO fingers in this laptop!!!! 2014 
                        MultitouchExample.Sounds.launch.Source.PlaySound();

                        item.rocket.Opacity = 1;
                        item.rocket.AccelerateAndFade();

                        RocketsPending.Remove(item.touch);

                        if (AtNotifyBuildRocket != null)
                            AtNotifyBuildRocket(Canvas.GetLeft(item.rocket), Canvas.GetTop(item.rocket));
                    }

                    var left_buildmode = left_touch.Any();
                    if (left_buildmode)
                    {
                        if (!__left_buildmode)
                        {
                            MultitouchExample.Sounds.building.Source.PlaySound();
                            // sound: build mode engaged!
                        }

                        // all other touches in range are now build orders!

                        foreach (var item in RocketsPendingToUpdate)
                        {
                            item.Update();
                        }

                        #region build
                        foreach (var item in buildmode_touches)
                        {
                            #region create a pending rocket
                            var n = new { Content = new Canvas().AttachTo(InfoOverlay) };

                            //Tuple

                            var i = new Avalon.Images.rocket
                            {

                            }.AttachTo(n.Content).MoveTo(
                               Avalon.Images.rocket.ImageDefaultWidth / -4,
                               Avalon.Images.rocket.ImageDefaultHeight / -4
                           ).SizeTo(
                               Avalon.Images.rocket.ImageDefaultWidth / 2,
                               Avalon.Images.rocket.ImageDefaultHeight / 2
                           );


                            // hold/build!
                            //i.Opacity = 0.5;
                            n.Content.Opacity = 0.5;
                            n.Content.MoveTo(item.x, item.y);
                            #endregion

                            RocketsPending[item.touch] = n.Content;


                            //n.Content.AccelerateAndFade();
                        }
                        #endregion


                        left.buildmode_off.Hide();
                        left.buildmode_on.Show();
                    }
                    else
                    {
                        left.buildmode_on.Hide();
                        left.buildmode_off.Show();
                    }
                    __left_buildmode = left_buildmode;
                }
            );

            #region SizeChanged


            Action SizeChanged =
                delegate
                {
                    c1.MoveTo(
    (Width - c1.Width) / 2, 0);

                    c2.MoveTo(
                        (Width - c1.Width) / 2, Height / 2);

                    left.SizeTo(

                        Width / 2,
                        Height
                    );


                    right.MoveTo(
                        Width / 2, 0).SizeTo(

                        Width / 2,
                        Height
                    );

                    TouchArea.SizeTo(Width, Height);
                };

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

            SizeChanged();
            #endregion


        }
        public TileFieldTest()
        {
            this.Width = DefaultWidth;
            this.Height = DefaultHeight;

            new[]
            {
                Colors.White,
                Colors.Blue,
                Colors.Red,
                Colors.Yellow
            }.ToGradient(DefaultHeight / 4).ForEach(
                (c, i) =>
                new Rectangle
                {
                    Fill = new SolidColorBrush(c),
                    Width = DefaultWidth,
                    Height = 5,
                }.MoveTo(0, i * 4).AttachTo(this)
            );

            var t = new TextBox
            {
                AcceptsReturn = true,
                Background = Brushes.White,
                BorderThickness = new Thickness(0),
                Text = "hello world" + Environment.NewLine,
                Width = DefaultWidth / 2,
                Height = DefaultHeight / 4
            }.AttachTo(this).MoveTo(DefaultWidth / 4, 4);

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

            var OverlayRectangle = new Rectangle
            {
                Width = DefaultWidth,
                Height = DefaultHeight,
                Fill = Brushes.Black,
                Opacity = 0
            }.AttachTo(OverlayCanvas);

            var field = new TileField(8, 6);
            var field_x = 64;
            var field_y = 200;

            field.Container.MoveTo(field_x, field_y).AttachTo(this);
            field.Overlay.MoveTo(field_x, field_y).AttachTo(OverlayCanvas);

            var WaterFlow = new Queue<Action>();

            #region pipes
            {

                var pipe = new Pipe.PumpToLeft();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 5, field_y + Tile.ShadowBorder + 52 * 0 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i =>
                        WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            Enumerable.Range(0, 2).ForEach(
                ix_ =>
                {
                    var ix = 4 - ix_;

                    var pipe = new Pipe.LeftToRight();

                    pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * ix, field_y + Tile.ShadowBorder + 52 * 0 - 12).AttachTo(this);

                    pipe.Water.ForEachReversed(
                        i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                    );

                }

            );

            {

                var pipe = new Pipe.RightToBottom();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 2, field_y + Tile.ShadowBorder + 52 * 0 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            Enumerable.Range(1, 2).ForEach(
                iy =>
                {

                    var pipe = new Pipe.TopToBottom();

                    pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 2, field_y + Tile.ShadowBorder + 52 * iy - 12).AttachTo(this);

                    pipe.Water.ForEach(
                        i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                    );

                }
            );

            {

                var pipe = new Pipe.TopToRight();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 2, field_y + Tile.ShadowBorder + 52 * 3 - 12).AttachTo(this);

                pipe.Water.ForEach(
                                i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                            );

            }

            Enumerable.Range(3, 3).ForEach(
                ix =>
                {

                    var pipe = new Pipe.LeftToRight();

                    pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * ix, field_y + Tile.ShadowBorder + 52 * 3 - 12).AttachTo(this);

                    pipe.Water.ForEach(
                        i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                    );

                }
            );

            field[3, 2].Drain.Visibility = Visibility.Visible;

            {

                var pipe = new Pipe.LeftToDrain();

                field[6, 3].Drain.Visibility = Visibility.Visible;

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 6, field_y + Tile.ShadowBorder + 52 * 3 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            {

                var pipe = new Pipe.PumpToRight();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 0, field_y + Tile.ShadowBorder + 52 * 1 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i =>
                        WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            {

                var pipe = new Pipe.LeftToRight();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 1, field_y + Tile.ShadowBorder + 52 * 1 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            {

                var pipe = new Pipe.LeftToRightBent();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 2, field_y + Tile.ShadowBorder + 52 * 1 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            Enumerable.Range(3, 4).ForEach(
                ix =>
                {

                    var pipe = new Pipe.LeftToRight();

                    pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * ix, field_y + Tile.ShadowBorder + 52 * 1 - 12).AttachTo(this);

                    pipe.Water.ForEach(
                        i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                    );

                }
            );

            {

                var pipe = new Pipe.LeftToBottom();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 7, field_y + Tile.ShadowBorder + 52 * 1 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            Enumerable.Range(2, 2).ForEach(
                iy =>
                {

                    var pipe = new Pipe.TopToBottom();

                    pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 7, field_y + Tile.ShadowBorder + 52 * iy - 12).AttachTo(this);

                    pipe.Water.ForEach(
                        i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                    );

                }
            );

            {

                var pipe = new Pipe.TopToLeft();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 7, field_y + Tile.ShadowBorder + 52 * 4 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }

            Enumerable.Range(0, 3).ForEach(
                ix_ =>
                {
                    var ix = 6 - ix_;

                    var pipe = new Pipe.LeftToRight();

                    pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * ix, field_y + Tile.ShadowBorder + 52 * 4 - 12).AttachTo(this);

                    pipe.Water.ForEachReversed(
                        i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                    );

                }
            );

            {

                var pipe = new Pipe.RightToDrain();

                pipe.Container.MoveTo(field_x + Tile.ShadowBorder + Tile.Size * 3, field_y + Tile.ShadowBorder + 52 * 4 - 12).AttachTo(this);

                pipe.Water.ForEach(
                    i => WaterFlow.Enqueue(() => i.Visibility = Visibility.Visible)
                );

            }
            #endregion

            field[3, 4].Drain.Visibility = Visibility.Visible;

            OverlayCanvas.AttachTo(this).MoveTo(0, 0);

            var Navigationbar = new AeroNavigationBar();

            Navigationbar.Container.MoveTo(4, 4).AttachTo(this);

            var c1 = new ArrowCursorControl
            {

            };

            c1.Container.MoveTo(32, 32).AttachTo(this);
            c1.Red.Opacity = 0.7;

            OverlayCanvas.MouseMove +=
                (sender, e) =>
                {
                    var p = e.GetPosition(OverlayCanvas);

                    c1.Container.MoveTo(32 + p.X, 32 + p.Y);
                };

            OverlayCanvas.MouseLeave +=
                delegate
                {
                    c1.Container.Visibility = Visibility.Hidden;
                };

            OverlayCanvas.MouseEnter +=
                delegate
                {
                    c1.Container.Visibility = Visibility.Visible;
                };

            foreach (var n in KnownAssets.Default.FileNames)
            {
                t.AppendTextLine(n);
            }

            3000.AtDelay(
                delegate
                {
                    (1000 / 10).AtIntervalWithTimer(
                        ttt =>
                        {
                            if (WaterFlow.Count == 0)
                            {
                                ttt.Stop();
                                return;
                            }

                            WaterFlow.Dequeue()();
                        }
                    );
                }
            );
        }
        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);

        }