public RedNumberDisplay(int Digits, int value, Assets MyAssets)
        {
            this.MyAssets = MyAssets;
            this.Digits = Digits;

            this.Control.style.SetSize(Width, Height);
            this.Control.style.backgroundColor = Color.Black;
            this.Control.style.position = IStyle.PositionEnum.relative;

            DigitControls = Enumerable.Range(0, Digits).Select(
                i =>
                {
                    var d = new IHTMLDiv();

                    d.style.SetLocation(i * DigitX, 0, DigitX, DigitY);
                    d.style.SetBackground(MyAssets.red_numbers[0]);

                    d.AttachTo(this.Control);

                    return d;
                }
                ).ToArray();


            this.Value = value;
        }
        public MineSweeperControl(int ButtonsX, int ButtonsY, double Mines, Assets MyAssets)
        {
            var sndclick = new click();
            var sndflag = new flag();
            var sndexplosion = new explosion();


            this.MyAssets = MyAssets;
            this.Alive = true;
            this.Mines = Mines;

            if (this.Mines > 0.8)
                this.Mines = 0.8;

            this.ButtonsX = ButtonsX;
            this.ButtonsY = ButtonsY;

            Control.style.backgroundColor = Color.Gray;
            Control.style.SetSize(Width, Height);
            Control.style.position = IStyle.PositionEnum.relative;

            for (int x = 0; x < ButtonsX; x++)
                for (int y = 0; y < ButtonsY; y++)
                {
                    var btn = new MineButton().AddTo(Buttons);

                    btn.MouseDownChanged +=
                        v =>
                        {
                            if (!Alive)
                                return;

                            if (v)
                            {
                                if (LookingForMines != null)
                                    LookingForMines();
                            }
                            else
                            {
                                if (DoneLookingForMines != null)
                                    DoneLookingForMines();
                            }


                        };

                    btn.Source = MyAssets.button;
                    btn.MouseDownSource = MyAssets.empty;

                    btn.Control.AttachTo(Control);
                    btn.MoveTo(x, y);

                    var NearbyButtons =
                               from i in Buttons
                               where i.IsNearTo(btn)
                               select i;

                    var NearbyMines =
                                from i in NearbyButtons
                                where i.IsMined
                                select i;

                    var NearbyFlags =
                               from i in NearbyButtons
                               where i.Source == MyAssets.flag
                               select i;

                    var NearbyNonFlags =
                               from i in NearbyButtons
                               where i.Source != MyAssets.flag
                               select i;

                    var IdleButtons =
                        from i in Buttons
                        where i.Source != MyAssets.flag
                        where !MyAssets.numbers.Contains(i.Source)
                        select i;

                    Action Resolve =
                        delegate
                        {
                            foreach (var v in NearbyNonFlags)
                            {
                                v.RaiseClick();
                            }
                        };


                    btn.ContextClick +=
                        delegate
                        {
                            sndflag.play();
                            sndflag = new flag();

                            if (MyAssets.numbers.Contains(btn.Source))
                            {
                                if (NearbyMines.Count() == NearbyFlags.Count())
                                {
                                    Resolve();

                                    CheckIdle(IdleButtons);
                                }

                                return;
                            }

                            if (btn.Source == MyAssets.button)
                                btn.Source = MyAssets.flag;
                            else
                                if (btn.Source == MyAssets.flag)
                                    btn.Source = MyAssets.question;
                                else
                                    if (btn.Source == MyAssets.question)
                                        btn.Source = MyAssets.button;

                            if (MinesFoundChanged != null)
                                MinesFoundChanged();

                            CheckIdle(IdleButtons);
                        };

                    //sndclick.load();

                    btn.Click +=
                        delegate
                        {
                            btn.Enabled = false;


                            sndclick.play();
                            sndclick = new click();

                            //sndclick.load();

                            if (btn.IsMined)
                            {
                                // end of game

                                foreach (var v in from i in Buttons
                                                  where !i.IsMined
                                                  where i.Source == MyAssets.flag
                                                  select i)
                                {
                                    v.Source = MyAssets.notmine;
                                }

                                foreach (var v in from i in Buttons
                                                  where i.IsMined
                                                  where i != btn
                                                  select i)
                                {
                                    v.Source = MyAssets.mine;
                                }

                                btn.Source = MyAssets.mine_found;

                                DisableButtons();

                                Alive = false;

                                sndexplosion.play();
                                sndexplosion = new explosion();

                                if (Bang != null)
                                    Bang();
                            }
                            else
                            {
                                // how many mines are near me?

                                var MineCount = NearbyMines.Count();

                                btn.Source = MyAssets.numbers[MineCount];

                                if (MineCount == 0)
                                {
                                    Resolve();

                                    CheckIdle(IdleButtons);

                                }

                            }


                        };
                }

            AttachMinesToButtons();
        }
        public MineSweeperControl(int ButtonsX, int ButtonsY, double Mines, Assets MyAssets)
        {
            var sndclick     = new click();
            var sndflag      = new flag();
            var sndexplosion = new explosion();


            this.MyAssets = MyAssets;
            this.Alive    = true;
            this.Mines    = Mines;

            if (this.Mines > 0.8)
            {
                this.Mines = 0.8;
            }

            this.ButtonsX = ButtonsX;
            this.ButtonsY = ButtonsY;

            Control.style.backgroundColor = Color.Gray;
            Control.style.SetSize(Width, Height);
            Control.style.position = IStyle.PositionEnum.relative;

            for (int x = 0; x < ButtonsX; x++)
            {
                for (int y = 0; y < ButtonsY; y++)
                {
                    var btn = new MineButton().AddTo(Buttons);

                    btn.MouseDownChanged +=
                        v =>
                    {
                        if (!Alive)
                        {
                            return;
                        }

                        if (v)
                        {
                            if (LookingForMines != null)
                            {
                                LookingForMines();
                            }
                        }
                        else
                        {
                            if (DoneLookingForMines != null)
                            {
                                DoneLookingForMines();
                            }
                        }
                    };

                    btn.Source          = MyAssets.button;
                    btn.MouseDownSource = MyAssets.empty;

                    btn.Control.AttachTo(Control);
                    btn.MoveTo(x, y);

                    var NearbyButtons =
                        from i in Buttons
                        where i.IsNearTo(btn)
                        select i;

                    var NearbyMines =
                        from i in NearbyButtons
                        where i.IsMined
                        select i;

                    var NearbyFlags =
                        from i in NearbyButtons
                        where i.Source == MyAssets.flag
                        select i;

                    var NearbyNonFlags =
                        from i in NearbyButtons
                        where i.Source != MyAssets.flag
                        select i;

                    var IdleButtons =
                        from i in Buttons
                        where i.Source != MyAssets.flag
                        where !MyAssets.numbers.Contains(i.Source)
                        select i;

                    Action Resolve =
                        delegate
                    {
                        foreach (var v in NearbyNonFlags)
                        {
                            v.RaiseClick();
                        }
                    };


                    btn.ContextClick +=
                        delegate
                    {
                        sndflag.play();
                        sndflag = new flag();

                        if (MyAssets.numbers.Contains(btn.Source))
                        {
                            if (NearbyMines.Count() == NearbyFlags.Count())
                            {
                                Resolve();

                                CheckIdle(IdleButtons);
                            }

                            return;
                        }

                        if (btn.Source == MyAssets.button)
                        {
                            btn.Source = MyAssets.flag;
                        }
                        else
                        if (btn.Source == MyAssets.flag)
                        {
                            btn.Source = MyAssets.question;
                        }
                        else
                        if (btn.Source == MyAssets.question)
                        {
                            btn.Source = MyAssets.button;
                        }

                        if (MinesFoundChanged != null)
                        {
                            MinesFoundChanged();
                        }

                        CheckIdle(IdleButtons);
                    };

                    //sndclick.load();

                    btn.Click +=
                        delegate
                    {
                        btn.Enabled = false;


                        sndclick.play();
                        sndclick = new click();

                        //sndclick.load();

                        if (btn.IsMined)
                        {
                            // end of game

                            foreach (var v in from i in Buttons
                                     where !i.IsMined
                                     where i.Source == MyAssets.flag
                                     select i)
                            {
                                v.Source = MyAssets.notmine;
                            }

                            foreach (var v in from i in Buttons
                                     where i.IsMined
                                     where i != btn
                                     select i)
                            {
                                v.Source = MyAssets.mine;
                            }

                            btn.Source = MyAssets.mine_found;

                            DisableButtons();

                            Alive = false;

                            sndexplosion.play();
                            sndexplosion = new explosion();

                            if (Bang != null)
                            {
                                Bang();
                            }
                        }
                        else
                        {
                            // how many mines are near me?

                            var MineCount = NearbyMines.Count();

                            btn.Source = MyAssets.numbers[MineCount];

                            if (MineCount == 0)
                            {
                                Resolve();

                                CheckIdle(IdleButtons);
                            }
                        }
                    };
                }
            }

            AttachMinesToButtons();
        }
        public MineSweeperPanel(int ButtonsX = 15, int ButtonsY = 16, double Mines = 0.2, Assets MyAssets = null)
        {
            if (MyAssets == null)
                MyAssets = Assets.Default;

            Control.style.position = IStyle.PositionEnum.relative;
            Control.style.backgroundColor = Color.FromGray(192);

            MineField = new MineSweeperControl(ButtonsX, ButtonsY, Mines, MyAssets);

            ControlWidth = MineField.Width + 20;
            ControlHeight = MineField.Height + 50;
            Control.style.SetSize(ControlWidth, ControlHeight);

            MineField.Control.AttachTo(Control).style.SetLocation(10, 40);


            var face = new Button(FaceSize, FaceSize);

            face.Source = MyAssets.face_ok;
            face.MouseDownSource = MyAssets.face_ok_down;

            var timer = new RedNumberDisplay(3, 0, MyAssets);


            var actualtimer = new Timer(
                t =>
                {
                    timer.Value = t.Counter;
                }
            );

            MineField.Bang += () =>
            {
                face.Source = MyAssets.face_dead;
                actualtimer.Stop();
            };

            MineField.LookingForMines += () => face.Source = MyAssets.face_scared;
            MineField.DoneLookingForMines += () => face.Source = MyAssets.face_ok;



            face.Click +=
                () =>
                {
                    face.Source = MyAssets.face_ok;

                    actualtimer.Stop();
                    timer.Value = 0;

                    MineField.Reset();
                };

            MineField.AllMinesFound +=
                delegate
                {


                    face.Source = MyAssets.face_cool;
                    actualtimer.Stop();

                    MineField.Alive = false;
                    MineField.DisableButtons();
                };

            face.Control.AttachTo(Control);
            face.Control.style.SetLocation(10 + (MineField.Width - FaceSize) / 2, 6);


            var minecounter = new RedNumberDisplay(3, MineField.MinesTotal, MyAssets);

            minecounter.Control.AttachTo(Control);
            minecounter.Control.style.SetLocation(10, 6);

            timer.Control.AttachTo(Control);
            timer.Control.style.SetLocation(10 + MineField.Width - timer.Width, 6);

            MineField.MinesFoundChanged += () => minecounter.Value = MineField.MinesTotal - MineField.MinesFound;

            MineField.Control.style.border = "1px inset gray";
            minecounter.Control.style.border = "1px inset gray";
            timer.Control.style.border = "1px inset gray";
            this.Control.style.border = "1px outset gray";


            MineField.DoneLookingForMines += () =>
                {
                    if (!actualtimer.IsAlive)
                        actualtimer.StartInterval(1000);
                };

        }