//Making a new set basically just entails creating a new directory from a name provided from a dialog box
        //then add this new directory to the list of sets
        private void BTN_Add_Set_Click(object sender, RoutedEventArgs e)
        {
            //First off we need a dialog to know what to call the new set, and hence the directory to put it in
            InputDialog input = new InputDialog("New Set Name?");

            if (input.ShowDialog() == true)
            {
                //Assuming they give a proper responce and didnt cancel we can use the value given as the
                //name of the new directory for the set
                //TODO make it so Set_Directory is available everywhere in the window
                const string Set_Directory     = @".\Sets";
                string       New_Set_Directory = Set_Directory + $@"\{input.Answer()}";
                //This new folder will be a subdirectory of the Set_Directory
                //We need to make sure we only make the directory if it does not already exist
                if (!Directory.Exists(New_Set_Directory))
                {
                    Directory.CreateDirectory(New_Set_Directory);
                    //Now we have the directory path all setup, we can use that to
                    //make the combobox item that will hold all this information
                    CMB_Set_Selector.Items.Add(Static_Methods_Container.Generate_Set_Item(New_Set_Directory));
                }
                else
                {
                    //Show an error saying that a folder by that name already exists
                    MessageBox.Show("Error: A folder by that name already exists! No new folder has been created.", "Folder Already Exists!", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
        }
 //This produces a cropped image of the currently selected card and makes it the source for the preview image item
 //on the screen
 private void BTN_Preview_Card_Click(object sender, RoutedEventArgs e)
 {
     //This should only work if there is a valid card selected
     if ((ComboBoxItem)CMB_Card_Selector.SelectedItem != null && (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag != null)
     {
         //Make sure the cards are all as up to date as possible
         Static_Methods_Container.Update_Current_Card(this);
         //and that changes wont be lost
         Set_Info info = (Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag);
         Functions.Save_Set(info.cards);
         //First step is to dispose of the existing bitmap source if any in the preview window
         IMG_Card_Preview.Source = null;
         //then from the selected card generate a cropped image from the card selected
         Card        c = (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag;
         BitmapImage i;
         //now make a new image source with standard boxes
         using (Bitmap b = Card.Generate_Cropped_Image(c, "PREVIEW", @".\Overlays\Overlay.png"))
         {
             using (MemoryStream mem = new MemoryStream())
             {
                 //save the bitmap to the stream for use of the image
                 b.Save(mem, System.Drawing.Imaging.ImageFormat.Bmp);
                 mem.Position = 0;
                 BitmapImage image = new BitmapImage();
                 image.BeginInit();
                 image.StreamSource = mem;
                 image.CacheOption  = BitmapCacheOption.OnLoad;
                 image.EndInit();
                 i = image;
             }
         }
         IMG_Card_Preview.Source = i;
     }
 }
        private void BTN_Delete_Card_Click(object sender, RoutedEventArgs e)
        {
            //This does basically the same thing to a card as Delete_Set does to a whole set
            //We need to ensure this is something the user wishes to do
            InputDialog input = new InputDialog("Are You Sure You Want To Delete This Card?\nThis Action Cannot Be Undone!\n(y/n)");

            if (input.ShowDialog() == true)
            {
                if (input.Answer().ToLower() == "y" && CMB_Card_Selector.SelectedItem != null)
                {
                    Static_Methods_Container.Clear_Text_Boxes(this);
                    //First we will need the card object out of the selected item
                    Card target = (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag;
                    //This card contains the fileinfo we can use to delete the file
                    FileInfo info = target.Text_File;
                    if (info.Exists)
                    {
                        info.Delete();
                    }
                    //We then remove the selected card from the selected sets list
                    //First we need to extract the list of cards from the selected set to remove from
                    List <Card> current_set = ((Set_Info)((ComboBoxItem)CMB_Set_Selector.SelectedItem).Tag).cards;
                    //Remove the target card from this list
                    current_set.Remove(target);
                    //Lastly Delete the entry on the combo box since it references nothing
                    CMB_Card_Selector.Items.RemoveAt(CMB_Card_Selector.SelectedIndex);
                }
            }
        }
 //This will take the currently selected set, update the current card and generate a set of full bleed sized cards
 //To a path specified by the user
 private void BTN_Export_Bleed_Set_Click(object sender, RoutedEventArgs e)
 {
     //TODO double check this method
     //first of all we need to only do this is there is a set selected and its tag is not null
     if ((ComboBoxItem)CMB_Set_Selector.SelectedItem != null && (Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag) != null)
     {
         //Make sure the cards are all as up to date as possible
         Static_Methods_Container.Update_Current_Card(this);
         //and that changes wont be lost
         Set_Info info = (Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag);
         Functions.Save_Set(info.cards);
         string set_code = "";
         //First of all we need the code used to identify the set in the corner
         InputDialog input = new InputDialog("Please Enter Set Identifier.\nIn form xxxx where 'x' is a letter or number!");
         if (input.ShowDialog() == true)
         {
             //We obviously only continue if they dont cancel the dialog
             set_code = input.Answer();
             //we also need to pick the overlay boxes we are using
             //we need the list of cards out of selected item
             List <Card> set = ((Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag)).cards;
             //we also need to make a bleed folder for the images if they dont exist
             string Bleed_Directory = ((Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag)).dir + @"\Bleed";
             Directory.CreateDirectory(Bleed_Directory);
             //we also need an overlay to use, user can pick but just in case have a default selected
             string overlay = Card.DEFAULT_OVERLAY;
             //but give the user a choice
             OpenFileDialog dialog = new OpenFileDialog();
             //set a file filter
             dialog.Filter = "Image Files (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp|All Files (*.*)|*.*";
             //and make sure it opens wherever the program is for access to the overlays folder
             dialog.InitialDirectory = $@"{Directory.GetCurrentDirectory()}\Overlays";
             if (dialog.ShowDialog() == true)
             {
                 //if they selected one set it as the new overlay
                 overlay = dialog.FileName;
             }
             //now for sake of efficiency we will generate and save the cards in a parrallel fashion
             //The limit of 12 concurrent tasks is mostly to avoid out of memory issues since in a stress
             //situation each iteration can use up to a gig of memory each so not bounding how many
             //could cause some problems, this still will on lower end systems but shouldn't be an issue
             //if you arent throwing massive images at it constantly
             Parallel.ForEach(set, new ParallelOptions {
                 MaxDegreeOfParallelism = 12
             }, c =>
             {
                 using (Bitmap b = Card.Generate_Bleed_Image(c, set_code, overlay))
                 {
                     //The encoder needs some set up to function properly
                     string s        = string.Format("{0:00000}", c.Index);
                     string filepath = $@"{Bleed_Directory}\{set_code}-{s}-Bleed.png";
                     b.Save(filepath, ImageFormat.Png);
                 }
             });
         }
     }
 }
 //This will remove the currently selected ability (if any) and then update the current card to remind it that it has one less ability
 private void BTN_Delete_Ability_Click(object sender, RoutedEventArgs e)
 {
     //This will delete the currently selected listview item if any and removes it
     if (LIV_Abilities.SelectedIndex >= 0 && LIV_Abilities.SelectedItems != null)
     {
         LIV_Abilities.Items.RemoveAt(LIV_Abilities.SelectedIndex);
     }
     //And update the card just for good measure
     Static_Methods_Container.Update_Current_Card(this);
 }
 private void CMB_Card_Selector_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
     //First we need to clear the textboxes
     Static_Methods_Container.Clear_Text_Boxes(this);
     //and then if the new selection has a functional Card in the tag update the textboxes with this new data
     if (CMB_Card_Selector.SelectedItem != null && (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag != null)
     {
         //Fill the textboxes
         Card card = (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag;
         Static_Methods_Container.Populate_Text_Boxes(this, card);
     }
 }
 private void BTN_Save_Card_Click(object sender, RoutedEventArgs e)
 {
     //This will save the individual card being worked on
     //First we update the current card so we save the up to date information
     Static_Methods_Container.Update_Current_Card(this);
     //Now ensuring we have a valid card to do this to save it to its associated file
     if ((ComboBoxItem)CMB_Card_Selector.SelectedItem != null && (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag != null)
     {
         Card c = (Card)((ComboBoxItem)CMB_Card_Selector.SelectedItem).Tag;
         Functions.Save_Card(c);
     }
 }
        //This Will Add A New Card To the Currently Selected Set
        private void BTN_Add_Card_Click(object sender, RoutedEventArgs e)
        {
            //First off we need the name of file to write this to
            InputDialog input = new InputDialog("Name Of File To Save New Card To!");

            if (input.ShowDialog() == true)
            {
                //Also need to make sure an actual set is selected to add the card to
                if (CMB_Set_Selector.SelectedItem != null)
                {
                    //The final name of the file
                    string New_File = input.Answer();
                    //sanitise the string so as not to crash the program
                    string regexSearch = new string(System.IO.Path.GetInvalidFileNameChars()) + new string(System.IO.Path.GetInvalidPathChars());
                    Regex  r           = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
                    //this removes invalid characters from the file name
                    New_File = r.Replace(New_File, "");
                    //Now we need to get the directory to put it in from the selected set
                    string directory = ((Set_Info)((ComboBoxItem)CMB_Set_Selector.SelectedItem).Tag).dir;
                    //Now make this described file and make a file info of it
                    FileInfo file = new FileInfo(directory + $@"\{New_File}.txt");
                    //Only create the file if there isn't an existing file by that name in the directory
                    if (!File.Exists(file.FullName))
                    {
                        //Actually create the file , making sure to close the filestream it leaves behind
                        file.Create().Close();
                        //the set we will be adding cards to
                        List <Card> set = ((Set_Info)((ComboBoxItem)CMB_Set_Selector.SelectedItem).Tag).cards;
                        //now make a card from the file, creating the file in the process
                        //we also need to give the card the index , which will be whatever the lists length is
                        //since indexing starts at 0
                        int  index = set.Count;
                        Card c     = Card.Generate_Card_From_File(file, index);
                        //Also give the card a generic name and title so it doesnt show up
                        //as a blank entry on the drop down
                        c.Name  = "New";
                        c.Title = "Card";
                        //We now add this card to the list of the current set
                        set.Add(c);
                        //And then append the card to the combobox
                        CMB_Card_Selector.Items.Add(Static_Methods_Container.Generate_Card_Item(c));
                    }
                    else
                    {
                        //If the file already exists dont make a new one, you will just end up fighting over access
                        //Show an error saying that a file by that name already exists
                        MessageBox.Show("Error: A file by that name already exists! No new file has been created.", "Folder Already Exists!", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }
            }
        }
        //This will add a new textbox to the list of abilities, with the correct formatting
        private void BTN_Add_Ability_Click(object sender, RoutedEventArgs e)
        {
            //First we need a new listviewitem and textbox to add to the list
            ListViewItem item = new ListViewItem();
            TextBox      box  = new TextBox();

            //now fill the box with the correct placeholder
            box.Text = Card.ABILITY_FORMAT;
            //fill the list item with the textbox and add it to the list
            item.Content = box;
            LIV_Abilities.Items.Add(item);
            //now update the current card to inform it that it has a new ability
            Static_Methods_Container.Update_Current_Card(this);
        }
 private void BTN_Save_Set_Click(object sender, RoutedEventArgs e)
 {
     //This saves the entire set of cards currently selected into their respective text files
     //First we need to make sure the current card is as up do date as can be
     Static_Methods_Container.Update_Current_Card(this);
     //Now it's simply a matter of extracting the list of currently selected cards from the set_info of the selected set
     //Obviously assuming its selected and it has an existant set_info
     if ((ComboBoxItem)(CMB_Set_Selector.SelectedItem) != null && (Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag) != null)
     {
         //Now we know it's safe to do so extract this set info and pass it as a directory to save all the cards
         Set_Info info = (Set_Info)(((ComboBoxItem)(CMB_Set_Selector.SelectedItem)).Tag);
         Functions.Save_Set(info.cards);
     }
 }
 private void CMB_Set_Selector_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
     //When the set drop down gets changed, the card list needs to be updated to represent the new set selected
     //Start by changing the selected Card in the combo box to an empty box
     CMB_Card_Selector.SelectedIndex = -1;
     //Empty The Text Boxes of any content
     Static_Methods_Container.Clear_Text_Boxes(this);
     //And Empty the card list
     CMB_Card_Selector.Items.Clear();
     //get the set from the selected item if they exist
     if (CMB_Set_Selector.SelectedItem != null && (Set_Info)((ComboBoxItem)CMB_Set_Selector.SelectedItem).Tag != null)
     {
         ComboBoxItem New_Selection = (ComboBoxItem)CMB_Set_Selector.SelectedItem;
         List <Card>  cards         = ((Set_Info)(New_Selection.Tag)).cards;
         //and repopulate the card drop down with those cards
         Static_Methods_Container.Populate_Card_List(this, cards);
     }
 }
        //Same as above but for the path to the artwork
        private void BTN_Art_Path_Finder_Click(object sender, RoutedEventArgs e)
        {
            //First we need an open file dialog to select the file from
            OpenFileDialog dialog = new OpenFileDialog();

            //Note, I'd set a relative file path but the file dialog wont accept a relative file path, so wherever it opens
            //is fine
            //And set it to filter just the image file formats we want
            //in this case .pngs or .jpgs, or failing that, basically anything although results may vary
            dialog.Filter = "Image Files (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp|All Files (*.*)|*.*";
            //now assuming the user doesn't cancel the file selection
            if (dialog.ShowDialog() == true)
            {
                //set the artists signature path as the path to the selected file
                string Absolute_Path = dialog.FileName;
                TBX_Artwork_Path.Text = Absolute_Path;
            }
            //and now all that is done update the current card
            Static_Methods_Container.Update_Current_Card(this);
        }
        private void BTN_Delete_Set_Click(object sender, RoutedEventArgs e)
        {
            //This will target and delete the directory of the selected item assuming a prompt is passed
            InputDialog input = new InputDialog("Are You Sure You Want To Delete The Selected Set?\nThis Action Cannot Be Undone!\n(y/n)");

            if (input.ShowDialog() == true)
            {
                if (input.Answer().ToLower() == "y" && CMB_Set_Selector.SelectedItem != null)
                {
                    //Can't delete what doesnt exist obviously
                    Static_Methods_Container.Clear_Text_Boxes(this);
                    CMB_Card_Selector.SelectedIndex = -1;
                    CMB_Card_Selector.Items.Clear();
                    //We need to get the directory from the currently selected set
                    Set_Info info = (Set_Info)((ComboBoxItem)CMB_Set_Selector.SelectedItem).Tag;
                    //And use the directory to delete the whole directory
                    //the true at the end indicates recursive delete so as to delete contents as well
                    Directory.Delete(info.dir, true);
                    //Lastly we Remove the currently selected item from the list since it holds nothing anymore
                    CMB_Set_Selector.Items.RemoveAt(CMB_Set_Selector.SelectedIndex);
                }
            }
        }
 //When the window is loaded little actually needs to be done, just populate the list of sets that are in the sets folder
 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     //The set list needs to be populated on startup
     Static_Methods_Container.Populate_Set_List(this);
 }