using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;

public class FileHelper
{
    //Private dirSourceDest As Dictionary(Of FileInfo, DirectoryInfo)
    private int filesPerFolder;
    private string suffix;
    private int counterSize;
    private int numerationType;
    private string filter;
    private bool separateFiles;

    private string extensions = "*.jpg,*.png,*.gif";

    public enum numerazione
    {
        Progressiva,
        Files
    }
    /// <summary>
    /// Preparazione per la separazione
    /// </summary>
    /// <param name="filesPerFolder"></param>
    /// <param name="suffix"></param>
    /// <param name="counterSize"></param>
    /// <param name="numerationType"></param>
    /// <remarks></remarks>
    public FileHelper(int filesPerFolder, string suffix, int counterSize, int numerationType)
    {
        this.filesPerFolder = filesPerFolder;
        this.suffix = suffix;
        this.counterSize = counterSize;
        this.numerationType = numerationType;
        this.separateFiles = true;
    }

    /// <summary>
    /// nessuna separazione
    /// </summary>
    /// <remarks></remarks>
    public FileHelper()
    {
        this.separateFiles = false;
    }


    public Dictionary<FileInfo, DirectoryInfo> GetFilesRecursive(DirectoryInfo root, DirectoryInfo destRoot, string filter)
    {
        Dictionary<FileInfo, DirectoryInfo> dirSourceDest = new Dictionary<FileInfo, DirectoryInfo>();
        List<FileInfo> result = new List<FileInfo>();

        //Dim stack As New Stack(Of DirectoryInfo)
        Stack<KeyValuePair<DirectoryInfo, DirectoryInfo>> stack = new Stack<KeyValuePair<DirectoryInfo, DirectoryInfo>>();


        this.filter = filter;
        KeyValuePair<DirectoryInfo, DirectoryInfo> pair = new KeyValuePair<DirectoryInfo, DirectoryInfo>();


        //stack.Push(root)
        stack.Push(new KeyValuePair<DirectoryInfo, DirectoryInfo>(root, destRoot));

        while ((stack.Count > 0))
        {
            KeyValuePair<DirectoryInfo, DirectoryInfo> curDirKV = stack.Pop();
            //curDirKP = stack.Pop()
            DirectoryInfo dir = curDirKV.Key;
            DirectoryInfo dDir = curDirKV.Value;
            try
            {
                //result.AddRange(dir.GetFiles(filter, SearchOption.TopDirectoryOnly))
                // dividere file qui
                if (filesPerFolder > 0 & separateFiles)
                {
                    appendDictionary(dirSourceDest, dividiFilesInDir(dir, dDir));
                }
                else
                {
                    appendDictionary(dirSourceDest, getAllFilesInDir(dir, dDir));
                }



                foreach (DirectoryInfo subDirectory in dir.GetDirectories())
                {
                    stack.Push(new KeyValuePair<DirectoryInfo, DirectoryInfo>(subDirectory, new DirectoryInfo(Path.Combine(dDir.FullName, subDirectory.Name))));

                }

            }
            catch (Exception ex)
            {
            }
        }

        return dirSourceDest;
    }

    public Dictionary<FileInfo, DirectoryInfo> appendDictionary(Dictionary<FileInfo, DirectoryInfo> dictA, Dictionary<FileInfo, DirectoryInfo> dictB)
    {
        foreach (KeyValuePair<FileInfo, DirectoryInfo> pair in dictB)
        {
            dictA.Add(pair.Key, pair.Value);
        }
        return dictA;
    }

    public Dictionary<FileInfo, DirectoryInfo> getAllFilesInDir(DirectoryInfo dir, DirectoryInfo dirDest)
    {
        Dictionary<FileInfo, DirectoryInfo> dict = new Dictionary<FileInfo, DirectoryInfo>();
        foreach (FileInfo File in dir.GetFiles(filter))
        {
            dict.Add(File, new DirectoryInfo(Path.Combine(dirDest.FullName, File.Name)));

        }
        return dict;
    }

    private Dictionary<FileInfo, DirectoryInfo> dividiFilesInDir(DirectoryInfo dir, DirectoryInfo dirDest)
    {
        int filesCount = dir.GetFiles(filter).Length;
        int contaFilePerDir = 0;
        int contaDirPerDir = 0;
        string tempText = string.Empty;
        Dictionary<FileInfo, DirectoryInfo> foldersDict = new Dictionary<FileInfo, DirectoryInfo>();

        DirectoryInfo destDir = null;
        destDir = new DirectoryInfo(Path.Combine(dirDest.FullName));

        foreach (FileInfo file in dir.GetFiles(filter))
        {
            contaFilePerDir += 1;

            if (contaFilePerDir == (contaDirPerDir * filesPerFolder) + 1)
            {
                contaDirPerDir += 1;

                if (numerazione.Progressiva.Equals(numerationType))
                {
                    tempText = contaDirPerDir.ToString();
                }
                else
                {
                    tempText = (contaDirPerDir * filesPerFolder).ToString();
                }
                int i = 0;
                for (i = 1; i <= (counterSize - tempText.Length); i++)
                {
                    tempText = "0" + tempText;
                }
                destDir = new DirectoryInfo(Path.Combine(dirDest.FullName, suffix + tempText));



            }

            if (!destDir.Exists)
            {
                destDir.Create();
            }

            foldersDict.Add(file, destDir);
        }

        return foldersDict;
    }
}