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 ApplicationSprite()
        {
            //Security.allowDomain("*");
            //Security.allowInsecureDomain("*");

            this.InvokeWhenStageIsReady(
                () =>
                {

                    var deal = KnownEmbeddedResources.Default[Sounds.Assets.deal];
                    var click = KnownEmbeddedResources.Default[Sounds.Assets.click];
                    var drag = KnownEmbeddedResources.Default[Sounds.Assets.drag];
                    var win = KnownEmbeddedResources.Default[Sounds.Assets.win];

                    content.Sounds.deal = () => deal.ToSoundAsset().play();
                    content.Sounds.click = () => click.ToSoundAsset().play();
                    content.Sounds.drag = () => drag.ToSoundAsset().play();
                    content.Sounds.win = () => win.ToSoundAsset().play();

                    content.AttachToContainer(this);
                    content.AutoSizeTo(this.stage);

                    if (Security.sandboxType == "application")
                    {
                        // AdMob!
                        // mochiAds wont work on Android!
                    }
                    else
                    {

                        var shadow = new Rectangle();

                        shadow.Fill = Brushes.Black;
                        shadow.Width = this.stage.stageWidth;
                        shadow.Height = this.stage.stageHeight;
                        shadow.Opacity = 0.5;

                        content.Children.Add(shadow);

                        var clip = new MovieClip().AttachTo(this);




                        //dynamic options = new object();

                        //options.clip = this;
                        //options.id = "47e72426ba7f4f3f";
                        //options.res = this.stage.stageWidth + "x" + this.stage.stageHeight;
                        //options.ad_finished = a;

                        // Error: MochiAd is missing the 'clip' parameter.  
                        // This should be a MovieClip, Sprite or an instance of a class that extends MovieClip or Sprite.

                        // https://www.mochimedia.com/community/forum/topic/desktop-air-application#46785de6

                        //                SecurityError: Error #2047: Security sandbox violation: parent: http://xs.mochiads.com/container/MochiAdsCDN-AS3.swf?do_init=1&cacheBust=1359132511880 cannot access app:/AvalonCardGames.AIRFreeCell.ApplicationSprite.swf.
                        //at flash.display::DisplayObject/get parent()
                        //at com.mochimedia.targeting::MochiAdsTargeting/removedFromStage()[/home/mochi/src/mochiads_erl/priv/as3/com/mochimedia/targeting/MochiAdsTargeting.as:128]
                        //at flash.display::DisplayObjectContainer/removeChildAt()
                        //at mochi.as3::MochiAd$/_cleanup()[W:\opensource\mochimedia.com\MochiAd.as:946]
                        //at Function/<anonymous>()[W:\opensource\mochimedia.com\MochiAd.as:195]
                        //at mochi.as3::MochiAd$/unload()[W:\opensource\mochimedia.com\MochiAd.as:924]
                        //at Function/<anonymous>()[W:\opensource\mochimedia.com\MochiAd.as:275]
                        //at Function/<anonymous>()[W:\opensource\mochimedia.com\MochiAd.as:41]


                        //                SecurityError: Error #2047: Security sandbox violation: parent: http://xs.mochiads.com/container/MochiAdsCDN-AS3.swf?do_init=1&cacheBust=1359134133659 cannot access app:/AvalonCardGames.AIRFreeCell.ApplicationSprite.swf.
                        //at flash.display::DisplayObject/get parent()
                        //at com.mochimedia.targeting::MochiAdsTargeting/removedFromStage()[/home/mochi/src/mochiads_erl/priv/as3/com/mochimedia/targeting/MochiAdsTargeting.as:128]
                        //at flash.display::DisplayObjectContainer/removeChildAt()
                        //at mochi.as3::MochiAd$/_cleanup()
                        //at MethodInfo-1806()
                        //at mochi.as3::MochiAd$/unload()
                        //at MethodInfo-1807()
                        //at MethodInfo-1793()

                        //    SecurityError: Error #2047: Security sandbox violation: parent: http://xs.mochiads.com/container/MochiAdsCDN-AS3.swf?do_init=1&cacheBust=1359134133659 cannot access app:/AvalonCardGames.AIRFreeCell.ApplicationSprite.swf.
                        //at flash.display::DisplayObject/get parent()
                        //at com.mochimedia.container::MochiAdsContainer/initalize()[/home/mochi/src/mochiads_erl/priv/as3/com/mochimedia/container/MochiAdsContainer.as:40]
                        //at com.mochimedia.targeting::MochiAdsTargeting/onJSONData()[/home/mochi/src/mochiads_erl/priv/as3/com/mochimedia/targeting/MochiAdsTargeting.as:780]
                        //at flash.events::EventDispatcher/dispatchEventFunction()
                        //at flash.events::EventDispatcher/dispatchEvent()
                        //at flash.net::URLLoader/onComplete()



                        var options = new MochiAdOptions
                        {

                            //TypeError: Error #1034: Type Coercion failed: cannot convert AvalonCardGames.AIRFreeCell::ApplicationSprite@14b37041 to flash.display.MovieClip.
                            //    at mochi.as3::MochiAd$/load()[W:\opensource\mochimedia.com\MochiAd.as:789]
                            //    at mochi.as3::MochiAd$/showPreGameAd()[W:\opensource\mochimedia.com\MochiAd.as:185]
                            //    at AvalonCardGames.AIRFreeCell::MochiAdOptions/showPreGameAd_100664136()[U:\web\AvalonCardGames\AIRFreeCell\MochiAdOptions.as:74]
                            //    at AvalonCardGames.AIRFreeCell::ApplicationSprite/__ctor_b__1_100663300()[U:\web\AvalonCardGames\AIRFreeCell\ApplicationSprite.as:82]

                            clip = clip,
                            id = _mochiads_game_id,
                            res = this.stage.stageWidth + "x" + this.stage.stageHeight,


                            ad_finished =
                             delegate
                             {
                                 this.removeChild(clip);

                                 shadow.Orphanize();

                                 {
                                     var now = DateTime.Now;
                                     Console.WriteLine(now + " ready! " + new { Security.sandboxType });
                                 }
                             }
                        };

                        {
                            var now = DateTime.Now;
                            Console.WriteLine(now + " can we get some ads? " + new { Security.sandboxType });
                        }
                        options.showPreGameAd();
                    }
                }
            );


            #region AtInitializeConsoleFormWriter

            var w = new __OutWriter();
            var o = Console.Out;
            var __reentry = false;

            var __buffer = new StringBuilder();

            w.AtWrite =
                x =>
                {
                    __buffer.Append(x);
                };

            w.AtWriteLine =
                x =>
                {
                    __buffer.AppendLine(x);
                };

            Console.SetOut(w);

            this.AtInitializeConsoleFormWriter = (
                Action<string> Console_Write,
                Action<string> Console_WriteLine
            ) =>
            {

                try
                {


                    w.AtWrite =
                        x =>
                        {
                            o.Write(x);

                            if (!__reentry)
                            {
                                __reentry = true;
                                Console_Write(x);
                                __reentry = false;
                            }
                        };

                    w.AtWriteLine =
                        x =>
                        {
                            o.WriteLine(x);

                            if (!__reentry)
                            {
                                __reentry = true;
                                Console_WriteLine(x);
                                __reentry = false;
                            }
                        };

                    Console.WriteLine("flash Console.WriteLine should now appear in JavaScript form!");
                    Console.WriteLine(__buffer.ToString());
                }
                catch
                {

                }
            };
            #endregion

        }
		private BitmapImage ApplyFrame(int imagenum)
		{
			if (ApplyFrameCache.ContainsKey(imagenum))
				return ApplyFrameCache[imagenum];

			var nw = DefaultWidth / 36;

			var n = new Rectangle
			{
				Width = nw,
				Height = nw / 2,
				Fill = Brushes.Blue
			}.MoveTo(nw * imagenum, DefaultHeight - nw / 2).AttachTo(this);

			var src_uri = new BitmapImage();
			ApplyFrameCache[imagenum] = src_uri;
			src_uri.DownloadCompleted +=
				delegate
				{
					//bg.Fill = Color_Active();

					500.AtDelay(
						delegate
						{
							n.Orphanize();
						}
					);
				};

			src_uri.DownloadFailed +=
				delegate
				{
					n.Fill = Brushes.Red;

					//bg.Fill = Color_Error();
				};

			src_uri.BeginInit();
			src_uri.UriSource = new Sketchup { mid = Current.mid, imagenum = imagenum };
			src_uri.EndInit();

			return src_uri;
		}
        public ImageCarouselCanvas(Arguments args)
        {
            this.CloseOnClick = true;

            this.Container = new Canvas
            {
                Width = DefaultWidth,
                Height = DefaultHeight
            };

            //var r = new Rectangle
            //{
            //    Fill = Brushes.Red,
            //    Opacity = 0.05
            //};

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

            //this.Container.Background = Brushes.Transparent;
            //this.Container.Background = Brushes.Red;

            var y = 0;

            var s = new Stopwatch();

            s.Start();

            var images = new List<XImage>();

            #region AddImages
            Func<Image, XImage> Add =
                i =>
                {
                    y += 32;

                    var n = new XImage
                    {
                        Image = i,
                        Opacity = 0,
                        Radius = 72
                    };


                    RenderOptions.SetBitmapScalingMode(i, BitmapScalingMode.Fant);
                    images.Add(n);
                    i.Opacity = 0;
                    i.AttachTo(this);

                    return n;
                };

            args.AddImages(Add);
            #endregion



            var size = 64;



            Action<DispatcherTimer> AtAnimation = delegate { };

            // .net is fast, but js will be slow :)

            var randomphase = Math.PI * 2 * new Random().NextDouble();

            #region AtIntervalWithTimer
            var AnimationTimer = (1000 / 50).AtIntervalWithTimer(
                t =>
                {
                    var ms = s.ElapsedMilliseconds;


                    var i = 0;

                    AtAnimation(t);

                    // using for each must be the last thing in a method 
                    // because .leave operator currently cannot be understood by jsc

                    foreach (var item_ in images)
                    {
                        var item = item_.Image;
                        var phase = Math.PI * 2 * i / images.Count + randomphase;


                        var cos = Math.Cos(step * ms + phase);
                        var sin = Math.Sin(step * ms + phase);

                        var z1margin = 0.7;
                        var z1 = (cos + (1 + z1margin)) / (2 + z1margin);

                        var z2margin = 1.0;
                        var z2 = (cos + (1 + z2margin)) / (2 + z2margin);


                        item.Opacity = z1 * item_.Opacity;
                        item.SizeTo(size * z2, size * z2);
                        item.MoveTo(
                            -sin * item_.Radius

                            + (DefaultWidth + args.ImageDefaultWidth * 0.3) / 2
                            //+ jsc.ImageDefaultWidth 

                            + cos * item_.Radius
                            - size * z2 * 0.5

                            ,
                            sin * item_.Radius

                            + (DefaultHeight + args.ImageDefaultHeight * 0.3) / 2
                            //+ jsc.ImageDefaultHeight

                            - size * z2 * 0.5

                        );

                        Canvas.SetZIndex(item, Convert.ToInt32(z1 * 1000));
                        i++;
                    }

                }
            );
            #endregion

            var logo = args.CreateCenterImage();


            #region WaitAndAppear
            Action<int, double, Action<double>> WaitAndAppear =
                (delay, step__, set_Opacity) =>
                {
                    var a = 0.0;

                    set_Opacity(a);

                    delay.AtDelay(
                        delegate
                        {


                            (1000 / 30).AtIntervalWithTimer(
                                t =>
                                {
                                    a += step__;

                                    if (a > 1)
                                    {
                                        set_Opacity(1);

                                        t.Stop();
                                        return;
                                    }
                                    set_Opacity(a);
                                }
                            );
                        }
                    );
                };
            #endregion


            WaitAndAppear(200, 0.07, n => logo.Opacity = n);
            SattelitesHidden = false;

            ShowSattelites(images, WaitAndAppear);

            ShowSattelitesAgain =
                delegate
                {
                    if (!SattelitesHidden)
                        return;

                    SattelitesHidden = false;

                    if (AtSattelitesShownAgain != null)
                        AtSattelitesShownAgain();

                    foreach (var item__ in images.ToArray())
                    {
                        var item = item__;

                        WaitAndAppear(0, StepSpeedToToggleSattelites, n => item.Opacity = n);
                    }

                };

            Canvas.SetZIndex(logo, 500);

            logo.AttachTo(this).MoveTo(
                (DefaultWidth - args.ImageDefaultWidth) / 2,
                (DefaultHeight - args.ImageDefaultHeight) / 2
            );

            var logo_hit = new Rectangle
            {
                Fill = Brushes.Red,
                Opacity = 0
            };

            Canvas.SetZIndex(logo_hit, 501);

            logo_hit.Cursor = Cursors.Hand;
            logo_hit.AttachTo(this).MoveTo(
                (DefaultWidth - args.ImageDefaultWidth) / 2,
                (DefaultHeight - args.ImageDefaultHeight) / 2
            );
            logo_hit.SizeTo(args.ImageDefaultWidth, args.ImageDefaultHeight);

            #region MouseLeftButtonUp
            logo_hit.MouseLeftButtonUp +=
                delegate
                {
                    if (AtLogoClick != null)
                        AtLogoClick();
                    //new Uri("http://www.jsc-solutions.net").NavigateTo(this.Container);

                    if (CloseOnClick)
                    {
                        Close();
                        logo_hit.Orphanize();
                    }
                };
            #endregion

            #region HideSattelites
            this.HideSattelites =
                delegate
                {
                    SattelitesHidden = true;

                    Action TriggerClose = () => AtAnimation =
                        t =>
                        {
                            if (images.Any(k => k.Opacity > 0))
                                return;

                            t.Stop();

                            if (AtClose != null)
                                AtClose();
                        };


                    AtAnimation =
                        t =>
                        {
                            if (images.Any(k => k.Opacity < 1))
                                return;

                            foreach (var item__ in images.ToArray())
                            {
                                var item = item__;

                                var NextDelay = 1;

                                if (!DisableTimerShutdown)
                                    NextDelay = 1 + 1000.Random();

                                WaitAndAppear(NextDelay, StepSpeedToToggleSattelites, n => item.Opacity = 1 - n);
                            }

                            if (DisableTimerShutdown)
                            {
                                AtAnimation = delegate { };
                            }
                            else
                                TriggerClose();
                        };


                };
            #endregion


            this.Close =
                delegate
                {
                    WaitAndAppear(1, 0.12, n => logo.Opacity = 1 - n);

                    HideSattelites();
                };
        }
		public void Step5_ShowMistakeMatrix(
			AeroNavigationBar.HistoryInfo History,
			LinkImage[] Source,
			ComparisionInfo[] Comparision,
			ComparisionValue[] Values)
		{
			History.AddFrame(
				delegate
				{
					var More = Comparision.Count(k => k.WaitingForUser && k.Value == null);



					#region headers
					var o = Source.Select<LinkImage, Action>(
						(k, i) =>
						{
							k.SizeTo(0.15);
							k.AttachContainerTo(this);
							k.MoveContainerTo(60, 150 + i * 60);

							var kx = new TextButtonControl
							{
								Text = "#" + (1 + i),
								Width = 40,
								Height = 32
							};

							kx.AttachContainerTo(this);
							kx.MoveContainerTo(130, 160 + i * 60);
							kx.Background.Fill = Brushes.White;
							kx.Background.Opacity = 0.3;

							var ky = new TextButtonControl
							{
								Text = "#" + (1 + i),
								Width = 40,
								Height = 32
							};

							ky.AttachContainerTo(this);
							ky.MoveContainerTo(200 + i * 60, 100);
							ky.Background.Fill = Brushes.White;
							ky.Background.Opacity = 0.3;

							var kxr = new Rectangle
							{
								Fill = Brushes.Black,
								Width = Source.Length * 60 + 140,
								Height = 1
							};

							kxr.AttachTo(this);
							kxr.MoveTo(60, 200 + i * 60);


							var kyr = new Rectangle
							{
								Fill = Brushes.Black,
								Height = Source.Length * 60 + 60,
								Width = 1
							};

							kyr.AttachTo(this);
							kyr.MoveTo(250 + i * 60, 100);

							return delegate
							{
								k.OrphanizeContainer();
								kx.OrphanizeContainer();
								ky.OrphanizeContainer();
								kxr.Orphanize();
								kyr.Orphanize();
							};
						}
					).ToArray();
					#endregion

					#region values

					var Mistakes = Comparision.Where(q => q.WaitingForUser).ToArray(
						q =>
						{

							var x_cells =
								Comparision.Where(k => k.X == q.Y).OrderBy(k => k.Y).ToArray();

							var x_product =
								x_cells.Product(k => k.GetCurrentValue());

							var y_cells =
								Comparision.Where(k => k.Y == q.X).OrderBy(k => k.X).ToArray();

							var y_product =
								y_cells.Product(k => k.GetCurrentValue());


							var z = Math.Pow(q.GetCurrentValue(), Source.Length);

							return new { q, Mistake = 1.0 / Math.Pow(x_product * y_product * z, 1.0 / (Source.Length - 2)) };

							/* 

							 1/POWER(PRODUCT(R4C2:R9C2)*PRODUCT(R9C2:R9C7)*POWER(R[-46]C;veerge);1/(veerge-2))
							 1/POWER(x_product*y_product*POWER(R[-46]C;veerge);1/(veerge-2))
							 1/POWER(x_product*y_product*z;1/(veerge-2))

							 */
						}
					).OrderBy(
						ContextMistakes =>
						{
							var Mistakes_Max = ContextMistakes.Max(k => k.Mistake);
							var Mistakes_Min = ContextMistakes.Min(k => k.Mistake);

							var Mistake_Value = Mistakes_Min;

							if (Mistakes_Max * Mistakes_Min > 1.0)
								Mistake_Value = Mistakes_Max;

							return ContextMistakes.First(k => k.Mistake == Mistake_Value);
						}
					).ToArray();

					var Gradient = Colors.Red.ToGradient(Colors.Blue, Mistakes.Length).ToArray();



					Title.Text = "Biggest mistake was made at " + Mistakes.First().q.ToVersusString() + ". Click on a cell to recompare.";


					var v = Mistakes.Select(
						(k, k_index) =>
						{
							var kt = new TextButtonControl
							{
								Text = "",
								Width = 60 - 4,
								Height = 32
							};

							kt.AttachContainerTo(this);
							kt.MoveContainerTo(192 + k.q.X * 60, 160 + k.q.Y * 60);

							kt.Background.Fill = new SolidColorBrush(Gradient[k_index]);


							kt.Text = k.Mistake.ToString();

							kt.Click +=
								delegate
								{
									var NewComparision = Comparision.ToArray(
										oo =>
										{
											var n = new ComparisionInfo
											{
												WaitingForUser = oo.WaitingForUser,
												Value = oo.Value,
												X = oo.X,
												Y = oo.Y
											};

											if (oo == k.q)
											{
												n.Value = null;
											}



											return n;
										}
									);


									Step3_Compare(History, Source, NewComparision, Values);
								};

							return new Action(
								delegate
								{
									kt.OrphanizeContainer();
								}
							);
						}
					).ToArray();

					#endregion

					return delegate
					{
						this.Title.Text = "...";

						o.ForEach(h => h());
						v.ForEach(h => h());
					};
				}
			);
		}
		public void Step4_ShowMatrix(
			AeroNavigationBar.HistoryInfo History,
			LinkImage[] Source,
			ComparisionInfo[] Comparision,
			ComparisionValue[] Values)
		{
			History.AddFrame(
				delegate
				{
					var More = Comparision.Count(k => k.WaitingForUser && k.Value == null);

					this.Title.Text = "The Matrix. You have " + More + " image pairs to compare...";

					#region headers
					var o = Source.Select<LinkImage, Action>(
						(k, i) =>
						{
							k.SizeTo(0.15);
							k.AttachContainerTo(this);
							k.MoveContainerTo(60, 150 + i * 60);

							var kx = new TextButtonControl
							{
								Text = "#" + (1 + i),
								Width = 40,
								Height = 32
							};

							kx.AttachContainerTo(this);
							kx.MoveContainerTo(130, 160 + i * 60);
							kx.Background.Fill = Brushes.White;
							kx.Background.Opacity = 0.3;

							var ky = new TextButtonControl
							{
								Text = "#" + (1 + i),
								Width = 40,
								Height = 32
							};

							ky.AttachContainerTo(this);
							ky.MoveContainerTo(200 + i * 60, 100);
							ky.Background.Fill = Brushes.White;
							ky.Background.Opacity = 0.3;

							var kxr = new Rectangle
							{
								Fill = Brushes.Black,
								Width = Source.Length * 60 + 140,
								Height = 1
							};

							kxr.AttachTo(this);
							kxr.MoveTo(60, 200 + i * 60);


							var kyr = new Rectangle
							{
								Fill = Brushes.Black,
								Height = Source.Length * 60 + 60,
								Width = 1
							};

							kyr.AttachTo(this);
							kyr.MoveTo(250 + i * 60, 100);

							return delegate
							{
								k.OrphanizeContainer();
								kx.OrphanizeContainer();
								ky.OrphanizeContainer();
								kxr.Orphanize();
								kyr.Orphanize();
							};
						}
					).ToArray();
					#endregion

					#region values

					var v = Comparision.Select<ComparisionInfo, Action>(
						k =>
						{
							var kt = new TextButtonControl
							{
								Text = "",
								Width = 40,
								Height = 32
							};

							kt.AttachContainerTo(this);
							kt.MoveContainerTo(200 + k.X * 60, 160 + k.Y * 60);

							kt.Background.Fill = Brushes.White;
							kt.Background.Opacity = 0.3;

							if (k.Value == null)
							{
								if (k.WaitingForUser)
								{
									kt.Background.Fill = Brushes.Yellow;
									kt.Background.Opacity = 0.5;
								}
							}
							else
							{
								kt.Text = k.Value.ToString();

								if (k.Value.Value == 1)
								{
									kt.Background.Fill = Brushes.Cyan;
									kt.Background.Opacity = 0.5;
								}
							}

							return delegate
							{
								kt.OrphanizeContainer();
							};
						}
					).ToArray();

					#endregion

					return delegate
					{
						this.Title.Text = "...";

						o.ForEach(h => h());
						v.ForEach(h => h());
					};
				}
			);
		}
            public void Apply(object Sender, OrcasAvalonApplicationCanvas World, Action<Action> AddDispose)
            {
                var Settings = new[] {
                    new {Brush = Brushes.Red, Opacity = 0.5 },
                    new {Brush = Brushes.Yellow, Opacity = 0.5 },
                    new {Brush = Brushes.Purple, Opacity = 0.2 },
                }.AtModulus(Z);

                var a = new Rectangle
                {
                    Width = 4,
                    Height = 8,
                    Fill = Settings.Brush,
                    Opacity = Settings.Opacity
                }.AttachTo(World).MoveTo(X + 2, Y);

                var b = new Rectangle
                {
                    Width = 8,
                    Height = 4,
                    Fill = Settings.Brush,
                    Opacity = Settings.Opacity
                }.AttachTo(World).MoveTo(X, Y + 2);

                AddDispose(() => a.Orphanize());
                AddDispose(() => b.Orphanize());

                if (Next != null)
                    Next.Apply(Sender, World, AddDispose);
            }
		public AvalonQueryExampleCanvas()
		{
			CheckIsPanel();

			Width = DefaultWidth;
			Height = DefaultHeight;

			#region Gradient
			for (int i = 0; i < DefaultHeight; i += 4)
			{
				new Rectangle
				{
					Fill = ((uint)(0xff00007F + Convert.ToInt32(128 * i / DefaultHeight))).ToSolidColorBrush(),
					Width = DefaultWidth,
					Height = 5,
				}.MoveTo(0, i).AttachTo(this);
			}
			#endregion

			new Image
			{
				Source = "assets/FlashAvalonQueryExample/labels.png".ToSource()
			}.MoveTo(0, 0).AttachTo(this);

			//var FaciconService = "http://www.google.com/s2/favicons?domain=";

			// http://www.google.com/s2/favicons?domain=wordpress.com
			var KnownDomains = "63/155262375_104aee1bb0, 3183/2825405970_a1469cd673, 2336/2454679206_de5176b827, 3178/2825551196_6548ff54b9";
			var KnownFilter = "31";

			Func<Brush> Color_Inactive = () => 0xffc0c0c0.ToSolidColorBrush();
			Func<Brush> Color_Active = () => 0xffffffff.ToSolidColorBrush();
			Func<Brush> Color_Error = () => 0xffffff80.ToSolidColorBrush();

			var KnownDomainsInputHeight = 100;

			var KnownDomainsInput = new TextBox
			{
				AcceptsReturn = true,
				FontSize = 15,
				Text = KnownDomains,
				BorderThickness = new Thickness(0),
				//Foreground = 0xffffffff.ToSolidColorBrush(),
				Background = Color_Inactive(),
				Width = 400,
				Height = KnownDomainsInputHeight,
				TextWrapping = TextWrapping.Wrap
			}.MoveTo(32, 32).AttachTo(this);

			KnownDomainsInput.Orphanize();
			KnownDomainsInput.AttachTo(this);

			Action<TextBox> ApplyActiveColor =
				e =>
				{
					e.GotFocus +=
						delegate
						{
							e.Background = Color_Active();
						};


					e.LostFocus +=
						delegate
						{
							e.Background = Color_Inactive();
						};
				};

			ApplyActiveColor(KnownDomainsInput);

			var FilterInputHeight = 22;

			var FilterInput = new TextBox
			{
				FontSize = 15,
				Text = KnownFilter,
				BorderThickness = new Thickness(0),
				//Foreground = 0xffffffff.ToSolidColorBrush(),
				Background = Color_Inactive(),
				Width = 400,
				Height = FilterInputHeight,
			}.MoveTo(32, 32 + KnownDomainsInputHeight + 4).AttachTo(this);

			ApplyActiveColor(FilterInput);


			var AnyInputChangedBefore = new List<Action>();

			Action AnyInputChanged =
				delegate
				{
					AnyInputChangedBefore.Do();
					AnyInputChangedBefore.Clear();

					var query = from k in KnownDomainsInput.Text.Split(',')
								let t = k.Trim()
								where t.Contains(FilterInput.Text)
								orderby t
								select t;


					query.ForEach(
						(k, i) =>
						{
							// http://static.flickr.com/63/155262375_104aee1bb0.jpg
							var src = "http://static.flickr.com/" + k + "_s.jpg";

							var y = 32 + KnownDomainsInputHeight + 4 + FilterInputHeight + 4 + i * 80;

							var bg = new Rectangle
							{
								Fill = Color_Inactive(),
								Width = 400,
								Height = 26

							}
							.MoveTo(32, y + 20).AttachTo(this);

							var img_shadow = new Rectangle
							{
								Fill = 0xff000000.ToSolidColorBrush(),
								Opacity = 0.3,
								Width = 75,
								Height = 75
							}
							.MoveTo(32 + 2 + 3, y + 2 + 3).AttachTo(this);

							var img = new Image
							{
								Width = 75,
								Height = 75
							}
							.MoveTo(32 + 2, y + 2).AttachTo(this);


							var text = new TextBox
							{
								IsReadOnly = true,
								Text = (i + 1) + ". " + src,
								Width = 400 - 88,
								Height = 20,
								BorderThickness = new Thickness(0),
								Foreground = 0xff0000ff.ToSolidColorBrush(),
								Background = 0xffffffff.ToSolidColorBrush()
							}.MoveTo(32 + 84, y + 22).AttachTo(this);




							var src_uri = new BitmapImage();

							src_uri.DownloadCompleted +=
								delegate
								{
									text.Foreground = 0xff000000.ToSolidColorBrush();
									//bg.Fill = Color_Active();
								};

							src_uri.DownloadFailed +=
								delegate
								{
									text.Text += " failed...";
									text.Foreground = 0xffff0000.ToSolidColorBrush();
									//bg.Fill = Color_Error();
								};

							src_uri.BeginInit();
                            Console.WriteLine(src);
							src_uri.UriSource = new Uri(src);
							src_uri.EndInit();


							img.Source = src_uri;

							text.Background = Color_Inactive();
							bg.Opacity = 0.3;

							text.GotFocus +=
								delegate
								{
									text.Background = Color_Active();
									bg.Opacity = 1;
								};

							text.LostFocus +=
								delegate
								{
									text.Background = Color_Inactive();
									bg.Opacity = 0.3;
								};

							AnyInputChangedBefore.Add(
								delegate
								{
									bg.Orphanize();
									img.Orphanize();
									text.Orphanize();
									img_shadow.Orphanize();
								}
							);

							//ResultOutput.AppendTextLine((i + 1) + ". " + k + " " + src);
						}
					);
					// we need to validate CNAMEs



				};

			#region attach AnyInputChanged
			KnownDomainsInput.TextChanged +=
				delegate
				{
					AnyInputChanged();
				};

			FilterInput.TextChanged +=
				delegate
				{
					AnyInputChanged();
				};

			AnyInputChanged();

			#endregion

		}