using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Math3;
using System.Windows.Forms;
using Wordinator;
using System.Security.Cryptography;
using SpriteEditor_2017;


namespace Bombing_Math
{

    public class formFlash : PerPixelForm.PerPixelAlphaForm
    {
        public static formFlash instance = null;
        public static classEventController.classEventTicket cEventTicket_Animate = null;
        static TextBox txtInput = new TextBox();
        static Random rnd = new Random();

        static public classSprite cSprite_Bomb = null;
        static public classSpriteData cSpriteDate_Bomb = null;


        public formFlash()
        {
            instance = this;
            Size szBomb = new Size(632, 682);// measured from source file 
            ptBombLocation = new Point((sz.Width - szBomb.Width) / 2,
                                       sz.Height - szBomb.Height);
            ptFuse_Base = new Point(ptBombLocation.X + ptFuse_Base_Pic.X,
                                    ptBombLocation.Y + ptFuse_Base_Pic.Y);
            int intGap = 25;
            ptFuse_Tip_Start = new Point(sz.Width - intGap,
                                         intGap);
            ptFuse_Tip = ptFuse_Tip_Start;

            Controls.Add(txtInput);
            txtInput.Top = sz.Height + 10;
            txtInput.KeyDown += TxtInput_KeyDown;
            txtInput.LostFocus += TxtInput_LostFocus;

            txtInput.Focus();
            cEventTicket_Animate = formBombingMath.cEC.Ticket("FlashAnimation", 100, tmrFlashAnimation_Tick);
            cEventTicket_Animate.AutoRepeat = true;

            new classSpriteMaker();
            string strBombSprite_Filename = System.IO.Directory.GetCurrentDirectory() + "\\Bomb.sp6";
            cSprite_Bomb = classSpriteMaker.instance.Load(strBombSprite_Filename);
            cSpriteDate_Bomb = new classSpriteData();
            cSpriteDate_Bomb.cAnimationData.cSprite = cSprite_Bomb;
            cSpriteDate_Bomb.cAnimationData.cAnimation = cSpriteDate_Bomb.cAnimationData.cSprite.lstAnimations[(int)enuBomb_Animations.Eyes_Center_Wink];
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_Shift_Sideways);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);
            lstBombAnimations.Add(enuBomb_Animations.eyes_Center_Blink);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);
            lstBombAnimations.Add(enuBomb_Animations.Eyes_up_to_Right);

            Activated += FormFlash_Activated;
        }

        static List<enuBomb_Animations> lstBombAnimations = new List<enuBomb_Animations>();


        private void TxtInput_LostFocus(object sender, EventArgs e)
        {
            txtInput.Focus();
        }

        bool bolActivated = false;
        private void FormFlash_Activated(object sender, EventArgs e)
        {
            if (bolActivated) return;
            //intFuseStep = intNumFuseSteps / 2;
            bolActivated = true;
        }

        private void TxtInput_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    {
                        quit();
                    }
                    break;

                default:
                    {

                    }
                    break;
            }
        }

        static Color clrTransparent = Color.Pink;
        static Brush brTransparent = Brushes.Pink;
        static void tmrFlashAnimation_Tick(object sender, EventArgs e)
        {
            instance.Location = new Point(0, 0);

            intFuseStep++;
            if (intFuseStep >= intNumFuseSteps)
            {
                intTextStep++;
                if (intTextStep >=intNumTextSteps)
                {
                    quit();
                    return;
                }
            }

            Draw();
        }

        static void Draw()
        {
            Graphics g = Graphics.FromImage(bmpWorking);
            {
                g.FillRectangle(brTransparent, new Rectangle(0, 0, bmpWorking.Width, bmpWorking.Height));

                if (intFuseStep < intNumFuseSteps)
                {
                    Draw_Bomb(ref g);
                    //Draw_Text(ref g);
                    Draw_Fuse(ref g);
                    Draw_Sparks(ref g);
                }
                else
                {
                    Draw_Text(ref g);
                }
            }
            g.Dispose();

            bmpWorking.MakeTransparent(clrTransparent);
            instance.SetBitmap(bmpWorking);
            instance.Show();
            instance.BringToFront();
        }

        static void Draw_Bomb(ref Graphics g)
        {
            cSpriteDate_Bomb.cAnimationData.intFrameIndex += 1;
            if (cSpriteDate_Bomb.cAnimationData.intFrameIndex >= cSpriteDate_Bomb.cAnimationData.cAnimation.lstFrames.Count)
            {
                cSpriteDate_Bomb.cAnimationData.intFrameIndex = 0;
                cSpriteDate_Bomb.cAnimationData.cAnimation = cSpriteDate_Bomb.cAnimationData.cSprite.lstAnimations[(int)lstBombAnimations[0]];
                lstBombAnimations.RemoveAt(0);
            }


            cSpriteDate_Bomb.cAnimationData.dblDrawSizeFactor = 2f;

            List<Bitmap> lstBmpBomb = cSpriteDate_Bomb.Draw();
            g.DrawImage(lstBmpBomb[0], ptBombLocation);

            //g.DrawImage(bmpBomb, ptBombLocation);
        }

        static Pen _pFuse = new Pen(Brushes.Orange, 10);
        static Pen pFuse
        {
            get { return _pFuse; }  
        }

        static void Draw_Text(ref Graphics g)
        {

            float fltPCText = 1f;
            if (intTextStep < intNumTextSteps/2)
             fltPCText =  (float) (intTextStep + intNumTextSteps/2)/ (float)intNumTextSteps;
            

            Size szBombing = new Size((int)(bmpTextBombing.Width * fltPCText),
                                      (int)(bmpTextBombing.Height * fltPCText));
            Rectangle recBombingSource = new Rectangle(0,0,bmpTextBombing.Width,bmpTextBombing.Height);
            Rectangle recBombingDest = new Rectangle((bmpWorking.Width - szBombing.Width) / 2, (bmpWorking.Height / 2 - szBombing.Height), szBombing.Width, szBombing.Height);
            g.DrawImage(bmpTextBombing, recBombingDest, recBombingSource, GraphicsUnit.Pixel);

            
            Size szMath = new Size((int)(bmpTextMath.Width * fltPCText),
                                      (int)(bmpTextMath.Height * fltPCText));
            Rectangle recMathSource = new Rectangle(0,0,bmpTextMath.Width,bmpTextMath.Height);
            Rectangle recMathDest = new Rectangle((bmpWorking.Width - szMath.Width) / 2, (bmpWorking.Height / 2), szMath.Width, szMath.Height);
            g.DrawImage(bmpTextMath, recMathDest, recMathSource, GraphicsUnit.Pixel);



        }

        static void Draw_Fuse(ref Graphics g)
        {
            Rectangle recFuse = new Rectangle(ptFuse_Base.X, ptFuse_Tip_Start.Y, (ptFuse_Tip_Start.X - ptFuse_Base.X), ptFuse_Base.Y-ptFuse_Tip_Start.Y);

            Point ptInflectionPoint = new Point(ptFuse_Base.X + (ptFuse_Tip_Start.X - ptFuse_Base.X) / 2,
                                                ptFuse_Base.Y + (ptFuse_Tip_Start.Y - ptFuse_Base.Y) / 2);
            
            Rectangle recFuseVisible_Start = new Rectangle(ptInflectionPoint.X, ptFuse_Tip_Start.Y, recFuse.Right-ptInflectionPoint.X, ptInflectionPoint.Y- recFuse.Top);
            Rectangle recFuseVisible_End = new Rectangle(recFuse.Left, ptInflectionPoint.Y, recFuseVisible_Start.Width, recFuseVisible_Start.Height);

            
            /*
                int intInflexionSize = 5;
                g.DrawRectangle(Pens.Orange, recFuse);
                g.FillEllipse(Brushes.Blue, new Rectangle(ptInflectionPoint.X - intInflexionSize, ptInflectionPoint.Y - intInflexionSize, 2 * intInflexionSize, 2 * intInflexionSize));
                g.DrawRectangle(Pens.Blue, recFuseVisible_Start);
                g.DrawRectangle(Pens.Green, recFuseVisible_End);
            // */

            Rectangle recFuseEnd = new Rectangle(recFuseVisible_End.Location, new Size(recFuseVisible_End.Width * 2, recFuseVisible_End.Height * 2));
            Rectangle recFuseStart = new Rectangle(recFuse.Left, ptInflectionPoint.Y - recFuseEnd.Height, recFuseEnd.Width, recFuseEnd.Height);

            float fltPC_Burned = (float)( intNumFuseSteps - intFuseStep) / (float)intNumFuseSteps;

            if (fltPC_Burned >.5f)
            {                
                g.DrawArc(pFuse, recFuseEnd, 180, 90);
                float fltPCStart_Burned = (fltPC_Burned - .5f)/.5f;
                float fltArc_Start =90* (1f- fltPCStart_Burned);
                float fltArc_Sweep = (90 *  fltPCStart_Burned);
                g.DrawArc(pFuse, recFuseStart, fltArc_Start, fltArc_Sweep);

                Point ptRecStartCenter = new Point(recFuseStart.X + recFuseStart.Width/2, 
                                                   recFuseStart.Y + recFuseStart.Height/2);
                float fltRad = (float)(Math.PI / 180f * fltArc_Start);
                int intFuseX = ptRecStartCenter.X + (int)((recFuseStart.Width / 2) * Math.Cos(fltRad));
                int intFuseY = ptRecStartCenter.Y +  (int)((recFuseStart.Height/ 2) * Math.Sin (fltRad));                

                ptFuse_Tip = new Point(intFuseX, intFuseY);
            }
            else
            {
                float fltPCEnd_Burned = 1f - (fltPC_Burned) / .5f;
                float fltArc_Start = 180;
                float fltArc_Sweep = 90 - (90 * fltPCEnd_Burned);
                g.DrawArc(pFuse, recFuseEnd, fltArc_Start, fltArc_Sweep);

                Point ptRecEndCenter = new Point(recFuseEnd.X + recFuseEnd.Width / 2,
                                                 recFuseEnd.Y + recFuseEnd.Height / 2);
                float fltSparkAngle = fltArc_Start + fltArc_Sweep;

                float fltRad = (float)(Math.PI / 180f * (fltSparkAngle));
                int intFuseX = ptRecEndCenter.X + (int)((recFuseEnd.Width / 2) * Math.Cos(fltRad));
                int intFuseY = ptRecEndCenter.Y + (int)((recFuseEnd.Height / 2) * Math.Sin(fltRad));

                ptFuse_Tip = new Point(intFuseX, intFuseY);
            }

        }

        static void Draw_Sparks(ref Graphics g)
        {
            //return;
            Bitmap bmpFuse_Back = bmpSpark_Back;
                Point ptFuseBack = new Point(ptFuse_Tip.X - bmpFuse_Back.Width / 2,
                                             ptFuse_Tip.Y - bmpFuse_Back.Height / 2);
                g.DrawImage(bmpFuse_Back, ptFuseBack);

                Bitmap bmpFuse_Front = bmpSpark_Front;
                Point ptFuseFront = new Point(ptFuse_Tip.X - bmpFuse_Front.Width / 2,
                                              ptFuse_Tip.Y - bmpFuse_Front.Height / 2);
                g.DrawImage(bmpFuse_Front, ptFuseFront);

        }

        static void quit()
        {
            cEventTicket_Animate.AutoRepeat = false;
            instance.Hide();
            formBombingMath.bolFlash = false;
        }


        #region Bitmaps
        //static Bitmap _bmpBomb = null;
        //static Bitmap bmpBomb
        //{
        //    get
        //    {
        //        if (_bmpBomb == null)
        //        {
        //            _bmpBomb = new Bitmap(Properties.Resources.Flash_Bomb);
        //            _bmpBomb.MakeTransparent(_bmpBomb.GetPixel(0, 0));
        //        }
        //        return _bmpBomb;
        //    }
        //}

        static Bitmap _bmpTextBombing = null;
        static Bitmap bmpTextBombing
        {
            get
            {
                if (_bmpTextBombing == null)
                {
                    string strBombing = "Bombing";
                    Font fntTextBombing = new Font("ms sans-serif", 72);
                    int intShift = 5;
                    Size szBombing = TextRenderer.MeasureText(strBombing, fntTextBombing);
                    _bmpTextBombing = new Bitmap(szBombing.Width + intShift, szBombing.Height+intShift);
                    using (Graphics g = Graphics.FromImage(_bmpTextBombing))
                    {
                        g.FillRectangle(Brushes.Pink, new RectangleF(0, 0, _bmpTextBombing.Width, _bmpTextBombing.Height));
                        g.DrawString(strBombing, fntTextBombing, Brushes.Black, new Point(0, 0));
                        g.DrawString(strBombing, fntTextBombing, Brushes.Yellow, new Point(intShift, intShift));
                        _bmpTextBombing.MakeTransparent(Color.Pink);
                    }
                } 
                return _bmpTextBombing; 
            }
        }
        
        static Bitmap _bmpTextMath = null;
        static Bitmap bmpTextMath
        {
            get
            {
                if (_bmpTextMath == null)
                {
                    string strMath = "Math";
                    Font fntTextMath = new Font("ms sans-serif", 72);
                    int intShift = 5;
                    Size szMath = TextRenderer.MeasureText(strMath, fntTextMath);
                    _bmpTextMath = new Bitmap(szMath.Width + intShift, szMath.Height+intShift);
                    using (Graphics g = Graphics.FromImage(_bmpTextMath))
                    {
                        g.FillRectangle(Brushes.Pink, new RectangleF(0, 0, _bmpTextMath.Width, _bmpTextMath.Height));
                        g.DrawString(strMath, fntTextMath, Brushes.Black, new Point(0, 0));
                        g.DrawString(strMath, fntTextMath, Brushes.Yellow, new Point(intShift, intShift));
                        _bmpTextMath.MakeTransparent(Color.Pink);
                    }
                } 
                return _bmpTextMath; 
            }
        }


        static Bitmap _bmpSpark_Back = null;
        static Bitmap bmpSpark_Back
        {
            get
            {
                if (_bmpSpark_Back != null)
                {
                    _bmpSpark_Back.Dispose();
                }
                _bmpSpark_Back = Math3.classGraphics.Rotate(bmpSparkBase_Back,(int)( rnd.NextDouble() * 360));

                return _bmpSpark_Back;
            }
        }

        static Bitmap _bmpSpark_Front = null;
        static Bitmap bmpSpark_Front
        {
            get
            {
                if (_bmpSpark_Front != null)
                {
                    _bmpSpark_Front.Dispose();
                }
                _bmpSpark_Front = Math3.classGraphics.Rotate(bmpSparkBase_Front, (int)(rnd.NextDouble() * 360));
                return _bmpSpark_Front;
            }
        }
        
        static Bitmap _bmpSparkBase_Back = null;
        static Bitmap bmpSparkBase_Back
        {
            get
            {
                if (_bmpSparkBase_Back == null)
                {
                    _bmpSparkBase_Back = new Bitmap(Properties.Resources.Flash_Spark_Back);
                    _bmpSparkBase_Back.MakeTransparent(_bmpSparkBase_Back.GetPixel(0, 0));
                }
                return _bmpSparkBase_Back;
            }
        }

        static Bitmap _bmpSparkBase_Front = null;
        static Bitmap bmpSparkBase_Front
        {
            get
            {
                if (_bmpSparkBase_Front == null)
                {
                    _bmpSparkBase_Front = new Bitmap(Properties.Resources.Flash_Spark_Front);
                    _bmpSparkBase_Front.MakeTransparent(_bmpSparkBase_Front.GetPixel(0, 0));
                }
                return _bmpSparkBase_Front;
            }
        }

        static Size _sz = new Size(0, 0);
        static Size sz
        {
            get
            {
                if (_sz.Width == 0)
                {
                    _sz = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);
                }
                return _sz;
            }
        }

        static Bitmap _bmpWorking = null;
        static Bitmap bmpWorking
        {
            get
            {
                if (_bmpWorking == null)
                {
                    _bmpWorking = new Bitmap(sz.Width, sz.Height);
                }
                return _bmpWorking;
            }
        }

        #endregion 

        static Point ptFuse_Base_Pic = new Point(475, 57);
        static Point ptFuse_Base = new Point(475, 57);
        static Point ptFuse_Tip_Start = new Point();
        static Point ptFuse_Tip = new Point();
        static Point ptBombLocation = new Point();
        static int intNumFuseSteps = 100;
        static int intFuseStep = 0;
        static int intNumTextSteps = 30;
        static int intTextStep = 0;


    }
}
