private static string[] TagBasedNaming(WallpaperData.ImageData[] imagesToRename, DirectoryInfo moveDirectory) { //! NOTE: THIS ONLY HANDLES TAGGED IMAGES | UNTAGGED OR UNNAMABLE IMAGES WILL HAVE TO BE HANDLED IN A SECOND SET Dictionary <string, Dictionary <string, HashSet <WallpaperData.ImageData> > > desiredNames = GetDesiredNames(imagesToRename, moveDirectory); //! Get extensions and names of images that aren't being touched using FileInfo, not //! Images that already exist, regardless of whether or not they are in the process of being renamed, cannot be touched //! If you were to rename an entire group of images with the same name, they'd have to be renamed twice to get the proper numbering in place //? Note that if a move directory was present, only one directory will be scanned // no need to group if there's only 1 image // not keeping this as a static option allows for more flexibility in when you want to keep a set of images together or not worry about that at all bool groupRenamedImages = imagesToRename.Length > 1 && MessageBox.Show("Group renamed images?", "Choose an option", MessageBoxButtons.YesNo) == DialogResult.Yes; Debug.WriteLine("Grouping: " + groupRenamedImages); List <string> finalNames = new List <string>(); foreach (string directory in desiredNames.Keys) { Debug.WriteLine("\n\n\nDirectory:\n" + directory); FileInfo[] directoryFiles = new DirectoryInfo(directory).GetFiles(); HashSet <string> filePaths = new HashSet <string>(); foreach (FileInfo file in directoryFiles) { string fileName = file.FullName; filePaths.Add(fileName.Substring(0, fileName.IndexOf(file.Extension, StringComparison.Ordinal)).ToLower()); } foreach (string name in desiredNames[directory].Keys) { int nameCount = 1; // image counts don't start at 0 bool canName = false; string directoryPath = directory + "\\"; string countlessName = directoryPath + name; string startingName = countlessName + nameCount; Debug.WriteLine("\nStarting Name: " + startingName); // This process will repeat until a group-able section is found (or none at all if groupRenamedImages is set to false) while (!canName) { // Finds the next possible starting name // There is no way to skip counting this 1 by 1 without *assuming* that all concurrent values of this name have been filled while (filePaths.Contains(startingName.ToLower())) { nameCount++; startingName = countlessName + nameCount; Debug.WriteLine("Updating Starting Name: " + startingName); } Debug.WriteLine("Checkpoint Starting Name: " + startingName); // Checks for the next fully available space // Ensures that a group of images can be renamed together canName = true; if (groupRenamedImages) { for (int i = 0; i < desiredNames[directory][name].Count; i++) { string testName = countlessName + (nameCount + i); if (filePaths.Contains(testName.ToLower())) //! Note: nameCount should only change if the process fails to update the position { Debug.WriteLine("Grouping Failed At: " + testName); nameCount += i + 1; // sets the count to the next possibly valid position canName = false; break; } } } } Debug.WriteLine("Final Starting Name: " + startingName); foreach (WallpaperData.ImageData image in desiredNames[directory][name]) { string oldPath = image.Path; string newPathWithoutExtension = countlessName + nameCount; // last call for conflicts | if the images aren't grouped this is expected, if not then there was an unexpected issue while (filePaths.Contains(newPathWithoutExtension.ToLower())) { nameCount++; newPathWithoutExtension = countlessName + nameCount; } string extension = new FileInfo(image.Path).Extension; string newPath = newPathWithoutExtension + extension; Debug.WriteLine("Setting Name: " + newPath); nameCount++; if (UpdateImagePath(oldPath, newPath, image)) { finalNames.Add(newPath); } else { finalNames.Add(oldPath); } } } } WallpaperData.SaveData(WallpaperPathing.ActiveWallpaperTheme); //! Forgetting to save after renaming images could destroy a theme depending on the scale return(finalNames.ToArray()); }