using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Ck_Objects;
using SpriteEditor_2017;
using StringLibrary;

namespace SpriteEditor_2017
{
    public class formCreateTextSprite : System.Windows.Forms.Form
    { // guided by Stories and Fairy Tales like bread crumbs in the woods, you may find that the rainbow you follow is twilight twinkling back at you and the pot of gold you sought an empty rusted bucket of mud.
        public static formCreateTextSprite instance = null;

        public static classCreateTextSprite_Data cCTSData = new classCreateTextSprite_Data();

        Label lblName = new Label();
        Ck_Objects.textBox_AlphaNumeric txtName = new textBox_AlphaNumeric();
        classLabelButton lbtnFont = new classLabelButton();
        Label lblText = new Label();
        textBox_AlphaNumeric txtText = new textBox_AlphaNumeric();
        classLabelButton lbtnForeColor = new classLabelButton();

        classLabelButton lbtnOk = new classLabelButton();
        classLabelButton lbtnCancel = new classLabelButton();

        public formCreateTextSprite()
        {
            instance = this;

            Text = "Create Text Sprite";
            ControlBox = false;
            //TopMost = true;

            //          name
            Controls.Add(lblName);
            lblName.Text = "Name:";
            lblName.AutoSize = true;

            Controls.Add(txtName);
            txtName.Multiline = false;
            txtName.TextChanged += TxtName_TextChanged;

            //          text
            Controls.Add(lblText);
            lblText.AutoSize = true;
            lblText.Text = "Text:";

            Controls.Add(txtText);
            txtText.Multiline = true;
            txtText.Text = "";
            txtText.TextChanged += TxtText_TextChanged;
            ContextMenu cMnuText = new ContextMenu();
            cMnuText.MenuItems.Add("set Backcolor", mnuSetBackColor_click);
            txtText.ContextMenu = cMnuText;

            //          font
            Controls.Add(lbtnFont);
            lbtnFont.AutoSize = true;
            lbtnFont.Text = "Font";
            lbtnFont.Click += LbtnFont_Click;

            //          Forecolor
            Controls.Add(lbtnForeColor);
            lbtnForeColor.AutoSize = true;
            lbtnForeColor.Text = "Forecolor";
            lbtnForeColor.Click += LbtnForeColor_Click;

            //          ok
            Controls.Add(lbtnOk);
            lbtnOk.Text = "Ok";
            lbtnOk.AutoSize = true;
            lbtnOk.Click += LbtnOk_Click;

            //          cancel
            Controls.Add(lbtnCancel);
            lbtnCancel.Text = "Cancel";
            lbtnCancel.AutoSize = true;
            lbtnCancel.Click += LbtnCancel_Click;

            Activated += FormCreateTextSprite_Activated;
            SizeChanged += FormCreateTextSprite_SizeChanged;
        }

        void mnuSetBackColor_click(object sender, EventArgs e)
        {
            ColorDialog cd = new ColorDialog();
            if (cd.ShowDialog() == DialogResult.OK)
            {
                txtText.BackColor = cd.Color;    
            }
        }

        void setText()
        {
            txtText.Font = cCTSData.Font;
            txtText.ForeColor = cCTSData.ForeColor;
            txtName.Text = cCTSData.Name;
        }


        private void FormCreateTextSprite_SizeChanged(object sender, EventArgs e)
        {
            placeObjects();
        }

        bool bolActivated = false;
        private void FormCreateTextSprite_Activated(object sender, EventArgs e)
        {
            if (bolActivated) return;
            bolActivated = true;
            cCTSData.Text 
                = txtText.Text 
                = "enter default text here.";

            cCTSData.Font = new Font("MS Sans-Serif", 18);
            cCTSData.ForeColor = Color.Yellow;

            cCTSData.Name
                = txtName.Text
                = cCTSData.Font.FontFamily
                    + " " + cCTSData.Font.Size.ToString()
                    + " " + cCTSData.ForeColor.Name;
            
            setText();
            placeObjects();
        }

        void placeObjects()
        {
            Size szForm = new Size(15, 55);

            lblName.Location = new Point(5, 10);
            txtName.Location = new Point(lblName.Right, lblName.Top);

            lbtnFont.Location = new Point(Width - szForm.Width - 5 - lbtnFont.Width , lblName.Top);
            lbtnForeColor.Location = new Point(lbtnFont.Left - lbtnForeColor.Width, lbtnFont.Top);
            txtName.Width = lbtnForeColor.Left - txtName.Left;

            lblText.Location = new Point(lblName.Left, txtName.Bottom);
            txtText.Location = new Point(lblText.Left , lblText.Bottom);
            txtText.Width = Width - txtText.Left - szForm.Width - txtText.Left;

            lbtnOk.Location = new Point(Width - szForm.Width - lbtnOk.Width, Height - szForm.Height - lbtnOk.Height);
            lbtnCancel.Location = new Point(lbtnOk.Left - lbtnCancel.Width, lbtnOk.Top);
            lbtnOk.BringToFront();
            lbtnCancel.BringToFront();
            txtText.Height = Height - szForm.Height - txtText.Top;
        }

        private void LbtnCancel_Click(object sender, EventArgs e)
        {
            Dispose();
        }

        private void LbtnOk_Click(object sender, EventArgs e)
        {
            CreateTextSprite();
        }

        void CreateTextSprite()
        {
            classSprite cSprite = new classSprite("TextSprite");

            IEnumerable<string> ietext = classStringLibrary.getFirstWords(cCTSData.Text).Distinct<string>().Distinct();
            List<string> lstText = (List<string>)ietext.ToList<string>();
            Bitmap bmpBlank = new Bitmap(3, 3);

            cSprite.Limb_New("Crane", bmpBlank, ref cSprite.cCostumeInfo_Default.cLimb_Master);
            classSprite_Limb cLimbCrane = cSprite.cCostumeInfo_Default.lstLimbs[cSprite.cCostumeInfo_Default.lstLimbs.Count - 1];
            cLimbCrane.Hinge.Contact.Slave.Magnitude = 500;
            cLimbCrane.Hinge.Angle = 0;

            cSprite.Limb_New("CraneAxis", bmpBlank, ref cLimbCrane);
            classSprite_Limb cLimbCraneAxis = cSprite.cCostumeInfo_Default.lstLimbs[cSprite.cCostumeInfo_Default.lstLimbs.Count - 1];

            while (lstText.Count > 0)
            {
                string strText = lstText[0];
                lstText.RemoveAt(0);

                Size szText = TextRenderer.MeasureText(strText, cCTSData.Font);
                Color clrInvisible = Color.Black;
                if (cCTSData.ForeColor.R == clrInvisible.R && cCTSData.ForeColor.G == clrInvisible.G && cCTSData.ForeColor.B == clrInvisible.B)
                    clrInvisible = Color.FromArgb(1, 1, 1);

                Bitmap bmpLimb = new Bitmap(szText.Width, szText.Height);

                using (Graphics g = Graphics.FromImage(bmpLimb))
                {
                    g.FillRectangle(new SolidBrush(clrInvisible), new RectangleF(0, 0, bmpLimb.Width, bmpLimb.Height));
                    g.DrawString(strText, cCTSData.Font, new SolidBrush(cCTSData.ForeColor), new Point(0, 0));
                }

                 cSprite.Limb_New(strText, bmpLimb, ref cLimbCraneAxis);
                classSprite_Limb cLimbNew = cSprite.cCostumeInfo_Default.lstLimbs[cSprite.cCostumeInfo_Default.lstLimbs.Count - 1];

                GenerateDefaultAnimations(ref cSprite, ref cLimbNew);
            }

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Title = "saving Text Sprite : " + cCTSData.Name;
            sfd.FileName = System.IO.Directory.GetCurrentDirectory() + "\\" + cCTSData.Name + ".sp3";
            sfd.DefaultExt = "sp3";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                if (classSpriteMaker.instance == null)
                    new classSpriteMaker();
                string strFilename = sfd.FileName;
                classSpriteMaker.instance.Save(ref cSprite, ref strFilename);
            }
        }

        void GenerateDefaultAnimations(ref classSprite cSprite, ref classSprite_Limb cLimbNew)
        {
            int intNumFramesPerQuarterRotation = 16;
            // rotate clockwise
            classAnimation cAnimation_RotateCW = cSprite.Animation_New(cLimbNew.Name + "_RotateCW");
            
            classSprite_Limb cCrane = (classSprite_Limb)cSprite.cCostumeInfo_Default.cBT_Limbs.Search("Crane");
            int intCrane = cSprite.cCostumeInfo_Default.lstLimbs.IndexOf(cCrane);
            if (intCrane < 0 || intCrane >= cSprite.cCostumeInfo_Default.lstLimbs.Count)
            {
                MessageBox.Show("crane not found");
                return;
            }
            double dblRadStart = 0;
            double dblRadEnd = -Math.PI / 2;
            double dblRadDelta = (-Math.PI / 2) / (double)intNumFramesPerQuarterRotation;

            for (int intQuarterRotation = 0; intQuarterRotation < 4; intQuarterRotation++)
            {
                for (int intFrameCounter = 0; intFrameCounter < intNumFramesPerQuarterRotation; intFrameCounter++)
                {
                    classAnimation_Frame cFrame = new classAnimation_Frame(ref cSprite);
                    classAnimation_Frame_LimbData cLimbData = new classAnimation_Frame_LimbData(ref cFrame);

                    cLimbData.Angle = dblRadStart + intFrameCounter * dblRadDelta;
                    cFrame.lstData.Add(cLimbData);

                    cFrame.lstData.Add(new classAnimation_Frame_LimbData(ref cFrame));
                    cAnimation_RotateCW.lstFrames.Add(cFrame);
                }
                dblRadStart = dblRadEnd;
                dblRadEnd -= Math.PI / 2;
            }
        }

        private void TxtName_TextChanged(object sender, EventArgs e)
        {
            cCTSData.Name = txtName.Text;
        }

        private void TxtText_TextChanged(object sender, EventArgs e)
        {
            cCTSData.Text = txtText.Text;
        }

        private void LbtnForeColor_Click(object sender, EventArgs e)
        {
            ColorDialog cd = new ColorDialog();
            if (cd.ShowDialog() == DialogResult.OK)
            {
                cCTSData.ForeColor = cd.Color;
                setText();
            }
        }

        private void LbtnFont_Click(object sender, EventArgs e)
        {
            FontDialog fntDialog = new FontDialog();
            if (fntDialog.ShowDialog() == DialogResult.OK)
            {
                cCTSData.Font = fntDialog.Font;
                setText();
            }
        }


        public class classCreateTextSprite_Data
        {
            public classSprite cSprite = null;

            string strName = "";
            public string Name
            {
                get { return strName; }
                set { strName = value; }
            }

            void setName()
            {
                Name = Font.FontFamily.Name + " " + Font.Size.ToString() + " " + ForeColor.Name;
            }

            string strText = "";
            public string Text
            {
                get { return strText; }
                set { strText = value; }
            }

            Font fnt = new Font("ms sans-serif", 10);
            public Font Font
            {
                get { return fnt; }
                set 
                {
                    fnt = value;
                    setName();
                }
            }

            Color foreColor = Color.Yellow;
            public Color ForeColor
            {
                get { return foreColor; }
                set 
                {
                    foreColor = value;
                    setName();
                }
            }

        }
    }
}