using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using Ck_Objects;
using Math3;
using BinTree;


namespace SpriteEditor_2017
{

    /// <summary>
    /// allows the user to edit the currenta animation's draw sequence
    /// </summary>
    public class panelDrawSequence : panelMoveable
    {
        public Ck_Objects.classMultiButtonPic mbpLimbs = new classMultiButtonPic();

        /// <summary>
        /// used to move multiple selected items inside lbxLimbs using mouseMove or keypressed controls
        /// </summary>
        Timer tmrKeyDown_Service = new Timer();

        /// <summary>
        /// used to identify the boolean variable array contents keeping track of which keys are depressed 
        /// </summary>
        enum enuKeys { Up, Down, PageUp, PageDown, Home, End, _numKeys };
        bool[] eKeys = new bool[(int)enuKeys._numKeys];

        /// <summary>
        /// current mouse location on the listbox lbxLimbs used to move multiple entries with a mouse move
        /// </summary>
        Point ptMouse = new Point();

        /// <summary>
        /// location where the right mouse button was pressed used to move multiple entries with a mouse move
        /// </summary>
        Point ptMouseDown = new Point();

        /// <summary>
        /// pointer to SpriteEditor_2017's current SpriteData
        /// </summary>
        public classSpriteData cSpriteData;

        Button btnDebug = new Button();
        System.Windows.Forms.Timer tmrDebug = new Timer();


        /// <summary>
        /// initializes panelDrawSequence with standard font
        /// </summary>
        public panelDrawSequence()
        { Init(panelMoveable.fntStandard); }

        /// <summary>
        /// initializes panelDrawSequence with specified font
        /// </summary>
        /// <param name="fnt"></param>
        public panelDrawSequence(Font fnt)
        {
            btnDebug.Text = "debug";
            btnDebug.Click += BtnDebug_Click;
            tmrDebug.Interval = 1000;
            tmrDebug.Tick += TmrDebug_Tick;

            Init(fnt);
        }
        List<classSprite_Limb> lstLimbsStart = null;

        List<classSprite_Limb> getLimbSequence()
        {
            List<classSprite_Limb> lstLimbs_RetVal = new List<classSprite_Limb>();
            for (int intLimbcounter = 0; intLimbcounter < mbpLimbs.cMap.lstElements.Count; intLimbcounter++)
            {
                classMultiButtonPic.classButton cBtn = (classMultiButtonPic.classButton)mbpLimbs.cMap.lstElements[intLimbcounter].obj;
                classSprite_Limb cLimb = (classSprite_Limb)cBtn.Tag;

                if (cLimb != null)
                    lstLimbs_RetVal.Add(cLimb);
            }
            return lstLimbs_RetVal;
        }

        public bool testMBPLimbSequence()
        {
            List<classSprite_Limb> lstLimbs_New = getLimbSequence();
            if (lstLimbsStart == null
                ||
                lstLimbsStart.Count != lstLimbs_New.Count) return true;

            for (int intLimbCounter = 0; intLimbCounter < lstLimbsStart.Count && intLimbCounter < lstLimbs_New.Count; intLimbCounter++)
                if (lstLimbs_New[intLimbCounter] != lstLimbsStart[intLimbCounter])
                {
                    return false;
                }
            return true;
        }
        enum enuDebugEvents { Move, Wheel, _num, Up, Down, Click };
        private void TmrDebug_Tick(object sender, EventArgs e)
        {
            tmrDebug.Enabled = false;

            int intDelta = classRND.Get_Sign() * 1;
            enuDebugEvents eDebugEvent = (enuDebugEvents)classRND.Get_Int(0, (int)enuDebugEvents._num);

            switch (eDebugEvent)
            {
                case enuDebugEvents.Click:
                    {
                        MouseEventArgs eMsgArg = new MouseEventArgs(MouseButtons.None, 0, 0, 0, intDelta);
                        mbpLimbs.Event_MouseClick((object)mbpLimbs, eMsgArg);
                    }
                    break;

                case enuDebugEvents.Down:
                    {
                        MouseEventArgs eMsgArg = new MouseEventArgs(MouseButtons.None, 0, 0, 0, intDelta);
                        mbpLimbs.Event_MouseDown((object)mbpLimbs, eMsgArg);
                    }
                    break;

                case enuDebugEvents.Move:
                    {
                        MouseEventArgs eMsgArg = new MouseEventArgs(MouseButtons.None, 0, 10, 266, intDelta);
                        mbpLimbs.Event_MouseMove((object)mbpLimbs, eMsgArg);
                        if (!testMBPLimbSequence())
                        {
                            lstLimbsStart = getLimbSequence();
                        }
                    }
                    break;

                case enuDebugEvents.Up:
                    {
                        MouseEventArgs eMsgArg = new MouseEventArgs(MouseButtons.None, 0, 0, 0, intDelta);
                        mbpLimbs.Event_MouseUp((object)mbpLimbs, eMsgArg);
                    }
                    break;

                case enuDebugEvents.Wheel:
                    {
                        MouseEventArgs eMsgArg = new MouseEventArgs(MouseButtons.None, 0, 0, 0, intDelta);
                        mbpLimbs.Event_MouseWheel((object)mbpLimbs, eMsgArg);
                    }
                    break;
            }


            tmrDebug.Enabled = true;
        }

        private void BtnDebug_Click(object sender, EventArgs e)
        {
            Ck_Objects.form_GetInteger frmGetInteger = new form_GetInteger("enter timer interval", tmrDebug.Interval);
            frmGetInteger._event_ValueChanged = debug_TimerInterval_ValueChanged;
            frmGetInteger.TopMost = true;
            frmGetInteger.Show();
        }

        void debug_TimerInterval_Finished(object sender, EventArgs e)
        {
            Ck_Objects.form_GetInteger frmSender = (Ck_Objects.form_GetInteger)sender;
            frmSender.Hide();
            frmSender.Dispose();
        }
        void debug_TimerInterval_ValueChanged(object sender, EventArgs e)
        {
            Ck_Objects.form_GetInteger frmSender = (Ck_Objects.form_GetInteger)sender;
            if (frmSender.Value > 0)
            {
                tmrDebug.Interval = frmSender.Value;
                tmrDebug.Enabled = true;
            }
            else
                tmrDebug.Enabled = false;

        }

        /// <summary>
        /// initializes the controls on the panelDrawSequence
        /// </summary>
        /// <param name="fnt">font to be used to draw panel's Header text</param>
        void Init(Font fnt)
        {
            cSpriteData = formSpriteEditor_2017.instance.cSpriteData;
            Heading.Font = fnt;

            /////////////////////////////////////////////////////////////////////////////////////////////////////
            ///                         initializes panel's controls
            /////////////////////////////////////////////////////////////////////////////////////////////////////

            tmrKeyDown_Service.Interval = 50;
            tmrKeyDown_Service.Tick += TmrKeyDown_Service_Tick;

            pnlContainer.Controls.Add(mbpLimbs);
            mbpLimbs.Dock = DockStyle.None;
            mbpLimbs.Name = "mbpLimbs";

            Heading.BackColor = Color.Green;
            mbpLimbs.BackColor = Color.LightGreen;
            mbpLimbs.MultiSelect = true;
            mbpLimbs.CanMoveSelection = true;


            /////////////////////////////////////////////////////////////////////////////////////////////////////
            //                                          declares all mbpLimbs event handlers
            /////////////////////////////////////////////////////////////////////////////////////////////////////
            mbpLimbs.MouseMove += MbpLimbs_MouseMove;
            mbpLimbs.MouseDown += MbpLimbs_MouseDown;
            mbpLimbs.MouseUp += MbpLimbs_MouseUp;
            mbpLimbs.KeyDown += MbpLimbs_KeyDown;
            mbpLimbs.KeyUp += MbpLimbs_KeyUp;
            mbpLimbs.eventHandler_ButtonListChanged = mbp_ButtonListChanged;

            init_Format();

            if (formSpriteEditor_2017.instance != null && formSpriteEditor_2017.instance.cSpriteData.cAnimationData.cSprite != null)
                Heading.Text = "Draw Sequence: " + formSpriteEditor_2017.instance.cSpriteData.cAnimationData.cSprite.Name;

            // initializes the lbxLimb according to the current animation frame's lstDrawSequence content
            if (cSpriteData.cAnimationData.cSprite != null
                && cSpriteData.cAnimationData.cAnimation != null)
            {
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                setToFrame(ref cFrame);
            }

            placeObjects();

            // binds all panel's controls to formSpriteEditor_2017's tooltip
            formSpriteEditor_2017.instance.toolTip.SetToolTip(mbpLimbs, formSpriteEditor_2017.conDefaultToolTip);

            LocationChanged += panelDrawSequence_LocationChanged;
            Disposed += PanelDrawSequence_Disposed;
            SizeChanged += panelDrawSequence_SizeChanged;
        }

        public void init_Format()
        {
            /////////////////////////////////////////////////////////////////////////////////////////////////////
            ///                                     sets panel variables according to formatting data
            /////////////////////////////////////////////////////////////////////////////////////////////////////
            formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].bolIgnoreChanges = true;
            Size = new Size(formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].size_Width,
                               formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].size_Height);
            ExpansionDirection = formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].ExpansionDirection;
            if (formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].Collapsed)
                Collapse();
            else
                Expand();
            Location = new Point(formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].location_X,
                                 formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].location_Y);
            formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].bolIgnoreChanges = false;
            placeObjects();
        }

        void mbp_ButtonListChanged(object sender, EventArgs e)
        {
            classMultiButtonPic mbpSender = (classMultiButtonPic)sender;
            if (mbpSender.cMap.lstElements.Count == cSpriteData.cCostumeInfo.lstLimbs.Count)
            {
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                cFrame.lstDrawSequence.Clear();

                for (int intButtonCounter = 0; intButtonCounter < mbpSender.cMap.lstElements.Count; intButtonCounter++)
                {
                    classMultiButtonPic.classButton cBtn = (classMultiButtonPic.classButton)mbpSender.cMap.lstElements[intButtonCounter].obj;
                    classSprite_Limb cLimb = (classSprite_Limb)cBtn.Tag;

                    int intIndex = cLimb != null
                                       ? cSpriteData.cCostumeInfo.lstLimbs.IndexOf(cLimb)
                                       : -1;
                    cFrame.lstDrawSequence.Add(intIndex);
                }
                formSpriteEditor_2017.instance.Draw_Sprite();
            }


        }


        /// <summary>
        /// records panel's current collapse/expansionDirection variables for panel formatting purposes
        /// </summary>
        private void PanelDrawSequence_Disposed(object sender, EventArgs e)
        {
            formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].Collapsed = Collapsed;
            formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].ExpansionDirection = ExpansionDirection;
        }

        /// <summary>
        /// positions lbxLimbs listBox onto the panel
        /// </summary>
        void placeObjects()
        {
            mbpLimbs.Location = new Point(0, 0);
            mbpLimbs.Width = pnlContainer.Width;
            mbpLimbs.Height = pnlContainer.Height - mbpLimbs.Top;
        }

        /// <summary>
        /// records panel's current location after a locationchange for panel formatting purposes
        /// </summary>
        private void panelDrawSequence_LocationChanged(object sender, EventArgs e)
        {
            if (!formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].bolIgnoreChanges)
            {
                formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].location_X = Location.X;
                formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].location_Y = Location.Y;
                formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].bolInit = true;
            }
        }

        /// <summary>
        /// records panel's current size after a sizeChange for panel formatting purposes
        /// </summary>
        private void panelDrawSequence_SizeChanged(object sender, EventArgs e)
        {
            if (!formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].bolIgnoreChanges
                && !Collapsed)
            {
                formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].bolInit = true;
                formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].size_Width = Size.Width;
                formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].size_Height = Size.Height;
            }
            formSpriteEditor_2017.cPanelSizeLocations[(int)formSpriteEditor_2017.enuPanels.DrawSequence].Collapsed = Collapsed;

            placeObjects();
        }

        classSprite_Limb cLimb_Selected = null;
        public classSprite_Limb Limb_Selected
        {
            get { return cLimb_Selected; }
            set
            {
                if (cLimb_Selected != value)
                {
                    lstLimbsStart = getLimbSequence();

                    cLimb_Selected = value;
                    List<int> lstIndicesSelected = new List<int>();
                    if (cSpriteData.cAnimationData.cAnimation != null)
                    {
                        classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                        int intLimbIndex = cSpriteData.cCostumeInfo.lstLimbs.IndexOf(cLimb_Selected);
                        lstIndicesSelected.Add(cFrame.lstDrawSequence.IndexOf(intLimbIndex));
                        mbpLimbs.Buttons_Select(lstIndicesSelected);
                    }
                }
            }
        }

        Font fntButtons = new Font("ms sans-serif", 8);
        /// <summary>
        /// reinitializes the listBox to reflect the current animation frame's lstDrawSequence content
        /// </summary>
        /// <param name="cFrame">animation frame currently loaded</param>
        public void setToFrame(ref classAnimation_Frame cFrame)
        {
            mbpLimbs.ClearButtons();
            mbpLimbs.Formation = classMultiButtonPic.enuButtonFormation.column;
            cSpriteData = formSpriteEditor_2017.instance.cSpriteData;
            if (cSpriteData.cAnimationData.cSprite == null)
                return;
            if (formSpriteEditor_2017.cPanelSizeLocations != null
                && cFrame != null)
            {
                Size szMin = new Size(10, 10);

                for (int intLimbCounter = 0; intLimbCounter < cFrame.lstDrawSequence.Count; intLimbCounter++)
                {
                    if (cFrame.lstDrawSequence[intLimbCounter] >= 0)
                    {
                        Size szLimb = TextRenderer.MeasureText(cSpriteData.cCostumeInfo.lstLimbs[cFrame.lstDrawSequence[intLimbCounter]].Name, fntButtons);

                        if (szLimb.Width > szMin.Width)
                            szMin.Width = szLimb.Width;
                        if (szLimb.Height > szMin.Height)
                            szMin.Height = szLimb.Height;
                    }
                }
                szMin.Width += 4;
                szMin.Height += 2;
                Color clrBorder = Color.LightSeaGreen;
                for (int intLimbCounter = 0; intLimbCounter < cFrame.lstDrawSequence.Count; intLimbCounter++)
                {
                    if (cFrame.lstDrawSequence[intLimbCounter] >= 0)
                    {
                        classSprite_Limb cLimb = cSpriteData.cCostumeInfo.lstLimbs[cFrame.lstDrawSequence[intLimbCounter]];
                        classMultiButtonPic.classButton cButton = new classMultiButtonPic.classButton(ref mbpLimbs);
                        cButton.Text = cLimb.Name;
                        cButton.AutoSize = false;
                        cButton.Size = szMin;
                        cButton.CanBeToggled = true;
                        cButton.ToggleDoubleClick = true;
                        cButton.Forecolor_Highlight
                            = cButton.Backcolor_Idle
                            = Color.White;
                        cButton.Forecolor_Idle
                            = cButton.Backcolor_Highlight
                            = Heading.BackColor;
                        cButton.BorderColor = clrBorder;
                        cButton.Font = fntButtons;
                        cButton.Toggled = cFrame.lstData[cLimb.intMyIndex].Override;
                        cButton.Tag = (object)cLimb;
                        cButton.ToggleChanged = cBtn_ToggleChanged;
                        mbpLimbs.Button_Add(ref cButton);
                    }
                    else
                    {
                        classMultiButtonPic.classButton cButton = new classMultiButtonPic.classButton(ref mbpLimbs);
                        cButton.Text = classSprite.conDrawSequenceDoNotDraw;
                        cButton.AutoSize = false;
                        cButton.Size = szMin;
                        cButton.CanBeToggled = true;
                        cButton.ToggleDoubleClick = true;
                        cButton.Forecolor_Highlight
                            = cButton.Backcolor_Idle
                            = Color.White;
                        cButton.BorderColor = clrBorder;
                        cButton.Forecolor_Idle
                            = cButton.Backcolor_Highlight
                            = Heading.BackColor;
                        cButton.Font = fntButtons;

                        mbpLimbs.Button_Add(ref cButton);
                    }
                }
                mbpLimbs.placeButtons();
                lstLimbsStart = getLimbSequence();
            }
        }

        void cBtn_ToggleChanged(object sender, EventArgs e)
        {
            classMultiButtonPic.classButton cBtnSender = (classMultiButtonPic.classButton)sender;
            classSprite_Limb cLimb = (classSprite_Limb)cBtnSender.Tag;
            classAnimation_Frame cFrame = formSpriteEditor_2017.instance.Frame_Current;
            if (cLimb != null && cFrame != null)
            {
                classAnimation_Frame_LimbData cData = cFrame.lstData[cLimb.intMyIndex];
                if (cData != null)
                    cData.Override = cBtnSender.Toggled;
            }
        }


        /// <summary>
        /// sets the formSpriteEditor_2017's currently selected limb
        /// </summary>
        private void MbpLimbs_MouseClick(object sender, MouseEventArgs e)
        {

        }

        /// <summary>
        /// triggers timer to move selected indices along with mouse move if right mouse button is depressed
        /// </summary>
        private void MbpLimbs_MouseUp(object sender, MouseEventArgs e)
        {
            tmrKeyDown_Service.Enabled = MouseButtons == MouseButtons.Right;
        }

        /// <summary>
        /// mouse button event that records where the mouse cursor was when the mouse button was pressed triggers selectionMove timer if rightMouseButton is pressed
        /// </summary>
        private void MbpLimbs_MouseDown(object sender, MouseEventArgs e)
        {
            tmrKeyDown_Service.Enabled = MouseButtons == MouseButtons.Right;
            ptMouseDown.X = e.X;
            ptMouseDown.Y = e.Y;

            classMultiButtonPic mbp = (classMultiButtonPic)sender;
            if (mbp.lstButtonsSelected.Count <= 1)
            {
                classMultiButtonPic.classButton cButton_Clicked = mbp.cButtonUnderMouse;
                if (cButton_Clicked != null)
                {
                    if (e.Button == MouseButtons.Right)
                        cButton_Clicked.Toggle();
                    //string strLimbName = cButton_Clicked.Text;
                    classSprite_Limb cLimbSelected = (classSprite_Limb)cButton_Clicked.Tag;// (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(strLimbName);
                    if (cLimbSelected != null)
                    {
                        formSpriteEditor_2017.instance.cmbLimbs_SetSelect(cLimbSelected.Name);
                    }
                }
            }
        }

        /// <summary>
        /// mouveMove event tracks location of the mouse over the limb listbox
        /// </summary>
        private void MbpLimbs_MouseMove(object sender, MouseEventArgs e)
        {
            ptMouse.X = e.X;
            ptMouse.Y = e.Y;
        }

        /// <summary>
        /// after a mouseMove or KeyPress operation the selected items in the listBox lbxLimbs are shifted upwards
        /// </summary>
        void lbxLimbs_ShiftSelected_Up()
        {
            /*       ListBox.SelectedIndexCollection lstSelected = lbxLimbs.SelectedIndices;
                   int intStart = lstSelected[0];
                   int intEnd = lstSelected[lstSelected.Count - 1];

                   if (intStart > 0)
                   {
                       string strFront = (string)lbxLimbs.Items[intStart - 1];

                       lbxLimbs.Items.Remove(lbxLimbs.Items[intStart - 1]);
                       lbxLimbs.Items.Insert(intEnd, strFront);
                   }*/
        }

        /// <summary>
        /// after a mouseMove or Keypress operation the selected items in the listbox lbxLimbs are shifted downwards
        /// </summary>
        void lbxLimbs_ShiftSelected_Down()
        {
            /*  ListBox.SelectedIndexCollection lstSelected = lbxLimbs.SelectedIndices;
              int intStart = lstSelected[0];
              int intEnd = lstSelected[lstSelected.Count - 1];

              if (intEnd < lbxLimbs.Items.Count - 1)
              {
                  string strTail = (string)lbxLimbs.Items[intEnd + 1];

                  lbxLimbs.Items.Remove(lbxLimbs.Items[intEnd + 1]);
                  lbxLimbs.Items.Insert(intStart, strTail);
              }
              */
        }

        /// <summary>
        /// the boolean array eKeys[] manages which keys are pressed/released
        /// </summary>
        private void MbpLimbs_KeyUp(object sender, KeyEventArgs e)
        {
            tmrKeyDown_Service.Enabled = false;
            switch (e.KeyCode)
            {
                case Keys.Up:
                    eKeys[(int)enuKeys.Up] = false;
                    break;

                case Keys.Down:
                    eKeys[(int)enuKeys.Down] = false;
                    break;

                case Keys.PageDown:
                    eKeys[(int)enuKeys.PageDown] = false;
                    break;

                case Keys.PageUp:
                    eKeys[(int)enuKeys.PageUp] = false;
                    break;

                case Keys.End:
                    eKeys[(int)enuKeys.End] = false;
                    break;

                case Keys.Home:
                    eKeys[(int)enuKeys.Home] = false;
                    break;

                default:
                    break;
            }
        }

        /// <summary>
        /// the boolean array eKeys[] manages which keys are pressed/released
        /// </summary>
        private void MbpLimbs_KeyDown(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true;
            tmrKeyDown_Service.Enabled = true;
            switch (e.KeyCode)
            {
                case Keys.Up:
                    eKeys[(int)enuKeys.Up] = true;
                    break;

                case Keys.Down:
                    eKeys[(int)enuKeys.Down] = true;
                    break;

                case Keys.PageDown:
                    eKeys[(int)enuKeys.PageDown] = true;
                    break;

                case Keys.PageUp:
                    eKeys[(int)enuKeys.PageUp] = true;
                    break;

                case Keys.End:
                    eKeys[(int)enuKeys.End] = true;
                    break;

                case Keys.Home:
                    eKeys[(int)enuKeys.Home] = true;
                    break;

                default:
                    tmrKeyDown_Service.Enabled = false;
                    break;
            }
        }

        /// <summary>
        /// triggered by keyPress or MouseClick timer moves selected items according to the UI input
        /// </summary>
        private void TmrKeyDown_Service_Tick(object sender, EventArgs e)
        {
            cSpriteData = formSpriteEditor_2017.instance.cSpriteData;
            bool bolRefreshImage = false;
            if (eKeys[(int)enuKeys.Up])
            {
                lbxLimbs_ShiftSelected_Up();
                bolRefreshImage = true;
            }
            if (eKeys[(int)enuKeys.Down])
            {
                lbxLimbs_ShiftSelected_Down();
                bolRefreshImage = true;
            }

            if (MouseButtons == MouseButtons.Right)
            {
                int intStep = mbpLimbs.Font.Height;
                int intDelta = ptMouse.Y - ptMouseDown.Y;
                do
                {
                    if (intDelta < -intStep)
                    {
                        lbxLimbs_ShiftSelected_Up();
                        bolRefreshImage = true;
                        ptMouseDown.Y -= intStep;
                    }
                    else if (intDelta > intStep)
                    {
                        lbxLimbs_ShiftSelected_Down();
                        bolRefreshImage = true;
                        ptMouseDown.Y += intStep;
                    }
                    intDelta = ptMouse.Y - ptMouseDown.Y;
                } while (Math.Abs(intDelta) > intStep);
            }

            if (bolRefreshImage)
            {
                classAnimation cAnimation = formSpriteEditor_2017.instance.cSpriteData.cAnimationData.cAnimation;
                classAnimation_Frame cFrame = cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                cFrame.lstDrawSequence.Clear();
                for (int intItemCounter = 0; intItemCounter < mbpLimbs.cMap.lstElements.Count; intItemCounter++)
                {
                    classMultiButtonPic.classButton cButton = (classMultiButtonPic.classButton)mbpLimbs.cMap.lstElements[intItemCounter].obj;
                    if (string.Compare((cButton.Text), classSprite.conDrawSequenceDoNotDraw) == 0)
                    { // stop drawing at null-limb
                        cFrame.lstDrawSequence.Add(-1);
                    }
                    else
                    {
                        classSprite_Limb cLimb = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(cButton.Text);
                        int intLimbIndex = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs.IndexOf(cLimb);
                        cFrame.lstDrawSequence.Add(intLimbIndex);
                    }
                }
                formSpriteEditor_2017.instance.Draw_Sprite();
            }
        }
    }
}
