private void newListButton_Click(object sender, EventArgs e)
        {
            ModeListEditor editor = new ModeListEditor(ModeListEditors.Count);

            this.modesListsFlowPanel.Controls.Add(editor);
            ModeListEditors.Add(editor);
            Storage.sequenceData.ModeLists.Add(editor.ListModes);
            LayoutPage();
        }
        public bool RemoveModeListEditor(ModeListEditor editor)
        {
            modesListsFlowPanel.Controls.Remove(editor);
            Storage.sequenceData.RemoveModeListID(editor.ListModes.ID);
            Storage.sequenceData.ModeLists.Remove(editor.ListModes);
            bool result = ModeListEditors.Remove(editor);

            if (result)
            {
                ReassignAllEditorIDs();
            }
            LayoutPage();
            return(result);
        }
        private void pasteListButton_Click(object sender, EventArgs e)
        {
            if (CopyEditor != null)
            {
                if (ModeListEditors.Contains(CopyEditor))
                {
                    CopyEditor = new ModeListEditor(ModeListEditors.Count, CopyEditor);
                }

                this.modesListsFlowPanel.Controls.Add(CopyEditor);
                ModeListEditors.Add(CopyEditor);
                Storage.sequenceData.ModeLists.Add(CopyEditor.ListModes);
                LayoutPage();
            }
        }
        /// <summary>
        /// Sets the margins of each ModeListEditor on the flow panel, and, if necessary, attaches group labels to the flow panel.
        /// </summary>
        private void arrangeModeListEditorLocations()
        {
            //First set the spacing between each pair of editors
            int spacing = 3;

            foreach (ModeListEditor editor in ModeListEditors)
            {
                editor.Margin = new Padding(spacing);
            }

            if (sortByGroup.Checked)
            {
                //Run through the editors, and every time the group changes add a
                //label for the new group

                int    extraSpacing = 20;                                                    //Pixels between each group label and the previous editor
                String lastGroup    = ModeListEditors.First().ListModes.OrderingGroup + 'a'; //So that we will definetely add a group label for the first editor (unless that editor's group is null)
                Label  groupNameBox;                                                         //The label we will add to the flowpanel denoting the current group
                int    groupNameBoxIndex;                                                    //Will store where in the flowpanel we'll add the label

                foreach (ModeListEditor editor in ModeListEditors)
                {
                    if (editor.ListModes.OrderingGroup != lastGroup &&
                        editor.ListModes.OrderingGroup != null)
                    {
                        groupNameBox        = new Label();
                        groupNameBox.Font   = new Font("Microsoft Sans Serif", 10F, FontStyle.Bold);
                        groupNameBox.Name   = editor.ListModes.OrderingGroup + " group box";
                        groupNameBox.Size   = new Size(editor.Width, 17);
                        groupNameBox.Text   = "Group: " + editor.ListModes.OrderingGroup;
                        groupNameBox.Margin = new Padding(spacing, spacing + extraSpacing, spacing, spacing);
                        this.modesListsFlowPanel.Controls.Add(groupNameBox);
                        groupNameBoxIndex = modesListsFlowPanel.Controls.IndexOf(editor);
                        this.modesListsFlowPanel.Controls.SetChildIndex(groupNameBox, groupNameBoxIndex);
                    }
                    lastGroup = editor.ListModes.OrderingGroup;
                }
            }
        }
        /// <summary>
        /// Remove editors from the page that contain duplicate mode lists.
        /// </summary>
        private void cleanupLists_Click(object sender, EventArgs e)
        {
            //Iterate through ModeListEditors and, if any editor is found to contain a
            //duplicate mode list, then we will remove that editor
            HashSet <ModeListEditor> uniqueModeListEditors     = new HashSet <ModeListEditor>();
            HashSet <int>            duplicateEditorsPositions = new HashSet <int>();
            bool editorIsADuplicate;

            for (int i = 0; i < ModeListEditors.Count; i++)
            {
                editorIsADuplicate = false;

                foreach (ModeListEditor alreadyFoundEditor in uniqueModeListEditors)
                {
                    if (ModeList.Equivalent(alreadyFoundEditor.ListModes, ModeListEditors[i].ListModes))
                    {
                        editorIsADuplicate = true;
                        duplicateEditorsPositions.Add(i);
                        //Since we've already determined that editor is a duplicate, we
                        //needn't continue checking whether this editor is unique
                        break;
                    }
                }

                if (!editorIsADuplicate)
                {
                    uniqueModeListEditors.Add(ModeListEditors[i]);
                }
            }

            //Finally, remove the duplicate editors and layout the page again
            foreach (int ind in duplicateEditorsPositions)
            {
                ModeListEditors.RemoveAt(ind);
            }
            LayoutPage();
        }
        /// <summary>
        /// Call to create mode list editors for each mode list stored in Storage.sequenceData
        /// </summary>
        public void LayoutPage()
        {
            this.modesListsFlowPanel.SuspendLayout();

            if (sortModeLists.Checked)
            {
                OrderModeListEditors(orderModeListsMethod.SelectedItem as String);
            }

            //Remove all the ordering group labels
            foreach (Control con in modesListsFlowPanel.Controls)
            {
                if (con is Label && con.Name.EndsWith("group box"))
                {
                    modesListsFlowPanel.Controls.Remove(con);
                }
            }

            if (Storage.sequenceData != null && Storage.sequenceData.ModeLists != null)
            {
                int            diff = Storage.sequenceData.ModeLists.Count - ModeListEditors.Count;
                ModeListEditor editor;
                if (diff > 0) //we need to create more mode list editors
                {
                    for (int ind = 0; ind < diff; ind++)
                    {
                        editor = new ModeListEditor(ModeListEditors.Count);
                        modesListsFlowPanel.Controls.Add(editor);
                        ModeListEditors.Add(editor);
                    }
                }
                else if (diff < 0) //We have too many mode list editors and must remove some
                {
                    diff = Math.Abs(diff);
                    for (int ind = 0; ind < diff; ind++)
                    {
                        editor = ModeListEditors[0];
                        modesListsFlowPanel.Controls.Remove(editor);
                        editor.Dispose();
                        ModeListEditors.RemoveAt(0);
                    }
                }

                // Now that we have the correct number of editors, let's update them to
                //point at the correct mode lists
                for (int ind = 0; ind < ModeListEditors.Count; ind++)
                {
                    ModeListEditors[ind].SetModeList(Storage.sequenceData.ModeLists[ind]);
                }
            }
            else //If there are no ModeLists saved in Storage:
            {
                //Remove all of the editors from the flow panel, and empty ModeListEditors
                foreach (ModeListEditor editorToDelete in ModeListEditors)
                {
                    this.modesListsFlowPanel.Controls.Remove(editorToDelete);
                    editorToDelete.Dispose();
                }
                ModeListEditors = new List <ModeListEditor>();

                //Repopulate the flow panel and hash set with any ModeLists saved in Storage
                if (Storage.sequenceData != null)
                {
                    ModeListEditor editor;
                    foreach (ModeList list in Storage.sequenceData.ModeLists)
                    {
                        editor = new ModeListEditor(ModeListEditors.Count, list);
                        this.modesListsFlowPanel.Controls.Add(editor);
                        ModeListEditors.Add(editor);
                    }
                }
            }

            if (ModeListEditors.Count > 0)
            {
                arrangeModeListEditorLocations();
            }

            this.modesListsFlowPanel.ResumeLayout();
        }