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

namespace SpriteEditor_2017
{
    /// <summary>
    /// SpriteEditor_2017 was designed, engineered and developed by Christ Kennedy between 2018/12/12 - 2019/01/20 for OpenSource publication
    ///         - comments can be made at   www.CodeProject.com 
    ///                                  or Christ.Kennedy@mail.mcgill.ca
    ///     this open source material is intended for general use.  
    ///     as this is the internet and i claim no authority over your imagination I only wish that your sprites roam free 
    /// </summary>

    public partial class formSpriteEditor_2017 : Form
    {
        Timer tmrDebugLimbList = new Timer();
        /// <summary>
        /// instance points to this form and can be called from anywhere using formSpriteEditor_2017.instance reference
        /// </summary>
        public static formSpriteEditor_2017 instance;


        /// <summary>
        /// Math class used by classSprite and SpriteEditor_2017
        /// </summary>
        classMath3 classMath3 = new classMath3();

        /// <summary>
        /// manages all tool tips in SpriteEditor_2017
        /// </summary>
        public ToolTip toolTip = new ToolTip();

        public static bool bolDisposed = false;

        /// <summary>
        /// distance sprite moves on the screen when move FocusControls are clicked on picMain
        /// </summary>
        public static int intFocusController_StepSize = 25;

        /// <summary>
        /// value by which Magnitude textboxes are changed using MouseWheel
        /// </summary>
        public static double dbl_Magnitude_StepSize = 0.1;

        /// <summary>
        /// value by which Radian textboxes are changed using MouseWheel
        /// </summary>
        public static double dbl_Radians_StepSize = Math.PI / 64;

        /// <summary>
        /// used to format print double variables
        /// </summary>
        public static string strMagnitudeFormat = "0.000";
        public static string strRadiansFormat = "0.00000";
        public static string strPercentageFormat = "%0";

        const string conCurrentDirectory_LoadFile = "(CurrentDirectory)";

        /// <summary>
        /// warns developer tooltip for an object has not been defined
        /// </summary>
        public const string conDefaultToolTip = "Tips defined in : ToolTip_SetUp()";

        /// <summary>
        /// panels that contains all the controls pertinent to the sprite's animation 
        /// </summary>
        panelAnimation_Controls pnlAnimationControls;

        /// <summary>
        /// panel that displays the animation in a storyboard strip which can be edited multiple frames at a time
        /// </summary>
        panelAnimationFrameEditor pnlAnimation_FrameEditor;

        /// <summary>
        /// panel that allows user to insert/delete animation frames to adjust the speed of output animation
        /// </summary>
        panelAnimationSpeed pnlAnimation_Speed;

        /// <summary>
        /// panel that allows user to select one of several Costumes for the current sprite
        /// </summary>
        public panelCostume_Selector pnlCostume_Selector;

        /// <summary>
        /// panel used to generate and insert multiple frames between two existing frames animating limbs to create a smooth sequence between them
        /// </summary>
        panelAutoInsertIntermediaryFrames pnlAutoInsertIntermediaryFrames;

        /// <summary>
        /// panel used for debugging purposes in order to test sprite internal data, detect bugs and display potential crash-failures
        /// </summary>
        panelDebug pnlDebug;

        /// <summary>
        /// panel used to set the sequence in which limbs will be drawn on an animation frame bitmap
        /// </summary>
        public panelDrawSequence pnlDrawSequence;

        /// <summary>
        /// panel that contains all controls pertinent to editing an animation frame
        /// </summary>
        panelFrameEditor pnlFrameEditor;

        /// <summary>
        /// panel used to graphically set the hinge contacts that bind limbs together
        /// </summary>
        panelHingeContact_Graphical pnlHingeContacts_Set_Graphical;

        /// <summary>
        /// panel used to numerically set the hinge contacts that bind limbs together
        /// </summary>
        panelHingeContact_Numerical pnlHingeContacts_Set_Numerical;

        /// <summary>
        /// panl used to deattach and reattach an existing limb from its current master to its new master limb
        /// </summary>
        panelLimb_Reattach pnlLimb_Reattach;

        /// <summary>
        /// panel used to copy frame values of selected limbs from one source animation to one or multiple destination animations
        /// </summary>
        panelLimb_CopyFrames pnlLimb_CopyFrames;
        
        /// <summary>
        /// panel used to set animation frames for selected limbs into existing animation frames
        /// </summary>
        public panelLimb_SetAnimation pnlLimb_SetAnimation;

        /// <summary>
        /// panel used to edit the list of images that determine a limb's Costume
        /// </summary>
        panelLimb_ImageController pnlLimb_ImageController;

        /// <summary>
        /// panel used to for text UI to ask user what to name a sprite component
        /// </summary>
        public panelMessenger pnlMessenger;

        /// <summary>
        /// panel that contains all options controls not related to frame or animation editing
        /// </summary>
        panelOptions pnlOptions;

        /// <summary>
        /// string used to parse text in the formatting of the SpriteEditor_2017 IDE
        /// </summary>
        const string conLineDelimiter = "\r\n";

        /// <summary>
        /// name of text file that holds all the SpriteEditor_2017 IDE format information 
        /// </summary>
        const string conFormatFilename = "Format.txt";

        /// <summary>
        /// data necessary for the drawing of a Sprite - 
        /// various sprites on the screen having their own classSpriteData instance can be drawn using the same instance of classSprite
        /// </summary>
        public SpriteEditor_2017.classSpriteData cSpriteData = new classSpriteData();

        /// <summary>
        ///  image drawn in the background to help recreate sprites from a model example
        /// </summary>
        Bitmap _bmpBackground = null;
        Bitmap bmpBackground
        { 
        get 
            {
                if (_bmpBackground == null)
                {
                    _bmpBackground = (Bitmap)new Bitmap(picMain.Width, picMain.Height);
                    using (Graphics g = Graphics.FromImage(bmpBackground))
                        g.FillRectangle(Brushes.White, new RectangleF(0, 0, bmpBackground.Width, bmpBackground.Height));
                }
                return _bmpBackground;
            }
        set { _bmpBackground = value; }
        }

        /// <summary>
        ///  memory stream used to load a background image and avoid issues with other image editing software
        /// </summary>
        MemoryStream sBackground = null;

        /// <summary>
        /// index of the current screen image used by the drawControls() function to supplement screen with control information
        /// </summary>
        int intScreen_WO_FocusController_Counter = 0;
        Bitmap[] bmpScreen_WO_FocusController = new Bitmap[2];

        /// <summary>
        /// focus control images used to highlight controls found beneath a mouseMove()
        /// </summary>
        Bitmap[] bmpFocusControllerImages = new Bitmap[(int)enuFocusControllerImages._numImages];

        /// <summary>
        /// position where the ptFocusControl is drawn
        /// </summary>
        Point _ptFocusControllerCenter = new Point();
        public Point ptFocusControllerCenter
        { 
            get { return _ptFocusControllerCenter; }
            set
            {
                if (_ptFocusControllerCenter.X != value.X || _ptFocusControllerCenter.Y != value.Y)
                {
                    _ptFocusControllerCenter = value;
                    System.Diagnostics.Debug.Print("ptFocusControllerCenter(" + ptFocusControllerCenter.X.ToString() + ", " + ptFocusControllerCenter.Y.ToString() + ")");
                }
            }
        }

        /// <summary>
        /// is set when the user right-clicks over the center of the focusControl
        /// </summary>
        bool _bolFocusController_Grabbed = false;
        public bool bolFocusController_Grabbed
        { 
            get { return _bolFocusController_Grabbed; }
            set
            {
                if (_bolFocusController_Grabbed != value)
                {
                    _bolFocusController_Grabbed = value;
                    System.Diagnostics.Debug.Print("bolFocusController_Grabbed:" + bolFocusController_Grabbed.ToString());
                }
            }
        }

        /// <summary>
        /// is set when mouse enters/leaves picMain
        /// </summary>
        bool bolMouseOverPic = false;

        /// <summary>
        /// records/loads/save panel information for formatting purposes
        /// </summary>
        public static classPanelSizeLocation[] cPanelSizeLocations = new classPanelSizeLocation[(int)enuPanels._numForms];

        /// <summary>
        /// keeps track of which keys are pressed or released
        /// </summary>
        bool[] bolKeys = new bool[(int)enuKeys._numKeys];

        /// <summary>
        /// points to the sprite limb currently under the mouse cursor
        /// </summary>
        classSprite_Limb cLimb_MouseOver = null;

        /// <summary>
        /// timer that runs the sprite animation
        /// </summary>
        public Timer tmrAnimation = new Timer();

        /// <summary>
        /// semaphore used to isolate Costume changes from frame-data-setting during animations
        /// </summary>
        public System.Threading.Semaphore semChangeCostume = new System.Threading.Semaphore(1, 1);

        /// <summary>
        /// semaphore used to smoothen MouseMove event over picMain
        /// </summary>
        public System.Threading.Semaphore semMouseMove = new System.Threading.Semaphore(1, 1);

        /// <summary>
        /// refreshes the text messages in the form's heading to update the user of the results of his commands
        /// </summary>
        Timer tmrRefreshText = new Timer();

        /// <summary>
        /// returns the FocusControl image to its default state after delay displaying sprite image's current draw size
        /// </summary>
        Timer tmrDrawSizeFactor_Refresh = new Timer();

        /// <summary>
        /// when triggered user commands to move the sprite about the screen are carried out
        /// </summary>
        public Timer tmrFocusDelta = new Timer();

        /// <summary>
        /// used by panelHingeContact_Numberical to allow user's commands to be completed before sprite is redrawn
        /// </summary>
        bool bolDraw_Sprite = true;

        /// <summary>
        /// border measurements of the form used to position objects after a SizeChange event
        /// </summary>
        Size szForm = new Size(15, 40);

        /// <summary>
        /// default font used throughout life of SpriteEditor_2017
        /// </summary>
        Font fnt = new Font("courier", 12, FontStyle.Regular);

        /// <summary>
        /// context menu available to the user when the animation timer is off
        /// </summary>
        public ContextMenu cMnuPic = new ContextMenu();

        /// <summary>
        /// position on the mouse during a mouseMove over the picMain picturebox
        /// </summary>
        Point ptPicMain_Mouse = new Point();

        /// <summary>
        /// variables that allows the keyboard to be used as an alternative to the mouse
        /// </summary>
        bool bolMouseRight_Down = false;
        bool bolMouseLeft_Down = false;

        /// <summary>
        /// cancels positioning of objects on the form in the formActivation event after the form has already been loaded
        /// </summary>
        bool bolFormatLoaded = false;

        /// <summary>
        /// is set during the Format_Load() phase before panels are loaded then used to help format the panels once they are ready
        /// </summary>
        bool[] bolPanelCheckedStates = new bool[(int)enuCheckedMenus._numCheckedMenus];

        /// <summary>
        /// used in the Format_Load() phase to remember various conditions of various types pertinent to the formatting of all the panels
        /// </summary>
        public object[] objOptions = new object[(int)enuOptions._numOptions];

        /// <summary>
        /// set during the Format_Load() phase before screen or sprite are ready then used before drawing the sprite on the screen
        /// </summary>
        double dblDrawFactor_Load = 1.0;

        #region enumerated_Types
        /// <summary>
        /// different components of the FocusContoller
        /// </summary>
        enum enuFocusControllerImages { Idle, Up, Down, Left, Right, Center, size_Reduce, size_100PC, _numImages };

        /// <summary>
        /// numeric key functions that enable the keyboard to be used for common mouse controls
        /// </summary>
        enum enuKeys { Mouse_Left, Mouse_Right, MouseWheel_Up, MouseWheel_Down, ControlKey, _numKeys };

        /// <summary>
        /// list of panels that need to be loaded/saved for Format purposes
        /// </summary>
        public enum enuPanels
        {
            AnimationControl,
            AnimationFrameEditor,
            AnimationSpeed,
            AutoInsertIntermediaryFrames,
            CostumeSelector,
            debugTestData,
            DrawSequence,
            FrameEditor,
            HingeContact_Graphical,
            HingeContact_Numerical,
            Limb_CopyFrames,
            Limb_ImageController,
            Limb_Reattach,
            Limb_SetAnimation,
            Messenger,
            Options,
            _numForms
        };

        /// <summary>
        /// UI options that need to be loaded/saved as part of the IDE format
        /// </summary>
        public enum enuOptions
        {
            Options_Show_LimbNames_checked,
            Options_Show_LimbCenters_checked,
            Options_Show_LimbPOsitions_checked,
            Options_Show_FocusController_checked,
            Options_Show_ToolTips_checked,
            Options_Show_Frame_checked,

            Options_UseRAMCache_checked,

            FrameEditor_Track_DrawSequence_checked,
            Options_Track_DrawRelativeTo_checked,
            Options_Track_Mirrors_checked,
            Options_Track_Limb_Radianss_checked,

            Options_LimbMouseController_checked,

            Options_RadiansStepSize,
            Options_MagnitudeStepSize,
            Options_TimerInterval,
            Options_FocusController_StepSize,
            Options_DrawAngle,
            _numOptions
        };

        /// <summary>
        /// states of the checked menus that need to be loaded before they are ready to be used
        /// </summary>
        public enum enuCheckedMenus
        {
            DrawSequence,
            HingeContact_Graphical,
            HingeContact_Numerical,
            debugTestData,
            LimbTracker,
            FrameEditor,
            AnimationControls,
            AnimationFrameEditor,
            AnimationSpeed,
            _numCheckedMenus
        };

        /// <summary>
        /// order in which the formatting information is recorded in the Format.txt file
        /// </summary>
        enum enuFormatData
        {
            DrawSequenceLeft,
            DrawSequenceTop,
            DrawSequenceWidth,
            DrawSequenceHeight,
            DrawCollapsed,
            DrawSequence_ExpansionDirection,

            HingeContact_Graphical_Left,
            HingeContact_Graphical_Top,
            HingeContact_Graphical_Width,
            HingeContact_Graphical_Height,
            HingeContact_Graphical_Collapsed,
            HingeContact_Graphical_ExpansionDirection,

            HingeContact_Numerical_Left,
            HingeContact_Numerical_Top,
            HingeContact_Numerical_Width,
            HingeContact_Numerical_Height,
            HingeContact_Numerical_Collapsed,
            HingeContact_Numerical_ExpansionDirection,

            FrameEditor_Left,
            FrameEditor_Top,
            FrameEditor_Width,
            FrameEditor_Height,
            FrameEditor_Collapsed,
            FrameEditor_ExpansionDirection,

            AnimationFrameEditor_Left,
            AnimationFrameEditor_Top,
            AnimationFrameEditor_Width,
            AnimationFrameEditor_Height,
            AnimationFrameEditor_Collapsed,
            AnimationFrameEditor_ExpansionDirection,

            AnimationSpeed_Left,
            AnimationSpeed_Top,
            AnimationSpeed_Width,
            AnimationSpeed_Height,
            AnimationSpeed_Collapsed,
            AnimationSpeed_ExpansionDirection,

            CostumeSelector_Left,
            CostumeSelector_Top,
            CostumeSelector_Width,
            CostumeSelector_Height,
            CostumeSelector_Collapsed,
            CostumeSelector_ExpansionDirection,

            AnimationControl_Left,
            AnimationControl_Top,
            AnimationControl_Width,
            AnimationControl_Height,
            AnimationControl_Collapsed,
            AnimationControl_ExpansionDirection,

            debugTestDataLeft,
            debugTestDataTop,
            debugTestDataWidth,
            debugTestDataHeight,
            debugCollapsed,
            debug_ExpansionDirection,

            MessengerLeft,
            MessengerTop,
            MessengerWidth,
            MessengerHeight,
            MessengerCollapsed,
            Messenger_ExpansionDirection,

            AutoInsertIntermediaryFrames_Left,
            AutoInsertIntermediaryFrames_Top,
            AutoInsertIntermediaryFrames_Width,
            AutoInsertIntermediaryFrames_Height,
            AutoInsertIntermediaryFrames_Collapsed,
            AutoInsertIntermediaryFrames_ExpansionDirection,

            Limb_Reattach_Left,
            Limb_Reattach_Top,
            Limb_Reattach_Width,
            Limb_Reattach_Height,
            Limb_Reattach_Collapsed,
            Limb_Reattach_ExpansionDirection,

            Limb_CopyFrames_Left,
            Limb_CopyFrames_Top,
            Limb_CopyFrames_Width,
            Limb_CopyFrames_Height,
            Limb_CopyFrames_Collapsed,
            Limb_CopyFrames_ExpansionDirection,
            
            Limb_SetAnimation_Left,
            Limb_SetAnimation_Top,
            Limb_SetAnimation_Width,
            Limb_SetAnimation_Height,
            Limb_SetAnimation_Collapsed,
            Limb_SetAnimation_ExpansionDirection,

            Limb_ImageController_Left,
            Limb_ImageController_Top,
            Limb_ImageController_Width,
            Limb_ImageController_Height,
            Limb_ImageController_Collapsed,
            Limb_ImageController_ExpansionDirection,

            OptionsPanel_Left,
            OptionsPanel_Top,
            OptionsPanel_Width,
            OptionsPanel_Height,
            OptionsPanel_Collapsed,
            OptionsPanel_ExpansionDirection,

            filename,

            Panels_DrawSequence_checked,
            Panels_HingeContacts_Graphical_checked,
            Panels_HingeContacts_Numerical_checked,
            Panels_Options_checked,
            Panels_FrameEditor_checked,
            Panels_AnimationFrameEditor_checked,
            Panels_AnimationSpeed_checked,
            Panels_CostumeSelector_checked,
            Panels_AnimationControls_checked,
            Panels_DebugDataTester_checked,

            Options_Show_LimbNames_checked,
            Options_Show_LimbCenters_checked,
            Options_Show_LimbPositions_checked,
            Options_Show_Frame,
            Options_Show_ToolTips,
            Options_Track_DrawRelativeTo_checked,
            Options_Track_Limb_Radianss_checked,
            Options_Show_FocusController_checked,
            Options_UseRAMCache_checked,
            Options_LimbMouseController_checked,
            Options_Radians_StepSize,
            Options_Magnitude_StepSize,
            Options_TimerInterval,
            Options_FocusController_StepSize,
            Options_DrawAngle,
            FrameEditor_Track_DrawSequence_checked,
            FrameEditor_Track_Mirrors,

            FocusController_X,
            FocusController_Y,
            Draw_Sprite_Screen_X,
            Draw_Sprite_Screen_Y,
            DrawZoom,

            Form_Width,
            Form_Height,
            Form_Location_X,
            Form_Location_Y,

            _numFormat
        };
        #endregion

        /// <summary>
        /// instantiation of the main form of SpriteEditor_2017
        /// </summary>
        public formSpriteEditor_2017()
        {
            instance = this;
            BackColor = Color.White;
            //bmpBackground = Properties.Resources.Background_Clear;
            classSprite.ShowErrorMessages = true;
            InitializeComponent();

            bckResize.WorkerReportsProgress = true;
            bckResize.WorkerSupportsCancellation = true;
            bckResize.DoWork += bckResize_DoWork;
            bckResize.RunWorkerCompleted += bckResize_RunWorkerCompleted;
            bckResize.ProgressChanged += bckResize_ProgressChanged;

            tmrIgnorMouseMove.Interval = 1000;
            tmrIgnorMouseMove.Tick += TmrIgnorMouseMove_Tick;
            tmrIgnorMouseMove.Enabled = false;

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //                                          form events
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            SizeChanged += FormSpriteEditor_2017_SizeChanged;
            Disposed += FormSpriteEditor_2017_Disposed;
            Activated += FormSpriteEditor_2017_Activated;

            // spriteMaker is needed in order to load, save or create sprites
            new classSpriteMaker();
            classSprite.Editor = true;

            // create instances of panelSizeLocation class ready to hold the format information about to be loaded
            for (int intFormCounter = 0; intFormCounter < (int)enuPanels._numForms; intFormCounter++)
                cPanelSizeLocations[intFormCounter] = new classPanelSizeLocation();

            if (!bolFormatLoaded)
            {   // loads the format information
                Format_Load();
                if (bolDieInWitheringAgony) return;
                bolFormatLoaded = true;
            }

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //                                              UI events
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            grbLimbEditor_Hinge_Contact_Master.Click += GrbLimbEditor_Hinge_Contact_Click;
            grbLimbEditor_Hinge_Contact_Slave.Click += GrbLimbEditor_Hinge_Contact_Click;

            txtHinge_Contact_Master_Magnitude.TextChanged += TxtHinge_Contact_Master_Magnitude_TextChanged;
            txtHinge_Contact_Master_Magnitude.MouseWheel += Txt_Magnitude_MouseWheel;
            txtHinge_Contact_Master_Radians.TextChanged += TxtHinge_Contact_Master_Radians_TextChanged;
            txtHinge_Contact_Master_Radians.MouseWheel += Txt_Radians_MouseWheel;

            txtHinge_Contact_Slave_Magnitude.TextChanged += TxtHinge_Contact_Slave_Magnitude_TextChanged;
            txtHinge_Contact_Slave_Magnitude.MouseWheel += Txt_Magnitude_MouseWheel;
            txtHinge_Contact_Slave_Radians.TextChanged += TxtHinge_Contact_Slave_Radians_TextChanged;
            txtHinge_Contact_Slave_Radians.MouseWheel += Txt_Radians_MouseWheel;

            txtHinge_Magnitude.MouseWheel += Txt_Magnitude_MouseWheel;
            txtHinge_Magnitude.KeyDown += txt_KeyDown_NumericOnly;
            txtHinge_Radians.MouseWheel += Txt_Radians_MouseWheel;

            txtOpacity.MouseWheel += txt_Byte_MouseWheel;

            cmbLimbs.SelectedIndexChanged += CmbLimbs_SelectedIndexChanged;

            picMain.MouseMove += PicMain_MouseMove;
            picMain.MouseDown += PicMain_MouseDown;
            picMain.MouseUp += PicMain_MouseUp;
            picMain.MouseWheel += PicMain_MouseWheel;
            picMain.KeyDown += PicMain_KeyDown;
            picMain.KeyUp += PicMain_KeyUp;

            cMnu_Build();
            cMnuPic.Popup += cMnuPic_Popup;

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ///                                         initialize timers
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            tmrAnimation.Interval = 100;
            tmrAnimation.Tick += TmrAnimation_Tick;

            tmrRefreshText.Interval = 10000;
            tmrRefreshText.Tick += TmrRefreshText_Tick;

            tmrDrawSizeFactor_Refresh.Interval = 5000;
            tmrDrawSizeFactor_Refresh.Tick += TmrDrawSizeFactor_Refresh_Tick;

            tmrFocusDelta.Interval = 250;
            tmrFocusDelta.Tick += TmrFocusDelta_Tick;

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //                                          create and format panels
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            pnlMessenger = new panelMessenger();
            Controls.Add(pnlMessenger);
            pnlMessenger.Text = "";
            pnlMessenger.Visible = false;

            pnlDrawSequence = new panelDrawSequence(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlDrawSequence);
            pnlDrawSequence.Heading.Text = "Draw Sequence";
            pnlDrawSequence.BringToFront();
            mnuPanels_DrawSequence.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.DrawSequence];
            pnlDrawSequence.Visible = mnuPanels_DrawSequence.Checked;

            pnlHingeContacts_Set_Graphical = new panelHingeContact_Graphical(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlHingeContacts_Set_Graphical);
            pnlHingeContacts_Set_Graphical.Heading.Text = "Set Contact Hinges";
            pnlHingeContacts_Set_Graphical.BringToFront();
            mnuPanels_HingeContact_Graphical.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.HingeContact_Graphical];
            pnlHingeContacts_Set_Graphical.Visible = mnuPanels_HingeContact_Graphical.Checked;

            pnlHingeContacts_Set_Numerical = new panelHingeContact_Numerical(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlHingeContacts_Set_Numerical);
            pnlHingeContacts_Set_Numerical.Heading.Text = "Set Contact Hinges";
            pnlHingeContacts_Set_Numerical.BringToFront();
            mnuPanels_HingeContact_Numerical.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.HingeContact_Numerical];
            pnlHingeContacts_Set_Numerical.Visible = mnuPanels_HingeContact_Numerical.Checked;

            pnlFrameEditor = new panelFrameEditor(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlFrameEditor);
            pnlFrameEditor.Heading.Text = "Frame Editor";
            pnlFrameEditor.BringToFront();
            mnuPanels_FrameEditor.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.FrameEditor];
            pnlFrameEditor.Visible = mnuPanels_FrameEditor.Checked;

            pnlAnimation_FrameEditor = new panelAnimationFrameEditor(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlAnimation_FrameEditor);
            pnlAnimation_FrameEditor.Heading.Text = "Animation Frame Editor";
            pnlAnimation_FrameEditor.BringToFront();
            mnuPanels_AnimationFrameEditor.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.AnimationFrameEditor];
            pnlAnimation_FrameEditor.Visible = mnuPanels_AnimationFrameEditor.Checked;

            pnlAnimation_Speed = new panelAnimationSpeed(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlAnimation_Speed);
            pnlAnimation_Speed.Heading.Text = "Animation Speed";
            pnlAnimation_Speed.BringToFront();
            mnuPanels_AnimationSpeed.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.AnimationSpeed];
            pnlAnimation_Speed.Visible = mnuPanels_AnimationSpeed.Checked;

            pnlCostume_Selector = new panelCostume_Selector(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlCostume_Selector);
            pnlCostume_Selector.Heading.Text = "Costume Selector";
            pnlCostume_Selector.BringToFront();
            pnlCostume_Selector.Collapsed = cPanelSizeLocations[(int)enuPanels.CostumeSelector].Collapsed;
            mnuPanels_CostumeSelector.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.AnimationFrameEditor];
            pnlCostume_Selector.Visible = mnuPanels_CostumeSelector.Checked;

            pnlAnimationControls = new panelAnimation_Controls(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlAnimationControls);
            pnlAnimation_container.BackColor = pnlAnimationControls.Heading.BackColor;
            pnlAnimation_container.ForeColor = pnlAnimationControls.Heading.ForeColor;
            pnlAnimationControls.Heading.Text = "Animation Control";
            pnlAnimationControls.BringToFront();
            pnlAnimationControls.Collapsed = cPanelSizeLocations[(int)enuPanels.AnimationControl].Collapsed;
            mnuPanels_AnimationControls.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.AnimationControls];
            pnlAnimationControls.Visible = mnuPanels_AnimationControls.Checked;

            pnlAutoInsertIntermediaryFrames = new panelAutoInsertIntermediaryFrames(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlAutoInsertIntermediaryFrames);
            pnlAutoInsertIntermediaryFrames.Heading.Text = "Autoinsert Intermediary Animation Frames";
            pnlAutoInsertIntermediaryFrames.BringToFront();
            pnlAutoInsertIntermediaryFrames.btnGo.Click += BtnAutoInsertIntermediaryFrames_Go_Click;
            pnlAutoInsertIntermediaryFrames.Visible = mnuAnimation_AutoInsertIntermediaryFrames.Checked;

            pnlLimb_Reattach = new panelLimb_Reattach(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlLimb_Reattach);
            pnlLimb_Reattach.btnOk.Click += pnlLimb_Reattach_BtnOk_Click;
            pnlLimb_Reattach.Heading.Text = "Reattach Limb";
            pnlLimb_Reattach.Visible = false;
            pnlLimb_Reattach.BringToFront();
                                 
            pnlLimb_CopyFrames = new panelLimb_CopyFrames(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlLimb_CopyFrames);
            pnlLimb_CopyFrames.btnOk.Click += pnlLimb_CopyFrames_BtnOk_Click;
            pnlLimb_CopyFrames.Heading.Text = "CopyFrames Limb";
            pnlLimb_CopyFrames.Visible = false;
            pnlLimb_CopyFrames.BringToFront();
                                             
            pnlLimb_SetAnimation = new panelLimb_SetAnimation(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlLimb_SetAnimation);
            pnlLimb_SetAnimation.btnOk.Click += pnlLimb_SetAnimation_BtnOk_Click;
            pnlLimb_SetAnimation.Heading.Text = "SetAnimation Limb";
            pnlLimb_SetAnimation.Visible = false;
            pnlLimb_SetAnimation.BringToFront();

            pnlLimb_ImageController = new panelLimb_ImageController(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlLimb_ImageController);
            pnlLimb_ImageController.Heading.Text = "Limbe Image Controller";
            pnlLimb_ImageController.BringToFront();
            mnuPanels_AnimationFrameEditor.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.AnimationFrameEditor];
            pnlLimb_ImageController.Visible = mnuPanels_AnimationFrameEditor.Checked;

            pnlOptions = new panelOptions(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlOptions);
            pnlOptions.Heading.Text = "Options";
            pnlOptions.Visible = mnuPanels_Options.Checked;
            pnlOptions.BringToFront();

            pnlDebug = new panelDebug(new Font("Mongolian Baiti", 12));
            Controls.Add(pnlDebug);
            pnlDebug.Heading.Text = "Debugger : Test Data";
            pnlDebug.Heading.ForeColor = Color.Black;
            pnlDebug.Heading.BackColor = Color.White;
            pnlDebug.BringToFront();
            mnuPanels_DataTester.Checked = bolPanelCheckedStates[(int)enuCheckedMenus.debugTestData];

            Controls.Add(grbDisjointedLimbs);
            grbDisjointedLimbs.Size = new Size(600, 450);
            grbDisjointedLimbs.Location = new Point((Screen.PrimaryScreen.WorkingArea.Size.Width - grbDisjointedLimbs.Width) / 2,
                                                    (Screen.PrimaryScreen.WorkingArea.Size.Height - grbDisjointedLimbs.Height) / 2);
            grbDisjointedLimbs.Hide();
            //
            loadFocusControllerImages();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ///                                         Load sprite
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            if (strFilename_Current != null && strFilename_Current.Length > 0)
                File_Load(strFilename_Current);
            else
                Sprite_New("New Sprite");


            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ///                                         reset components that need initializing with new sprite loaded
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            lblFrame_Value_Set();
            cmbLimbs_Reset();
            cmbLimbs_SetSelect(classSprite.conMasterLimb_Name);
            cmbAnimation_Refresh();

            if (cSpriteData.cAnimationData.cAnimation != null)
            {
                cmbAnimation_Set(cSpriteData.cAnimationData.cAnimation.Name);
                DrawSizeFactor = dblDrawFactor_Load;
                cSpriteData.cAnimationData.dblDrawAngle = (double)objOptions[(int)enuOptions.Options_DrawAngle];
            }
            pnlFrameEditor.cSprite = cSpriteData.cAnimationData.cSprite;

            pnlOptions.lstLimbImageRotationSelection[(int)cSpriteData.cAnimationData.cSprite.eRotatedLimbImage].Checked = true;

            ToolTip_SetUp();

        }


        /// <summary>
        /// classToolTip allows multiple tips to be assigned to each control
        /// </summary>
        public classToolTip cTTips = new classToolTip();

        /// <summary>
        /// initializes an instance of classToolTip with all the tips for each control
        /// </summary>
        void ToolTip_SetUp()
        {
            cTTips.Tip_Clear_All();

            // Set up the delays for the ToolTip.
            toolTip.AutoPopDelay = 5000;
            toolTip.InitialDelay = 1000;
            toolTip.ReshowDelay = 100;
            toolTip.UseAnimation = true;
            toolTip.Popup += ToolTip_Popup;

            // Force the ToolTip text to be displayed whether or not the form is active.
            toolTip.ShowAlways = true;

            #region DrawSequence
            string[] strTips = {
                "sets the order in which the limbs will be drawn in a given animation.",
                "Limbs drawn later may cover limbs drawn earlier.",
                "move over list with left-mouse button down to select multiple entries.",
                "you can grab multiple entries with the right mouse button and move them up or down together."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
                cTTips.Tip_set(pnlDrawSequence.mbpLimbs.Name, strTips[intCounter]);
            #endregion

            #region FrameEditor
            // panelFrameEditor
            strTips = new string[] {
                "selects the limb currently being edited and positioned in an animation frame.",
                "you can select a limb using the DrawSequence.",
                "you can select a limb by clicking on the center of its image on the sprite display screen."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblLimb.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlFrameEditor.cmbLimb.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "provides tool used to select which Limb image to be drawn in a given frame of an animation",
                "you can use the Limb Editor to add, delete or change the images available for this limb."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblLimbImageList_Index.Name, strTips[0]);
                cTTips.Tip_set(pnlFrameEditor.pnlScr_LimbImageList.Name, strTips[0]);
            }

            strTips = new string[] {
                "angle which a limb makes with its master limb",
                "angle can be controlled using the MouseController option in the Frame Editor panel",
                "you can change this value in the textbox using the mouse wheel",
                "the amount by which this value is changed using the mouse wheel is set in the Options Panel Radians Step textbox"
            };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblHinge_Radians.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlFrameEditor.txtHinge_Radians.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "factor by which the magnitude component of radial coordinate describing the limb's Slave Contact is multiplied.",
                "values above 1.0 push the limb away from its master, values below 1.0 pull the limb towards its master.",
                "you can change this value in the textbox using the mouse wheel",
                "the amount by which this value is changed using the mouse wheel is set in the Options Panel Magnitude Step textbox"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblHinge_Magnitude.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlFrameEditor.txtHinge_Magnitude.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "selects which frame of an animation is to be displayed.",
                "use the mouse-wheel to scroll through the animation frames without setting any Track options."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblFrameCounter.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlFrameEditor.nudFrameCounter.Name, strTips[intCounter]);
                cTTips.Tip_set(lblFrameCounter_ValueDisplay.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "adds a copy of the current animation frame to the animation immediately after the currently selected frame",
                "using the Animation Frame Editor panel can help adding, removing and copying frames in an animation."
            };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblFrame_Add.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                 "deletes the current animation frame from the animation",
                 "using the Animation Frame Editor panel can help adding, removing and copying frames in an animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblFrame_Sub.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "makes a copy of the currently viewed frame and stores it in memory to be later inserted into an animation with the 'insert' button",
                "using the Animation Frame Editor panel can help adding, removing and copying frames in an animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblFrame_Copy.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "inserts the frame last copied to memory using the 'copy' button into the animation",
                "using the Animation Frame Editor panel can help adding, removing and copying frames in an animation." };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.lblFrame_Insert.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "determines whether the current frame will be mirrored horizontally in the animation"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.chkMirror_Horizontal.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "determines whether the current frame will be mirrored vertically in the animation"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.chkMirror_Vertical.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "Selects the limb about which the rest of the animation will be drawn.  MasterLimb is the default setting.",
                "toggling the draw RelativeToLimb checkbox off helps while editing limb positions."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.cmbDrawRelativeToLimb.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlFrameEditor.chkDrawRelativeToLimb_EditorToggle.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "copies the radial coordinate of the selected limbs from their current state onto the following frame when an animation 'step' or 'run' cycles through the frames.",
                "you can copy All Tracked information from one frame to the next by 'stepping' through an animation.",
                "running the animation with a Tracker on will copy current values being tracked to ALL frames in the animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.clbLimbTracker_Radians.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlFrameEditor.chkTrack_Limb_Radians.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "when set the current DrawSequence will be copied over to the next frame using the animation 'step' or 'run' controls. ",
                "you can copy All Tracked information from one frame to the next by 'stepping' through an animation.",
                "running the animation with a Tracker on will copy current values being tracked to ALL frames in the animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.chkTrack_DrawSequence.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "when set the current mirror settings will be copied over to the next frame using the animation 'step' or 'run' controls",
                "you can copy All Tracked information from one frame to the next by 'stepping' through an animation.",
                "running the animation with a Tracker on will copy current values being tracked to ALL frames in the animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.chkTrack_Mirrors.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "when set the DrawRelativeTo limb setting is copied onto the next frame using the animation 'step' or 'run' controls",
                "you can copy All Tracked information from one frame to the next by 'stepping' through an animation.",
                "running the animation with a Tracker on will copy current values being tracked to ALL frames in the animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.chkTrack_DrawRelativeTo.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "when checked the mouse can be used to control a selected limb directly on the Sprite Display screen",
                "toggling off the DrawRelativeTo checkbox may help editing limb positions with the mouse control"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlFrameEditor.chkMouse_LimbControl.Name, strTips[intCounter]);
            }
            #endregion

            #region HingeContact_Graphical
            // pnlHingeContact_Graphical
            strTips = new string[] {
                "The angle the selected limb makes with its master in the current frame.",
                "you can change this angle on the Sprite Draw Screen with the mouse by setting the MouseControl option in the Frame Editor Panel"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.lblAngle_Name.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.lblAngle_Value.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "The factor by which the limb hinge's Slave Contact's magnitude is multiplied in the current frame.",
                "a value of 1.0 draw the limb as it was set using either the Graphical or Numerical Hinge Contact controls",
                "a value greater than 1.0 pushes the limb away from its master",
                "a value less than 1.0 pulls the limb closer to its master"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.lblMagnitude_Name.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.lblMagnitude_Value.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "radial coordinate describing the position of the limb's hinge relative to the Master Limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls",
                "you can zoom in or out using the mouse wheel"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.grbMaster.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.picMaster.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "angle of radial coordinate that describes the Limb's hinge's Master-Contact relative to the Master Limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.lblMaster_Radians.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "magnitude of radial coordinate that describes the Limb's hinge's Master_Contacdt relative to the Master Limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.lblMaster_Magnitude.Name, strTips[intCounter]);
            }

            strTips = new string[] { "radial coordinate describing the position of the limb's hinge relative to the Limb's center",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls",
                "you can zoom in or out using the mouse wheel"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.grbSlave.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Graphical.picSlave.Name, strTips[intCounter]);
            }
            #endregion

            #region HingeContact_Numerical
            // pnlHingeContact_Numerical

            strTips = new string[] {
                "radial coordinate describing the position of Limb's Hinge relative to the center of its Master Limb.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.grbMaster.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "radial coordinate describing the position of Limb's Hinge relative to that Limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.grbSlave.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "angular component of the radial coordinate describing the limb's hinge position relative to the limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls",
                "you can set the amount of change the mouseWheel makes on the Options Panel's Radian Step textbox"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.lblSlave_Rad.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.txtSlave_Rad.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "magnitude component of the radial coordinate describing the limb's hinge position relative to the limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls",
                "you can set the amount of change the mouseWheel makes on the Options Panel's Magnitude Step textbox",
                "scrolling the mouse wheel will change the value in the Options Panel's Magnitude Step textbox",
                "scrolling while holding down the left mouse button will change the OptionPanel's Magnitude Step textbox value"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.lblSlave_Mag.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.txtSlave_Mag.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "angular component of the radial coordinate describing the limb's hinge position relative to the master limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls",
                "you can set the amount of change the mouseWheel makes on the Options Panel's Radian Step textbox"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.lblMaster_Rad.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.txtMaster_Rad.Name, strTips[intCounter]);
            }

            strTips = new string[] { "magnitude component of the radial coordinate describing the limb's hinge position relative to the master limb's center.",
                "this value can be changed either using the Grahpical or Numerical Hinge Contact Controls",
                "you can set the amount of change the mouseWheel makes on the Options Panel's Magnitude Step textbox",
                "scrolling the mouse wheel will change the value in the Options Panel's Magnitude Step textbox",
                "scrolling while holding down the left mouse button will change the OptionPanel's Magnitude Step textbox value"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.lblMaster_Mag.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlHingeContacts_Set_Numerical.txtMaster_Mag.Name, strTips[intCounter]);
            }

            #endregion

            #region Animation_Controls

            // pnlAnimation_Controls

            strTips = new string[] {
                "select.Name, step through or run an animation"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimationControls.pnlAnimation.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "lets an animation to run on a timer.",
                "running the animation with any of the Tracking options set will set all frames of that animation to Tracked values."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimationControls.lbtnRun.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "advances animation frame by one",
                "Stepping to the next frame will carry any Tracked data over and overwrite the data of the next frame that you are Tracking"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimationControls.lbtnStep.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "selects an animation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimationControls.lblAnimation.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlAnimationControls.cmbAnimation.Name, strTips[intCounter]);
            }

            #endregion

            #region AnimationFrameEditor

            strTips = new string[] {
                "control bar holds all the Animation Frame Editor's controls",
                "you can also use the Frame Editor's Copy and Insert options to manipulate one frame at a time."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.pnlBar.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "shifts to previous frame",
                "using the mouse wheel allows you to shift Left or Right more easily"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblLeft.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "shifts to next frame",
                "using the mouse wheel allows you to shift Left or Right more easily"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblRight.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "makes a copy of selected frames and adds them to the AnimationFrameEditor's clipboard",
                "to clear the frames already on the ClipBoard just press the 'Clear Clipboard' button"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblCopy_ToClipBoard.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "inserts all clipboard frames into animation after the first selected frame in animation(0th frame if none selected).",
                "you can use the Frame Editor's Copy/Insert options to manipulate one frame at a time."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblInsert_Clipboard.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "removes selected frames from animation and copies them onto the AnimationFrameEditor's clipboard.",
                "you can use the Frame Editor's Copy/Insert options to manipulate one frame at a time."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblCut_ToClipBoard.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "deletes all selected frames from the animation.",
                "you can use the Frame Editor's Copy/Insert options to manipulate one frame at a time."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblDelete.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "Unselect all animation frames",
                "you can either click on each frame individually or click this button to unselect all frames at once"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblSelect_All.Name, strTips[intCounter]);
            }
            
            strTips = new string[] {
                "select all animation frames",
                "you can either click on each frame individually or click this button to select all frames at once"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblUnselect_All.Name, strTips[intCounter]);
            }
            
            strTips = new string[] {
                "reverse the order of the frames that are in the clipboard by clicking this button",
                "by inserting certain frames in reverse order you can reverse the actions of your sprite"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblReverseOrder.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "invaluable tool used by the writer to get this thing to scroll properly."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlAnimation_FrameEditor.lblDebug.Name, strTips[intCounter]);
            }
            #endregion

            #region Messenger

            strTips = new string[] {
               "enter the requested information here.",
                "will only allow :" +classSprite_Limb.ValidLimbNameChar,
                "press ESC anytime or ENTER with an empty textbox to cancel"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlMessenger.txtUserInput.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "this is the information needed to complete your operation."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlMessenger.txtText.Name, strTips[intCounter]);
            }
            #endregion

            #region Options
            // pnlOptions}
            strTips = new string[] {
                "amount by which all magnitude text boxes will change using the mouse wheel.",
                "you can change this value by scrolling in any Magnitude textboxes using the Left Mouse Button"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.lblOptions_Magnitude_StepSize.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlOptions.txtOptions_Magnitude_StepSize.Name, strTips[intCounter]);
            }

            strTips = new string[] { "amount by which all radian textboxes will change using the mouse wheel.",
                "you can change this value by scrolling in any Radian textboxes using the Left Mouse Button"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.lblOptions_Radians_StepSize.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlOptions.txtOptions_Radians_StepSize.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "Angle to which the entire sprite will be rotated on the screen.",
                "you can steer a sprite's direction by changing this value while an animation is running",
                "you can change this value using the mouse wheel",
                "the amount by which this value changes using the mouse wheel is set in the Options Panel's Radian Step textbox",
                "you can change the Option Panel's Radian Step textbox value by scrolling here with the Left Mouse button held down"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.lblOptions_DrawAngle.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlOptions.txtOptions_DrawAngle.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "Distance by which the Sprite will move on the screen using the Focus Controller direction arrows.",
                "you can change this value using the mouse wheel",
                "the amount by which this value is changed using the mouse wheel is set in the Option's Panel's Magnitude Step textbox",
                "you can change the Option Panel's Magnitude Step textbox value here using the MouseWheel while holding down the left Mouse button"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.lblFocusController_StepSize.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlOptions.txtFocusController_StepSize.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "time in milliseconds between the drawing of each frame when the animation 'run' option is set.",
                "using the RAMCache option should improve the Sprite's performance and allow for faster animation"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.lblTimerDelay.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlOptions.txtTimerDelay.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "toggles the Costume of limb names on the sprite display screen."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.chkShow_LimbNames.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "toggles the Costume of the limb positions on the sprite display screen.",
                "select limbs whose positions are to be displayed on the sprite display screen."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.chkShow_LimbPositions.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlOptions.clbShow_LimbPositions.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "toggles the Costume of limb center locator displays to help select and position limbs.",
                "seeing where the limb's center is makes it easier to select it using the mouse on the Sprite Draw screen"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.chkShow_LimbCenters.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "toggles the Costume of the four-direction sprite location controller.",
                "you can use the Focus Controller to move the sprite on the screen",
                "Focus Controller allows you to zoom the sprite in/out to help in the editing"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.chkShow_FocusController.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "toggles the Costume of a red box to frame the sprite on the sprite display screen.",
                "remember that all limb positions are measured from the Top Left of the frame's output Bitmap"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.chkShow_Frame.Name, strTips[intCounter]);
            }

            strTips = new string[] {
                "toggles the sprite's use of the RAM cache.",
                "All changes made to the sprite will be ignored as it will retrieve and display cached images and not redraw recent changes.",
                "RAM cache does not draw new images NO NEW CHANGES WILL BE DRAWN",
                "RAM cache will be forced to redraw images when there are changes to the output : angle or size"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlOptions.chkUseRAMCache.Name, strTips[intCounter]);
            }
            #endregion 

            #region Limb_Reattach
            // pnlLimb_Reattach}
            strTips = new string[] {
                "limb about to be reattached to a different master-limb.",
                "reattaching this limb to a different master-limb will alter this limb's position on the final sprite"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_Reattach.picLimbToReattach.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlLimb_Reattach.lblLimbToReattach.Name, strTips[intCounter]);
            }

            strTips = new string[] { "limb's current master limb." };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_Reattach.picMasterLimb_Current.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlLimb_Reattach.lblMasterLimb_Current.Name, strTips[intCounter]);
            }

            strTips = new string[] { "limb to be new master limb" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_Reattach.picMasterLimb_New.Name, strTips[intCounter]);
                cTTips.Tip_set(pnlLimb_Reattach.lblMasterLimb_new.Name, strTips[intCounter]);
            }

            strTips = new string[] { "list of limbs from which a new master limb is to be chosen." };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_Reattach.cmbMasterLimbs.Name, strTips[intCounter]);
            }
            
            strTips = new string[] { "the currently selected limb can be detached from its master limb and reattached to a new master limb." };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                for (int intLabelCounter = 0; intLabelCounter < pnlLimb_Reattach.lblText.Length; intLabelCounter++)
                {
                    pnlLimb_Reattach.lblText[intLabelCounter].Name = "pnlLimb_ReattachLabel_" + intLabelCounter.ToString();
                    cTTips.Tip_set(pnlLimb_Reattach.lblText[intLabelCounter].Name, strTips[intCounter]);
                }
            }

            strTips = new string[] { "completes the operation with selected new master limb." };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_Reattach.btnOk.Name, strTips[intCounter]);
            }

            strTips = new string[] { "cancels reattach limb operation and hides this form" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_Reattach.btnCancel.Name, strTips[intCounter]);
            }

            #endregion

            #region Limb_CopyFrames

            strTips = new string[] {
                "click here when you're done setting up your Limb Copy Frame instructions",
                "just click here when you're done."};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.btnOk.Name ,strTips[intCounter]);
            }

            strTips = new string[] { "click here to cancel your Limb Copy Frames operation" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.btnCancel.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose the limbs that will have their data overwritten by this operation",
                                     "all limbs selected here will behave as they do in the source animation"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lbxLimbs.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose which animations will have their limbs behave as they do in the source animation",
                                     "you can choose which animations will be affected by this operation here"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lbxAnimations_Destination.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select one animation from which the data will be copied to your chosen destination animations",
                                     "you can copy the limb information of one source animation to one or more destination animations"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lbxAnimation_Source.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select which frames from the source animation will be copied to the destination animations",
                                     "only the frames selected here will be copied to the destination animations" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lbxFramesToCopy.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select which limbs of your destination animations to behave as they do in the source animation" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lblLimbs.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select which animations will have their limbs behave as they do in the source animation",
                                     "you can select multiple destination animations to mimic the one source animation"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lblAnimations_Destination.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose which animation will be copied onto the destination animations",
                                    "only one animation will be source of the data which is then copied onto the selected destination animations"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lblAnimation_Source.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select which frames of the source animation will be copied onto the desetination animations",
                                     "all frames of the destination animation will be overwritten regardless of how many source frames your choose here"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.lblFramesToCopy.Name, strTips[intCounter]);
            }

            strTips = new string[] { "copy all the limbs from the source to the destination exactly the same when checked",
                                    "unchecking this will allow the app to vary which frames are deleted from one limb to the next",
                                    "all destination frames are overwritten with the source frames - regardless of the number"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_CopyFrames.chkKeepFrameIntegrity.Name, strTips[intCounter]);
            }

            #endregion

            #region panel_Limb_SetAnimation

            strTips = new string[] { "click here when you're done" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.btnOk.Name, strTips[intCounter]);
            }

            strTips = new string[] { "click here to cancel the operation" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.btnCancel.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose which animation you want to edit",
                                     "Limb Set Animation allows you to create flowing animations of specific limbs while keeping previously edit limb motions intact"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.cmbAnimations.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose which animation yo uwant to edit here below" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.lblAnimations.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select only the limbs you want to edit",
                                    "only those limbs selected will be affected"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.lbxLimbs.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose the frame you want to start editing from",
                                    "you can use the editor to position the selected limbs for this frame before pressing the 'ok' button below",
                                     "be sure to position the selected limbs where you want them to start from at the frame selected here"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.nudFrame_Start.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose the frame you want to end edting at",
                                      "use the editor to position the limbs you've selected before pressing the 'ok' button",
                                     "be sure to position the selected limbs where you want them to end at the frame selected here"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.nudFrame_End.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose the frame at which you will start your editing" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.lblFrame_Start.Name, strTips[intCounter]);
            }

            strTips = new string[] { "choose which frame will end your editing" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.lblFrame_End.Name, strTips[intCounter]);
            }

            strTips = new string[] { "select which limbs you want to edit" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(pnlLimb_SetAnimation.lblLimbs.Name, strTips[intCounter]);
            }

            #endregion

            #region PicMain_ToolTips
            //enuPic_ToolTip

            strTips = new string[] {
                "sets Sprite's draw size to its original default size"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_100PC.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "left click here to center the sprite on the Sprite Draw Screen",
                "you can scroll the mouse here to zoom in/out",
                "right click here to grab the Focus Controller and move it wherever you like"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_Center.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "hold the mouse button down here to move the sprite down on the Sprite Draw Screen",
                "the amount by which the Sprite is moved on the screen is set in the Options Panel's Focus Controller textbox"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_Down.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "the Sprite Draw Screen is where you can see and edit your sprite"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_Idle.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "hold the mouse button down here to move the sprite to the left on the Sprite Draw Screen",
                "the amount by which the Sprite is moved on the screen is set in the Options Panel's Focus Controller textbox"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_Left.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "clicking here halves the size at which the sprite is drawn"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_ReduceSize.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "hold the mouse button down here to move the sprite to the right on the Sprite Draw Screen",
                "the amount by which the Sprite is moved on the screen is set in the Options Panel's Focus Controller textbox"};
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_Right.ToString(), strTips[intCounter]);
            }

            strTips = new string[] {
                "hold the mouse button down here to move the sprite up on the Sprite Draw Screen",
                "the amount by which the Sprite is moved on the screen is set in the Options Panel's Focus Controller textbox" };
            for (int intCounter = 0; intCounter < strTips.Length; intCounter++)
            {
                cTTips.Tip_set(enuPic_ToolTip.FC_UP.ToString(), strTips[intCounter]);
            }
            #endregion
        }

        /// <summary>
        /// prevents tool tip from giving the same control a tip every mousemove over that control
        /// </summary>
        object objAssociatedControl = null;
        /// <summary>
        /// stops edits tool tip with the multiple tips available for a given control
        /// </summary>
        private void ToolTip_Popup(object sender, PopupEventArgs e)
        {
            if (e.AssociatedControl == objAssociatedControl
                || e.AssociatedControl == null
                || e.AssociatedControl.Name.Length == 0) return;
            objAssociatedControl = e.AssociatedControl;
            string strName = e.AssociatedControl.Name;
            string strTip = cTTips.Tip_get(strName);

            if (strTip.Length > 0)
                toolTip.SetToolTip(e.AssociatedControl, strTip);
        }
        private void cMnuPic_Popup(object sender, EventArgs e)
        {
            cMnu_Build();
        }

        /// <summary>
        /// creates all the menu options for the context menues
        /// </summary>
        void cMnu_Build() { cMnu_Build(tmrAnimation.Enabled); }
        void cMnu_Build(bool bolAnimationRunning)
        {
            cMnuPic.MenuItems.Clear();
            if (bolAnimationRunning)
            {
                MenuItem mnuStep_stopped = new MenuItem("Step", mnuAnimation_Frames_Step_Click);
                cMnuPic.MenuItems.Add(mnuStep_stopped);
            }
            else
            {
                cMnuPic.MenuItems.Add("panel.options.placeobjects()", mnuDebug_PnlOptions_PlaceObjects_Clicked);

                MenuItem mnuStep_stopped = new MenuItem("Step", mnuAnimation_Frames_Step_Click);
                cMnuPic.MenuItems.Add(mnuStep_stopped);

                MenuItem mnuRun = new MenuItem("Run", mnuAnimation_Frames_Run_Click);
                cMnuPic.MenuItems.Add(mnuRun);

                MenuItem mnuLimb_Image_Select = new MenuItem("Limb Image Select");
                mnuLimb_Image_Select.Click += mnuLimb_Image_Select_Click;
                cMnuPic.MenuItems.Add(mnuLimb_Image_Select);

                MenuItem mnuLimb_CopyFrames = new MenuItem("Limb Copy Frames", mnuLimb_CopyFrames_click);
                cMnuPic.MenuItems.Add(mnuLimb_CopyFrames);

                MenuItem mnuLimb_SetAnimation = new MenuItem("Limb Set Animation", mnuLimb_SetAnimation_click);
                cMnuPic.MenuItems.Add(mnuLimb_SetAnimation);

                MenuItem mnuAutoInsertIntermediaryFrames = new MenuItem("Auto Insert Intermediary Frames");
                mnuAutoInsertIntermediaryFrames.Click += mnuAnimation_AutoInsertIntermediaryFrames_Click;
                cMnuPic.MenuItems.Add(mnuAutoInsertIntermediaryFrames);

                //MenuItem mnuCreateTextSprite = new MenuItem("Create Text Sprite", mnuCreateTextSprite_Click);
                //cMnuPic.MenuItems.Add(mnuCreateTextSprite);


                MenuItem mnuDebug = new MenuItem("Toggle Debug", mnuToggleDebug_click);
                cMnuPic.MenuItems.Add(mnuDebug);


                MenuItem mnuEditor = new MenuItem("Editor : " + (classSprite.Editor ? "turn off" : "turn on"), mnuToggleEditor_click);
                cMnuPic.MenuItems.Add(mnuEditor);

                // /*
                MenuItem mnuFormatResetCreateStringForIDE = new MenuItem("Format Reset : create string for IDE", mnuFormatResetCreateStringForIDE_click);
                cMnuPic.MenuItems.Add(mnuFormatResetCreateStringForIDE);
                // /*/
            }
            picMain.ContextMenu = cMnuPic;
        }


        void mnuToggleDebug_click(object sender, EventArgs e)
        {
            classSprite.bolDebug = !classSprite.bolDebug;
            Draw_Sprite();
        }
        
        void mnuToggleEditor_click(object sender, EventArgs e)
        {
            classSprite.Editor = !classSprite.Editor;
            Draw_Sprite();
            cMnu_Build();
        }

        void mnuCreateTextSprite_Click(object sender, EventArgs e)
        {
            if (formCreateTextSprite.instance == null || formCreateTextSprite.instance.IsDisposed)
                new formCreateTextSprite();

            formCreateTextSprite.instance.ShowDialog();
        }

        void mnuAnimation_ShowDisjointedLimbList_click(object sender, EventArgs e)
        {
            grbDisjointedLimbs.Visible = !grbDisjointedLimbs.Visible;
            if (grbDisjointedLimbs.Visible)
                grbDisjointedLimbs.BringToFront();
        }

        /// <summary>
        /// displaces Limb image selection list from panelFrameEditor to position it beneath the mouse cursor over picMain
        /// </summary>
        private void mnuLimb_Image_Select_Click(object sender, EventArgs e)
        {
            if (!picMain.Contains(pnlFrameEditor.pnlScr_LimbImageList))
                picMain.Controls.Add(pnlFrameEditor.pnlScr_LimbImageList);
            pnlFrameEditor.pnlScr_LimbImageList.Location = new Point(ptPicMain_Mouse.X - 2, ptPicMain_Mouse.Y - 2);
            classSprite_Limb cLimbRef = cLimb;
            pnlFrameEditor.pnlScr_LimbImageList_Init(ref cLimbRef);
            pnlFrameEditor.pnlScr_LimbImageList.Show();
        }

        /// <summary>
        /// returns the focusController's image to its default state after having displayed the sprite's current DrawSize
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TmrDrawSizeFactor_Refresh_Tick(object sender, EventArgs e)
        {
            tmrDrawSizeFactor_Refresh.Enabled = false;
            strSizeDrawFactor = "";
            Draw_Controls();
        }

        /// <summary>
        /// moves the sprite on the screen according to the user's FocusControl commands
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TmrFocusDelta_Tick(object sender, EventArgs e)
        {
            cSpriteData.pt = classMath3.AddTwoPoints(cSpriteData.pt, ptFocus_Delta);
            ptDraw_DrawRel_Off = classMath3.AddTwoPoints(ptDraw_DrawRel_Off, ptFocus_Delta);

            if (MouseButtons != MouseButtons.Left && (ptFocus_Delta.X != 0 || ptFocus_Delta.Y != 0))
            {
                tmrFocusDelta.Enabled = false;
                ptFocus_Delta = new Point();
            }
            Draw_Sprite();
        }

        /// <summary>
        /// carries out the operation of detaching a limb from its current master and reattaching it to its new master determined by the user via the panelLimb_Reattach UI
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pnlLimb_Reattach_BtnOk_Click(object sender, EventArgs e)
        {
            classSprite_Limb cLimbMaster_New = (classSprite_Limb)cSpriteData.cCostumeInfo.cBT_Limbs.Search(pnlLimb_Reattach.cmbMasterLimbs.Text);
            classSprite_Limb cLimbToReattach = cLimb;

            Limb_Reattach(ref cLimbToReattach, ref cLimbMaster_New);
            pnlLimb_Reattach.Hide();

            Costumes_MatchDefault();
            Draw_Sprite();

            setLimbInfo();
        }

        /// <summary>
        /// completes the reattaching limb operation
        /// </summary>
        /// <param name="cLimb"></param>
        /// <param name="cLimb_Master_New"></param>
        void Limb_Reattach(ref classSprite_Limb cLimb, ref classSprite_Limb cLimb_Master_New)
        {
            if (cLimb_Master_New == null) return;

            classSprite_Hinge cHinge = cLimb.Hinge;
            cHinge.Limb_Master.lstHinge_Slaves.Remove(cHinge);
            cLimb_Master_New.lstHinge_Slaves.Add(cHinge);
            cHinge.Limb_Master = cLimb_Master_New;
        }

        /// <summary>
        /// loads the images necessary for the highlighting of parts of the FocusControl images that are beneath the mouse cursor
        /// </summary>
        void loadFocusControllerImages()
        {//enum enuFocusControllerImages { Idle, Up, Down, Left, Right, Center, size_Reduce, size_100PC, _numImages };

            List<Bitmap> lstBmp = new List<Bitmap>();
            lstBmp.Add(Properties.Resources.FocusController);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Up);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Down);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Left);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Right);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Center);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Size_Reduce);
            lstBmp.Add(Properties.Resources.FocusController_HighLight_Size_100PC);

            for (int intImageCounter = 0; intImageCounter < (int)enuFocusControllerImages._numImages; intImageCounter++)
            {
                Bitmap bmpTemp = (Bitmap)new Bitmap(lstBmp[intImageCounter]);
                bmpTemp.MakeTransparent(bmpTemp.GetPixel(0, 0));
                bmpFocusControllerImages[intImageCounter] = bmpTemp;
            }
        }

        /// <summary>
        /// carries out the operation of generating and inserting new animation frame images between two existing frames as determined by the user with the panelAutoInsertIntermediaryFrames UI
        /// </summary>
        private void BtnAutoInsertIntermediaryFrames_Go_Click(object sender, EventArgs e)
        {
            pnlAutoInsertIntermediaryFrames.Collapse();
            pnlAutoInsertIntermediaryFrames.Hide();
            double dblNumFrames = (double)pnlAutoInsertIntermediaryFrames.nudNumberIntermediaryFrames.Value;
            int intStartIndex = cSpriteData.cAnimationData.intFrameIndex;

            AutoInsertIntermediaryFrames(intStartIndex, dblNumFrames);


            nudFrameCounter_Reset();
            if (pnlAnimation_FrameEditor.Visible && !pnlAnimation_FrameEditor.Collapsed)
            {
                pnlAnimation_FrameEditor.SetAnimationFrameEditor();
            }
        }

        public void AutoInsertIntermediaryFrames(int intStartIndex, double dblNumFrames)
        {
            List<double> lstDelta_Angle = new List<double>();
            List<double> lstDelta_Magnitude = new List<double>();
            classAnimation_Frame cFrame_Start = cSpriteData.cAnimationData.cAnimation.lstFrames[intStartIndex];
            classAnimation_Frame cFrame_End = cSpriteData.cAnimationData.cAnimation.lstFrames[(cSpriteData.cAnimationData.intFrameIndex + 1) % cSpriteData.cAnimationData.cAnimation.lstFrames.Count];

            for (int intLimbCounter = 0; intLimbCounter < cFrame_Start.lstDrawSequence.Count; intLimbCounter++)
            {
                double dblAngle_End = classMath3.cleanAngle(cFrame_End.lstData[intLimbCounter].Angle);
                double dblAngle_Start = classMath3.cleanAngle(cFrame_Start.lstData[intLimbCounter].Angle);
                double dblDelta_Angle_Total =  dblAngle_End- dblAngle_Start;

                if (dblDelta_Angle_Total > 0)
                {
                    if (Math.Abs(dblDelta_Angle_Total) > Math.PI)
                        dblDelta_Angle_Total = dblDelta_Angle_Total - classMath3.TwoPi;
                }
                else // difference b/w (end-start)<0 -> counter clockwise
                {
                    if (dblDelta_Angle_Total < -Math.PI) // unless >Pi then Counter-clockwise
                        dblDelta_Angle_Total = dblDelta_Angle_Total + classMath3.TwoPi;
                }


                double dblDelta_Angle_Step = dblDelta_Angle_Total / (dblNumFrames + 1);// * (bolClockwise ? 1 : -1);
                lstDelta_Angle.Add(dblDelta_Angle_Step);
                double dblDelta_Magnitude = (cFrame_End.lstData[intLimbCounter].SlaveContactMagnitude_Factor - cFrame_Start.lstData[intLimbCounter].SlaveContactMagnitude_Factor) / (dblNumFrames + 1);
                lstDelta_Magnitude.Add(dblDelta_Magnitude);
            }

            int[] intDrawSequence = new int[cFrame_Start.lstDrawSequence.Count];
            cFrame_Start.lstDrawSequence.CopyTo(intDrawSequence);
            int intNumberNewFrames = (int)dblNumFrames;// (int)pnlAutoInsertIntermediaryFrames.nudNumberIntermediaryFrames.Value;
            for (int intFrameCounter = 1; intFrameCounter <= intNumberNewFrames; intFrameCounter++)
            {
                classAnimation_Frame cFrameNew = new classAnimation_Frame(ref cSpriteData.cAnimationData.cSprite);
                cFrameNew.Horizontal_Mirror = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex].Horizontal_Mirror;
                cFrameNew.Vertical_Mirror = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex].Vertical_Mirror;

                cFrameNew.lstDrawSequence.Clear();
                for (int intLimbCounter = 0; intLimbCounter < cFrame_Start.lstDrawSequence.Count; intLimbCounter++)
                {
                    classAnimation_Frame_LimbData cData = new classAnimation_Frame_LimbData(ref cFrameNew);
                    cData.intLimbIndex = cFrame_Start.lstData[intLimbCounter].intLimbIndex;

                    cData.Angle = cFrame_Start.lstData[intLimbCounter].Angle + intFrameCounter * lstDelta_Angle[intLimbCounter];
                    cData.SlaveContactMagnitude_Factor = cFrame_Start.lstData[intLimbCounter].SlaveContactMagnitude_Factor + intFrameCounter * lstDelta_Magnitude[intLimbCounter];

                    cData.ImageList_Index = cFrame_Start.lstData[intLimbCounter].ImageList_Index;
                    cFrameNew.lstData.Add(cData);
                   // cFrameNew.lstData.Add(cData.Copy());
                    cFrameNew.lstDrawSequence = intDrawSequence.ToList();

                }
                cFrameNew.Limb_DrawRelativeTo = cFrame_Start.Limb_DrawRelativeTo;
                cSpriteData.cAnimationData.cAnimation.Frame_Add(cSpriteData.cAnimationData.intFrameIndex++, ref cFrameNew, false);
            }
        }
        /*
        private void mnuAnimation_Speed_Click(object sender, EventArgs e)
        {
            Ck_Objects.form_GetInteger frmGetNumFramesInsert = new form_GetInteger("How many Insert Frames? (> 0 inserts frames & < 0 deletes frames)", 1);
            frmGetNumFramesInsert.QuitOnEnter = true;
            if (frmGetNumFramesInsert.ShowDialog() == DialogResult.OK)
            {
                bool bolAnimationEnabled = tmrAnimation.Enabled;
                tmrAnimation.Enabled = false;

                double dblNumFrames = (double)frmGetNumFramesInsert.Value;
                if (dblNumFrames < 0)
                {
                    for (int intAnimationCounter = 0; intAnimationCounter < cSpriteData.cAnimationData.cSprite.lstAnimations.Count; intAnimationCounter++)
                    {
                        cSpriteData.cAnimationData.cAnimation = cSpriteData.cAnimationData.cSprite.lstAnimations[intAnimationCounter];

                        int intFrameCounter = 1;
                        while ( intFrameCounter < cSpriteData.cAnimationData.cAnimation.lstFrames.Count)
                        {
                            cSpriteData.cAnimationData.cAnimation.lstFrames.RemoveAt(intFrameCounter);
                            intFrameCounter++;
                        }
                    }
                }
                else
                {
                    for (int intAnimationCounter = 0; intAnimationCounter < cSpriteData.cAnimationData.cSprite.lstAnimations.Count; intAnimationCounter++)
                    {
                        cSpriteData.cAnimationData.cAnimation = cSpriteData.cAnimationData.cSprite.lstAnimations[intAnimationCounter];

                        for (int intFrameCounter = cSpriteData.cAnimationData.cAnimation.lstFrames.Count - 1; intFrameCounter >= 0; intFrameCounter--)
                        {
                            cSpriteData.cAnimationData.intFrameIndex = intFrameCounter;
                            AutoInsertIntermediaryFrames(intFrameCounter, dblNumFrames);
                        }
                    }
                }
                tmrAnimation.Enabled = bolAnimationEnabled;
            }
        }
        */

        Size szForm_Load = new Size();
        Point ptForm_Location = new Point();

        bool bolInit = false;
        /// <summary>
        /// positions controls on the form the first time it is activated
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormSpriteEditor_2017_Activated(object sender, EventArgs e)
        {
            if (!bolFormatLoaded && cSpriteData.cAnimationData.cSprite != null)
            {
                Draw_Sprite();
            }
            if (bolInit) return;
            bolInit = true;
            Size = szForm_Load;
            Location = ptForm_Location;
        }

        /// <summary>
        ///  positions controls on the screen every time the form is resized
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormSpriteEditor_2017_SizeChanged(object sender, EventArgs e)
        {
            Draw_Sprite();
        }

        void DieInWitheringAgony()
        {
            bolDieInWitheringAgony = true;
            Hide();
            Dispose();
        }

        bool bolDieInWitheringAgony = false;
        /// <summary>
        /// forces the saving the formatting information should when the SpriteEditor_2017 is disposed
        /// </summary>
        private void FormSpriteEditor_2017_Disposed(object sender, EventArgs e)
        {
            bolDisposed = true;
            if (!bolDieInWitheringAgony)
            Format_Save();
        }

        /// <summary>
        /// records the current position and size of all the panels, the state of control options and checked menues to a text file to be loaded the next time SpriteEditor_2017 is launched
        /// </summary>
        void Format_Save()
        {
            string strOutput = "";
            for (enuFormatData eFormatCounter = (enuFormatData)0; eFormatCounter < enuFormatData._numFormat; eFormatCounter = (enuFormatData)((int)eFormatCounter + 1))
            {
                strOutput += eFormatCounter.ToString() + " ";
                switch (eFormatCounter)
                {
                    #region ContactHinge_Graphical
                    ///////////////////////////////////////////  SET HINGE CONTACT  graphical
                    case enuFormatData.HingeContact_Graphical_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].size_Height;
                        break;
                    case enuFormatData.HingeContact_Graphical_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].location_X;
                        break;

                    case enuFormatData.HingeContact_Graphical_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].location_Y;
                        break;

                    case enuFormatData.HingeContact_Graphical_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].size_Width;
                        break;

                    case enuFormatData.HingeContact_Graphical_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.HingeContact_Graphical_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region ContactHinge_Numerical
                    ///////////////////////////////////////////  SET HINGE CONTACT  Numerical
                    case enuFormatData.HingeContact_Numerical_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].size_Height;
                        break;
                    case enuFormatData.HingeContact_Numerical_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].location_X;
                        break;

                    case enuFormatData.HingeContact_Numerical_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].location_Y;
                        break;

                    case enuFormatData.HingeContact_Numerical_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].size_Width;
                        break;

                    case enuFormatData.HingeContact_Numerical_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.HingeContact_Numerical_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Frame Editor
                    ///////////////////////////////////////////  SET HINGE CONTACT  Numerical
                    case enuFormatData.FrameEditor_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.FrameEditor].size_Height;
                        break;
                    case enuFormatData.FrameEditor_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.FrameEditor].location_X;
                        break;

                    case enuFormatData.FrameEditor_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.FrameEditor].location_Y;
                        break;

                    case enuFormatData.FrameEditor_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.FrameEditor].size_Width;
                        break;

                    case enuFormatData.FrameEditor_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.FrameEditor].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.FrameEditor_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.FrameEditor].ExpansionDirection).ToString();
                        break;
                    #endregion
                        
                    #region Animation_Speed
                    ///////////////////////////////////////////  SET HINGE CONTACT  Numerical
                    case enuFormatData.AnimationSpeed_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationSpeed].size_Height;
                        break;
                    case enuFormatData.AnimationSpeed_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationSpeed].location_X;
                        break;

                    case enuFormatData.AnimationSpeed_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationSpeed].location_Y;
                        break;

                    case enuFormatData.AnimationSpeed_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationSpeed].size_Width;
                        break;

                    case enuFormatData.AnimationSpeed_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.AnimationSpeed].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.AnimationSpeed_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.AnimationSpeed].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Animation Frame Editor
                    ///////////////////////////////////////////  SET HINGE CONTACT  Numerical
                    case enuFormatData.AnimationFrameEditor_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].size_Height;
                        break;
                    case enuFormatData.AnimationFrameEditor_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].location_X;
                        break;

                    case enuFormatData.AnimationFrameEditor_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].location_Y;
                        break;

                    case enuFormatData.AnimationFrameEditor_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].size_Width;
                        break;

                    case enuFormatData.AnimationFrameEditor_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.AnimationFrameEditor_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Costume Selector
                    ///////////////////////////////////////////  SET HINGE CONTACT  Numerical
                    case enuFormatData.CostumeSelector_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.CostumeSelector].size_Height;
                        break;
                    case enuFormatData.CostumeSelector_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.CostumeSelector].location_X;
                        break;

                    case enuFormatData.CostumeSelector_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.CostumeSelector].location_Y;
                        break;

                    case enuFormatData.CostumeSelector_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.CostumeSelector].size_Width;
                        break;

                    case enuFormatData.CostumeSelector_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.CostumeSelector].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.CostumeSelector_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.CostumeSelector].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Messenger
                    ///////////////////////////////////////////////MESSENGER
                    case enuFormatData.MessengerHeight:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Messenger].size_Height;
                        break;

                    case enuFormatData.MessengerLeft:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Messenger].location_X;
                        break;

                    case enuFormatData.MessengerTop:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Messenger].location_Y;
                        break;

                    case enuFormatData.MessengerWidth:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Messenger].size_Width;
                        break;

                    case enuFormatData.MessengerCollapsed:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Messenger].Collapsed ? "1" : "0";
                        break;

                    case enuFormatData.Messenger_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.Messenger].ExpansionDirection).ToString();
                        break;

                    #endregion

                    #region AnimationControl_
                    ///////////////////////////////////////////////AnimationControl_
                    case enuFormatData.AnimationControl_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationControl].size_Height;
                        break;

                    case enuFormatData.AnimationControl_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationControl].location_X;
                        break;

                    case enuFormatData.AnimationControl_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationControl].location_Y;
                        break;

                    case enuFormatData.AnimationControl_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationControl].size_Width;
                        break;

                    case enuFormatData.AnimationControl_Collapsed:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AnimationControl].Collapsed ? "1" : "0";
                        break;

                    case enuFormatData.AnimationControl_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.AnimationControl].ExpansionDirection).ToString();
                        break;

                    #endregion

                    #region Debug_TestData
                    //////////////////////////////////////////// DEBUG : TEST DATA
                    case enuFormatData.debugTestDataHeight:
                        strOutput += cPanelSizeLocations[(int)enuPanels.debugTestData].size_Height;
                        break;

                    case enuFormatData.debugTestDataLeft:
                        strOutput += cPanelSizeLocations[(int)enuPanels.debugTestData].location_X;
                        break;

                    case enuFormatData.debugTestDataTop:
                        strOutput += cPanelSizeLocations[(int)enuPanels.debugTestData].location_Y;
                        break;

                    case enuFormatData.debugTestDataWidth:
                        strOutput += cPanelSizeLocations[(int)enuPanels.debugTestData].size_Width;
                        break;

                    case enuFormatData.debugCollapsed:
                        strOutput += cPanelSizeLocations[(int)enuPanels.debugTestData].Collapsed ? "1" : "0";
                        break;

                    case enuFormatData.debug_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.debugTestData].ExpansionDirection).ToString();
                        break;

                    #endregion

                    #region DrawSequence
                    /////////////////////////////////////   DRAW SEQUENCE
                    case enuFormatData.DrawSequenceHeight:
                        strOutput += cPanelSizeLocations[(int)enuPanels.DrawSequence].size_Height;
                        break;

                    case enuFormatData.DrawSequenceLeft:
                        strOutput += cPanelSizeLocations[(int)enuPanels.DrawSequence].location_X;
                        break;

                    case enuFormatData.DrawSequenceTop:
                        strOutput += cPanelSizeLocations[(int)enuPanels.DrawSequence].location_Y;
                        break;

                    case enuFormatData.DrawSequenceWidth:
                        strOutput += cPanelSizeLocations[(int)enuPanels.DrawSequence].size_Width;
                        break;

                    case enuFormatData.DrawCollapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.DrawSequence].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.DrawSequence_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.DrawSequence].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region AutoInsertIntermediaryFrames
                    case enuFormatData.AutoInsertIntermediaryFrames_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].size_Height;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].location_X;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].location_Y;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].size_Width;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Limb_Reattach
                    case enuFormatData.Limb_Reattach_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_Reattach].size_Height;
                        break;

                    case enuFormatData.Limb_Reattach_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_Reattach].location_X;
                        break;

                    case enuFormatData.Limb_Reattach_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_Reattach].location_Y;
                        break;

                    case enuFormatData.Limb_Reattach_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_Reattach].size_Width;
                        break;

                    case enuFormatData.Limb_Reattach_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.Limb_Reattach].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.Limb_Reattach_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.Limb_Reattach].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Limb_CopyFrames
                    case enuFormatData.Limb_CopyFrames_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].size_Height;
                        break;

                    case enuFormatData.Limb_CopyFrames_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].location_X;
                        break;

                    case enuFormatData.Limb_CopyFrames_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].location_Y;
                        break;

                    case enuFormatData.Limb_CopyFrames_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].size_Width;
                        break;

                    case enuFormatData.Limb_CopyFrames_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.Limb_CopyFrames_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].ExpansionDirection).ToString();
                        break;
                    #endregion
                        
                    #region Limb_SetAnimation
                    case enuFormatData.Limb_SetAnimation_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].size_Height;
                        break;

                    case enuFormatData.Limb_SetAnimation_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].location_X;
                        break;

                    case enuFormatData.Limb_SetAnimation_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].location_Y;
                        break;

                    case enuFormatData.Limb_SetAnimation_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].size_Width;
                        break;

                    case enuFormatData.Limb_SetAnimation_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.Limb_SetAnimation_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Limb_ImageController
                    case enuFormatData.Limb_ImageController_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_ImageController].size_Height;
                        break;

                    case enuFormatData.Limb_ImageController_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_ImageController].location_X;
                        break;

                    case enuFormatData.Limb_ImageController_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_ImageController].location_Y;
                        break;

                    case enuFormatData.Limb_ImageController_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Limb_ImageController].size_Width;
                        break;

                    case enuFormatData.Limb_ImageController_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.Limb_ImageController].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.Limb_ImageController_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.Limb_ImageController].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Options
                    case enuFormatData.OptionsPanel_Height:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Options].size_Height;
                        break;

                    case enuFormatData.OptionsPanel_Left:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Options].location_X;
                        break;

                    case enuFormatData.OptionsPanel_Top:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Options].location_Y;
                        break;

                    case enuFormatData.OptionsPanel_Width:
                        strOutput += cPanelSizeLocations[(int)enuPanels.Options].size_Width;
                        break;

                    case enuFormatData.OptionsPanel_Collapsed:
                        strOutput += (cPanelSizeLocations[(int)enuPanels.Options].Collapsed ? "1" : "0");
                        break;

                    case enuFormatData.OptionsPanel_ExpansionDirection:
                        strOutput += ((int)cPanelSizeLocations[(int)enuPanels.Options].ExpansionDirection).ToString();
                        break;
                    #endregion

                    #region Panels_visible
                    case enuFormatData.Panels_DrawSequence_checked:
                        strOutput += mnuPanels_DrawSequence.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_HingeContacts_Graphical_checked:
                        strOutput += mnuPanels_HingeContact_Graphical.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_HingeContacts_Numerical_checked:
                        strOutput += mnuPanels_HingeContact_Numerical.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_DebugDataTester_checked:
                        strOutput += mnuPanels_DataTester.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_Options_checked:
                        strOutput += mnuPanels_Options.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_FrameEditor_checked:
                        strOutput += mnuPanels_FrameEditor.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_AnimationSpeed_checked:
                        strOutput += mnuPanels_AnimationSpeed.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_AnimationFrameEditor_checked:
                        strOutput += mnuPanels_AnimationFrameEditor.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_CostumeSelector_checked:
                        strOutput += mnuPanels_CostumeSelector.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Panels_AnimationControls_checked:
                        strOutput += mnuPanels_AnimationControls.Checked ? "1" : "0";
                        break;


                    #endregion

                    #region Menus_And_Controllers
                    case enuFormatData.filename:
                        strOutput += strFilename_Current;
                        break;

                    case enuFormatData.FrameEditor_Track_DrawSequence_checked:
                        strOutput += pnlFrameEditor.chkTrack_DrawSequence.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Track_DrawRelativeTo_checked:
                        strOutput += pnlFrameEditor.chkTrack_DrawRelativeTo.Checked ? "1" : "0";
                        break;

                    case enuFormatData.FrameEditor_Track_Mirrors:
                        strOutput += pnlFrameEditor.chkTrack_Mirrors.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Track_Limb_Radianss_checked:
                        strOutput += pnlFrameEditor.chkTrack_Limb_Radians.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Show_Frame:
                        strOutput += pnlOptions.chkShow_Frame.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Show_LimbNames_checked:
                        strOutput += pnlOptions.chkShow_LimbNames.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Show_LimbCenters_checked:
                        strOutput += pnlOptions.chkShow_LimbCenters.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Show_ToolTips:
                        strOutput += pnlOptions.chkShow_ToolTips.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Show_LimbPositions_checked:
                        strOutput += pnlOptions.chkShow_LimbPositions.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_Show_FocusController_checked:
                        strOutput += pnlOptions.chkShow_FocusController.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_LimbMouseController_checked:
                        strOutput += pnlFrameEditor.chkMouse_LimbControl.Checked ? "1" : "0";
                        break;

                    case enuFormatData.Options_UseRAMCache_checked:
                        strOutput += pnlOptions.UseRAMCache ? "1" : "0";
                        break;

                    case enuFormatData.FocusController_X:
                        strOutput += ptFocusControllerCenter.X.ToString();
                        break;

                    case enuFormatData.FocusController_Y:
                        strOutput += ptFocusControllerCenter.Y.ToString();
                        break;

                    case enuFormatData.Options_FocusController_StepSize:
                        strOutput += intFocusController_StepSize.ToString();
                        break;

                    case enuFormatData.Options_DrawAngle:
                        strOutput += formSpriteEditor_2017.instance.cSpriteData.cAnimationData.dblDrawAngle;
                        break;

                    case enuFormatData.Draw_Sprite_Screen_X:
                        strOutput += cSpriteData.pt.X;
                        break;

                    case enuFormatData.Draw_Sprite_Screen_Y:
                        strOutput += cSpriteData.pt.Y;
                        break;

                    case enuFormatData.DrawZoom:
                        strOutput += DrawSizeFactor.ToString();
                        break;

                    case enuFormatData.Options_Radians_StepSize:
                        strOutput += dbl_Radians_StepSize.ToString();
                        break;

                    case enuFormatData.Options_Magnitude_StepSize:
                        strOutput += dbl_Magnitude_StepSize.ToString();
                        break;

                    case enuFormatData.Options_TimerInterval:
                        strOutput += tmrAnimation.Interval.ToString();
                        break;

                    #endregion

                    #region Form
                    case enuFormatData.Form_Width:
                        {
                            strOutput += Width.ToString();
                        }
                        break;

                    case enuFormatData.Form_Height:
                        {
                            strOutput += Height.ToString();
                        }
                        break;

                    case enuFormatData.Form_Location_X:
                        {
                            strOutput += Left.ToString();
                        }
                        break;

                    case enuFormatData.Form_Location_Y:
                        {
                            strOutput += Top.ToString();
                        }
                        break;
                        #endregion
                }
                strOutput += conLineDelimiter;
            }

            string strPathSave = FormatPath();
            System.IO.File.WriteAllText(strPathSave, strOutput);

        }

        /// <summary>
        /// ensures both save/load functions are working with the same file
        /// </summary>
        /// <returns></returns>
        string FormatPath() { return System.IO.Directory.GetCurrentDirectory() + "\\" + conFormatFilename; }

        void mnuFormatResetCreateStringForIDE_click(object sender, EventArgs e)
        {
            if (intFormatLoadErrorCounter > 5) return;
            string strPathLoad = FormatPath();
            if (!System.IO.File.Exists(strPathLoad))
            {
                MessageBox.Show("file :" + strPathLoad + " not found", "Error: file not found");
                return;
            }
            string strFormat_Input = System.IO.File.ReadAllText(strPathLoad);

            int intCut = 0;
            string strLine = "";

            string strFormat_Output = "\t\tstring strFormat = \"";

            for (enuFormatData eFormatCounter = (enuFormatData)0; eFormatCounter < enuFormatData._numFormat; eFormatCounter = (enuFormatData)((int)eFormatCounter + 1))
            {
                string strFormatName = eFormatCounter.ToString();
                try
                {
                    intCut = strFormat_Input.IndexOf(conLineDelimiter);
                    strLine = strFormat_Input.Substring(0, intCut);
                    if (strLine.ToUpper().Contains("C:"))
                    {
                        strLine = ("filename " + System.IO.Directory.GetCurrentDirectory() + "\\Spider.sp3").Replace("\\", "\\\\");

                    }


                    strFormat_Input = strFormat_Input.Substring(strLine.Length + conLineDelimiter.Length);
                }
                catch (Exception err)
                {
                    MessageBox.Show("Format Load error (" + strFormatName + "):" + err.Message);
                    return;
                }
                strFormat_Output += strLine + "\""
                                    + "\r\n\t\t\t\t\t\t\t\t\t+ \"\\r\\n";
            }

            strFormat_Output += "\";\r\n";

            System.Windows.Forms.Clipboard.SetText(strFormat_Output);
        }

            int intFormatLoadErrorCounter = 0;
        /// <summary>
        /// loads formatting information recorded the last time the SpriteEditor_2017 was used
        /// </summary>
        void Format_Load()
        {
            if (intFormatLoadErrorCounter > 5) return;
            string strPathLoad = FormatPath();
            if (!System.IO.File.Exists(strPathLoad))
            {
                intFormatLoadErrorCounter++;
                Format_Reset();
                return;
            }
            string strFormat = System.IO.File.ReadAllText(strPathLoad);

            int intCut = 0;
            string strLine = "";
            string strValue = "0";
            double dblValue = 0;

            for (enuFormatData eFormatCounter = (enuFormatData)0; eFormatCounter < enuFormatData._numFormat; eFormatCounter = (enuFormatData)((int)eFormatCounter + 1))
            {
                string strFormatName = eFormatCounter.ToString();
                try
                {
                    intCut = strFormat.IndexOf(conLineDelimiter);
                    strLine = strFormat.Substring(0, intCut);

                    strFormat = strFormat.Substring(strLine.Length + conLineDelimiter.Length);

                    strValue = strLine.Substring(strFormatName.Length + 1);
                }
                catch (Exception e)
                {
                    MessageBox.Show("Format Load error (" + strFormatName + "):" + e.Message);

                    intFormatLoadErrorCounter++;
                    Format_Reset();
                    return;
                }

                if (eFormatCounter != enuFormatData.filename)
                {
                    try
                    {
                        dblValue = Convert.ToDouble(strValue);
                    }
                    catch (Exception err)
                    {
                        MessageBox.Show("error loading format : " + err.Message);
                        intFormatLoadErrorCounter++;
                        Format_Reset();
                        return;
                    }
                }

                switch (eFormatCounter)
                {
                    #region Panel_ContactHinge_Graphical
                    case enuFormatData.HingeContact_Graphical_Height:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Graphical_Left:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].location_X = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Graphical_Top:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Graphical_Width:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Graphical_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.HingeContact_Graphical_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Graphical].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_ContactHinge_Numerical
                    case enuFormatData.HingeContact_Numerical_Height:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Numerical_Left:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].location_X = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Numerical_Top:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Numerical_Width:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.HingeContact_Numerical_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.HingeContact_Numerical_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.HingeContact_Numerical].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Frame_Editor
                    case enuFormatData.FrameEditor_Height:
                        cPanelSizeLocations[(int)enuPanels.FrameEditor].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.FrameEditor_Left:
                        cPanelSizeLocations[(int)enuPanels.FrameEditor].location_X = (int)dblValue;
                        break;

                    case enuFormatData.FrameEditor_Top:
                        cPanelSizeLocations[(int)enuPanels.FrameEditor].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.FrameEditor_Width:
                        cPanelSizeLocations[(int)enuPanels.FrameEditor].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.FrameEditor_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.FrameEditor].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.FrameEditor_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.FrameEditor].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion
                        
                    #region Animation_Speed
                    case enuFormatData.AnimationSpeed_Height:
                        cPanelSizeLocations[(int)enuPanels.AnimationSpeed].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.AnimationSpeed_Left:
                        cPanelSizeLocations[(int)enuPanels.AnimationSpeed].location_X = (int)dblValue;
                        break;

                    case enuFormatData.AnimationSpeed_Top:
                        cPanelSizeLocations[(int)enuPanels.AnimationSpeed].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.AnimationSpeed_Width:
                        cPanelSizeLocations[(int)enuPanels.AnimationSpeed].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.AnimationSpeed_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.AnimationSpeed].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.AnimationSpeed_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.AnimationSpeed].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region AnimationFrame_Editor
                    case enuFormatData.AnimationFrameEditor_Height:
                        cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.AnimationFrameEditor_Left:
                        cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].location_X = (int)dblValue;
                        break;

                    case enuFormatData.AnimationFrameEditor_Top:
                        cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.AnimationFrameEditor_Width:
                        cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.AnimationFrameEditor_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.AnimationFrameEditor_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.AnimationFrameEditor].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Costume_Editor
                    case enuFormatData.CostumeSelector_Height:
                        cPanelSizeLocations[(int)enuPanels.CostumeSelector].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.CostumeSelector_Left:
                        cPanelSizeLocations[(int)enuPanels.CostumeSelector].location_X = (int)dblValue;
                        break;

                    case enuFormatData.CostumeSelector_Top:
                        cPanelSizeLocations[(int)enuPanels.CostumeSelector].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.CostumeSelector_Width:
                        cPanelSizeLocations[(int)enuPanels.CostumeSelector].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.CostumeSelector_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.CostumeSelector].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.CostumeSelector_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.CostumeSelector].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_Messenger
                    case enuFormatData.MessengerHeight:
                        cPanelSizeLocations[(int)enuPanels.Messenger].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.MessengerLeft:
                        cPanelSizeLocations[(int)enuPanels.Messenger].location_X = (int)dblValue;
                        break;

                    case enuFormatData.MessengerTop:
                        cPanelSizeLocations[(int)enuPanels.Messenger].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.MessengerWidth:
                        cPanelSizeLocations[(int)enuPanels.Messenger].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.MessengerCollapsed:
                        cPanelSizeLocations[(int)enuPanels.Messenger].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Messenger_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.Messenger].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_AnimationControl
                    case enuFormatData.AnimationControl_Height:
                        cPanelSizeLocations[(int)enuPanels.AnimationControl].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.AnimationControl_Left:
                        cPanelSizeLocations[(int)enuPanels.AnimationControl].location_X = (int)dblValue;
                        break;

                    case enuFormatData.AnimationControl_Top:
                        cPanelSizeLocations[(int)enuPanels.AnimationControl].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.AnimationControl_Width:
                        cPanelSizeLocations[(int)enuPanels.AnimationControl].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.AnimationControl_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.AnimationControl].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.AnimationControl_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.AnimationControl].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_Debug_TestData
                    case enuFormatData.debugTestDataHeight:
                        cPanelSizeLocations[(int)enuPanels.debugTestData].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.debugTestDataLeft:
                        cPanelSizeLocations[(int)enuPanels.debugTestData].location_X = (int)dblValue;
                        break;

                    case enuFormatData.debugTestDataTop:
                        cPanelSizeLocations[(int)enuPanels.debugTestData].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.debugTestDataWidth:
                        cPanelSizeLocations[(int)enuPanels.debugTestData].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.debugCollapsed:
                        cPanelSizeLocations[(int)enuPanels.debugTestData].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.debug_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.debugTestData].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_DrawSequence
                    case enuFormatData.DrawSequenceHeight:
                        cPanelSizeLocations[(int)enuPanels.DrawSequence].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.DrawSequenceLeft:
                        cPanelSizeLocations[(int)enuPanels.DrawSequence].location_X = (int)dblValue;
                        break;

                    case enuFormatData.DrawSequenceTop:
                        cPanelSizeLocations[(int)enuPanels.DrawSequence].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.DrawSequenceWidth:
                        cPanelSizeLocations[(int)enuPanels.DrawSequence].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.DrawCollapsed:
                        cPanelSizeLocations[(int)enuPanels.DrawSequence].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.DrawSequence_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.DrawSequence].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_AutoInsertIntermediaryFrames
                    case enuFormatData.AutoInsertIntermediaryFrames_Height:
                        cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Left:
                        cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].location_X = (int)dblValue;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Top:
                        cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Width:
                        cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.AutoInsertIntermediaryFrames_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.AutoInsertIntermediaryFrames].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;
                    #endregion

                    #region Panel_Limb_Reattach
                    case enuFormatData.Limb_Reattach_Height:
                        cPanelSizeLocations[(int)enuPanels.Limb_Reattach].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.Limb_Reattach_Left:
                        cPanelSizeLocations[(int)enuPanels.Limb_Reattach].location_X = (int)dblValue;
                        break;

                    case enuFormatData.Limb_Reattach_Top:
                        cPanelSizeLocations[(int)enuPanels.Limb_Reattach].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.Limb_Reattach_Width:
                        cPanelSizeLocations[(int)enuPanels.Limb_Reattach].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.Limb_Reattach_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.Limb_Reattach].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Limb_Reattach_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.Limb_Reattach].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;

                    #endregion

                    #region Panel_Limb_CopyFrames
                    case enuFormatData.Limb_CopyFrames_Height:
                        cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.Limb_CopyFrames_Left:
                        cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].location_X = (int)dblValue;
                        break;

                    case enuFormatData.Limb_CopyFrames_Top:
                        cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.Limb_CopyFrames_Width:
                        cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.Limb_CopyFrames_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Limb_CopyFrames_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;

                    #endregion
                        
                    #region Panel_Limb_SetAnimation
                    case enuFormatData.Limb_SetAnimation_Height:
                        cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.Limb_SetAnimation_Left:
                        cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].location_X = (int)dblValue;
                        break;

                    case enuFormatData.Limb_SetAnimation_Top:
                        cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.Limb_SetAnimation_Width:
                        cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.Limb_SetAnimation_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Limb_SetAnimation_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;

                    #endregion

                    #region Panel_Limb_ImageController
                    case enuFormatData.Limb_ImageController_Height:
                        cPanelSizeLocations[(int)enuPanels.Limb_ImageController].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.Limb_ImageController_Left:
                        cPanelSizeLocations[(int)enuPanels.Limb_ImageController].location_X = (int)dblValue;
                        break;

                    case enuFormatData.Limb_ImageController_Top:
                        cPanelSizeLocations[(int)enuPanels.Limb_ImageController].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.Limb_ImageController_Width:
                        cPanelSizeLocations[(int)enuPanels.Limb_ImageController].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.Limb_ImageController_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.Limb_ImageController].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Limb_ImageController_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.Limb_ImageController].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;

                    #endregion

                    #region Panel_Options
                    case enuFormatData.OptionsPanel_Height:
                        cPanelSizeLocations[(int)enuPanels.Options].size_Height = (int)dblValue;
                        break;

                    case enuFormatData.OptionsPanel_Left:
                        cPanelSizeLocations[(int)enuPanels.Options].location_X = (int)dblValue;
                        break;

                    case enuFormatData.OptionsPanel_Top:
                        cPanelSizeLocations[(int)enuPanels.Options].location_Y = (int)dblValue;
                        break;

                    case enuFormatData.OptionsPanel_Width:
                        cPanelSizeLocations[(int)enuPanels.Options].size_Width = (int)dblValue;
                        break;

                    case enuFormatData.OptionsPanel_Collapsed:
                        cPanelSizeLocations[(int)enuPanels.Options].Collapsed = ((int)dblValue == 1);
                        break;

                    case enuFormatData.OptionsPanel_ExpansionDirection:
                        cPanelSizeLocations[(int)enuPanels.Options].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
                        break;

                    #endregion

                    #region Panels_visible
                    case enuFormatData.Panels_DrawSequence_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.DrawSequence] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_HingeContacts_Graphical_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.HingeContact_Graphical] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_HingeContacts_Numerical_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.HingeContact_Numerical] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_DebugDataTester_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.debugTestData] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_FrameEditor_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.FrameEditor] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_AnimationSpeed_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.AnimationSpeed] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_AnimationControls_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.AnimationControls] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_AnimationFrameEditor_checked:
                        bolPanelCheckedStates[(int)enuCheckedMenus.AnimationFrameEditor] = ((int)dblValue == 1);
                        break;

                    case enuFormatData.Panels_Options_checked:
                        mnuPanels_Options.Checked = ((int)dblValue == 1);
                        break;

                    #endregion

                    #region Options_Controller_Data
                    case enuFormatData.filename:
                        strFilename_Current = strValue;

                        if (strFilename_Current.Contains(conCurrentDirectory_LoadFile))
                        {
                            strFilename_Current = strFilename_Current.Replace(conCurrentDirectory_LoadFile, System.IO.Directory.GetCurrentDirectory() + "\\");
                        }
                        break;

                    case enuFormatData.FrameEditor_Track_DrawSequence_checked:
                        objOptions[(int)enuOptions.FrameEditor_Track_DrawSequence_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Track_DrawRelativeTo_checked:
                        objOptions[(int)enuOptions.Options_Track_DrawRelativeTo_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Track_Limb_Radianss_checked:
                        objOptions[(int)enuOptions.Options_Track_Limb_Radianss_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.FrameEditor_Track_Mirrors:
                        objOptions[(int)enuOptions.Options_Track_Mirrors_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Show_LimbNames_checked:
                        objOptions[(int)enuOptions.Options_Show_LimbNames_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Show_LimbCenters_checked:
                        objOptions[(int)enuOptions.Options_Show_LimbCenters_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Show_ToolTips:
                        objOptions[(int)enuOptions.Options_Show_ToolTips_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Show_LimbPositions_checked:
                        objOptions[(int)enuOptions.Options_Show_LimbPOsitions_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Show_FocusController_checked:
                        objOptions[(int)enuOptions.Options_Show_FocusController_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Show_Frame:
                        objOptions[(int)enuOptions.Options_Show_Frame_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_UseRAMCache_checked:
                        objOptions[(int)enuOptions.Options_UseRAMCache_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_LimbMouseController_checked:
                        objOptions[(int)enuOptions.Options_LimbMouseController_checked] = (object)((int)dblValue == 1);
                        break;

                    case enuFormatData.Options_Radians_StepSize:
                        objOptions[(int)enuOptions.Options_RadiansStepSize] = (object)(dblValue);
                        break;

                    case enuFormatData.Options_Magnitude_StepSize:
                        objOptions[(int)enuOptions.Options_MagnitudeStepSize] = (object)(dblValue);
                        break;

                    case enuFormatData.Options_TimerInterval:
                        int intInterval = (int)dblValue;
                        if (intInterval > 0)
                            tmrAnimation.Interval = intInterval;
                        else
                            tmrAnimation.Interval = 100;
                        break;

                    case enuFormatData.FocusController_X:
                        ptFocusControllerCenter = new Point((int)dblValue, ptFocusControllerCenter.Y);
                        break;

                    case enuFormatData.FocusController_Y:
                        ptFocusControllerCenter = new Point(ptFocusControllerCenter.X, (int)dblValue);
                        break;

                    case enuFormatData.Options_FocusController_StepSize:
                        intFocusController_StepSize = (int)dblValue;
                        break;

                    case enuFormatData.Options_DrawAngle:
                        cSpriteData.cAnimationData.dblDrawAngle = dblValue;
                        objOptions[(int)enuOptions.Options_DrawAngle] = (object)(dblValue);
                        break;

                    case enuFormatData.Draw_Sprite_Screen_X:
                        cSpriteData.pt = new Point((int)dblValue, cSpriteData.pt.Y);
                        break;

                    case enuFormatData.Draw_Sprite_Screen_Y:
                        cSpriteData.pt = new Point(cSpriteData.pt.X, (int)dblValue);
                        break;

                    case enuFormatData.DrawZoom:
                        dblDrawFactor_Load = dblValue;
                        break;
                    #endregion

                    #region Form
                    case enuFormatData.Form_Width:
                        {
                            szForm_Load.Width = (int)dblValue;
                        }
                        break;

                    case enuFormatData.Form_Height:
                        {
                            szForm_Load.Height = (int)dblValue;
                        }
                        break;

                    case enuFormatData.Form_Location_X:
                        {
                            ptForm_Location.X = (int)dblValue;
                        }
                        break;

                    case enuFormatData.Form_Location_Y:
                        {
                            ptForm_Location.Y = (int)dblValue;
                        }
                        break;
                        #endregion
                }
            }
        }

        /// <summary>
        /// uses a default set of settings to reinitialize SpriteEditor_2017's IDE to the default state
        /// </summary>
        private void mnuPanels_ResetDefaultSettings_Click(object sender, EventArgs e)
        {
            Format_Reset();
        }

        void Format_Reset()
        {
            string strFormat = "DrawSequenceLeft 240"
                                + "\r\nDrawSequenceTop 49"
                                + "\r\nDrawSequenceWidth 140"
                                + "\r\nDrawSequenceHeight 370"
                                + "\r\nDrawCollapsed 0"
                                + "\r\nDrawSequence_ExpansionDirection 2"
                                + "\r\nHingeContact_Graphical_Left 1340"
                                + "\r\nHingeContact_Graphical_Top 34"
                                + "\r\nHingeContact_Graphical_Width 600"
                                + "\r\nHingeContact_Graphical_Height 530"
                                + "\r\nHingeContact_Graphical_Collapsed 1"
                                + "\r\nHingeContact_Graphical_ExpansionDirection 3"
                                + "\r\nHingeContact_Numerical_Left 1339"
                                + "\r\nHingeContact_Numerical_Top 568"
                                + "\r\nHingeContact_Numerical_Width 220"
                                + "\r\nHingeContact_Numerical_Height 140"
                                + "\r\nHingeContact_Numerical_Collapsed 1"
                                + "\r\nHingeContact_Numerical_ExpansionDirection 3"
                                + "\r\nFrameEditor_Left 1"
                                + "\r\nFrameEditor_Top 342"
                                + "\r\nFrameEditor_Width 220"
                                + "\r\nFrameEditor_Height 290"
                                + "\r\nFrameEditor_Collapsed 0"
                                + "\r\nFrameEditor_ExpansionDirection 1"
                                + "\r\nAnimationFrameEditor_Left 398"
                                + "\r\nAnimationFrameEditor_Top 32"
                                + "\r\nAnimationFrameEditor_Width 940"
                                + "\r\nAnimationFrameEditor_Height 280"
                                + "\r\nAnimationFrameEditor_Collapsed 1"
                                + "\r\nAnimationFrameEditor_ExpansionDirection 2"
                                + "\r\nAnimationSpeed_Left 898"
                                + "\r\nAnimationSpeed_Top 232"
                                + "\r\nAnimationSpeed_Width 210"
                                + "\r\nAnimationSpeed_Height 280"
                                + "\r\nAnimationSpeed_Collapsed 1"
                                + "\r\nAnimationSpeed_ExpansionDirection 2"
                                + "\r\nCostumeSelector_Left 2"
                                + "\r\nCostumeSelector_Top 619"
                                + "\r\nCostumeSelector_Width 220"
                                + "\r\nCostumeSelector_Height 90"
                                + "\r\nCostumeSelector_Collapsed 0"
                                + "\r\nCostumeSelector_ExpansionDirection 1"
                                + "\r\nAnimationControl_Left 22"
                                + "\r\nAnimationControl_Top 22"
                                + "\r\nAnimationControl_Width 210"
                                + "\r\nAnimationControl_Height 320"
                                + "\r\nAnimationControl_Collapsed 0"
                                + "\r\nAnimationControl_ExpansionDirection 3"
                                + "\r\ndebugTestDataLeft 394"
                                + "\r\ndebugTestDataTop 686"
                                + "\r\ndebugTestDataWidth 640"
                                + "\r\ndebugTestDataHeight 700"
                                + "\r\ndebugCollapsed 1"
                                + "\r\ndebug_ExpansionDirection 0"
                                + "\r\nMessengerLeft 391"
                                + "\r\nMessengerTop 271"
                                + "\r\nMessengerWidth 600"
                                + "\r\nMessengerHeight 120"
                                + "\r\nMessengerCollapsed 1"
                                + "\r\nMessenger_ExpansionDirection 0"
                                + "\r\nAutoInsertIntermediaryFrames_Left 365"
                                + "\r\nAutoInsertIntermediaryFrames_Top 650"
                                + "\r\nAutoInsertIntermediaryFrames_Width 170"
                                + "\r\nAutoInsertIntermediaryFrames_Height 60"
                                + "\r\nAutoInsertIntermediaryFrames_Collapsed 0"
                                + "\r\nAutoInsertIntermediaryFrames_ExpansionDirection 0"
                                + "\r\nLimb_Reattach_Left 245"
                                + "\r\nLimb_Reattach_Top 472"
                                + "\r\nLimb_Reattach_Width 1050"
                                + "\r\nLimb_Reattach_Height 490"
                                + "\r\nLimb_Reattach_Collapsed 1"
                                + "\r\nLimb_Reattach_ExpansionDirection 0"
                                + "\r\nLimb_CopyFrames_Left 100"
                                + "\r\nLimb_CopyFrames_Top 100"
                                + "\r\nLimb_CopyFrames_Width 200"
                                + "\r\nLimb_CopyFrames_Height 300"
                                + "\r\nLimb_CopyFrames_Collapsed 1"
                                + "\r\nLimb_CopyFrames_ExpansionDirection 0"
                                + "\r\nLimb_SetAnimation_Left 200"
                                + "\r\nLimb_SetAnimation_Top 200"
                                + "\r\nLimb_SetAnimation_Width 200"
                                + "\r\nLimb_SetAnimation_Height 300"
                                + "\r\nLimb_SetAnimation_Collapsed 1"
                                + "\r\nLimb_SetAnimation_ExpansionDirection 0"
                                + "\r\nLimb_ImageController_Left 17"
                                + "\r\nLimb_ImageController_Top 342"
                                + "\r\nLimb_ImageController_Width 220"
                                + "\r\nLimb_ImageController_Height 360"
                                + "\r\nLimb_ImageController_Collapsed 0"
                                + "\r\nLimb_ImageController_ExpansionDirection 3"
                                + "\r\nOptionsPanel_Left 4"
                                + "\r\nOptionsPanel_Top 81"
                                + "\r\nOptionsPanel_Width 210"
                                + "\r\nOptionsPanel_Height 260"
                                + "\r\nOptionsPanel_Collapsed 0"
                                + "\r\nOptionsPanel_ExpansionDirection 1"
                                + "\r\nfilename C:\\C#\\SpriteEditor_2017\\SpriteEditor_2017\\bin\\Debug\\Spider.sp4"
                                + "\r\nuence_checked 1"
                                + "\r\nPanels_HingeContacts_Graphical_checked 1"
                                + "\r\nPanels_HingeContacts_Numerical_checked 1"
                                + "\r\nPanels_Options_checked 1"
                                + "\r\nPanels_FrameEditor_checked 1"
                                + "\r\nPanels_AnimationFrameEditor_checked 1"
                                + "\r\nPanels_AnimationSpeed_checked 1"
                                + "\r\nPanels_CostumeSelector_checked 1"
                                + "\r\nPanels_AnimationControls_checked 1"
                                + "\r\nPanels_DebugDataTester_checked 0"
                                + "\r\nOptions_Show_LimbNames_checked 0"
                                + "\r\nOptions_Show_LimbCenters_checked 0"
                                + "\r\nOptions_Show_LimbPositions_checked 0"
                                + "\r\nOptions_Show_Frame 1"
                                + "\r\nOptions_Show_ToolTips 0"
                                + "\r\nOptions_Track_DrawRelativeTo_checked 0"
                                + "\r\nOptions_Track_Limb_Radianss_checked 0"
                                + "\r\nOptions_Show_FocusController_checked 1"
                                + "\r\nOptions_UseRAMCache_checked 0"
                                + "\r\nOptions_LimbMouseController_checked 1"
                                + "\r\nOptions_Radians_StepSize 0.04909"
                                + "\r\nOptions_Magnitude_StepSize 0.1"
                                + "\r\nOptions_TimerInterval 100"
                                + "\r\nOptions_FocusController_StepSize 27"
                                + "\r\nOptions_DrawAngle 0"
                                + "\r\nFrameEditor_Track_DrawSequence_checked 0"
                                + "\r\nFrameEditor_Track_Mirrors 0"
                                + "\r\nFocusController_X 298"
                                + "\r\nFocusController_Y 646"
                                + "\r\nDraw_Sprite_Screen_X 1109"
                                + "\r\nDraw_Sprite_Screen_Y 443"
                                + "\r\nDrawZoom 1"
                                + "\r\nForm_Width 1382"
                                + "\r\nForm_Height 754"
                                + "\r\nForm_Location_X -8"
                                + "\r\nForm_Location_Y -8"
                                + "\r\n";



            string strFilename = FormatPath();
            if (System.IO.File.Exists(strFilename))
                System.IO.File.Delete(strFilename);

            System.IO.File.WriteAllText(strFilename, strFormat);
            DieInWitheringAgony();
            return;


            //int intCut = 0;
            //string strLine = "";
            //string strValue = "0";
            //double dblValue = 0;

            //for (enuFormatData eFormatCounter = (enuFormatData)0; eFormatCounter < enuFormatData._numFormat; eFormatCounter = (enuFormatData)((int)eFormatCounter + 1))
            //{
            //    string strFormatName = eFormatCounter.ToString();
            //    try
            //    {
            //        intCut = strFormat.IndexOf(conLineDelimiter);
            //        strLine = strFormat.Substring(0, intCut);

            //        strFormat = strFormat.Substring(strLine.Length + conLineDelimiter.Length);

            //        strValue = strLine.Substring(strFormatName.Length + 1);

            //    }
            //    catch (Exception err1)
            //    {
            //        MessageBox.Show("an error occured loading default format : " + err1.Message);
            //    }

            //    if (eFormatCounter != enuFormatData.filename)
            //    {
            //        try
            //        {
            //            dblValue = Convert.ToDouble(strValue);
            //        }
            //        catch (Exception err2)
            //        {
            //            MessageBox.Show("error loading format : " + err2.Message);
            //        }
            //    }

            //    switch (eFormatCounter)
            //    {
            //        #region Panel_ContactHinge_Graphical
            //        case enuFormatData.HingeContact_Graphical_Height:
            //            pnlHingeContacts_Set_Graphical.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Graphical_Left:
            //            pnlHingeContacts_Set_Graphical.Left = (int)dblValue;

            //            break;

            //        case enuFormatData.HingeContact_Graphical_Top:
            //            pnlHingeContacts_Set_Graphical.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Graphical_Width:
            //            pnlHingeContacts_Set_Graphical.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Graphical_Collapsed:
            //            pnlHingeContacts_Set_Graphical.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.HingeContact_Graphical_ExpansionDirection:
            //            pnlHingeContacts_Set_Graphical.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_ContactHinge_Numerical
            //        case enuFormatData.HingeContact_Numerical_Height:
            //            pnlHingeContacts_Set_Numerical.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Numerical_Left:
            //            pnlHingeContacts_Set_Numerical.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Numerical_Top:
            //            pnlHingeContacts_Set_Numerical.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Numerical_Width:
            //            pnlHingeContacts_Set_Numerical.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.HingeContact_Numerical_Collapsed:
            //            pnlHingeContacts_Set_Numerical.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.HingeContact_Numerical_ExpansionDirection:
            //            pnlHingeContacts_Set_Numerical.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Frame_Editor
            //        case enuFormatData.FrameEditor_Height:
            //            pnlFrameEditor.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.FrameEditor_Left:
            //            pnlFrameEditor.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.FrameEditor_Top:
            //            pnlFrameEditor.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.FrameEditor_Width:
            //            pnlFrameEditor.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.FrameEditor_Collapsed:
            //            pnlFrameEditor.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.FrameEditor_ExpansionDirection:
            //            pnlFrameEditor.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region AnimationFrame_Editor
            //        case enuFormatData.AnimationFrameEditor_Height:
            //            pnlAnimation_FrameEditor.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationFrameEditor_Left:
            //            pnlAnimation_FrameEditor.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationFrameEditor_Top:
            //            pnlAnimation_FrameEditor.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationFrameEditor_Width:
            //            pnlAnimation_FrameEditor.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationFrameEditor_Collapsed:
            //            pnlAnimation_FrameEditor.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.AnimationFrameEditor_ExpansionDirection:
            //            pnlAnimation_FrameEditor.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_Messenger
            //        case enuFormatData.MessengerHeight:
            //            pnlMessenger.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.MessengerLeft:
            //            pnlMessenger.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.MessengerTop:
            //            pnlMessenger.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.MessengerWidth:
            //            pnlMessenger.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.MessengerCollapsed:
            //            pnlMessenger.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Messenger_ExpansionDirection:
            //            pnlMessenger.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_AnimationControl
            //        case enuFormatData.AnimationControl_Height:
            //            pnlAnimationControls.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationControl_Left:
            //            pnlAnimationControls.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationControl_Top:
            //            pnlAnimationControls.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationControl_Width:
            //            pnlAnimationControls.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.AnimationControl_Collapsed:
            //            pnlAnimationControls.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.AnimationControl_ExpansionDirection:
            //            pnlAnimationControls.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_Debug_TestData
            //        case enuFormatData.debugTestDataHeight:
            //            pnlDebug.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.debugTestDataLeft:
            //            pnlDebug.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.debugTestDataTop:
            //            pnlDebug.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.debugTestDataWidth:
            //            pnlDebug.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.debugCollapsed:
            //            pnlDebug.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.debug_ExpansionDirection:
            //            pnlDebug.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_Limb_SetAnimation
            //        case enuFormatData.Limb_SetAnimation_Height:
            //            cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].size_Height = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_SetAnimation_Left:
            //            cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].location_X = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_SetAnimation_Top:
            //            cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].location_Y = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_SetAnimation_Width:
            //            cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].size_Width = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_SetAnimation_Collapsed:
            //            cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Limb_SetAnimation_ExpansionDirection:
            //            cPanelSizeLocations[(int)enuPanels.Limb_SetAnimation].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;

            //        #endregion

            //        #region Costume_Editor
            //        case enuFormatData.CostumeSelector_Height:
            //            cPanelSizeLocations[(int)enuPanels.CostumeSelector].size_Height = (int)dblValue;
            //            break;

            //        case enuFormatData.CostumeSelector_Left:
            //            cPanelSizeLocations[(int)enuPanels.CostumeSelector].location_X = (int)dblValue;
            //            break;

            //        case enuFormatData.CostumeSelector_Top:
            //            cPanelSizeLocations[(int)enuPanels.CostumeSelector].location_Y = (int)dblValue;
            //            break;

            //        case enuFormatData.CostumeSelector_Width:
            //            cPanelSizeLocations[(int)enuPanels.CostumeSelector].size_Width = (int)dblValue;
            //            break;

            //        case enuFormatData.CostumeSelector_Collapsed:
            //            cPanelSizeLocations[(int)enuPanels.CostumeSelector].Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.CostumeSelector_ExpansionDirection:
            //            cPanelSizeLocations[(int)enuPanels.CostumeSelector].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_Limb_CopyFrames
            //        case enuFormatData.Limb_CopyFrames_Height:
            //            cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].size_Height = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_CopyFrames_Left:
            //            cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].location_X = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_CopyFrames_Top:
            //            cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].location_Y = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_CopyFrames_Width:
            //            cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].size_Width = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_CopyFrames_Collapsed:
            //            cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Limb_CopyFrames_ExpansionDirection:
            //            cPanelSizeLocations[(int)enuPanels.Limb_CopyFrames].ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;

            //        #endregion

            //        #region Panel_DrawSequence
            //        case enuFormatData.DrawSequenceHeight:
            //            pnlDrawSequence.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.DrawSequenceLeft:
            //            pnlDrawSequence.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.DrawSequenceTop:
            //            pnlDrawSequence.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.DrawSequenceWidth:
            //            pnlDrawSequence.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.DrawCollapsed:
            //            pnlDrawSequence.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.DrawSequence_ExpansionDirection:
            //            pnlDrawSequence.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_AutoInsertIntermediaryFrames
            //        case enuFormatData.AutoInsertIntermediaryFrames_Height:
            //            pnlAutoInsertIntermediaryFrames.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.AutoInsertIntermediaryFrames_Left:
            //            pnlAutoInsertIntermediaryFrames.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.AutoInsertIntermediaryFrames_Top:
            //            pnlAutoInsertIntermediaryFrames.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.AutoInsertIntermediaryFrames_Width:
            //            pnlAutoInsertIntermediaryFrames.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.AutoInsertIntermediaryFrames_Collapsed:
            //            pnlAutoInsertIntermediaryFrames.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.AutoInsertIntermediaryFrames_ExpansionDirection:
            //            pnlAutoInsertIntermediaryFrames.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;
            //        #endregion

            //        #region Panel_Limb_Reattach
            //        case enuFormatData.Limb_Reattach_Height:
            //            pnlLimb_Reattach.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_Reattach_Left:
            //            pnlLimb_Reattach.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_Reattach_Top:
            //            pnlLimb_Reattach.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_Reattach_Width:
            //            pnlLimb_Reattach.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_Reattach_Collapsed:
            //            pnlLimb_Reattach.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Limb_Reattach_ExpansionDirection:
            //            pnlLimb_Reattach.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;

            //        #endregion

            //        #region Panel_Limb_ImageController
            //        case enuFormatData.Limb_ImageController_Height:
            //            pnlLimb_ImageController.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_ImageController_Left:
            //            pnlLimb_ImageController.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_ImageController_Top:
            //            pnlLimb_ImageController.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_ImageController_Width:
            //            pnlLimb_ImageController.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.Limb_ImageController_Collapsed:
            //            pnlLimb_ImageController.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Limb_ImageController_ExpansionDirection:
            //            pnlLimb_ImageController.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;

            //        #endregion

            //        #region Panel_Options
            //        case enuFormatData.OptionsPanel_Height:
            //            pnlOptions.Height = (int)dblValue;
            //            break;

            //        case enuFormatData.OptionsPanel_Left:
            //            pnlOptions.Left = (int)dblValue;
            //            break;

            //        case enuFormatData.OptionsPanel_Top:
            //            pnlOptions.Top = (int)dblValue;
            //            break;

            //        case enuFormatData.OptionsPanel_Width:
            //            pnlOptions.Width = (int)dblValue;
            //            break;

            //        case enuFormatData.OptionsPanel_Collapsed:
            //            pnlOptions.Collapsed = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.OptionsPanel_ExpansionDirection:
            //            pnlOptions.ExpansionDirection = (panelMoveable.enuExpansionDirection)(int)dblValue;
            //            break;

            //        #endregion

            //        #region Panels_visible
            //        case enuFormatData.Panels_DrawSequence_checked:
            //            mnuPanels_DrawSequence.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_HingeContacts_Graphical_checked:
            //            mnuPanels_HingeContact_Graphical.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_HingeContacts_Numerical_checked:
            //            mnuPanels_HingeContact_Numerical.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_DebugDataTester_checked:
            //            mnuPanels_DataTester.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_FrameEditor_checked:
            //            mnuPanels_FrameEditor.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_AnimationControls_checked:
            //            mnuPanels_AnimationControls.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_AnimationFrameEditor_checked:
            //            mnuPanels_AnimationFrameEditor.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Panels_Options_checked:
            //            mnuPanels_Options.Checked = ((int)dblValue == 1);
            //            break;

            //        #endregion

            //        #region Options_Controller_Data
            //        case enuFormatData.filename:
            //            strFilename_Current = strValue;

            //            if (strFilename_Current.Contains(conCurrentDirectory_LoadFile))
            //            {
            //                strFilename_Current = strFilename_Current.Replace(conCurrentDirectory_LoadFile, System.IO.Directory.GetCurrentDirectory() + "\\");
            //            }
            //            File_Load(strFilename_Current);
            //            break;

            //        case enuFormatData.FrameEditor_Track_DrawSequence_checked:
            //            pnlFrameEditor.chkTrack_DrawSequence.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Track_DrawRelativeTo_checked:
            //            pnlFrameEditor.chkTrack_DrawRelativeTo.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Track_Limb_Radianss_checked:
            //            pnlFrameEditor.chkTrack_Limb_Radians.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.FrameEditor_Track_Mirrors:
            //            pnlFrameEditor.chkTrack_Mirrors.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Show_LimbNames_checked:
            //            pnlOptions.chkShow_LimbNames.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Show_LimbCenters_checked:
            //            pnlOptions.chkShow_LimbCenters.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Show_ToolTips:
            //            pnlOptions.chkShow_ToolTips.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Show_LimbPositions_checked:
            //            pnlOptions.chkShow_LimbPositions.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Show_FocusController_checked:
            //            pnlOptions.chkShow_FocusController.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Show_Frame:
            //            pnlOptions.chkShow_Frame.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_UseRAMCache_checked:
            //            pnlOptions.chkUseRAMCache.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_LimbMouseController_checked:
            //            pnlFrameEditor.chkMouse_LimbControl.Checked = ((int)dblValue == 1);
            //            break;

            //        case enuFormatData.Options_Radians_StepSize:
            //            pnlOptions.txtOptions_Radians_StepSize.Text = (dblValue).ToString(strRadiansFormat);
            //            break;

            //        case enuFormatData.Options_Magnitude_StepSize:
            //            pnlOptions.txtOptions_Magnitude_StepSize.Text = dblValue.ToString(strMagnitudeFormat);
            //            break;

            //        case enuFormatData.Options_TimerInterval:
            //            int intInterval = (int)dblValue;
            //            if (intInterval > 0)
            //                tmrAnimation.Interval = intInterval;
            //            else
            //                tmrAnimation.Interval = 100;
            //            break;

            //        case enuFormatData.FocusController_X:
            //            ptFocusControllerCenter = new Point((int)dblValue, ptFocusControllerCenter.Y);
            //            break;

            //        case enuFormatData.FocusController_Y:
            //            ptFocusControllerCenter = new Point(ptFocusControllerCenter.X, (int)dblValue);
            //            Draw_Controls();
            //            break;

            //        case enuFormatData.Options_FocusController_StepSize:
            //            pnlOptions.txtFocusController_StepSize.Text = ((int)dblValue).ToString();
            //            break;

            //        case enuFormatData.Draw_Sprite_Screen_X:
            //            cSpriteData.pt = new Point((int)dblValue, cSpriteData.pt.Y);
            //            break;

            //        case enuFormatData.Draw_Sprite_Screen_Y:
            //            cSpriteData.pt = new Point(cSpriteData.pt.X, (int)dblValue);
            //            break;

            //        case enuFormatData.DrawZoom:
            //            cSpriteData.cAnimationData.dblDrawSizeFactor = dblValue;
            //            break;
            //        #endregion

            //        #region Form
            //        case enuFormatData.Form_Width:
            //            {
            //                szForm_Load.Width = (int)dblValue;
            //            }
            //            break;

            //        case enuFormatData.Form_Height:
            //            {
            //                szForm_Load.Height = (int)dblValue;
            //            }
            //            break;

            //        case enuFormatData.Form_Location_X:
            //            {
            //                ptForm_Location.X = (int)dblValue;
            //            }
            //            break;

            //        case enuFormatData.Form_Location_Y:
            //            {
            //                ptForm_Location.Y = (int)dblValue;
            //            }
            //            break;
            //        #endregion

            //        default:
            //            { 
                        
            //            }
            //            break;
            //    }
            //}

            //Draw_Sprite();
        }

        /// <summary>
        /// toggles whether the DrawSequence panel is visible
        /// </summary>
        public void mnuPanels_DrawSequence_CheckStateChanged(object sender, EventArgs e)
        {
            pnlDrawSequence.Visible = mnuPanels_DrawSequence.Checked;
            pnlDrawSequence.BringToFront();
            Message(pnlDrawSequence.Visible ? "showing draw sequence"
                                                      : "hiding draw sequence");
            Debug_TestData("exiting mnuPanels_DrawSequence_CheckStateChanged");
            Focus();
        }

        /// <summary>
        /// toggles whether the HingeContacts_Numerical panel is visible
        /// </summary>
        private void mnuPanels_HingeContacts_Numerical_Click(object sender, EventArgs e)
        {
            pnlHingeContacts_Set_Numerical.Visible = mnuPanels_HingeContact_Numerical.Checked;
        }

        /// <summary>
        /// toggles whether the HingeContacts_Graphical panel is visible
        /// </summary>
        private void mnuPanels_HingeContacts_Graphical_CheckStateChanged(object sender, EventArgs e)
        {
            pnlHingeContacts_Set_Graphical.Visible = mnuPanels_HingeContact_Graphical.Checked;
        }

        /// <summary>
        /// toggles whther the DataTester panel is visible
        /// </summary>
        private void mnuPanels_DataTester_CheckStateChanged(object sender, EventArgs e)
        {
            pnlDebug.Visible
                = pnlDebug.Enabled
                = mnuPanels_DataTester.Checked;
        }

        /// <summary>
        /// toggles whether the Options panel is visible
        /// </summary>
        private void mnuPanels_Options_ChckStateChange(object sender, EventArgs e)
        {
            if (pnlOptions != null)
            {
                pnlOptions.Visible = mnuPanels_Options.Checked;
                if (pnlOptions.Visible) pnlOptions.BringToFront();
            }
        }

        /// <summary>
        /// toggles whether the FrameEditor panel is visible
        /// </summary>
        private void mnuPanels_FrameEditor_Click(object sender, EventArgs e)
        {
            pnlFrameEditor.Visible = mnuPanels_FrameEditor.Checked;
        }

        /// <summary>
        /// toggles whether the FrameEditor panel is visible
        /// </summary>
        private void mnuPanels_FrameEditor_CheckStateChanged(object sender, EventArgs e)
        {
            pnlFrameEditor.Visible = mnuPanels_FrameEditor.Checked;
        }

        /// <summary>
        /// toggles whether the animationControls panel is visible
        /// </summary>
        private void mnuPanels_AnimationControls_Click(object sender, EventArgs e)
        {
            pnlAnimationControls.Visible = mnuPanels_AnimationControls.Checked;
        }

        /// <summary>
        /// toggles whether the AnimationFrameEditor panel is visible
        /// </summary>
        private void mnuPanels_AnimationFrameEditor_Click(object sender, EventArgs e)
        {
            pnlAnimation_FrameEditor.Visible = mnuPanels_AnimationFrameEditor.Checked;
        }

        /// <summary>
        /// toggles whether or not the AnimationSpeed editing panel is visible
        /// </summary>
        private void mnuPanels_AnimationSpeed_Click(object sender, EventArgs e)
        {
            pnlAnimation_Speed.Visible = mnuPanels_AnimationSpeed.Checked;
        }

        /// <summary>
        /// toggles whether the CostumeSelector panel is visible
        /// </summary>
        private void mnuPanels_CostumeSelector_Click(object sender, EventArgs e)
        {
            pnlCostume_Selector.Visible = mnuPanels_CostumeSelector.Checked;
        }

        /// <summary>
        /// runs the classDebug's testing algorithms to verify the internal state of a sprite's data and notify developer(me) of bugs along the development road
        /// </summary>
        private void Debug_TestData(string strMarker)
        {
            if (cSpriteData.cAnimationData.cSprite != null)
                pnlDebug.debugTestData(ref cSpriteData, strMarker);
        }

        #region Events

        #region Events_Menu

        /// <summary>
        /// launches panelMessenger to get the New Sprite's name before create new sprite
        /// </summary>
        private void mnuFile_New_Click(object sender, EventArgs e)
        {
            pnlMessenger.getName("Enter Name of New Sprite", "New Sprite Name", (KeyEventHandler)frmMessenger_UserReply, panelMessenger.enuMessage.Sprite_New_Name);
            pnlDebug.Clear();
            Message("enter new sprite's name");
            Debug_TestData("exiting mnuFile_New_click");
        }

        classSpriteMaker.enuFileExtensionsSupported eSpriteExtension_Previous = classSpriteMaker.enuFileExtensionsSupported.SP6;
        string SpriteFileFilter
        {
            get
            {
                string strFilter = classSpriteMaker.FileFileExtension_GetString(eSpriteExtension_Previous);
                
                for (int intExCounter = 0; intExCounter < (int)classSpriteMaker.enuFileExtensionsSupported._numFileExtensionsSupported; intExCounter++)
                {
                    classSpriteMaker.enuFileExtensionsSupported eSpriteEx = (classSpriteMaker.enuFileExtensionsSupported)intExCounter;
                    if (eSpriteEx != eSpriteExtension_Previous)
                    {
                        strFilter += "|" + classSpriteMaker.FileFileExtension_GetString(eSpriteEx);
                    }
                }
                return strFilter;
            }
        }

        /// <summary>
        /// allows the user to load a sprite from a file
        /// </summary>
        private void mnuFile_Load_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = SpriteFileFilter;
            Message("select a file to load");
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                strFilename_Current = ofd.FileName;
                File_Load(strFilename_Current);
                pnlFrameEditor.cSprite = cSpriteData.cAnimationData.cSprite;
                pnlLimb_SetAnimation.SetObjects();
            }
            Debug_TestData("exiting mnuFile_Load_click");
        }

        /// <summary>
        /// save the current sprite to the current filename
        /// </summary>
        private void mnuFile_Save_Click(object sender, EventArgs e)
        {
            Message("saving " + strFilename_Current);
            string strFilename = strFilename_Current;

            classSpriteMaker.instance.Save(ref cSpriteData.cAnimationData.cSprite, ref strFilename);

            strFilename_Current = strFilename;
            Message("file saved :" + strFilename_Current);
            Debug_TestData("exiting mnuFile_Save_New_click");
            Focus();
        }


        /// <summary>
        /// allows the user to save the sprite to a new filename
        /// </summary>
        private void mnuFile_SaveAs_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "SP5 | *.sp5";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                strFilename_Current = sfd.FileName;
                Message("saving " + strFilename_Current);

                classSpriteMaker.instance.Save(ref cSpriteData.cAnimationData.cSprite, ref cSpriteData.cAnimationData.filename);

                Message("sprite saved as : " + strFilename_Current);
                Debug_TestData("exiting mnuFile_SaveAs_New_click");
            }
            Focus();
        }

        /// <summary>
        /// launches panelMessenger to get user input about what size to resize the sprite
        /// </summary>
        public void Costume_Resize()
        {
            pnlMessenger.getName("Resize the sprite " + cSpriteData.cAnimationData.cSprite.Name + " costume:" + cSpriteData.cCostumeInfo.Name, // heading 
                                 "enter a percentage value of the desired output size", // text
                                 "50", // suggested input
                                 (KeyEventHandler)frmMessenger_UserReply,
                                 panelMessenger.enuMessage.Resize);
            pnlDebug.Clear();
            Message("enter percentage resize");
            Debug_TestData("exiting mnuFile_Resize_click");
        }

        /// <summary>
        /// terminates SpriteEditor_2017
        /// </summary>
        private void mnuFile_Exit_Click(object sender, EventArgs e)
        {
            Dispose();
        }

        /// <summary>
        /// launches panelMessenger to get a name for the new limb before a new limb is created
        /// </summary>
        private void mnuLimbs_NewRegular_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();
            if (cmbLimbs.Text.Length == 0 || cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(cmbLimbs.Text) == null)
            {
                MessageBox.Show("You must select a Limb from the limbs combo box onto which a new limb may be attached", "no Master Limb selected");
                return;
            }

            pnlMessenger.getName("New Limb attached to : " + cLimb.Name, "Name of new Limb", frmMessenger_UserReply, panelMessenger.enuMessage.Limb_New_Name);
            Message("enter name of new limb");
            pnlMessenger.txtUserInput.Focus();
            pnlMessenger.Expand();
            Debug_TestData("exiting mnuLimbs_NewRegular_Click");
        }

        private void mnuLimbs_NewText_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();

            formLimb_New_Text frmLimbNewText = new formLimb_New_Text();
            if (frmLimbNewText.ShowDialog() == DialogResult.OK)
            {
                List<string> lstLimbs = new List<string>();
                if (frmLimbNewText.LimbInfo.MultipleLimbs)
                {
                    char[] chrSplit = " .,:;-+!?/\\|[]{}()".ToArray<char>();
                    ////lstLimbs.AddRange(classStringLibrary.getFirstWords(frmLimbNewText.LimbInfo.Text, ",.;:\"'?!(){}[]"));
                    lstLimbs.AddRange(frmLimbNewText.LimbInfo.Text.Split(chrSplit).ToList<string>());
                    lstLimbs = (List<string>)lstLimbs.Distinct().ToList<string>(); 
                }
                else
                {
                    lstLimbs.Add(frmLimbNewText.LimbInfo.Text);
                }

                while (lstLimbs.Count > 0)
                {
                    string strLimbName = lstLimbs[0];
                    lstLimbs.RemoveAt(0);
                    classSprite_Limb cLimbFind = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(strLimbName);
                    if (cLimbFind == null)
                        cSpriteData.cAnimationData.cSprite.Limb_New(strLimbName,
                                                                    frmLimbNewText.LimbInfo.Font,
                                                                    frmLimbNewText.LimbInfo.Color_Fore,
                                                                    frmLimbNewText.LimbInfo.Color_Transparent);
                }
                cmbLimbs_Reset();
                cmbLimbs_SetSelect(frmLimbNewText.LimbInfo.Text);
                if (cSpriteData.cAnimationData.cSprite != null
                    && cSpriteData.cAnimationData.cAnimation != null
                    && cSpriteData.cAnimationData.cAnimation.lstFrames.Count > 0
                    && cSpriteData.cAnimationData.intFrameIndex < cSpriteData.cAnimationData.cAnimation.lstFrames.Count)
                {
                    classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                    pnlDrawSequence.setToFrame(ref cFrame);
                }
                cmbAnimation_Refresh();
            }
        }

        /// <summary>
        /// deletes the currently selected limb and all the slave-limbs attached to it
        /// </summary>
        private void mnuLimbs_Delete_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();
            List<string> lstLimbsToBeDeleted = cSpriteData.cAnimationData.cSprite.Limb_Slaves_Get(cLimb.Name);
            string strMessageBox = "Are you sure you want to delete "
                                    + cLimb.Name
                                    + "?\n\rDoing so will also delete the following limbs :";
            for (int intLimbCounter = 0; intLimbCounter < lstLimbsToBeDeleted.Count; intLimbCounter++)
                strMessageBox += lstLimbsToBeDeleted[intLimbCounter] + (intLimbCounter < lstLimbsToBeDeleted.Count - 1 ? ", " : ".");

            if (MessageBox.Show(strMessageBox, "Delete " + cLimb.Name + "?", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                pnlDebug.Enabled = false;

                cSpriteData.cAnimationData.cSprite.Limb_Delete(ref _cLimb);

                cLimb = null;
                for (int intLimbCounter = 0; intLimbCounter < cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs.Count; intLimbCounter++)
                {
                    if (cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[intLimbCounter] != cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master)
                    {
                        cLimb = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[intLimbCounter];
                        break;
                    }
                }
                if (cLimb == null) cLimb = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master;

                cmbLimbs_Reset();
                cmbLimbs_SetSelect(cLimb.Name);

                if (pnlDrawSequence != null)
                {
                    classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                    pnlDrawSequence.setToFrame(ref cFrame);
                }

                Costumes_MatchDefault();


                pnlFrameEditor.clbLimbTracker_Init();
                pnlDebug.Enabled = true;
            }
            Debug_TestData("exiting mnuLimbs_Delete_click");
        }

        /// <summary>
        /// launches panelMessenger to get a name for a new Animation 
        /// </summary>
        private void mnuAnimation_New_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();
            pnlMessenger.getName("New Animation for \"" + cSpriteData.cAnimationData.cSprite.Name + "\"", "Name of new Animation", frmMessenger_UserReply, panelMessenger.enuMessage.Animation_New_Name);
            pnlMessenger.txtUserInput.Focus();
            pnlMessenger.Expand();
            Message("enter name of new animation");
            Debug_TestData("exiting mnuAnimation_New_click");
        }

        /// <summary>
        /// launches panelMessenger to get a new name for the currently selected animation
        /// </summary>
        private void mnuAnimation_ChangeName_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite == null || cSpriteData.cAnimationData.cAnimation == null) return;
            Costume_SetToDefault();
            pnlMessenger.getName("Change animation name from \"" + cSpriteData.cAnimationData.cAnimation.Name + "\" to", "New name of Animation " + cSpriteData.cAnimationData.cAnimation.Name, frmMessenger_UserReply, panelMessenger.enuMessage.Animation_Rename);
            pnlMessenger.txtUserInput.Focus();
            Message("enter new name for animation " + cSpriteData.cAnimationData.cAnimation.Name);
            Debug_TestData("exiting mnuAnimation_Change_name");
        }



        /// <summary>
        /// deletes the currently selected animation
        /// </summary>
        private void mnuAnimation_Delete_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite.lstAnimations.Count < 2)
            {
                MessageBox.Show("You cannot delete this sprite's only animation.");
                return;
            }
            Costume_SetToDefault();
            cSpriteData.cAnimationData.cSprite.Animation_Delete(ref cSpriteData.cAnimationData.cAnimation);
            cmbAnimation_Refresh();
            pnlLimb_SetAnimation.SetObjects();
            Debug_TestData("exiting mnuAnimation_Delete_Click");
        }

        /// <summary>
        /// launches the panelAutoInsertIntermediaryFrames
        /// </summary>
        public void mnuAnimation_AutoInsertIntermediaryFrames_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();
            pnlAutoInsertIntermediaryFrames.InsertIntermediaryFrames(true);
        }

        public void pnlLimb_SetAnimation_BtnOk_Click(object sender, EventArgs e)
        {
            classAnimation cAnimation = pnlLimb_SetAnimation.Animation;
            {
                if (cAnimation == null)
                {
                    MessageBox.Show("no animation selected", "animation not selected");
                    return;
                }

                if (cAnimation.lstFrames.Count < 2)
                {
                    MessageBox.Show("animation selected must have more than one frame", "insufficient frames in animation");
                    return;
                }
            }

            int intIndex_Start= pnlLimb_SetAnimation.FrameStart;
            int intIndex_End = pnlLimb_SetAnimation.FrameEnd;
            {
                if (intIndex_Start < 0 || intIndex_Start >= cAnimation.lstFrames.Count)
                {
                    MessageBox.Show("invalid start frame selected", "start-frame not valid");
                    return;
                }
                if (intIndex_End >= cAnimation.lstFrames.Count || intIndex_End < 0)
                {
                    MessageBox.Show("Invalid end Frame selected", "end-frame not-valid");
                    return;
                }

                if (intIndex_Start == intIndex_End)
                {
                    MessageBox.Show("start and end frames must be different", "identical start & end frame error");
                    return;
                }
            }

            List<classSprite_Limb> lstLimbs = pnlLimb_SetAnimation.Limbs;
            {
                if (lstLimbs == null || lstLimbs.Count < 1)
                {
                    MessageBox.Show("no limbs selected", "limbs not selected");
                    return;
                }
            }

            double dblNumFrames = (intIndex_Start > intIndex_End 
                                                  ? cAnimation.lstFrames.Count - intIndex_Start + intIndex_End
                                                  : intIndex_End - intIndex_Start)
                                   -1;

            List<double> lstDelta_Angle = new List<double>();
            List<double> lstDelta_Magnitude = new List<double>();
            classAnimation_Frame cFrame_Start = cAnimation.lstFrames[intIndex_Start];
            classAnimation_Frame cFrame_End = cAnimation.lstFrames[intIndex_End];

            for (int intLimbCounter = 0; intLimbCounter < lstLimbs.Count; intLimbCounter++)
            {
                bool bolClockwise = true;
                classSprite_Limb cLimb = lstLimbs[intLimbCounter];
                classAnimation_Frame_LimbData cLimbData_End = cFrame_End.getData(cLimb.Name);
                classAnimation_Frame_LimbData cLimbData_Start = cFrame_Start.getData(cLimb.Name);
                if (cLimbData_End == null || cLimbData_Start == null)
                {
                    MessageBox.Show("limb info not found for " + cLimb.Name, "Set Limb Animation aborted");
                    return;
                }
                double dblDelta_Angle_Total = (cLimbData_End.Angle - cLimbData_Start.Angle);

                if (dblDelta_Angle_Total > 0)
                {
                    if (Math.Abs(dblDelta_Angle_Total) > Math.PI)
                    {
                        dblDelta_Angle_Total = Math.Abs(dblDelta_Angle_Total - classMath3.TwoPi);
                        bolClockwise = false;
                    }
                    else
                    {
                        bolClockwise = true;
                    }
                }
                else // difference b/w (end-start)<0 -> counter clockwise
                {
                    if (dblDelta_Angle_Total < -Math.PI) // unless >Pi then Counter-clockwise
                    {
                        dblDelta_Angle_Total = Math.Abs(dblDelta_Angle_Total + classMath3.TwoPi);
                        bolClockwise = true;
                    }
                    else
                    {
                        bolClockwise = false;
                        dblDelta_Angle_Total = Math.Abs(dblDelta_Angle_Total);
                    }
                }

                double dblDelta_Angle_Step = (dblDelta_Angle_Total / (dblNumFrames + 1)) * (bolClockwise ? 1 : -1);
                lstDelta_Angle.Add(dblDelta_Angle_Step);
                //double dblDelta_Magnitude = (cFrame_End.lstData[intLimbCounter].SlaveContactMagnitude_Factor - cFrame_Start.lstData[intLimbCounter].SlaveContactMagnitude_Factor) / (dblNumFrames + 1);
                double dblDelta_Magnitude = (cLimbData_End.SlaveContactMagnitude_Factor - cLimbData_Start.SlaveContactMagnitude_Factor)/(dblNumFrames +1);
                lstDelta_Magnitude.Add(dblDelta_Magnitude);
            }

            for (int intLimbCounter = 0; intLimbCounter < lstLimbs.Count; intLimbCounter++)
            {
                classSprite_Limb cLimb = lstLimbs[intLimbCounter];
                classAnimation_Frame_LimbData cLimbData_Start = cFrame_Start.getData(cLimb.Name);

                for (int intFrameCounter = 1; intFrameCounter <= dblNumFrames; intFrameCounter++)
                {
                    int intFrameIndex = (intIndex_Start + intFrameCounter) % cAnimation.lstFrames.Count;
                    classAnimation_Frame cFrame = cAnimation.lstFrames[intFrameIndex];
                    classAnimation_Frame_LimbData cLimbData_Edit = cFrame.getData(cLimb.Name);
                    cLimbData_Edit.Angle = cLimbData_Start.Angle + intFrameCounter * lstDelta_Angle[intLimbCounter];
                    cLimbData_Edit.SlaveContactMagnitude_Factor =cLimbData_Start.SlaveContactMagnitude_Factor + intFrameCounter * lstDelta_Magnitude[intLimbCounter];
                }
            }
        }

        public void mnuLimb_SetAnimation_click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite == null)
            {
                MessageBox.Show("No sprite loaded", "sprite not loaded");
                return;
            }
            pnlLimb_SetAnimation.Show();

        }
        public void pnlLimb_CopyFrames_BtnOk_Click(object sender, EventArgs e)
        {
            pnlLimb_CopyFrames.Hide();
            classAnimation cAnimation_Source = pnlLimb_CopyFrames.Animation_Source;
            List<classAnimation> lstAnimations_Destination = pnlLimb_CopyFrames.Animations_Destination;
            List<classSprite_Limb> lstLimbsToCopy = pnlLimb_CopyFrames.LimbsToCopy;
            List<classAnimation_Frame> lstFramesSource = pnlLimb_CopyFrames.Frames_Source;

            if (cAnimation_Source == null)
            {
                MessageBox.Show("No Source Animation Selected", "Source Animation not selected");
                return;
            }
            if (lstAnimations_Destination == null || lstAnimations_Destination.Count == 0)
            {
                MessageBox.Show("no destination animations selected", "Destination Animation not Selected");
                return;
            }
            if (lstLimbsToCopy == null && lstLimbsToCopy.Count == 0)
            {
                MessageBox.Show("no limbs selected", "limbs not selected");
                return;
            }
            if (lstFramesSource == null || lstFramesSource.Count == 0)
            {
                MessageBox.Show("no source frames selected", "source frames not selected");
                return;
            }

            //  copy frames
            for (int intAnimationCounter =0; intAnimationCounter < lstAnimations_Destination.Count; intAnimationCounter++)
            {
                classAnimation cAnimationDestination = lstAnimations_Destination[intAnimationCounter];
                Limb_CopyFrames(ref cAnimationDestination, ref lstLimbsToCopy, ref lstFramesSource);
            }

        }

        void Limb_CopyFrames(ref classAnimation cAni_Dest, 
                             ref List<classSprite_Limb> lstLimbs, 
                             ref List<classAnimation_Frame> lstFramesIn)
        {
            List<classAnimation_Frame> lstFramesSource_KeepFrameIntegrity = pnlLimb_CopyFrames.KeepFrameIntegrity
                                                                          ? Limb_CopyFrames_GetSourceFrames(cAni_Dest.lstFrames.Count, ref lstFramesIn)
                                                                          : null;

            for (int intLimbCounter = 0; intLimbCounter < lstLimbs.Count; intLimbCounter++)
            {
                List<classAnimation_Frame> lstFrames_Source = pnlLimb_CopyFrames.KeepFrameIntegrity
                                                                                ? lstFramesSource_KeepFrameIntegrity
                                                                                : Limb_CopyFrames_GetSourceFrames(cAni_Dest.lstFrames.Count, ref lstFramesIn);
                for (int intFrameCounter = 0; intFrameCounter < lstFrames_Source.Count; intFrameCounter++)
                {
                    classAnimation_Frame cFrameSource = lstFrames_Source[intFrameCounter];
                    classAnimation_Frame cFrameDest = cAni_Dest.lstFrames[intFrameCounter];

                    classAnimation_Frame_LimbData cLimbData_Source = cFrameSource.getData(lstLimbs[intLimbCounter].Name);
                    classAnimation_Frame_LimbData cLimbData_Dest = cFrameDest.getData(lstLimbs[intLimbCounter].Name);

                    if (cLimbData_Source == null)
                    {
                        MessageBox.Show("Error loading frames for limb:" + lstLimbs[intLimbCounter].Name, "Error during Limb Copy Frames");
                        break;
                    }
                    if (cLimbData_Dest == null)
                    {
                        MessageBox.Show("Error loading frames for limb:" + lstLimbs[intLimbCounter].Name + " in animation \"" + cAni_Dest.Name + "\"", "Error during Limb Copy Frames");
                        break;
                    }

                    cLimbData_Dest.Angle = cLimbData_Source.Angle;
                    cLimbData_Dest.SlaveContactMagnitude_Factor = cLimbData_Source.SlaveContactMagnitude_Factor;
                }
            }
        }

        List<classAnimation_Frame> Limb_CopyFrames_GetSourceFrames(int intNumFrames_Dest, 
                                                                   ref List<classAnimation_Frame> lstFramesIn)
        {
            int intNumFrames_Source = lstFramesIn.Count;
            List<classAnimation_Frame> lstRetVal = new List<classAnimation_Frame>();
            while (lstRetVal.Count < intNumFrames_Dest)
                lstRetVal.AddRange(lstFramesIn);

            while (lstRetVal.Count > intNumFrames_Dest)
            {
                lstRetVal.RemoveAt(classRND.Get_Int(0, lstRetVal.Count));
            }
            return lstRetVal;
        }


        public void mnuLimb_CopyFrames_click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite == null)
            {
                MessageBox.Show("No sprite loaded", "sprite not loaded");
                return; 
            }
            pnlLimb_CopyFrames.Show();
        }

        #endregion // Events_Menu

        #region Events_LimbEditor
        /// <summary>
        /// selects the next limb to be edited
        /// </summary>
        private void CmbLimbs_SelectedIndexChanged(object sender, EventArgs e)
        {
            Limb_Selected_Set();
        }

        void Limb_Selected_Set()
        {
            cLimb = (classSprite_Limb)cSpriteData.cCostumeInfo.cBT_Limbs.Search(cmbLimbs.Text);
            setLimbInfo();
            setLimbInfo_Graphical_Show();
            if (pnlLimb_ImageController.Visible)
                pnlLimb_ImageController.Limb = cLimb;
            Debug_TestData("exiting cmbLimbs_SelectedIndexChanged");
            Focus();
        }

        /// <summary>
        /// sets the currently selected limb's HingeContact.slave's radian coordinate to the value set in txtHinge_Contact_Slave_Radians
        /// </summary>
        private void TxtHinge_Contact_Slave_Radians_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                 && cLimb.Hinge != null
                 && cLimb.Hinge.Contact != null
                 && cLimb.Hinge.Contact.Slave != null)
            {
                cLimb.Hinge.Contact.Slave.Radians = txtBox_ReadValue(txtHinge_Contact_Slave_Radians.Text);
                Draw_Sprite();
                if (pnlHingeContacts_Set_Graphical != null) pnlHingeContacts_Set_Graphical.drawSlave();
                Debug_TestData("exiting txtHinge_Contact_slave_radians_textchanged");
            }
        }

        /// <summary>
        /// sets the currently selected limb's HingeContact.slave's magnitude coordinate to the value set in txtHinge_Contact_Slave_Radians
        /// </summary>
        private void TxtHinge_Contact_Slave_Magnitude_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                 && cLimb.Hinge != null
                 && cLimb.Hinge.Contact != null
                 && cLimb.Hinge.Contact.Slave != null)
            {
                cLimb.Hinge.Contact.Slave.Magnitude = txtBox_ReadValue(txtHinge_Contact_Slave_Magnitude.Text);
                Draw_Sprite();
                if (pnlHingeContacts_Set_Graphical != null) pnlHingeContacts_Set_Graphical.drawSlave();
                Debug_TestData("exiting txtHinge_Contact_slave_magnitude");
            }
        }

        /// <summary>
        /// sets the currently selected limb's HingeContact.Master's radian coordinate to the value set in txtHinge_Contact_Slave_Radians
        /// </summary>
        private void TxtHinge_Contact_Master_Radians_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                   && cLimb.Hinge != null
                   && cLimb.Hinge.Contact != null
                   && cLimb.Hinge.Contact.Master != null)
            {
                cLimb.Hinge.Contact.Master.Radians = txtBox_ReadValue(txtHinge_Contact_Master_Radians.Text);
                Draw_Sprite();
                if (pnlHingeContacts_Set_Graphical != null)
                    pnlHingeContacts_Set_Graphical.drawMaster();
                Debug_TestData("exiting txtHinge_Contact_Master_radians_textchanged");
            }
        }

        /// <summary>
        /// sets the currently selected limb's HingeContact.Master's magnitude coordinate to the value set in txtHinge_Contact_Slave_Radians
        /// </summary>
        private void TxtHinge_Contact_Master_Magnitude_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                && cLimb.Hinge != null
                && cLimb.Hinge.Contact != null
                && cLimb.Hinge.Contact.Master != null)
            {
                cLimb.Hinge.Contact.Master.Magnitude = txtBox_ReadValue(txtHinge_Contact_Master_Magnitude.Text);
                Draw_Sprite();
                if (pnlHingeContacts_Set_Graphical != null)
                    pnlHingeContacts_Set_Graphical.drawMaster();
                Debug_TestData("exiting txtHinge_Contact_Master_Magnitude_textchanged");
            }
        }

        /// <summary>
        /// sets the currently selected limb's Hinge angle to the value in txtHinge_Radians
        /// </summary>
        private void txtHinge_Radians_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                && cLimb.Hinge != null)
            {
                cLimb.Hinge.Angle = txtBox_ReadValue(txtHinge_Radians.Text);
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                classAnimation_Frame_LimbData cHingeData = cFrame.getData(cLimb.Name);//.lstData[cLimb.intMyIndex];
                cHingeData.Angle = cLimb.Hinge.Angle;
                cFrame.StandardSizeInitialized = false;
                if (pnlHingeContacts_Set_Graphical != null)
                    pnlHingeContacts_Set_Graphical.lblAngle_Value.Text = txtHinge_Radians.Text;
                
                if (!tmrAnimation.Enabled)
                    Draw_Sprite();

                TextBox txtSender = (TextBox)sender;

                Debug_TestData("exiting txt|Hinge_radians_textchanged");
            }
        }



        private void txtOpacity_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                && cLimb.Hinge != null)
            {
                byte bytOpacity = 0;

                try
                {
                    bytOpacity = (byte)Convert.ToByte(txtOpacity.Text);
                }
                catch (Exception)
                {

                }

                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];

                classAnimation_Frame_LimbData cHingeDataOverride = cFrame.getOverrideData(cLimb.Name);
                classAnimation_Frame_LimbData cHingeData = cFrame.getData(cLimb.Name);

                cHingeDataOverride.Opacity
                    = cHingeData.Opacity
                    = bytOpacity;

                cFrame.StandardSizeInitialized = false;

                if (!tmrAnimation.Enabled)
                    Draw_Sprite();

                Debug_TestData("exiting txtOpacity_textchanged");
            }
        }


        /// <summary>
        /// sets the currently selected limb's SlaveContactMagnitude_Factor to the value in txtHinge_Magnitude
        /// </summary>
        private void txtHinge_Magnitude_TextChanged(object sender, EventArgs e)
        {
            if (cLimb != null
                && cLimb.Hinge != null)
            {
                double dblSlaveContactHinge_Factor = txtBox_ReadValue(txtHinge_Magnitude.Text);
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];

                classAnimation_Frame_LimbData cHingeDataOverride = cFrame.getOverrideData(cLimb.Name);
                classAnimation_Frame_LimbData cHingeData = cFrame.getData(cLimb.Name);

                if (Math.Abs(dblSlaveContactHinge_Factor) > 20)
                    txtHinge_Magnitude.Text = cHingeDataOverride.SlaveContactMagnitude_Factor.ToString(strMagnitudeFormat);
                else
                    cHingeDataOverride.SlaveContactMagnitude_Factor 
                        = cHingeData.SlaveContactMagnitude_Factor
                        = dblSlaveContactHinge_Factor;

                cFrame.StandardSizeInitialized = false;
                if (pnlHingeContacts_Set_Graphical != null)
                    pnlHingeContacts_Set_Graphical.lblMagnitude_Value.Text = txtHinge_Magnitude.Text;
                if (!tmrAnimation.Enabled)
                    Draw_Sprite();

                //classAnimation_Frame_LimbData cHingeData = cFrame.getData(cLimb.Name);

                Debug_TestData("exiting txtHinge_Magnitude_textchanged");
            }
        }

        /// <summary>
        /// sets the panelHingeContacts_Graphical's limb setting and picturebox image
        /// </summary>
        private void GrbLimbEditor_Hinge_Contact_Click(object sender, EventArgs e)
        {
            setLimbInfo_Graphical_Show();
            Debug_TestData("exiting grbLimbEditoe_Hinge_contact_click");
        }

        /// <summary>
        /// ensures textboxes containing values addressed to sprite variables only contain valid numeric values
        /// </summary>
        public void txt_KeyDown_NumericOnly(object sender, KeyEventArgs e)
        {
            TextBox txtSender = (TextBox)sender;

            if (tmrAnimation.Enabled)
            {
                if (txtSender != pnlOptions.txtTimerDelay
                    && txtSender != pnlOptions.txtFocusController_StepSize
                    && txtSender != pnlOptions.txtOptions_Magnitude_StepSize
                    && txtSender != pnlOptions.txtOptions_Radians_StepSize
                    && txtSender != pnlOptions.txtOptions_DrawAngle)
                {
                    e.SuppressKeyPress = true;
                    return;
                }
            }

            switch (e.KeyCode)
            {
                case Keys.Shift:
                case Keys.Left:
                case Keys.Right:
                case Keys.Back:
                case Keys.Insert:
                case Keys.Delete:
                case Keys.D0:
                case Keys.D1:
                case Keys.D2:
                case Keys.D3:
                case Keys.D4:
                case Keys.D5:
                case Keys.D6:
                case Keys.D7:
                case Keys.D8:
                case Keys.D9:
                case Keys.NumPad0:
                case Keys.NumPad1:
                case Keys.NumPad2:
                case Keys.NumPad3:
                case Keys.NumPad4:
                case Keys.NumPad5:
                case Keys.NumPad6:
                case Keys.NumPad7:
                case Keys.NumPad8:
                case Keys.NumPad9:
                    break;

                case Keys.Decimal:
                case Keys.OemPeriod:
                    int intFirstIndex = txtSender.Text.IndexOf('.');
                    int intLastIndex = txtSender.Text.LastIndexOf('.');
                    if ((intFirstIndex >= 0 && intFirstIndex != txtSender.SelectionStart)
                        ||
                        (intLastIndex >= 0 && intLastIndex != txtSender.SelectionStart))
                        e.SuppressKeyPress = true;
                    break;

                case Keys.Up:
                    try
                    {
                        double dblValue = Convert.ToDouble(txtSender.Text);
                        dblValue += 0.05;

                        txtSender.Text = dblValue.ToString(txtSender.Name.ToLower().Contains("radi")
                                                                            ? strRadiansFormat
                                                                            : strMagnitudeFormat);
                    }
                    catch (Exception)
                    { }
                    break;
                case Keys.Down:
                    try
                    {
                        double dblValue = Convert.ToDouble(txtSender.Text);
                        dblValue -= 0.05;

                        txtSender.Text = dblValue.ToString(txtSender.Name.ToLower().Contains("radi")
                                                                            ? strRadiansFormat
                                                                            : strMagnitudeFormat);
                    }
                    catch (Exception)
                    { }
                    break;

                default:
                    Message("key suppressed : use only alpha numberic keys");
                    e.SuppressKeyPress = true;
                    break;
            }
            Debug_TestData("exiting txt_keyDown_NumericOnly Key:" + e.KeyValue);
        } 
        /// <summary>
        /// ensures textboxes containing values addressed to sprite variables only contain valid integer values
        /// </summary>
        public void txt_KeyDown_NumericIntegerOnly(object sender, KeyEventArgs e)
        {
            TextBox txtSender = (TextBox)sender;

            if (tmrAnimation.Enabled)
            {
                if (txtSender != pnlOptions.txtTimerDelay
                    && txtSender != pnlOptions.txtFocusController_StepSize
                    && txtSender != pnlOptions.txtOptions_Magnitude_StepSize
                    && txtSender != pnlOptions.txtOptions_Radians_StepSize
                    && txtSender != pnlOptions.txtOptions_DrawAngle)
                {
                    e.SuppressKeyPress = true;
                    return;
                }
            }

            switch (e.KeyCode)
            {
                case Keys.Shift:
                case Keys.Left:
                case Keys.Right:
                case Keys.Back:
                case Keys.Insert:
                case Keys.Delete:
                case Keys.D0:
                case Keys.D1:
                case Keys.D2:
                case Keys.D3:
                case Keys.D4:
                case Keys.D5:
                case Keys.D6:
                case Keys.D7:
                case Keys.D8:
                case Keys.D9:
                case Keys.NumPad0:
                case Keys.NumPad1:
                case Keys.NumPad2:
                case Keys.NumPad3:
                case Keys.NumPad4:
                case Keys.NumPad5:
                case Keys.NumPad6:
                case Keys.NumPad7:
                case Keys.NumPad8:
                case Keys.NumPad9:
                    break;
            
                case Keys.Up:
                    try
                    {
                        int intValue = Convert.ToInt16(txtSender.Text);
                        intValue++;

                        txtSender.Text = intValue.ToString();
                    }
                    catch (Exception)
                    { }
                    break;

                case Keys.Down:
                    try
                    {
                        int intValue = Convert.ToInt16(txtSender.Text);
                        intValue--;

                        txtSender.Text = intValue.ToString();
                    }
                    catch (Exception)
                    { }
                    break;

                default:
                    Message("key suppressed : use only alpha numberic keys");
                    e.SuppressKeyPress = true;
                    break;
            }
            Debug_TestData("exiting txt_keyDown_NumericOnly Key:" + e.KeyValue);
        }
        #endregion // Events_LimbEditor

        #region Events_Objects

        /// <summary>
        /// enables key controls to work as mouse controls
        /// </summary>
        private void PicMain_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left:
                    bolKeys[(int)enuKeys.Mouse_Left]
                        = bolMouseLeft_Down
                        = true;
                    break;

                case Keys.Right:
                    bolKeys[(int)enuKeys.Mouse_Right]
                        = bolMouseRight_Down
                        = true;
                    break;

                case Keys.Up:
                    bolKeys[(int)enuKeys.MouseWheel_Up] = true;
                    PicMain_MouseWheel((object)picMain, new MouseEventArgs(MouseButtons.None, 0, ptPicMain_Mouse.X, ptPicMain_Mouse.Y, -10));
                    break;

                case Keys.Down:
                    bolKeys[(int)enuKeys.MouseWheel_Down] = true;
                    PicMain_MouseWheel((object)picMain, new MouseEventArgs(MouseButtons.None, 0, ptPicMain_Mouse.X, ptPicMain_Mouse.Y, 10));
                    break;

                case Keys.ControlKey:
                    bolKeys[(int)enuKeys.ControlKey] = true;
                    break;

                default:
                    System.Diagnostics.Debug.Print(e.KeyCode.ToString());
                    break;
            }

        }

        /// <summary>
        /// works in conjunction with picMain_KeyDown to enable key control of mouse operations
        /// </summary>
        private void PicMain_KeyUp(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left:
                    bolKeys[(int)enuKeys.Mouse_Left]
                        = bolMouseLeft_Down
                        = false;
                    break;


                case Keys.Right:
                    bolKeys[(int)enuKeys.Mouse_Right]
                        = bolMouseRight_Down
                        = false;
                    break;


                case Keys.Up:
                    bolKeys[(int)enuKeys.MouseWheel_Up] = false;
                    break;

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

                case Keys.ControlKey:
                    bolKeys[(int)enuKeys.ControlKey] = false;
                    break;

            }
        }

        /// <summary>
        /// responds to the change in the current animation frame selection
        /// </summary>
        private void nudFrameCounter_ValueChanged(object sender, EventArgs e)
        {
            setObjectsToAnimationFrame();
        }


        public classAnimation_Frame Frame_Current
        {
            get
            {
                return cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
            }
        }

        /// <summary>
        /// resets current animation controls to reflect the new animation Frame selected
        /// </summary>
        void setObjectsToAnimationFrame()
        {
            cSpriteData.cAnimationData.intFrameIndex = (int)nudFrame_Counter.Value;
            frame_SetLimbs();

            classAnimation_Frame cFrame = Frame_Current;
            pnlDrawSequence.setToFrame(ref cFrame);
            classSprite_Limb cLimbDrawRelativeTo = cFrame.Limb_DrawRelativeTo >= 0
                                                                       ? cSpriteData.cCostumeInfo.lstLimbs[cFrame.Limb_DrawRelativeTo]
                                                                       : cSpriteData.cCostumeInfo.cLimb_Master;
            cmbFrameRelativeTo_SetSelected(cLimbDrawRelativeTo.Name);

            ContactHinge_Show();
            lblFrame_Value_Set();
            chkMirror_Set();
            if (pnlAutoInsertIntermediaryFrames.Visible && !pnlAutoInsertIntermediaryFrames.Collapsed)
                pnlAutoInsertIntermediaryFrames.InsertIntermediaryFrames();
            Debug_TestData("exiting nudFrameCounter_ValueChanged");
        }

        /// <summary>
        /// sets Sprite's mirror values according to the current mirror checkbox settings
        /// </summary>
        void chkMirror_Set()
        {
            if (cSpriteData.cAnimationData.cSprite != null && cSpriteData.cAnimationData.cAnimation != null)
            {
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                chkFrame_Mirror_Horizontal.Checked = cFrame.Horizontal_Mirror;
                chkFrame_Mirror_Vertical.Checked = cFrame.Vertical_Mirror;
            }
        }

        /// <summary>
        /// changes the value of the numericUpDown Frame counter according to mousewheel controls
        /// </summary>
        public void nudFrameCounter_MouseWheel(object sender, MouseEventArgs e)
        {
            HandledMouseEventArgs handledArgs = e as HandledMouseEventArgs;
            handledArgs.Handled = true;

            nudFrame_Counter.Value = (handledArgs.Delta > 0)
                                                       ? (nudFrame_Counter.Value + 1) % (nudFrame_Counter.Maximum + 1)
                                                       : (nudFrame_Counter.Value + nudFrame_Counter.Maximum) % (nudFrame_Counter.Maximum + 1);


        }

        /// <summary>
        /// resets frame index values to zero after change in animation or sprite
        /// </summary>
        public void nudFrameCounter_Reset()
        {
            if (cSpriteData.cAnimationData.cSprite != null
                && cSpriteData.cAnimationData.cAnimation != null)
                nudFrame_Counter.Maximum = cSpriteData.cAnimationData.cAnimation.lstFrames.Count - 1;
            nudFrame_Counter.Minimum = 0;
            nudFrame_Counter.Value
                = cSpriteData.cAnimationData.intFrameIndex
                = 0;
            ContactHinge_Show();
            lblFrame_Value_Set();
            Draw_Sprite();
            Debug_TestData("exiting nudFrameCpimteer+Reeset");
        }

        /// <summary>
        /// displays current frame index information 
        /// </summary>
        void lblFrame_Value_Set()
        {
            lblFrameCounter_ValueDisplay.Text = "(" + nudFrame_Counter.Value.ToString() + "/" + (nudFrame_Counter.Maximum).ToString() + ")";
        }

        /// <summary>
        /// sets textboxes displaying the currently selected limb's hinge values 
        /// </summary>
        void ContactHinge_Show()
        {
            if (cSpriteData.cAnimationData.cAnimation == null) return;
            classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
            int intContactHinge_FrameData_Index = -1;
            for (int intDataCounter = 0; intDataCounter < cFrame.lstData.Count; intDataCounter++)
            {
                classAnimation_Frame_LimbData cData = cFrame.lstData[intDataCounter];
                if (cData.intLimbIndex == cSpriteData.cCostumeInfo.lstLimbs.IndexOf(cLimb))
                {
                    intContactHinge_FrameData_Index = intDataCounter;
                    break;
                }
            }

            if (intContactHinge_FrameData_Index >= 0)
            {
                txtHinge_Magnitude.Text = cFrame.lstData[intContactHinge_FrameData_Index].SlaveContactMagnitude_Factor.ToString(strMagnitudeFormat);
                txtHinge_Radians.Text = cFrame.lstData[intContactHinge_FrameData_Index].Angle.ToString(strRadiansFormat);
            }
        }

        /// <summary>
        /// changes the current animation to the one selected by the user
        /// </summary>
        private void cmbAnimation_SelectedIndexChanged(object sender, EventArgs e)
        {
            cSpriteData.cAnimationData.cAnimation = (classAnimation)cSpriteData.cAnimationData.cSprite.cBT_Animations.Search(cmbAnimation.Text);
            if (cSpriteData.cAnimationData.cAnimation != null)
            {
                Message("animation selected : " + cSpriteData.cAnimationData.cAnimation.Name);
                if (cSpriteData.cAnimationData.cAnimation.lstFrames.Count == 0)
                {
                    lblFrame_Add_Click((object)lblFrame_Add, new EventArgs());
                }
            }
            nudFrameCounter_Reset();
            setObjectsToAnimationFrame();
            if (pnlDrawSequence != null)
            {
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                pnlDrawSequence.setToFrame(ref cFrame);
            }
            if (!pnlAnimation_FrameEditor.Collapsed)
            {
                pnlAnimation_FrameEditor.SetAnimationFrameEditor();
            }
            Debug_TestData("exiting cmbAnimation_selectedIndexchanged");
        }

        /// <summary>
        /// steps through to the animation's next frame
        /// </summary>
        private void TmrAnimation_Tick(object sender, EventArgs e)
        {
            semChangeCostume.WaitOne();
            AnimationFrame_Step();
            Debug_TestData("exiting tmrAnimation_Tick");
            semChangeCostume.Release();
        }

        /// <summary>
        /// refreshes the text message in the form's header to the default value after a previous message was displayed
        /// </summary>
        private void TmrRefreshText_Tick(object sender, EventArgs e)
        {
            tmrRefreshText.Enabled = false;
            Text = strFilename_Current.Length > 0
                                              ? strFilename_Current
                                              : (cSpriteData.cAnimationData.cSprite != null
                                                                                     ? cSpriteData.cAnimationData.cSprite.Name + " not saved"
                                                                                     : "no sprite loaded");
            strSizeDrawFactor = "";
            Debug_TestData("exiting tmrRefreshText_tick");
        }

        /// <summary>
        /// reacts to user's mouse wheel event over the main picturebox
        /// </summary>
        private void PicMain_MouseWheel(object sender, MouseEventArgs e)
        {
            ///*
            switch (MouseButtons)
            {
                case MouseButtons.Right:
                    {
                        if (cLimb_MouseOver != null)
                        {
                            Txt_Radians_MouseWheel((object)txtHinge_Radians, e);

                        }
                    }
                    break;

                case MouseButtons.Left:
                    {
                        if (cLimb != null)
                        {
                            Txt_Magnitude_MouseWheel((object)txtHinge_Magnitude, e);
                        }
                    }
                    break;

                default:
                    {
                        if (eFocusControllerImage == enuFocusControllerImages.Center || bolKeys[(int)enuKeys.ControlKey])
                        {
                            if (e.Delta > 0)
                                DrawSizeFactor *= 1.1;
                            else
                                DrawSizeFactor /= 1.1;

                            Draw_Sprite();
                        }
                    }
                    break;
            }
        }

        /// <summary>
        /// reacts to the user releaseing the mouse button while over the main picturebox
        /// </summary>
        private void PicMain_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                bolMouseRight_Down = false;
            }
            else if (e.Button == MouseButtons.Left)
            {
                bolMouseLeft_Down = false;
                if (cLimb != null && pnlFrameEditor.chkMouse_LimbControl.Checked) Draw_Controls();
            }
            bolFocusController_Grabbed 
                = bolSpriteGrabbed 
                = false;
            Debug_TestData("exiting picMain_MouseUp:L(" + bolMouseLeft_Down.ToString() + "),R(" + bolMouseRight_Down.ToString() + ")");
        }


        bool bolSpriteGrabbed = false;
        Point ptSpriteGrabPoint = new Point();
        
        /// <summary>
        /// reacts to the user pressing a mouse button while over the main picturebox
        /// </summary>
        private void PicMain_MouseDown(object sender, MouseEventArgs e)
        {
            switch (e.Button)
            {
                case MouseButtons.Left:
                    {
                        bolMouseLeft_Down = true;
                    }
                    break;

                case MouseButtons.Right:
                    {
                        bolMouseRight_Down = true;
                        if (cLimb_MouseOver != null)
                            cLimb = cLimb_MouseOver;
                    }
                    break;

                case MouseButtons.Middle:
                    {
                        if (Math3.classMath3.PointIsInsideARectangle(new PointF(e.X, e.Y), recSpriteFrame))
                        {
                            ptSpriteGrabPoint = new Point(e.X, e.Y);
                            bolSpriteGrabbed = true;
                        }
                        else if (eFocusControllerImage == enuFocusControllerImages.Center && MouseButtons == MouseButtons.Middle)
                        {
                            bolFocusController_Grabbed = true;
                        }
                        return;
                    }
            }


            if (cLimb_MouseOver != null)
            {
                cmbLimbs_SetSelect(cLimb_MouseOver.Name);
            }

            tmrFocusDelta.Enabled = (eFocusControllerImage != enuFocusControllerImages.Idle);
            switch (eFocusControllerImage)
            {
                case enuFocusControllerImages.Center:
                    if (bolMouseLeft_Down)
                    {
                        tmrFocusDelta.Enabled = true;
                        cSpriteData.pt = new Point(picMain.Width / 2, picMain.Height / 2);
                        ptDraw_DrawRel_Off.X = cSpriteData.pt.X;
                        ptDraw_DrawRel_Off.Y = cSpriteData.pt.Y;
                        Draw_Sprite();
                    }
                    break;

                case enuFocusControllerImages.Up:
                    tmrFocusDelta.Enabled = true;
                    ptFocus_Delta = new Point(0, -intFocusController_StepSize);
                    break;

                case enuFocusControllerImages.Down:
                    tmrFocusDelta.Enabled = true;
                    ptFocus_Delta = new Point(0, intFocusController_StepSize);
                    break;

                case enuFocusControllerImages.Left:
                    tmrFocusDelta.Enabled = true;
                    ptFocus_Delta = new Point(-intFocusController_StepSize, 0);
                    break;

                case enuFocusControllerImages.Right:
                    tmrFocusDelta.Enabled = true;
                    ptFocus_Delta = new Point(intFocusController_StepSize, 0);
                    break;

                case enuFocusControllerImages.size_100PC:
                    DrawSizeFactor = 1.0;

                    Draw_Sprite();
                    break;

                case enuFocusControllerImages.size_Reduce:
                    DrawSizeFactor *= 0.5;

                    Draw_Sprite();
                    break;

            }


            //picMain.Focus();
            Debug_TestData("exiting Picmain_MouseDown ");
        }
        enum enuPic_ToolTip { FC_Center, FC_Down, FC_UP, FC_Left, FC_Right, FC_Idle, FC_100PC, FC_ReduceSize, _numToolTip };

        Timer tmrIgnorMouseMove = new Timer();
        public void IgnoreMouseMove()
        {
            tmrIgnorMouseMove.Enabled = true;
        }

        private void TmrIgnorMouseMove_Tick(object sender, EventArgs e)
        {
            tmrIgnorMouseMove.Enabled = false;
        }

        /// <summary>
        /// reacts to user moving the mouse over the main picturebox
        /// </summary>
        private void PicMain_MouseMove(object sender, MouseEventArgs e)
        {
            if (tmrIgnorMouseMove.Enabled) 
                return;

            semMouseMove.WaitOne();

            ptPicMain_Mouse.X = e.X;
            ptPicMain_Mouse.Y = e.Y;
            switch (e.Button)
            {
                case MouseButtons.Middle:
                    {
                        if (bolSpriteGrabbed)
                        {
                            Point ptShift = new Point(e.X - ptSpriteGrabPoint.X, e.Y - ptSpriteGrabPoint.Y);

                            cSpriteData.pt = classMath3.AddTwoPoints(cSpriteData.pt, ptShift);

                            ptDraw_DrawRel_Off = classMath3.AddTwoPoints(ptDraw_DrawRel_Off, ptShift);

                            ptSpriteGrabPoint = new Point(e.X, e.Y);
                            Draw_Sprite();
                        }

                        if (bolFocusController_Grabbed)
                        {
                            ptFocusControllerCenter = new Point(ptPicMain_Mouse.X, ptPicMain_Mouse.Y);
                            Draw_Controls();
                            picMain.Refresh();
                        }

                        semMouseMove.Release();
                            return;
                    }

                default:
                    {
                        classSprite_Limb cLimbMouseOver_new = detectLimb();
                        if (cLimbMouseOver_new != null)
                        {
                            cLimb_MouseOver = cLimbMouseOver_new;
                            Message("Mouse over " + cLimbMouseOver_new.Name + " (" + cLimb_MouseOver.cCostumeInfo.Name + ")");
                            Draw_Sprite();
                        }
                        else if (cLimb_MouseOver != null)
                        {
                            cLimb_MouseOver = null;
                            Draw_Sprite();
                        }
                        bool bolDraw_Controls = false;
                        detectFocusController();

                        switch (eFocusControllerImage)
                        {
                            case enuFocusControllerImages.Center:
                                ePic_ToolTip = enuPic_ToolTip.FC_Center;
                                break;

                            case enuFocusControllerImages.Down:
                                ePic_ToolTip = enuPic_ToolTip.FC_Down;
                                break;

                            case enuFocusControllerImages.Idle:
                                ePic_ToolTip = enuPic_ToolTip.FC_Idle;
                                break;

                            case enuFocusControllerImages.Left:
                                ePic_ToolTip = enuPic_ToolTip.FC_Left;
                                break;

                            case enuFocusControllerImages.Right:
                                ePic_ToolTip = enuPic_ToolTip.FC_Right;
                                break;

                            case enuFocusControllerImages.size_100PC:
                                ePic_ToolTip = enuPic_ToolTip.FC_100PC;
                                break;

                            case enuFocusControllerImages.size_Reduce:
                                ePic_ToolTip = enuPic_ToolTip.FC_ReduceSize;
                                break;

                            case enuFocusControllerImages.Up:
                                ePic_ToolTip = enuPic_ToolTip.FC_UP;
                                break;
                        }


                        if (pnlFrameEditor.chkMouse_LimbControl.Checked
                            && MouseButtons == MouseButtons.Left)
                            bolDraw_Controls = true;

                        if (bolDraw_Controls)
                        {
                            Draw_Controls();
                            picMain.Refresh();
                        }
                    }
                    break;
            }
            semMouseMove.Release();
        }

        /// <summary>
        /// tests to see where the mouse is over the main picturebox to determine which if any FocusController item is selected by user
        /// </summary>
        void detectFocusController()
        {
            int intVariance_Narrow = 7;
            int intVariance_Wide = 28;
            int intHalfBmp = bmpFocusControllerImages[0].Width / 2;


            bool bolVertical = (ptPicMain_Mouse.Y > ptFocusControllerCenter.Y - intVariance_Narrow && ptPicMain_Mouse.Y < ptFocusControllerCenter.Y + intVariance_Narrow);
            bool bolHorizontal = (ptPicMain_Mouse.X > ptFocusControllerCenter.X - intVariance_Narrow && ptPicMain_Mouse.X < ptFocusControllerCenter.X + intVariance_Narrow);

            if (bolVertical && bolHorizontal)
            {
                eFocusControllerImage = enuFocusControllerImages.Center;
                return;
            }
            else if (bolVertical)
            {
                if (ptPicMain_Mouse.X > ptFocusControllerCenter.X - intHalfBmp
                    && ptPicMain_Mouse.X < ptFocusControllerCenter.X - intHalfBmp + intVariance_Wide)
                {
                    eFocusControllerImage = enuFocusControllerImages.Left;
                    return;
                }
                else if (ptPicMain_Mouse.X > ptFocusControllerCenter.X + intHalfBmp - intVariance_Wide
                         && ptPicMain_Mouse.X < ptFocusControllerCenter.X + intHalfBmp)
                {
                    eFocusControllerImage = enuFocusControllerImages.Right;
                    return;
                }
            }
            else if (bolHorizontal)
            {
                if (ptPicMain_Mouse.Y > ptFocusControllerCenter.Y - intHalfBmp
             && ptPicMain_Mouse.Y < ptFocusControllerCenter.Y - intHalfBmp + intVariance_Wide)
                {
                    eFocusControllerImage = enuFocusControllerImages.Up;
                    return;
                }
                else if (ptPicMain_Mouse.Y > ptFocusControllerCenter.Y + intHalfBmp - intVariance_Wide
                         && ptPicMain_Mouse.Y < ptFocusControllerCenter.Y + intHalfBmp)
                {
                    eFocusControllerImage = enuFocusControllerImages.Down;
                    return;
                }
            }
            else
            {
                Point ptMouseTL = classMath3.SubTwoPoints(ptPicMain_Mouse, ptFocusControllerCenter);
                ptMouseTL = classMath3.AddTwoPoints(ptMouseTL, new Point(bmpFocusControllerImages[0].Width / 2, bmpFocusControllerImages[0].Height / 2));
                if (ptMouseTL.X >= 18 && ptMouseTL.X <= 47
                    && ptMouseTL.Y >= 20 && ptMouseTL.Y <= 45)
                {
                    eFocusControllerImage = enuFocusControllerImages.size_Reduce;
                    return;
                }
                else if (ptMouseTL.X >= 74 && ptMouseTL.X <= 103
                    && ptMouseTL.Y >= 20 && ptMouseTL.Y <= 45)
                {
                    eFocusControllerImage = enuFocusControllerImages.size_100PC;
                    return;
                }

            }
            eFocusControllerImage = enuFocusControllerImages.Idle;

        }

        #endregion

        #region Events_UserInputForms

        public void lbl_MouseEnter(object sender, EventArgs e)
        {
            Label lblSender = (Label)sender;
            Panel pnlParent = (Panel)lblSender.Parent;

            lblSender.BackColor = pnlParent.ForeColor;
            lblSender.ForeColor = pnlParent.BackColor;
        }

        public void lbl_MouseLeave(object sender, EventArgs e)
        {

            Label lblSender = (Label)sender;
            Panel pnlParent = (Panel)lblSender.Parent;



            lblSender.BackColor = pnlParent.BackColor;
            lblSender.ForeColor = pnlParent.ForeColor;
        }

        List<string> TrackEnabled()
        {
            List<string> lstTracksEnabled = new List<string>();
            if (pnlFrameEditor.chkTrack_Limb_Radians.Checked)
                lstTracksEnabled.Add("Limb Radians");

            if (pnlFrameEditor.chkTrack_Limb_Magnitude.Checked)
                lstTracksEnabled.Add("Limb Magnitude");

            if (pnlFrameEditor.chkTrack_DrawSequence.Checked)
                lstTracksEnabled.Add("Draw Sequence");

            if (pnlFrameEditor.chkTrack_DrawRelativeTo.Checked)
                lstTracksEnabled.Add("Draw Relative to Limb");
            

            if (pnlFrameEditor.chkTrack_Override.Checked)
                lstTracksEnabled.Add("Override");

            if (pnlFrameEditor.chkTrack_Mirrors.Checked)
                lstTracksEnabled.Add("Mirrors");

            return lstTracksEnabled;
        }

        public void lblFrame_Run_Click(object sender, EventArgs e)
        {
            List<string> lstTracksEnabled = TrackEnabled();
            if (lstTracksEnabled.Count > 0 && !tmrAnimation.Enabled)
            {
                string strMessage = "You are currently tracking:\t";
                for (int intCounter = 0; intCounter < lstTracksEnabled.Count; intCounter++)
                    strMessage += lstTracksEnabled[intCounter] + "\r\n\t\t\t";
                strMessage += "\r\nRunning the Animation :" + cSpriteData.cAnimationData.cAnimation.Name + " will track values from the current frame to all frames.\r\nAre you sure you want to run the animation?";
                if (MessageBox.Show(strMessage, "Run while Tracking?", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                    return;
            }

            tmrAnimation_Enabled = !tmrAnimation_Enabled;

            Debug_TestData("exiting lblAnimatinoFrame_Run_click");
        }

        public void lblFrame_Step_Click(object sender, EventArgs e)
        {
            tmrAnimation_Enabled = false;
            AnimationFrame_Step();
            Debug_TestData("exiting lblFrame_step_click");
        }

        private void lblFrame_Sub_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null)
            {
                if (cSpriteData.cAnimationData.cAnimation != null)
                {
                    if (cSpriteData.cAnimationData.cAnimation.lstFrames.Count > 1)
                    {
                        if (cSpriteData.cAnimationData.intFrameIndex < cSpriteData.cAnimationData.cAnimation.lstFrames.Count)
                        {
                            int intFrame_Current = (int)nudFrame_Counter.Value;
                            cSpriteData.cAnimationData.cAnimation.Frame_Sub(cSpriteData.cAnimationData.intFrameIndex);
                            nudFrameCounter_Reset();
                            cSpriteData.cAnimationData.intFrameIndex = intFrame_Current;
                            nudFrame_Counter.Value = (intFrame_Current < nudFrame_Counter.Maximum ? intFrame_Current : nudFrame_Counter.Maximum);
                            Draw_Sprite();
                            Message("animation frame removed");
                            Debug_TestData("exiting lblFrame_Sub_click");
                            if (pnlAnimation_FrameEditor.Visible && !pnlAnimation_FrameEditor.Collapsed)
                                pnlAnimation_FrameEditor.SetAnimationFrameEditor();
                        }
                    }
                }
            }
        }

        private void lblFrame_Add_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cAnimation != null)
            {
                int intCurrentFrame = (int)nudFrame_Counter.Value;
                classAnimation_Frame cFrameNew = cSpriteData.cAnimationData.cAnimation.Frame_Add(cSpriteData.cAnimationData.intFrameIndex);
                cFrameNew.Limb_DrawRelativeTo = cSpriteData.cAnimationData.cAnimation.lstFrames[intCurrentFrame].Limb_DrawRelativeTo;
                nudFrameCounter_Reset();
                cSpriteData.cAnimationData.intFrameIndex =(intCurrentFrame +1) % cSpriteData.cAnimationData.cAnimation.lstFrames.Count;
                nudFrame_Counter.Value = cSpriteData.cAnimationData.intFrameIndex;
                if (pnlAnimation_FrameEditor.Visible && !pnlAnimation_FrameEditor.Collapsed)
                    pnlAnimation_FrameEditor.SetAnimationFrameEditor();
                Message("new animation frame added");
            }
            Debug_TestData("exiting lblFrame_Add_click");
        }

        string strLimb_New_Name = "";
        public static double txtBox_ReadValue(string str)
        {
            try
            {
                return Convert.ToDouble(str);
            }
            catch (Exception) { }
            return 0;
        }

        void Sprite_New(string strName)
        {
            pnlDebug.Enabled = false;
            cSpriteData.cAnimationData.cSprite = new classSprite(strName);//, true);
            cLimb = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[0];
            cSpriteData.cAnimationData.filename = System.IO.Directory.GetCurrentDirectory() + "\\" + strName + classSpriteMaker.conSpriteFileExtension4;
            classAnimation_Frame cFrame = cSpriteData.cAnimationData.cSprite.lstAnimations[0].lstFrames[0];
            
            Bitmap bmp = new Bitmap(10, 10);
            Point ptMasterLimb = new Point();
            object objPtMasterLimb = (object)ptMasterLimb;

            cSpriteData.cAnimationData.cSprite.setSpriteDataInfo(ref cSpriteData, ref bmp);
            if (cSpriteData.cAnimationData.cSprite.lstCostumeInfo != null)
            {
                pnlCostume_Selector.cmbCostume_Load();
            }

            Draw_Sprite();
            cmbLimbs_Reset();

            cmbAnimation_Refresh();

            cmbAnimation_Set(cSpriteData.cAnimationData.cSprite.lstAnimations[0].Name);
            pnlDebug.Enabled = true;
            Debug_TestData("Exiting Sprite_New(" + strName + ")");
            Message("new sprite created :" + cSpriteData.cAnimationData.cSprite.Name);
        }

        enum enuPicFileExtensions { bmp, gif, jpg, png, all, _num };
        enuPicFileExtensions ePicExtension_Previous = enuPicFileExtensions.png;

        string FileFileExtension_GetString(enuPicFileExtensions ePicExtension)
        {
            switch (ePicExtension)
            {
                case enuPicFileExtensions.all:

                    {
                        return "All files (*.*)|*.*";
                    }

                default:
                    {
                        return "(*." + ePicExtension.ToString() + ") | *." + ePicExtension.ToString();
                    }

            }
        }
        
  
        void BckRotate_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            cmbLimbs_Reset();
            cmbLimbs_SetSelect(strLimb_New_Name);
            pnlFrameEditor.clbLimbTracker_Init();
            Draw_Sprite();

            classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
            pnlFrameEditor.clbLimbTracker_Init();
            pnlDrawSequence.setToFrame(ref cFrame);

            Costumes_MatchDefault();
            pnlLimb_SetAnimation.SetObjects();

            setLimbInfo_Graphical_Show();
            Message("new limb created : " + strLimb_New_Name);
            pnlOptions.clbShowLimbPositions_Set();
            Enabled = true;
            BringToFront();
        }

        public void frmMessenger_UserReply(object sender, KeyEventArgs e)
        {
            pnlMessenger.txtUserInput.Text = pnlMessenger.txtUserInput.Text.Trim();
            bool bolMouseControl = pnlFrameEditor.chkMouse_LimbControl.Checked;
            pnlFrameEditor.chkMouse_LimbControl.Checked = false;

            switch (pnlMessenger.Message)
            {
                case panelMessenger.enuMessage.Costume_New:
                    {
                        classSprite_CostumeInfo cCostumeInfo_New = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.Copy();
                        cSpriteData.cCostumeInfo = cCostumeInfo_New;
                        cSpriteData.cAnimationData.cSprite.lstCostumeInfo.Add(cCostumeInfo_New);
                        cCostumeInfo_New.Name = pnlMessenger.txtUserInput.Text;

                        pnlCostume_Selector.cmbCostume_Load();
                    }
                    break;

                case panelMessenger.enuMessage.Costume_Rename:
                    {
                        if (cSpriteData.cCostumeInfo == cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default)
                        {
                            MessageBox.Show("You cannot rename the default costume", "cannot rename default costume");
                            return;
                        }

                        cSpriteData.cCostumeInfo.Name = pnlMessenger.txtUserInput.Text;
                        pnlCostume_Selector.cmbCostume_Load();
                    }
                    break;

                case panelMessenger.enuMessage.Sprite_New_Name:
                    {
                        if (pnlMessenger.txtUserInput.Text.Length > 0)
                        {
                            cSpriteData = new classSpriteData();

                            Sprite_New(pnlMessenger.txtUserInput.Text);
                        }
                        else
                            Message("New sprite cancelled because invalid sprite name");
                        pnlFrameEditor.cSprite = cSpriteData.cAnimationData.cSprite;
                        Debug_TestData("exiting frmMessager_UserReplay:Sprite_new_name");
                        pnlFrameEditor.cFrame_Copy = null;
                        pnlOptions.clbShowLimbPositions_Set();
                    }
                    break;

                case panelMessenger.enuMessage.Limb_New_Name:
                    {
                        if (pnlMessenger.txtUserInput.Text.Length > 0)
                        {
                            Costume_SetToDefault();
                            strLimb_New_Name = pnlMessenger.txtUserInput.Text;
                            classSprite_Limb cLimbExistsAlready = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(strLimb_New_Name);
                            if (cLimbExistsAlready != null)
                            {
                                MessageBox.Show("the limb " + strLimb_New_Name + " already exists.  All limbs must have unique names.", "New Limb Naming Error");
                                return;
                            }

                            string strHinge_New_Name = strLimb_New_Name + classSprite_Hinge.conHingeNameExtension;
                            OpenFileDialog ofd = new OpenFileDialog();
                            ofd.Title = "Load " + pnlMessenger.txtUserInput.Text + " bitmap";
                            string strFilter = FileFileExtension_GetString(ePicExtension_Previous);

                            for (int intExCounter = 0; intExCounter < (int)enuPicFileExtensions._num; intExCounter++)
                            {
                                enuPicFileExtensions ePicEx = (enuPicFileExtensions)intExCounter;
                                if (ePicEx != ePicExtension_Previous)
                                {
                                    strFilter += "|" + FileFileExtension_GetString(ePicEx);
                                }
                            }
                            ofd.Filter = strFilter;
                            ofd.DefaultExt = "png";

                            if (ofd.ShowDialog() == DialogResult.OK)
                            {
                                if (System.IO.File.Exists(ofd.FileName))
                                {
                                    try
                                    {
                                        Char chrFileExtension = ofd.FileName.Substring(ofd.FileName.Length - 3)[0];
                                        int intExt = "bgjp".IndexOf(chrFileExtension);
                                        if (intExt >= 0)
                                            ePicExtension_Previous = (enuPicFileExtensions)intExt;

                                        Bitmap bmpNewLimb = (Bitmap)Bitmap.FromFile(ofd.FileName);
                                        bmpNewLimb.MakeTransparent(bmpNewLimb.GetPixel(0, 0));
                                        classSprite_Limb cLimb_Ref = cLimb;
                                        Enabled = false;
                                        
                                        cSpriteData.cAnimationData.cSprite.Limb_New(strLimb_New_Name, bmpNewLimb, ref cLimb_Ref);
                                        classSprite_Limb cLimbNew = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(strLimb_New_Name);

                                        cmbLimbs_Reset();
                                        cmbLimbs_SetSelect(strLimb_New_Name);
                                        pnlFrameEditor.clbLimbTracker_Init();
                                        Draw_Sprite();

                                        classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                                        pnlFrameEditor.clbLimbTracker_Init();
                                        pnlDrawSequence.setToFrame(ref cFrame);

                                        Costumes_MatchDefault();
                                        pnlLimb_SetAnimation.SetObjects();

                                        setLimbInfo_Graphical_Show();
                                        Message("new limb created : " + strLimb_New_Name);
                                        pnlOptions.clbShowLimbPositions_Set();
                                        Enabled = true;
                                        BringToFront();

                                    }
                                    catch (Exception err)
                                    {
                                        MessageBox.Show("Error createing a new limb : " + err.Message);
                                    }
                                }
                            }
                        }
                        else
                            Message("New limb cancelled because invalid limb name.");
                    }
                    break;

                case panelMessenger.enuMessage.Limb_Rename:
                    {
                        if (pnlMessenger.txtUserInput.Text.Length > 0)
                        {
                            Costume_SetToDefault();
                            string strNameNew = pnlMessenger.txtUserInput.Text.Trim();
                            classSprite_Limb cLimbInATree = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(strNameNew);
                            if (cLimbInATree != null)
                            {
                                MessageBox.Show("name :" + cLimbInATree.Name + " already exists.  Limb names must be unique.");
                                return;
                            }
                            string strName_Old = cLimb.Name;
                            cLimb.Name = strNameNew;

                            for (int intCostumecounter = 0; intCostumecounter < cSpriteData.cAnimationData.cSprite.lstCostumeInfo.Count; intCostumecounter++)
                            {
                                classSprite_CostumeInfo cCostume = cSpriteData.cAnimationData.cSprite.lstCostumeInfo[intCostumecounter];
                                if (cCostume != cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default)
                                    cCostume.Limb_Rename(strName_Old, strNameNew);
                            }
                            
                            cmbLimbs_Reset();
                            cmbLimbs_SetSelect(cLimb.Name);
                            pnlLimb_SetAnimation.SetObjects();
                            pnlFrameEditor.clbLimbTracker_Init();
                            classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                            pnlDrawSequence.setToFrame(ref cFrame);
                            Message("Limb \"" + strName_Old + "\" has been renamed \"" + cLimb.Name + "\"");
                            Debug_TestData("frmMessenger_UserReply -> Limb_Rename completed");
                            pnlOptions.clbShowLimbPositions_Set();
                        }
                        else
                            Message("Rename limb:" + cLimb.Name + " cancelled.");
                    }
                    break;

                case panelMessenger.enuMessage.Animation_New_Name:
                    {
                        if (pnlMessenger.txtUserInput.Text.Length == 0)
                        {
                            Message("New Animation cancelled");
                            return;
                        }

                        classAnimation cAnimationAlreadyExists = (classAnimation)cSpriteData.cAnimationData.cSprite.cBT_Animations.Search(pnlMessenger.txtUserInput.Text);
                        if (cAnimationAlreadyExists != null)
                        {
                            MessageBox.Show("the Animation " + pnlMessenger.txtUserInput.Text + " already exists.  All Animations must have unique names.", "New Animation Naming Error");

                            return;
                        }

                        Costume_SetToDefault();
                        classAnimation cAnimation_New = cSpriteData.cAnimationData.cSprite.Animation_New(pnlMessenger.txtUserInput.Text, cSpriteData.cAnimationData.cAnimation.lstFrames[0].lstDrawSequence);
                        cmbAnimation_Refresh();
                        cmbAnimation_Set(cAnimation_New.Name);
                        pnlLimb_SetAnimation.SetObjects();
                        Message("new animation created : " + cAnimation_New.Name);
                        Debug_TestData("exiting frmMessager_UserReplay :Animation");
                    }
                    break;

                case panelMessenger.enuMessage.Animation_Rename:
                    {
                        if (pnlMessenger.txtUserInput.Text.Length > 0)
                        {
                            classAnimation cAnimationNewNameAlreadyExists = (classAnimation)cSpriteData.cAnimationData.cSprite.cBT_Animations.Search(pnlMessenger.txtUserInput.Text);
                            if (cAnimationNewNameAlreadyExists != null)
                            {
                                MessageBox.Show("the Animation " + pnlMessenger.txtUserInput.Text + " already exists.  All Animations must have unique names.", "New Animation Naming Error");
                                return;
                            }
                            Costume_SetToDefault();
                            string strAnimationOldName = cSpriteData.cAnimationData.cAnimation.Name;
                            cSpriteData.cAnimationData.cAnimation.ChangeName(pnlMessenger.txtUserInput.Text);

                            cmbAnimation_Refresh();
                            cmbAnimation_Set(pnlMessenger.txtUserInput.Text);
                            pnlLimb_SetAnimation.SetObjects();
                            Message("animation " + strAnimationOldName + " has been renamed " + pnlMessenger.txtUserInput.Text);
                            Debug_TestData("exiting frmMessager_UserReplay : Animation_Rename");
                        }
                        else
                            Message("rename animation:" + cSpriteData.cAnimationData.cAnimation.Name + " cancelled");
                    }
                    break;

                case panelMessenger.enuMessage.Resize:
                    {
                        bool bolTimerEnabled = tmrAnimation.Enabled;
                        tmrAnimation_Enabled = false;
                        double dblResize = txtBox_ReadValue(pnlMessenger.txtUserInput.Text);
                        Costume_Resize(dblResize / 100);
                        tmrAnimation_Enabled = bolTimerEnabled;
                    }
                    break;
            }
            pnlFrameEditor.chkMouse_LimbControl.Checked = bolMouseControl;
        }

        BackgroundWorker bckResize = new BackgroundWorker();
        static double dblBckResizeFactor = 1;
        static int[] intBckResizeImagesPerLimb = null;
        static int intBckResizeLimbCounter = 0;
        void Costume_Resize(double dblSizeFactor)
        {
            if (dblSizeFactor < .20)
            {
                MessageBox.Show("Size factor percentage must be greater than 20%.", "Percentage too small");
                return;
            }

            if (dblSizeFactor >= 4.00)
            {
                MessageBox.Show("Size factor percentage must be les than 400%.", "Percentage too big");
                return;
            }
            dblBckResizeFactor = dblSizeFactor;

            classSprite cSprite = cSpriteData.cAnimationData.cSprite;
            intBckResizeImagesPerLimb = new int[cSpriteData.cCostumeInfo.lstLimbs.Count];

            for (int intLimbCounter = 0; intLimbCounter < cSpriteData.cCostumeInfo.lstLimbs.Count; intLimbCounter++)
            {
                classSprite_Limb cLimb = cSpriteData.cCostumeInfo.lstLimbs[intLimbCounter];
                intBckResizeImagesPerLimb[intLimbCounter] = 0;
                if (cLimb != cSpriteData.cCostumeInfo.cLimb_Master)
                {
                    for (int intLimbImageCounter = 0; intLimbImageCounter < cLimb.lstImages.Count; intLimbImageCounter++)
                    {
                        intBckResizeImagesPerLimb[intLimbCounter] += (4 * cSprite.NumImagesPerQuadrant);
                    }
                }
            }

            for (int intAnimationCounter = 0; intAnimationCounter < cSprite.lstAnimations.Count; intAnimationCounter++)
            {
                classAnimation cAnimation = cSprite.lstAnimations[intAnimationCounter];
                for (int intFrameCounter = 0; intFrameCounter < cAnimation.lstFrames.Count; intFrameCounter++)
                {
                    classAnimation_Frame cFrame = cAnimation.lstFrames[intFrameCounter];
                    for (int intLimbCounter = 0; intLimbCounter < cFrame.lstData.Count; intLimbCounter++)
                    {
                        classAnimation_Frame_LimbData cLimbData_Standard = cFrame.lstData[intLimbCounter];
                        cLimbData_Standard.ptDrawCenter = classMath3.Point_FactorSize(cLimbData_Standard.ptDrawCenter, (float)dblSizeFactor);
                    }
                    /*for (int intLimbCounter = 0; intLimbCounter < cFrame.lstData.Count; intLimbCounter++)
                    {
                        classAnimation_Frame_LimbData cLimbData = cFrame.lstData[intLimbCounter];
                        cLimbData.ptDrawCenter = classMath3.Point_FactorSize(cLimbData.ptDrawCenter, (float)dblSizeFactor);
                    }*/
                }
            }

            intBckResizeLimbCounter = 0;

            bckResize.RunWorkerAsync();
        }
        private void bckResize_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //formFeedback frmFeedback = formFeedback.instance;
            //formFeedback.probar.Value = e.ProgressPercentage;
            //while (intBckResizeImagesPerLimb[intBckResizeLimbCounter] < formFeedback.probar.Value)
            //{
            //    intBckResizeLimbCounter++;
            //}
            //formFeedback.lblHeading.Text = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[intBckResizeLimbCounter].Name;
            //frmFeedback.Refresh();
        }

        private void bckResize_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            double dblSizeFactor = formSpriteEditor_2017.dblBckResizeFactor;
           // classSprite cSprite = cSpriteData.cAnimationData.cSprite;

            for (int intLimbCounter = 0; intLimbCounter < cSpriteData.cCostumeInfo.lstLimbs.Count; intLimbCounter++)
            {
                classSprite_Limb cLimb = cSpriteData.cCostumeInfo.lstLimbs[intLimbCounter];
                if (cLimb != cSpriteData.cCostumeInfo.cLimb_Master)
                {
                    cLimb.Hinge.Contact.Master.Magnitude = cLimb.Hinge.Contact.Master.Magnitude * dblSizeFactor;
                    cLimb.Hinge.Contact.Slave.Magnitude = cLimb.Hinge.Contact.Slave.Magnitude * dblSizeFactor;

                    string strFeedback = "resizing " + cLimb.Name + " -> ";

                    for (int intLimbImageCounter = 0; intLimbImageCounter < cLimb.lstImages.Count; intLimbImageCounter++)
                    {
                        classSprite_Limb.classSprite_Limb_Images lstImages = cLimb.lstImages[intLimbImageCounter];

                        for (int intBmpCounter = 0; intBmpCounter < 4 * cSpriteData.cAnimationData.cSprite.NumImagesPerQuadrant; intBmpCounter++)
                        {
                            Bitmap bmp_Original = lstImages.bmpImages[intBmpCounter];
                            if (bmp_Original != null)
                            {
                                Bitmap bmp_Resized = (Bitmap)new Bitmap(bmp_Original, new Size((int)Math.Ceiling(bmp_Original.Width * dblSizeFactor), (int)Math.Ceiling(bmp_Original.Height * dblSizeFactor)));
                                lstImages.bmpImages[intBmpCounter] = bmp_Resized;
                            }
                        }
                    }
                }
            }

        }
        private void bckResize_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {

            }
            else if (e.Error != null)
            {

            }
            else
            {

            }
            //formFeedback.instance.Hide();
            Draw_Sprite();
        }

        void AddLimbToAnimationDrawSequences(ref classSprite_Limb cLimbNew)
        {
            int intNewLimbIndex = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs.IndexOf(cLimbNew);
            for (int intAnimationCounter = 0; intAnimationCounter < cSpriteData.cAnimationData.cSprite.lstAnimations.Count; intAnimationCounter++)
            {
                classAnimation cAni = cSpriteData.cAnimationData.cSprite.lstAnimations[intAnimationCounter];

                for (int intFrameCounter = 0; intFrameCounter < cAni.lstFrames.Count; intFrameCounter++)
                {
                    classAnimation_Frame cFrame = cAni.lstFrames[intFrameCounter];
                    cFrame.lstDrawSequence.Add(-1); // add NULL to the end

                    // shift all limbs forward by one
                    for (int intDrawCounter = cFrame.lstDrawSequence.Count - 1; intDrawCounter > 0; intDrawCounter--)
                        cFrame.lstDrawSequence[intDrawCounter] = cFrame.lstDrawSequence[intDrawCounter - 1];

                    // insert new limb at index =0
                    cFrame.lstDrawSequence[0] = intNewLimbIndex;
                    Debug_TestData("exiting AddLimbToAnimationDrawSequence");
                }
            }
            Debug_TestData("exiting AddLimbToAnimationDrawSequence");
        }

        public void Txt_Radians_MouseWheel(object sender, MouseEventArgs e)
        {
            TextBox txtSender = (TextBox)sender;
            if (tmrAnimation.Enabled)
            {
                if (txtSender != pnlOptions.txtOptions_DrawAngle
                        && txtSender != pnlOptions.txtOptions_Magnitude_StepSize
                        && txtSender != pnlOptions.txtOptions_Radians_StepSize)
                    return;
            }
            double dblValue = txtBox_ReadValue(txtSender.Text);
            if (txtSender.Focused && MouseButtons == MouseButtons.Left)
            {
                if (e.Delta > 0)
                {
                    dbl_Radians_StepSize += 0.05;
                    pnlOptions.txtOptions_Radians_StepSize.Text = dbl_Radians_StepSize.ToString(strRadiansFormat);
                }
                else
                {
                    dbl_Radians_StepSize -= 0.05;
                    pnlOptions.txtOptions_Radians_StepSize.Text = dbl_Radians_StepSize.ToString(strRadiansFormat);
                }
            }
            else
            {
                if (e.Delta > 0)
                {
                    dblValue += dbl_Radians_StepSize;
                }
                else
                {
                    dblValue -= dbl_Radians_StepSize;
                }
                classMath3.cleanAngle(ref dblValue);

                txtSender.Text = dblValue.ToString(strRadiansFormat);
            }
        }

        static public void txt_Byte_MouseWheel(object sender, MouseEventArgs e)
        {
            if (instance == null) return;
            TextBox txtSender = (TextBox)sender;
            if (instance.tmrAnimation.Enabled)
            {
                if (txtSender != instance.pnlOptions.txtOptions_DrawAngle
                        && txtSender != instance.pnlOptions.txtOptions_Magnitude_StepSize
                        && txtSender != instance.pnlOptions.txtOptions_Radians_StepSize
                        && txtSender != instance.pnlOptions.txtFocusController_StepSize)
                    return;
            }

            byte bytStepSize = 1;
            switch (MouseButtons)
            {
                case MouseButtons.Right:
                    {
                        bytStepSize = 10;
                    }
                    break;

                case MouseButtons.Left:
                    {
                        bytStepSize = 25;
                    }
                    break;

                default:
                    {

                    }
                    break;
            }


            try
            {

                byte bytValue =  (byte)Convert.ToByte(txtSender.Text);

                if (e.Delta > 0)
                {
                    bytValue += bytStepSize;
                }
                else
                {
                    bytValue -= bytStepSize;
                }
                bytValue = (byte)(bytValue % 256);

                txtSender.Text = bytValue.ToString();


            }
            catch (Exception)
            {
            }

            txtMagnitude_MouseWheel_End:

            instance.Debug_TestData("exiting txt_magnitude_mousewheel");
        }

        public void Txt_Magnitude_MouseWheel(object sender, MouseEventArgs e)
        {
            TextBox txtSender = (TextBox)sender;
            if (tmrAnimation.Enabled)
            {
                if (txtSender != pnlOptions.txtOptions_DrawAngle
                        && txtSender != pnlOptions.txtOptions_Magnitude_StepSize
                        && txtSender != pnlOptions.txtOptions_Radians_StepSize
                        && txtSender != pnlOptions.txtFocusController_StepSize)
                    return;
            }
            dbl_Magnitude_StepSize = Convert.ToDouble(pnlOptions.txtOptions_Magnitude_StepSize.Text);

            switch (MouseButtons)
            {
                case MouseButtons.Right:
                    { }
                    break;

                case MouseButtons.Left:
                    {
                        if (pnlOptions.txtOptions_Magnitude_StepSize.Focused)
                        {
                            double dblStepChange = 1.0;
                            double dblValue_Old = txtBox_ReadValue(pnlOptions.txtOptions_Magnitude_StepSize.Text);
                            if (e.Delta > 0)
                            {
                                pnlOptions.txtOptions_Magnitude_StepSize.Text = (dblValue_Old + dblStepChange).ToString(strMagnitudeFormat);
                            }
                            else
                            {
                                pnlOptions.txtOptions_Magnitude_StepSize.Text = (dblValue_Old - dblStepChange).ToString(strMagnitudeFormat);
                            }
                            goto txtMagnitude_MouseWheel_End;
                        }
                    }
                    break;

                default:
                    {

                    }
                    break;
            }

                double dblValue = txtBox_ReadValue(txtSender.Text);
                if (e.Delta > 0)
                {
                    dblValue += dbl_Magnitude_StepSize;
                }
                else
                {
                    dblValue -= dbl_Magnitude_StepSize;
                }
                txtSender.Text = dblValue.ToString(strMagnitudeFormat);
                txtMagnitude_MouseWheel_End:
                Debug_TestData("exiting txt_magnitude_mousewheel");
        }

        #endregion // Events_UserInputForms

        #endregion // events

        #region Methods
        /// <summary>
        /// returns the currently selected animation frame
        /// </summary>
        classAnimation_Frame AnimationFrame
        {
            get
            {
                classAnimation_Frame cRetVal = null;
                if (cSpriteData.cAnimationData.cAnimation != null)
                {
                    if (cSpriteData.cAnimationData.intFrameIndex < cSpriteData.cAnimationData.cAnimation.lstFrames.Count
                        && cSpriteData.cAnimationData.intFrameIndex >= 0)
                    {
                        cRetVal = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                    }
                    else
                    {
                        if (cSpriteData.cAnimationData.cAnimation.lstFrames.Count > 0)
                            cRetVal = cSpriteData.cAnimationData.cAnimation.lstFrames[0];
                        else
                            cRetVal = null;
                    }
                }

                return cRetVal;
            }
        }

        /// <summary>
        /// returns the currently selected limb and sets the textboxes reflecting that limb's hinge contacts
        /// </summary>
        classSprite_Limb _cLimb = null;
        public classSprite_Limb cLimb
        {
            get { return _cLimb; }
            set
            {
                if (value != null)
                {
                    if (_cLimb != null && value != null
                        &&
                        _cLimb.cCostumeInfo != value.cCostumeInfo
                        &&
                        string.Compare(_cLimb.Name, value.Name) == 0
                        && value.Hinge != null)
                    {
                        // set frame values for this limb
                        value.Hinge.Angle = _cLimb.Hinge.Angle;
                        value.Hinge.SlaveContact_MagnitudeFactor = _cLimb.Hinge.SlaveContact_MagnitudeFactor;
                    }
                    
                    _cLimb 
                        = pnlLimb_ImageController.Limb 
                        = pnlDrawSequence.Limb_Selected
                        = value;
                    setLimbInfo();
                    
                    
                    Message("Costume : " + _cLimb.cCostumeInfo.Name + ", limb selected : " + _cLimb.Name );
                }
                Debug_TestData("exiting cLimb.Set");
            }
        }

        /// <summary>
        /// controls the size the sprite is drawn on the screen
        /// </summary>
        double DrawSizeFactor
        {
            get { return cSpriteData.cAnimationData.dblDrawSizeFactor; }
            set
            {
                if (cSpriteData.cAnimationData.dblDrawSizeFactor != value)
                {
                    cSpriteData.cAnimationData.dblDrawSizeFactor = value;
                    strSizeDrawFactor = DrawSizeFactor.ToString(strPercentageFormat);
                    tmrDrawSizeFactor_Refresh.Enabled = true;
                }
            }
        }

        /// <summary>
        /// when set tool tips will appear under the mouse cursor 
        /// </summary>
        public bool ToolTips_Enabled
        {
            get { return toolTip.Active; }
            set
            {
                if (value != toolTip.Active)
                    toolTip.Active = value;
            }
        }

        /// <summary>
        /// filename of the sprite currently loaded
        /// </summary>
        public string strFilename_Current
        {
            get { return cSpriteData.cAnimationData.filename; }
            set
            {
                if (value == "")
                    MessageBox.Show("file must have a valid name");
                cSpriteData.cAnimationData.filename = value;

                int intIndexLastRS = cSpriteData.cAnimationData.filename.LastIndexOf('\\');
                if (intIndexLastRS >= 0)
                    Directory_Current = cSpriteData.cAnimationData.filename.Substring(0, intIndexLastRS);
            }
        }

        string strDirectory_Current = System.IO.Directory.GetCurrentDirectory();
        /// <summary>
        /// Directory of the sprite currently loaded
        /// </summary>
        public string Directory_Current
        {
            get { return strDirectory_Current; }
            set
            {
                if (value == "")
                    MessageBox.Show("file must have a valid name");
                strDirectory_Current = value;
            }
        }

        /// <summary>
        /// describes which control the use's mouse is over
        /// </summary>
        enuFocusControllerImages _eFocusControllerImage = enuFocusControllerImages.Idle;
        enuFocusControllerImages eFocusControllerImage
        {
            get { return _eFocusControllerImage; }
            set
            {
                bool bolDraw_Sprite = (_eFocusControllerImage != value);
                _eFocusControllerImage = value;
                if (bolDraw_Sprite) Draw_Sprite();
            }
        }

        /// <summary>
        /// lets the tooltip know which tool tip to provide the user depending on where the mouse is over the main picturebox 
        /// depending on which part of the FocusControl(drawn on the main picturebox) the mouse is over
        /// </summary>
        enuPic_ToolTip _ePic_ToolTip = enuPic_ToolTip.FC_Idle;
        enuPic_ToolTip ePic_ToolTip
        {
            get { return _ePic_ToolTip; }
            set
            {
                if (_ePic_ToolTip != value)
                {
                    _ePic_ToolTip = value;
                    switch (_ePic_ToolTip)
                    {
                        case enuPic_ToolTip.FC_Idle:
                            if (pnlFrameEditor.chkMouse_LimbControl.Checked
                                && pnlFrameEditor.chkDrawRelativeToLimb_EditorToggle.Checked)
                            {
                                toolTip.SetToolTip(picMain, "toggling OFF TrackDrawRelativeTo options in the Frame Editor Panel may help editing limb positions with the mouse controller");
                                return;
                            }
                            break;

                        default:
                            break;
                    }

                    toolTip.SetToolTip(picMain, cTTips.Tip_get(_ePic_ToolTip.ToString()));
                }

            }
        }

        /// <summary>
        /// variable used to move the sprite on user-command via a timer tmrFocusDelta
        /// </summary>
        Point _ptFocus_Delta = new Point();
        public Point ptFocus_Delta
        {
            get { return _ptFocus_Delta; }
            set
            {
                _ptFocus_Delta = value;
            }
        }

        /// <summary>
        /// when enabled the sprite's animation will be loaded and drawn the the screen one frame at a time
        /// </summary>
        bool tmrAnimation_Enabled
        {
            get { return tmrAnimation.Enabled; }
            set
            {
                tmrAnimation.Enabled = value;

                pnlFrameEditor.EnableControls = !tmrAnimation_Enabled;

                picMain.ContextMenu
                    = panelOptions.instance.ContextMenu
                    = panelFrameEditor.instance.ContextMenu
                    = cMnuPic;

                if (tmrAnimation.Enabled)
                {
                    Message("run animation : started");
                    lblFrame_Run.Text = "stop";
                }
                else
                {
                    Message("run animation : stopped");
                    lblFrame_Run.Text = "run";
                }
            }
        }
        #endregion

        /// <summary>
        /// writes a message for the user updating current commands operations then sets a timer to write the default message on the form's header
        /// </summary>
        /// <param name="strMessage"></param>
        public void Message(string strMessage)
        {
            Text = strMessage;
            tmrRefreshText.Enabled = true;
        }

        bool bolAnimationSequence = false;

        public bool AnimationSequence
        { 
        get { return bolAnimationSequence; }
        set 
            {
                bolAnimationSequence
                    = tmrAnimation_Enabled
                    = value;// !bolAnimationSequence;
                
                pnlAnimationControls.lbtnRunSequence_SetText();
            }
        }


        /// <summary>
        /// advances the frame counter by one then draws the sprite for that animation frame
        /// </summary>
        void AnimationFrame_Step()
        {
            cSpriteData.cAnimationData.cSprite.DoNotDraw = true;

            int intFrameCounter_Current = cSpriteData.cAnimationData.intFrameIndex;
            int intFrameCounter_Next = (intFrameCounter_Current + 1) % cSpriteData.cAnimationData.cAnimation.lstFrames.Count;

            if (AnimationSequence && intFrameCounter_Next == 0)
            {
                pnlAnimationControls.AnimationSequence_Next();
                intFrameCounter_Current = 0;
            }

            if (!AnimationSequence
                && (pnlFrameEditor.chkTrack_Limb_Radians.Checked
                        || pnlFrameEditor.chkTrack_Limb_Magnitude.Checked
                        || pnlFrameEditor.chkTrack_Mirrors.Checked
                        || pnlFrameEditor.chkTrack_DrawSequence.Checked
                        || pnlFrameEditor.chkTrack_DrawRelativeTo.Checked
                        || pnlFrameEditor.chkTrack_Override.Checked))
            {
                classAnimation_Frame cFrame_Current = cSpriteData.cAnimationData.cAnimation.lstFrames[intFrameCounter_Current];
                classAnimation_Frame cFrame_Next = cSpriteData.cAnimationData.cAnimation.lstFrames[intFrameCounter_Next];
                if (pnlFrameEditor.chkTrack_Limb_Radians.Checked)
                {
                    for (int intLimbCounter = 0; intLimbCounter < pnlFrameEditor.clbLimbTracker_Radians.Items.Count; intLimbCounter++)
                    {
                        if (pnlFrameEditor.clbLimbTracker_Radians.GetItemChecked(intLimbCounter))
                        {
                            classAnimation_Frame_LimbData cData_FrameCurrent = cFrame_Current.getData(pnlFrameEditor.clbLimbTracker_Radians.Items[intLimbCounter].ToString());
                            classAnimation_Frame_LimbData cData_FrameNext = cFrame_Next.getData(pnlFrameEditor.clbLimbTracker_Radians.Items[intLimbCounter].ToString());
                            cData_FrameNext.Angle = cData_FrameCurrent.Angle;
                            cData_FrameNext.ImageList_Index = cData_FrameCurrent.ImageList_Index;
                        }
                    }
                }
                if (pnlFrameEditor.chkTrack_Limb_Magnitude.Checked)
                {
                    for (int intLimbCounter = 0; intLimbCounter < pnlFrameEditor.clbLimbTracker_Magnitude.Items.Count; intLimbCounter++)
                    {
                        if (pnlFrameEditor.clbLimbTracker_Magnitude.GetItemChecked(intLimbCounter))
                        {
                            classAnimation_Frame_LimbData cData_FrameCurrent = cFrame_Current.getData(pnlFrameEditor.clbLimbTracker_Magnitude.Items[intLimbCounter].ToString());
                            classAnimation_Frame_LimbData cData_FrameNext = cFrame_Next.getData(pnlFrameEditor.clbLimbTracker_Magnitude.Items[intLimbCounter].ToString());
                            cData_FrameNext.SlaveContactMagnitude_Factor = cData_FrameCurrent.SlaveContactMagnitude_Factor;
                            cData_FrameNext.ImageList_Index = cData_FrameCurrent.ImageList_Index;
                        }
                    }
                }

                if (pnlFrameEditor.chkTrack_Mirrors.Checked)
                {
                    cFrame_Next.Horizontal_Mirror = cFrame_Current.Horizontal_Mirror;
                    cFrame_Next.Vertical_Mirror = cFrame_Current.Vertical_Mirror;
                }

                if (pnlFrameEditor.chkTrack_DrawSequence.Checked)
                {
                    for (int intLimbCounter = 0; intLimbCounter < cFrame_Current.lstDrawSequence.Count; intLimbCounter++)
                    {
                        cFrame_Next.lstDrawSequence[intLimbCounter] = cFrame_Current.lstDrawSequence[intLimbCounter];
                    }
                }

                if (pnlFrameEditor.chkTrack_Override.Checked)
                {
                    for (int intLimbCounter = 0; intLimbCounter < pnlFrameEditor.clbLimbTracker_Magnitude.Items.Count; intLimbCounter++)
                    {
                        classAnimation_Frame_LimbData cData_FrameCurrent = cFrame_Current.getData(pnlFrameEditor.clbLimbTracker_Magnitude.Items[intLimbCounter].ToString());
                        classAnimation_Frame_LimbData cData_FrameNext = cFrame_Next.getData(pnlFrameEditor.clbLimbTracker_Magnitude.Items[intLimbCounter].ToString());
                        cData_FrameNext.Override = cData_FrameCurrent.Override;
                    }
                }

                if (pnlFrameEditor.chkTrack_DrawRelativeTo.Checked)
                {
                    cFrame_Next.Limb_DrawRelativeTo = cFrame_Current.Limb_DrawRelativeTo;
                }
            }

            if (pnlAnimation_FrameEditor.Visible && !pnlAnimation_FrameEditor.Collapsed)
                pnlAnimation_FrameEditor.Shift_Frame_Next();

            nudFrame_Counter.Maximum = cSpriteData.cAnimationData.cAnimation.lstFrames.Count - 1;
            cSpriteData.cAnimationData.cSprite.DoNotDraw = false;
            nudFrame_Counter.Value = intFrameCounter_Next % cSpriteData.cAnimationData.cAnimation.lstFrames.Count;
            //System.Diagnostics.Debug.Print("Ani:" + cSpriteData.cAnimationData.cAnimation.Name + ", frame(" + cSpriteData.cAnimationData.intFrameIndex.ToString() + ")");
            Debug_TestData("exiting AnimationFrame_Step");
        }

        /// <summary>
        /// returns the Angle and Magnitude hinge values of the currently selected limb 
        /// </summary>
        /// <param name="cFrame">frame for which the information is requested</param>
        /// <returns>the radian coordinates of the currently selected limb's hinge</returns>
        classAnimation_Frame_LimbData getFrameData(ref classAnimation_Frame cFrame)
        {
            if (cFrame != null)
            {
                for (int intDataCounter = 0; intDataCounter < cFrame.lstData.Count; intDataCounter++)
                {
                    if (cLimb == cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[cFrame.lstData[intDataCounter].intLimbIndex])
                        return cFrame.lstData[intDataCounter];
                }
            }
            Debug_TestData("exiting getFramedata");
            return null;
        }

        void Costume_SetToDefault()
        {
            pnlCostume_Selector.cmbCostume.SelectedIndex = 0;
            Limb_Selected_Set();
        }

        /// <summary>
        /// sets the panelHingeContact_Graphical's parameters to reflect the currently selected limb's values
        /// </summary>
        void setLimbInfo_Graphical_Show()
        {
            classSprite_Limb cLimb_Ref = cLimb;
            pnlHingeContacts_Set_Graphical.setLimbContact(ref cLimb_Ref);
            Debug_TestData("exiting setLimbInfo_Graphical_Show");
        }

        /// <summary>
        /// sets the panelHingeContact_Numerical's parameters to reflect the currently selected limb's values
        /// </summary>
        void setLimbInfo()
        {
            bolDraw_Sprite = false;
            if (cLimb.Hinge != null)
                pnlHingeContacts_Set_Numerical.Heading.Text = cLimb.Hinge.Limb_Slave.Name;
            else
                pnlHingeContacts_Set_Numerical.Heading.Text = "null";

            if (cLimb != null
                && cLimb.Hinge != null
                && cLimb.Hinge.Limb_Master != null)
            {
                grbLimbEditor_Hinge_Contact_Master.Text = cLimb.Hinge.Limb_Master.Name + "(Master) Contact";
                txtHinge_Contact_Master_Magnitude.Text = cLimb.Hinge.Contact.Master.Magnitude.ToString(strMagnitudeFormat);
                txtHinge_Contact_Master_Radians.Text = cLimb.Hinge.Contact.Master.Radians.ToString(strRadiansFormat);
            }
            else if (cLimb != null)
            {
                grbLimbEditor_Hinge_Contact_Master.Text = cLimb.Name + " has no master";
                txtHinge_Contact_Master_Magnitude.Text = strMagnitudeFormat;
                txtHinge_Contact_Master_Radians.Text = strRadiansFormat;
            }

            if (cLimb != null
                && cLimb.Hinge != null
                && cLimb.Hinge.Limb_Slave != null)
            {
                grbLimbEditor_Hinge_Contact_Slave.Text = cLimb.Hinge.Limb_Slave.Name + "(Slave) Contact";
                txtHinge_Contact_Slave_Magnitude.Text = cLimb.Hinge.Contact.Slave.Magnitude.ToString(strMagnitudeFormat);
                txtHinge_Contact_Slave_Radians.Text = cLimb.Hinge.Contact.Slave.Radians.ToString(strRadiansFormat);
            }
            else
            {
                grbLimbEditor_Hinge_Contact_Slave.Text = "Slave not loaded";
                txtHinge_Contact_Slave_Magnitude.Text = strMagnitudeFormat;
                txtHinge_Contact_Slave_Radians.Text = strRadiansFormat;
            }

            if (cLimb != null
                && cLimb.Hinge != null)
            {
                if (cSpriteData.cAnimationData.cAnimation != null 
                    && cSpriteData.cAnimationData.cAnimation.lstFrames.Count > cSpriteData.cAnimationData.intFrameIndex)
                {
                    classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                    classAnimation_Frame_LimbData cLimbData = cFrame.getOverrideData(cLimb.Name);
                    txtHinge_Radians.Text = cLimbData.Angle.ToString();// cLimb.Hinge.Angle.ToString(strRadiansFormat);
                    txtHinge_Magnitude.Text = cLimbData.SlaveContactMagnitude_Factor.ToString(); //cLimb.Hinge.SlaveContact_MagnitudeFactor.ToString(strRadiansFormat);
                    txtOpacity.Text = cLimbData.Opacity.ToString();
                    grbColorFilter.ColorFilter = cLimbData.ColorFilter;
                }
            }
            else
            {
                txtHinge_Radians.Text = strRadiansFormat;
                txtHinge_Magnitude.Text = strMagnitudeFormat;
            }
         
            
            pnlHingeContacts_Set_Graphical.setLimbContact(ref _cLimb);

            bolDraw_Sprite = true;
            Draw_Sprite();
            Debug_TestData("exiting setLimbInfo_Numerical");
        }

        /// <summary>
        /// loads the sprite requested from file and draws it to the screen
        /// </summary>
        /// <param name="strFilename">name of the file of the sprite to be loaded</param>
        void File_Load(string strFilename)
        {
            pnlDebug.Enabled = false;
            int intCutChr = strFilename.LastIndexOf("\\");
            if (intCutChr > 0)
            {
                ptDraw_DrawRel_Off = cSpriteData.pt;
                cSpriteData
                    = pnlDrawSequence.cSpriteData
                    = new classSpriteData();
                strFilename_Current = strFilename;
                cSpriteData.cAnimationData.cSprite = classSpriteMaker.instance.Load(strFilename_Current);
                
                if (cSpriteData.cAnimationData.cSprite == null)
                    cSpriteData.cAnimationData.cSprite = classSpriteMaker.instance.New("New Sprite");
                if (cSpriteData.cAnimationData.cSprite.lstAnimations.Count == 0)
                    cSpriteData.cAnimationData.cSprite.Animation_New("New Animation");
                cSpriteData.cAnimationData.cAnimation = cSpriteData.cAnimationData.cSprite.lstAnimations[0];


                cSpriteData.cAnimationData.cSprite.UseRamCache = pnlOptions.UseRAMCache;
                DrawSizeFactor = dblDrawFactor_Load;
                cSpriteData.pt = ptDraw_DrawRel_Off;
                Draw_Sprite();

                cmbLimbs_Reset();
                if (cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs.Count > 0)
                {
                    if (cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master.lstHinge_Slaves.Count > 0)
                    {
                        cmbLimbs_SetSelect(cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master.lstHinge_Slaves[0].Limb_Slave.Name);
                    }
                    else
                        cmbLimbs_SetSelect(cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[0].Name);
                }
                cmbAnimation_Refresh();

                if (cSpriteData.cAnimationData.cAnimation == null && cSpriteData.cAnimationData.cSprite.lstAnimations.Count > 0)
                {
                    cSpriteData.cAnimationData.cAnimation = cSpriteData.cAnimationData.cSprite.lstAnimations[0];
                    cSpriteData.cAnimationData.intFrameIndex = 0;
                }

                if (cSpriteData.cAnimationData.cSprite.lstCostumeInfo != null)
                {
                    pnlCostume_Selector.cmbCostume_Load();
                }

                nudFrameCounter_Reset();
                Message("file loaded : " + strFilename_Current);

                pnlOptions.clbShowLimbPositions_Set();
                pnlAnimationControls.AnimationSequence_Clear();
            }
            Focus();
            pnlDebug.Clear();
            pnlDebug.Enabled = true;
            pnlFrameEditor.cFrame_Copy = null;
            Debug_TestData("Exiting File_Load (" + strFilename + ")");
        }

        /// <summary>
        /// searches the QuadTree to see whether the current mouse cursor location on the main picturebox is near a limb
        /// </summary>
        /// <returns>returns the limb beneath the mouse cursor if the mouse cursor is above a limb</returns>
        classSprite_Limb detectLimb()
        {
            classSprite_Limb cRetVal = null;
            if (cSpriteData.cAnimationData.cSprite != null && cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions != null)
            {
                //List<classQuadTree.classQuadTreeData> lstTraversalResults = cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions.TraverseQuadTree();

                Point ptLimb = classMath3.SubTwoPoints(ptPicMain_Mouse, ptDraw);
                if (cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions != null)
                {
                    cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions.SearchVariance_X = 10;
                    cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions.SearchVariance_Y = 10;

                    List<classQuadTree.classQuadTreeData> lstResults = cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions.Search(ptLimb);

                    //List<classQuadTree.classQuadTreeData> lstTraverseResults = cSpriteData.cCostumeInfo.cDrawData_current.cQT_LimbPositions.TraverseQuadTree();

                    if (lstResults.Count > 0)
                    {
                        List<int> lstDrawSequence = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex].lstDrawSequence;
                        int intDoNotDrawIndex = lstDrawSequence.IndexOf(-1);
                        for (int intCounter = 0; intCounter < lstResults.Count; intCounter++)
                        {
                            classSprite_Limb cThisLimb = (classSprite_Limb)lstResults[intCounter].Data;
                            int intThisLimbIndex = cSpriteData.cCostumeInfo.lstLimbs.IndexOf(cThisLimb); //.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs.IndexOf(cThisLimb);
                            int intDrawIndexOfThisLimb = lstDrawSequence.IndexOf(intThisLimbIndex);
                            if (intDrawIndexOfThisLimb < intDoNotDrawIndex)
                            {
                                cRetVal = cThisLimb;
                                break;
                            }
                        }
                    }
                    else
                        cRetVal = null;
                }
            }
            Debug_TestData("exiting DetectLimb");
            return cRetVal;
        }

        /// <summary>
        /// used to display the recent change in the sprite's draw size onto the FocusController
        /// </summary>
        string strSizeDrawFactor = "";

        /// <summary>
        /// point where the sprite is to be drawn on the screen 
        /// </summary>
        Point ptDraw = new Point();

        /// <summary>
        /// offset value used to position the sprite when the DrawRelativeToLimb checkbox is unchecked
        /// </summary>
        public Point ptDraw_DrawRel_Off = new Point();

        public Rectangle recSpriteFrame = new Rectangle();

        /// <summary>
        /// draw the sprite onto the screen
        /// </summary>
        public void Draw_Sprite()
        {
            if (bolDraw_Sprite && picMain.Height > 0 && picMain.Width > 0)
            {
                classAnimation_Frame cFrame = null;
                if (cSpriteData.cAnimationData.cSprite != null)
                {
                    cSpriteData.cAnimationData.cSprite.UseRamCache = pnlOptions.UseRAMCache;
                    Bitmap bmpSprite = cSpriteData.cAnimationData.cSprite.draw_Animation_Frame(ref cSpriteData);
                    bool bolDebug = false;
                    if (bolDebug)
                    {
                        List<Bitmap> lstSprite = cSpriteData.cAnimationData.cSprite.draw_Animation_Frame(ref cSpriteData, grbDisjointedLimbs.lstLimbSelected);
                        for (int intFrameCounter = 0; intFrameCounter < lstSprite.Count; intFrameCounter++)
                            lstSprite[intFrameCounter].Save(@"c:\debug\" + grbDisjointedLimbs.lstLimbSelected[intFrameCounter].Name + ".bmp");
                    }

                    if (bmpSprite == null) return;

                    cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                    Bitmap bmpScreen = (Bitmap)new Bitmap(picMain.Width, picMain.Height);
                    using (Graphics g = Graphics.FromImage(bmpScreen))
                    {
                        Rectangle recSource = new Rectangle(classGraphics.ptZero, bmpBackground.Size);
                        Rectangle recDestination = new Rectangle(classGraphics.ptZero, picMain.Size);
                        g.DrawImage(bmpBackground, recDestination, recSource, GraphicsUnit.Pixel);

                        if (pnlFrameEditor.chkDrawRelativeToLimb_EditorToggle.Checked)
                        {
                            classSprite_Limb cLimbDrawRelativeTo = cSpriteData.cCostumeInfo.lstLimbs[cFrame.Limb_DrawRelativeTo];
                            object objPt = cSpriteData.cCostumeInfo.cDrawData_current.cBT_LimbPositions.Search(cLimbDrawRelativeTo.Name);
                            if (objPt == null) return;
                            Point ptLimb = (Point)objPt;
                            Point ptRelLimb = ptLimb;
                            ptDraw = classMath3.SubTwoPoints(cSpriteData.pt, ptRelLimb);
                        }
                        else
                        {
                            Point ptRelLimb = classMath3.SubTwoPoints(classGraphics.ptZero, cSpriteData.cCostumeInfo.cDrawData_current.cFrame.ptTL);
                            ptDraw = classMath3.SubTwoPoints(ptDraw_DrawRel_Off, ptRelLimb);
                        }

                        if (bmpSprite != null)
                        {
                            recSource = new Rectangle(classGraphics.ptZero, bmpSprite.Size);
                            Size szDestination = new Size((int)((double)bmpSprite.Width), (int)((double)bmpSprite.Height));

                            recSpriteFrame = new Rectangle(ptDraw, szDestination);

                            g.DrawImage(bmpSprite, recSpriteFrame, recSource, GraphicsUnit.Pixel);
                            if (pnlOptions.chkShow_Frame.Checked)
                            {
                                g.DrawRectangle(Pens.Red, recSpriteFrame);
                             /*   // debug - half-frame
                                Point ptCenter = new Point(recSpriteFrame.Left + recSpriteFrame.Width / 2, recSpriteFrame.Top + recSpriteFrame.Height / 2);
                                Size szHalf = new Size(recSpriteFrame.Width / 2, recSpriteFrame.Height / 2);
                                Rectangle recHalfFrame = new Rectangle(new Point(ptCenter.X - szHalf.Width / 2, ptCenter.Y - szHalf.Height / 2), szHalf);
                                g.DrawRectangle(Pens.Green, recHalfFrame);

                                int intRadius = 3;
                                Pen pCenter = new Pen(Color.GreenYellow, 2);
                                Point ptTemp = new Point(ptDraw.X - cFrame.ptTL.X,
                                                               ptDraw.Y - cFrame.ptTL.Y);
                                g.DrawEllipse(pCenter, new RectangleF(ptTemp.X - intRadius, ptTemp.Y - intRadius, 2 * intRadius, 2 * intRadius));
                             */
                            }
                        }

                        Point ptMasterLimb = classMath3.SubTwoPoints(new Point(0, 0), AnimationFrame.ptTL);
                        if (pnlOptions.chkShow_LimbCenters.Checked
                            || pnlOptions.chkShow_LimbNames.Checked
                            || pnlOptions.chkShow_LimbPositions.Checked)
                        {
                            for (int intLimbCounter = 0; intLimbCounter < cFrame.lstDrawSequence.Count; intLimbCounter++)
                            {
                                int intLimbIndex = cFrame.lstDrawSequence[intLimbCounter];
                                classSprite_Limb cLimb = intLimbIndex >= 0
                                                                      ? cSpriteData.cCostumeInfo.lstLimbs[intLimbIndex]
                                                                      : null;
                                if (cLimb == null) break;
                                if (cLimb.Hinge != null)
                                {
                                    Point ptLimb= (Point)cSpriteData.cCostumeInfo.cDrawData_current.cBT_LimbPositions.Search(cLimb.Name);

                                    Point ptLimbCenter = classMath3.AddTwoPoints(ptLimb,
                                                                                 ptDraw);
                                    
                                    if (pnlOptions.chkShow_LimbCenters.Checked)
                                    {
                                        g.DrawArc((cLimb == cLimb_MouseOver ? Pens.Yellow : Pens.Black), new Rectangle(new Point(ptLimbCenter.X - 2, ptLimbCenter.Y - 2), new Size(4, 4)), 0, 360);
                                        g.DrawArc((cLimb == cLimb_MouseOver ? Pens.Red : Pens.White), new Rectangle(new Point(ptLimbCenter.X - 3, ptLimbCenter.Y - 3), new Size(6, 6)), 0, 360);

                                        if (cLimb_MouseOver == cLimb)
                                        {
                                            Font fntUI_MouseOver = new Font("courier", 8);
                                            string strUI_MouseOver = "(" + cLimb.ptDrawCenter.X.ToString() + "," + cLimb.ptDrawCenter.Y.ToString() + ")\r\n" + cLimb.Name;
                                            Size szUI_MouseOver = TextRenderer.MeasureText(strUI_MouseOver, fntUI_MouseOver);
                                            Point ptUI_MouseOver = new Point(ptLimbCenter.X - szUI_MouseOver.Width / 2, ptLimbCenter.Y - szUI_MouseOver.Height - 1);
                                            g.DrawString(strUI_MouseOver, fntUI_MouseOver, Brushes.Black, ptUI_MouseOver);
                                            g.DrawString(strUI_MouseOver, fntUI_MouseOver, Brushes.White, new Point(ptUI_MouseOver.X +1, ptUI_MouseOver.Y +1));
                                        }
                                    }

                                    if (pnlOptions.chkShow_LimbNames.Checked)
                                    {
                                        int intGap = 2;
                                        g.DrawString(cLimb.Name, fnt, (cLimb == cLimb_MouseOver ? Brushes.Gray : Brushes.Yellow), new Point(ptLimbCenter.X + 10 - intGap, ptLimbCenter.Y - intGap));
                                        g.DrawString(cLimb.Name, fnt, (cLimb == cLimb_MouseOver ? Brushes.Red : Brushes.Black), new Point(ptLimbCenter.X + 10, ptLimbCenter.Y));
                                    }

                                    if (pnlOptions.chkShow_LimbPositions.Checked
                                        && cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[ cLimb.intMyIndex].DisplayPosition)
                                    {
                                        Font fntPositions = new Font("courier", 12, FontStyle.Regular);
                                        string strPosition = "(" + cLimb.ptDrawCenter.X.ToString() + ", " + cLimb.ptDrawCenter.Y.ToString() + ")";
                                        Size szPosition = TextRenderer.MeasureText(strPosition, fnt);
                                        Point ptPosition = new Point(ptLimbCenter.X - szPosition.Width / 2, ptLimbCenter.Y + 10);
                                        g.DrawString(strPosition, fntPositions, Brushes.Yellow, new Point(ptPosition.X + 2, ptPosition.Y + 2));
                                        g.DrawString(strPosition, fntPositions, Brushes.Black, ptPosition);
                                    }
                                }
                            }
                        }

                        if (cSpriteData.cAnimationData.cSprite.UseRamCache)
                        {
                            Font fntRAMCache_Red = new Font("Mongolian Baiti", 24, FontStyle.Bold);
                            Size szUseRAMCach_Red = TextRenderer.MeasureText("RAM Cache", fntRAMCache_Red);
                            Point ptRAMCache = new Point((picMain.Width - szUseRAMCach_Red.Width) / 2, (picMain.Height - szUseRAMCach_Red.Height) / 2);
                            g.DrawString("RAM Cache", fntRAMCache_Red, Brushes.Red, ptRAMCache);
                        }
                    }

                    int intPTY = cSpriteData.pt.Y;
                    int intPTX = cSpriteData.pt.X;

                    if (ptDraw.X + bmpSprite.Width < 0)
                        intPTX += (Screen.PrimaryScreen.WorkingArea.Width + bmpSprite.Width);
                    if (ptDraw.X > Screen.PrimaryScreen.WorkingArea.Width)
                        intPTX -= (Screen.PrimaryScreen.WorkingArea.Width + bmpSprite.Width);

                    if (ptDraw.Y + bmpSprite.Height < 0)
                        intPTY += (Screen.PrimaryScreen.WorkingArea.Height + bmpSprite.Height - 1);
                    if (ptDraw.Y > Screen.PrimaryScreen.WorkingArea.Height)
                        intPTY -= (Screen.PrimaryScreen.WorkingArea.Height + bmpSprite.Height - 1);

                    cSpriteData.pt = new Point(intPTX, intPTY);
                    
                    intScreen_WO_FocusController_Counter = (intScreen_WO_FocusController_Counter + 1) % 2;
                    bmpScreen_WO_FocusController[intScreen_WO_FocusController_Counter] = bmpScreen;
                    picMain.Image = bmpScreen;
                    Draw_Controls();
                }
            }
            Debug_TestData("exiting Draw_Sprite");
        }

        /// <summary>
        /// draws FocusControl UI onto the screen as well as the mouseControl limb editing 
        /// </summary>
        void Draw_Controls()
        {
            if ((pnlOptions.chkShow_FocusController.Checked && bmpScreen_WO_FocusController != null) // FocusControl being moved by user
                ||
                (pnlOptions != null && pnlFrameEditor.chkMouse_LimbControl.Checked)                 // mouse controlling limb position editing Frame
                ||
                strSizeDrawFactor.Length > 0)                                                        // DrawSizeFactor needs to be displayed
            {
                try
                {
                    Bitmap bmpScreen_W_Controller = new Bitmap(bmpScreen_WO_FocusController[intScreen_WO_FocusController_Counter]);
                    Graphics g = Graphics.FromImage(bmpScreen_W_Controller);
                    {
                        drawFocus(ref g);

                        drawMouseLimbControl(ref g);
                        
                        picMain.Image = bmpScreen_W_Controller;
                        picMain.Refresh();
                    }
                    g.Dispose();
                }
                catch (Exception err)
                {
                    MessageBox.Show("Error in DrawControl() : " + err.Message);
                }
            }
        }

        void drawFocus(ref Graphics g)
        {
            if (pnlOptions.chkShow_FocusController.Checked && bmpScreen_WO_FocusController != null)
            {
                Bitmap bmpFCI = bmpFocusControllerImages[(int)eFocusControllerImage];
                g.DrawImage(bmpFCI, new Point(ptFocusControllerCenter.X - bmpFCI.Width / 2, ptFocusControllerCenter.Y - bmpFCI.Height / 2));
                if (strSizeDrawFactor.Length > 0)
                {
                    Size szDrawSizeFactor = TextRenderer.MeasureText(strSizeDrawFactor, fnt);
                    int intHalfWidthBmp = bmpFCI.Width / 2;
                    Point ptDrawSizeFactor = new Point(ptFocusControllerCenter.X - intHalfWidthBmp + (intHalfWidthBmp - szDrawSizeFactor.Width) / 2,
                                                       ptFocusControllerCenter.Y + (intHalfWidthBmp - szDrawSizeFactor.Height) / 2);
                    g.DrawString(strSizeDrawFactor, fnt, Brushes.Black, ptDrawSizeFactor);
                }
            }
        }
        bool bolDrawMouseLimbControl = false;
        void drawMouseLimbControl(ref Graphics g)
        {
            if (bolDrawMouseLimbControl) return;
            if (eFocusControllerImage == enuFocusControllerImages.Idle
                                && !tmrAnimation.Enabled
                                && bolMouseOverPic
                                && MouseButtons == MouseButtons.Left
                                && pnlOptions != null && pnlFrameEditor.chkMouse_LimbControl.Checked
                                && cLimb.Hinge != null)
            {
                bolDrawMouseLimbControl = true;
                classSprite_Limb cMasterLimb = cLimb.Hinge.Limb_Master;

                if (cMasterLimb != null && cMasterLimb.Hinge != null)
                {
                    /*
                        cSpriteData.pt = new Point(picMain.Width / 2, picMain.Height / 2);
                        ptDraw_DrawRel_Off.X = cSpriteData.pt.X;
                        ptDraw_DrawRel_Off.Y = cSpriteData.pt.Y;
                    */
                    
                    classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                    cFrame.StandardSizeInitialized = false;
                    classAnimation_Frame_LimbData cFrameData_Master = cFrame.lstDataOverride[cMasterLimb.intMyIndex];

                    classAnimation_Frame_LimbData cFrameData_Limb = cFrame.lstDataOverride[cLimb.intMyIndex];
                    Point ptSprite = new Point();

                    if (pnlFrameEditor.chkDrawRelativeToLimb_EditorToggle.Checked)
                    {
                        classSprite_Limb cLimbDrawRelativeTo = cSpriteData.cCostumeInfo.lstLimbs[cFrame.Limb_DrawRelativeTo];
                        ptSprite = classMath3.SubTwoPoints(cSpriteData.pt, cLimbDrawRelativeTo.ptDrawCenter);
                    }
                    else
                    {
                        //Point ptRelLimb = classMath3.SubTwoPoints(classGraphics.ptZero, cSpriteData.cCostumeInfo.cDrawData_current.cFrame.ptTL);
                        //ptSprite = classMath3.SubTwoPoints(ptDraw_DrawRel_Off, ptRelLimb);
                        ptSprite = ptDraw_DrawRel_Off;
                    }
                    /*
                    Point ptHinge = classMath3.AddTwoPoints(ptSprite,
                                                            new Point((chkFrame_Mirror_Horizontal.Checked 
                                                                                                ? (int)(-cFrameData_Limb.ptDrawHinge.X * DrawSizeFactor )
                                                                                                : (int)(cFrameData_Limb.ptDrawHinge.X * DrawSizeFactor)),
                                                                      (chkFrame_Mirror_Vertical.Checked
                                                                                                ? (int)(-cFrameData_Limb.ptDrawHinge.Y * DrawSizeFactor)
                                                                                                : (int)(cFrameData_Limb.ptDrawHinge.Y * DrawSizeFactor)))); 
                    /*/
                    Point ptHinge = classMath3.AddTwoPoints(ptSprite,
                                                            new Point((int)(cFrameData_Limb.ptDrawHinge.X * DrawSizeFactor),
                                                                      (int)(cFrameData_Limb.ptDrawHinge.Y * DrawSizeFactor)));
                    // */
                    if (false && pnlFrameEditor.chkDrawRelativeToLimb_EditorToggle.Checked)
                        {
                        classSprite_Limb cLimbRelTo = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[cFrame.Limb_DrawRelativeTo];

                        ptHinge = classMath3.AddTwoPoints(ptHinge, cLimbRelTo.ptDrawCenter);
                    }


                    double dblRadians_HingeToMouse = (double)Math.Atan2((double)(ptPicMain_Mouse.Y - ptHinge.Y), (double)(ptPicMain_Mouse.X - ptHinge.X));

                    if (chkFrame_Mirror_Horizontal.Checked && chkFrame_Mirror_Vertical.Checked)
                    {
                        dblRadians_HingeToMouse += Math.PI;
                    }
                    else if (chkFrame_Mirror_Vertical.Checked)
                    {
                        dblRadians_HingeToMouse *= -1;
                    }
                    else if (chkFrame_Mirror_Horizontal.Checked)
                    {
                        dblRadians_HingeToMouse *= -1;
                        dblRadians_HingeToMouse += Math.PI;
                    }
                    double dblRadians = classMath3.cleanAngle(-dblRadians_HingeToMouse - cFrameData_Master.DrawAngle + cLimb.Hinge.Contact.Slave.Radians);

                    txtHinge_Radians.Text = classMath3.cleanAngle(dblRadians).ToString(strRadiansFormat);

                    int intRadiusHinge = 4;
                    g.FillEllipse(Brushes.Green, new Rectangle(new Point(ptHinge.X - intRadiusHinge, ptHinge.Y - intRadiusHinge), new Size(2 * intRadiusHinge, 2 * intRadiusHinge)));
                    intRadiusHinge = 2;
                    g.FillEllipse(Brushes.Black, new Rectangle(new Point(ptHinge.X - intRadiusHinge, ptHinge.Y - intRadiusHinge), new Size(2 * intRadiusHinge, 2 * intRadiusHinge)));

                    g.DrawLine(Pens.Red, ptHinge, ptPicMain_Mouse);
                }
                bolDrawMouseLimbControl = false;
            }
        }

        /// <summary>
        /// positions the sprite's limbs to the values determined by the current from selected
        /// </summary>
        void frame_SetLimbs()
        {
            if (AnimationFrame != null)
            {
                for (int intLimbCounter = 0; intLimbCounter < AnimationFrame.lstData.Count; intLimbCounter++)
                {
                    classAnimation_Frame_LimbData cData = AnimationFrame.lstData[intLimbCounter];
                    if (cData.intLimbIndex >= 0 && cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[cData.intLimbIndex].Hinge != null)
                    {

                        cSpriteData.cCostumeInfo.lstLimbs[cData.intLimbIndex].Hinge.Angle = cData.Angle;
                        cSpriteData.cCostumeInfo.lstLimbs[cData.intLimbIndex].Hinge.SlaveContact_MagnitudeFactor = cData.SlaveContactMagnitude_Factor;
                        cSpriteData.cCostumeInfo.lstLimbs[cData.intLimbIndex].ptDrawCenter = cData.ptDrawCenter;
                    }
                }
            }
            Draw_Sprite();
            Debug_TestData("exiting frame_SetLimbs");
        }

        /// <summary>
        /// sets the Limb combobox to the limb specified
        /// </summary>
        /// <param name="strLimb">name of limb which the combobox is to be set to</param>
        public void cmbLimbs_SetSelect(string strLimb)
        {
            strLimb = strLimb.ToLower();
            for (int intItemsCounter = 0; intItemsCounter < cmbLimbs.Items.Count; intItemsCounter++)
            {
                if (string.Compare(cmbLimbs.Items[intItemsCounter].ToString().ToLower(), strLimb) == 0)
                {
                    cmbLimbs.SelectedIndex = intItemsCounter;
                    return;
                }
            }
            cmbLimbs.SelectedIndex = 0;
            Debug_TestData("exiting cmbLimbs_setSelect");
        }

        /// <summary>
        /// sets the current animation frame's DrawRelativeToLimb to the user selected value
        /// </summary>
        /// <param name="strLimb"></param>
        public void cmbFrameRelativeTo_SetSelected(string strLimb)
        {
            strLimb = strLimb.ToLower();
            for (int intItemsCounter = 0; intItemsCounter < cmbFrame_DrawRelativeTo.Items.Count; intItemsCounter++)
            {
                if (string.Compare(cmbFrame_DrawRelativeTo.Items[intItemsCounter].ToString().ToLower(), strLimb) == 0)
                {
                    cmbFrame_DrawRelativeTo.SelectedIndex = intItemsCounter;
                    return;
                }
            }
            cmbFrame_DrawRelativeTo.SelectedIndex = 0;
            Debug_TestData("exiting cmbLimbs_setSelect");
        }

        /// <summary>
        /// reinitializes the limbs combobox and loads it with the values found in the current sprite's list of limbs
        /// </summary>
        void cmbLimbs_Reset()
        {
            cmbLimbs.Items.Clear();
            pnlDrawSequence.mbpLimbs.ClearButtons();
            int intSelectedIndex = -1;
            List<string> lstLimbNames = new List<string>();
            for (int intLimbCounter = 0; intLimbCounter < cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs.Count; intLimbCounter++)
            {
                classSprite_Limb cThisLimb = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs[intLimbCounter];
                lstLimbNames.Add(cThisLimb.Name);
            }

            IEnumerable<string> query = lstLimbNames.OrderBy(num => num, new classSpriteMaker.Compare_Alphabetical());
            lstLimbNames = query.ToList<string>();


            for (int intLimbCounter = 0; intLimbCounter < lstLimbNames.Count; intLimbCounter++)
            {
                classSprite_Limb cThisLimb = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(lstLimbNames[intLimbCounter]);
                if (cThisLimb == cLimb)
                    intSelectedIndex = intLimbCounter;
                cmbLimbs.Items.Add(lstLimbNames[intLimbCounter]);
            }
            cmbLimbs.SelectedIndex = intSelectedIndex;

            cmbFrame_DrawRelativeTo.Items.Clear();
            classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
            for (int intLimbCounter = 0; intLimbCounter < lstLimbNames.Count; intLimbCounter++)
            {
                classSprite_Limb cThisLimb = (classSprite_Limb)cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cBT_Limbs.Search(lstLimbNames[intLimbCounter]);
                if (cThisLimb == cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master)
                {
                    if (cFrame.Limb_DrawRelativeTo < 0)
                        intSelectedIndex = intLimbCounter;

                }
                else if (cThisLimb == cSpriteData.cCostumeInfo.lstLimbs[cFrame.Limb_DrawRelativeTo])
                {
                    intSelectedIndex = intLimbCounter;
                }
                cmbFrame_DrawRelativeTo.Items.Add(lstLimbNames[intLimbCounter]);
            }
            cmbFrame_DrawRelativeTo.SelectedIndex = intSelectedIndex;

            Debug_TestData("exiting cmbLimbs_Reset");
        }

        /// <summary>
        /// reinitializes the Animation combobox to reflect the currently selected sprite's list of animations
        /// </summary>
        void cmbAnimation_Refresh()
        {
            string strSelected = cmbAnimation.SelectedIndex >= 0
                                                            ? (string)cmbAnimation.Items[cmbAnimation.SelectedIndex]
                                                            : "";

            List<classAnimation> lstAnimations = (List<classAnimation>)cSpriteData.cAnimationData.cSprite.lstAnimations.ToList<classAnimation>();
            IEnumerable<classAnimation> query = lstAnimations.OrderBy(animation => animation.Name);
            lstAnimations = (List<classAnimation>)query.ToList<classAnimation>();

            cmbAnimation.Items.Clear();
            int intSelectedIndex = 0;
            for (int intAnimationCounter = 0; intAnimationCounter < lstAnimations.Count; intAnimationCounter++)
            {
                cmbAnimation.Items.Add(lstAnimations[intAnimationCounter].Name);
                if (string.Compare(strSelected, lstAnimations[intAnimationCounter].Name) == 0)
                {
                    intSelectedIndex = intAnimationCounter;
                }
            }

            if (intSelectedIndex >= 0 && intSelectedIndex < cmbAnimation.Items.Count)
                cmbAnimation.SelectedIndex = intSelectedIndex;
            Debug_TestData("exiting cmbAnimation_refresh");
            //panelDebug.instance.Hide();
        }

        /// <summary>
        /// sets the animation combobox to the specified value
        /// </summary>
        /// <param name="strAnimation">name of limb to which the combobox is to be set</param>
        void cmbAnimation_Set(string strAnimation)
        {
            for (int intAnimationCounter = 0; intAnimationCounter < cmbAnimation.Items.Count; intAnimationCounter++)
            {
                if (string.Compare(strAnimation, cmbAnimation.Items[intAnimationCounter].ToString()) == 0)
                {
                    cmbAnimation.SelectedIndex = intAnimationCounter;
                    Debug_TestData("exiting cmbAnimation_Set");
                    return;
                }
            }
        }

        /// <summary>
        /// changes the currently selected limb's currently selected limb image to the image selected by filename
        /// </summary>
        private void mnuLimbs_SetNewImage_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null
                && cLimb != null)
            {
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "Reset " + cLimb.Name + " image to :";

                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    Bitmap bmpNewLimbImage = (Bitmap)Bitmap.FromFile(ofd.FileName);
                    cLimb.Image_SetNew(bmpNewLimbImage);
                    Draw_Sprite();
                    classSprite_Limb cLimbRef = cLimb;
                    pnlHingeContacts_Set_Graphical.setLimbContact(ref cLimbRef);
                }
            }
            Debug_TestData("exiting mnuLimbs_SetNewImage_click");
        }

        /// <summary>
        /// launches the panelMessenger to get the new name of the currently selected limb from the user
        /// </summary>
        private void mnuLimbs_Rename_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();
            if (cLimb == cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master)
            {
                MessageBox.Show("Cannot change the name of Master_Limb");
                Message("Change Limb Name cancelled");
                return;
            }
            pnlMessenger.getName("Change name of Limb " + cLimb.Name + " to", "Rename limb " + cLimb.Name, frmMessenger_UserReply, panelMessenger.enuMessage.Limb_Rename);
            Message("enter new name for limb " + cLimb.Name);
            pnlMessenger.txtUserInput.Focus();
            Debug_TestData("exiting mnuLimbs_Rename_Click");
        }

        /// <summary>
        /// launches the panelLimb_Reattach to reattach the currently selected limb from its current master to a new master
        /// </summary>
        private void mnuLimbs_Reattach_Click(object sender, EventArgs e)
        {
            Costume_SetToDefault();
            if (cLimb != cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.cLimb_Master)
            {
                classSprite_Limb cLimbToReattach = cLimb;

                pnlLimb_Reattach.Limb_Reattach(ref cLimbToReattach);
                pnlLimb_Reattach.Show();
                pnlLimb_Reattach.Expand();
            }
        }

        /// <summary>
        /// relaunches the function that builds the ToolTip data
        /// </summary>
        void mnuBuildToolTip_Click(object sender, EventArgs e)
        {
            ToolTip_SetUp();
        }


        void mnuDebug_PnlOptions_PlaceObjects_Clicked(object sender, EventArgs e)
        {
            pnlOptions.placeObjects();
        }

        /// <summary>
        /// advances the frame counter by one and detaches the panelAnimationControls's controls and places them beneath the mouse cursor
        /// </summary>
        public void mnuAnimation_Frames_Step_Click(object sender, EventArgs e)
        {
            lblFrame_Step_Click(sender, e);
            Size frmSize = new Size(25, 45);
            pnlAnimationControls.pnlAnimation.Dock = DockStyle.None;

            Controls.Add(pnlAnimationControls.pnlAnimation);
            pnlAnimationControls.pnlAnimation.BringToFront();
            pnlAnimationControls.pnlAnimation.Left = MousePosition.X - Left - szForm.Width - 3;
            pnlAnimationControls.pnlAnimation.Top = MousePosition.Y - Top - szForm.Height - 3;
        }

        /// <summary>
        /// sets the animation timer to step through the animation's frames one frame at a time and draw them on the main picturebox
        /// </summary>
        public void mnuAnimation_Frames_Run_Click(object sender, EventArgs e)
        {
            lblFrame_Run_Click(sender, e);
        }

        /// <summary>
        /// changes the current animation frame's DrawRelativeToLimb to the user selected limb
        /// </summary>
        private void cmbFrame_DrawRelativeTo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null && cSpriteData.cAnimationData.cAnimation != null)
            {
                int intAnimationIndex = cSpriteData.cAnimationData.cSprite.lstAnimations.IndexOf(cSpriteData.cAnimationData.cAnimation);
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                classSprite_Limb cLimbDrawRelTo = (classSprite_Limb)cSpriteData.cCostumeInfo.cBT_Limbs.Search(cmbFrame_DrawRelativeTo.Text);

                cFrame.Limb_DrawRelativeTo = cSpriteData.cCostumeInfo.lstLimbs.IndexOf(cLimbDrawRelTo);

            }
        }

        /// <summary>
        /// reacts to mouse cursor leaving the main picturebox
        /// </summary>
        private void picMain_MouseLeave(object sender, EventArgs e)
        {
            tmrFocusDelta.Enabled = false;
            bolMouseOverPic = false;
        }

        /// <summary>
        /// reacts to mouse cursor entering the main picturebox
        /// </summary>
        private void picMain_MouseEnter(object sender, EventArgs e)
        {
            bolMouseOverPic = true;
        }

        /// <summary>
        /// reacts to user checking the vertical mirror checkbox
        /// </summary>
        private void chkFrame_Mirror_Vertical_CheckedChanged(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null && cSpriteData.cAnimationData.cAnimation != null)
            {
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                cFrame.Vertical_Mirror = chkFrame_Mirror_Vertical.Checked;
                Draw_Sprite();
            }

        }

        /// <summary>
        /// reacts to teh user chcking the horizontal mirror checkbox
        /// </summary>
        private void chkFrame_Mirror_Horizontal_CheckedChanged(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null && cSpriteData.cAnimationData.cAnimation != null)
            {
                classAnimation_Frame cFrame = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex];
                cFrame.Horizontal_Mirror = chkFrame_Mirror_Horizontal.Checked;
                Draw_Sprite();
            }
        }

        /// <summary>
        /// inserts the animation frame previous copied with the FrameEditor panel's 'copy' label into the animation immediately after the currently selected frame index
        /// </summary>
        private void lblFrame_Insert_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null
                && cSpriteData.cAnimationData.cAnimation != null
                && pnlFrameEditor.cFrame_Copy != null)
            {
                if (pnlFrameEditor.cFrame_Copy.lstData != null
                    && pnlFrameEditor.cFrame_Copy.lstData.Count > 0)
                {
                    if (pnlFrameEditor.cFrame_Copy.cSprite == cSpriteData.cAnimationData.cSprite)
                    {
                        int intCurrentFrame = (int)nudFrame_Counter.Value;
                        classAnimation_Frame cFrameNew_Copy = pnlFrameEditor.cFrame_Copy.Copy();
                        classAnimation_Frame cFrameNew = cSpriteData.cAnimationData.cAnimation.Frame_Add(cSpriteData.cAnimationData.intFrameIndex, ref cFrameNew_Copy, false);

                        nudFrameCounter_Reset();
                        cSpriteData.cAnimationData.intFrameIndex = ++intCurrentFrame;
                        nudFrame_Counter.Value = cSpriteData.cAnimationData.intFrameIndex;
                        Message("animation frame inserted");
                    }
                }
            }
        }

        /// <summary>
        /// copies the currently selected frame into memory to be inserted into an animtion with the FrameEditor panel's 'insert' label
        /// </summary>
        private void lblFrame_Copy_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null
                && cSpriteData.cAnimationData.cAnimation != null)
            {
                pnlFrameEditor.cFrame_Copy = cSpriteData.cAnimationData.cAnimation.lstFrames[cSpriteData.cAnimationData.intFrameIndex].Copy();
                Message("frame copied to memory.");
            }
        }

        /// <summary>
        /// draws every frame in the currently selected animation and saves them to the hard drive
        /// </summary>
        private void mnuAnimation_SaveImagesToHardDrive_Click(object sender, EventArgs e)
        {
            if (cSpriteData.cAnimationData.cSprite != null && cSpriteData.cAnimationData.cAnimation != null)
            {
                if (MessageBox.Show("Record animation \"" + cSpriteData.cAnimationData.cAnimation.Name + "\" to the Hard drive?", "save animation files?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    FolderBrowserDialog fbd = new FolderBrowserDialog();

                    if (fbd.ShowDialog() == DialogResult.OK)
                    {
                        classAnimation cAnimation = cSpriteData.cAnimationData.cAnimation;
                        string strBaseFilename = fbd.SelectedPath + "\\" + cAnimation.Name;
                        for (cSpriteData.cAnimationData.intFrameIndex = 0; cSpriteData.cAnimationData.intFrameIndex < cAnimation.lstFrames.Count; cSpriteData.cAnimationData.intFrameIndex++)
                        {
                            string strFilename = strBaseFilename + cSpriteData.cAnimationData.intFrameIndex.ToString("00") + ".bmp";
                            Bitmap bmpFrame = cSpriteData.cAnimationData.cSprite.draw_Animation_Frame(ref cSpriteData);
                            bmpFrame.Save(strFilename);
                        }
                        cSpriteData.cAnimationData.intFrameIndex = 0;
                    }
                }
            }
        }

        /// <summary>
        /// allows the user to load a background to be displayed in the main picturebox during sprite/animation editing
        /// </summary>
        private void mnuBackground_Load_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "image files (*.bmp)|*.bmp|All files (*.*)|*.*";
            ofd.Title = "Load background image";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    sBackground = new MemoryStream(File.ReadAllBytes(ofd.FileName));
                    bmpBackground = (Bitmap)Bitmap.FromStream(sBackground);

                    Draw_Sprite();
                }
                catch (Exception err)
                {
                    MessageBox.Show("There was an error loading background file : " + err.Message);
                }
            }
        }




        /// <summary>
        /// clears the background image from the screen
        /// </summary>
        private void mnuBackground_Clear_Click(object sender, EventArgs e)
        {

            bmpBackground = null;
            Draw_Sprite();
        }

        /// <summary>
        /// writes a string of text usable as a viable enumerated type declaration then saves this string onto the Windows Clipboard
        /// </summary>
        private void mnuAnimation_CopyEnu_Click(object sender, EventArgs e)
        {
            string strEnuAnimation = "enum enu" + cSpriteData.cAnimationData.cSprite.Name + "_Animations { ";
            for (int intAnimationCounter = 0; intAnimationCounter < cSpriteData.cAnimationData.cSprite.lstAnimations.Count; intAnimationCounter++)
            {
                strEnuAnimation += "\r\n\t\t\t" + cSpriteData.cAnimationData.cSprite.lstAnimations[intAnimationCounter].Name + ",";
            }
            strEnuAnimation += "\r\n\t\t\t" + " _numAnimations };";

            Clipboard.SetText(strEnuAnimation, TextDataFormat.Text);
        }

        /// <summary>
        /// launches the panelImageController
        /// </summary>
        private void mnuImageController_Click(object sender, EventArgs e)
        {
            pnlLimb_ImageController.Limb = cLimb;
            pnlLimb_ImageController.Show();
        }

        /// <summary>
        /// generates a string of text usable as a viable enumerated type declaration then saves this string onto the Windows Clipboard
        /// </summary>
        private void mnuLimbs_CopyEnuLimbsToClipboard_Click(object sender, EventArgs e)
        {
            List<classSprite_Limb> lstLimbs = cSpriteData.cAnimationData.cSprite.cCostumeInfo_Default.lstLimbs;
            string strLimbs = "enum enu"
                                + cSpriteData.cAnimationData.cSprite.Name
                                + "_Limbs"
                                + "\r\n\t{";
            for (int intLimbCounter = 0; intLimbCounter < lstLimbs.Count; intLimbCounter++)
            {
                strLimbs += "\r\n\t\t"
                            + lstLimbs[intLimbCounter].Name
                            + ",\t\t\t//" + intLimbCounter.ToString() ;
            }
            strLimbs += "\r\n\t\t_num"
                        + cSpriteData.cAnimationData.cSprite.Name
                        + "Limbs"
                        + "\r\n\t};";
            Clipboard.SetText(strLimbs);
        }


        public void Costumes_MatchDefault()
        {
            classSprite cSprite = cSpriteData.cAnimationData.cSprite;
            for (int intCostumeCounter = 0; intCostumeCounter < cSpriteData.cAnimationData.cSprite.lstCostumeInfo.Count; intCostumeCounter++)
            {
                classSprite_CostumeInfo cCostume = cSpriteData.cAnimationData.cSprite.lstCostumeInfo[intCostumeCounter];
                if (cCostume != cSprite.cCostumeInfo_Default)
                    cCostume.MatchDefault(ref cSprite);
            }
        }

    }

   
}
