// Partical File Form1.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.IO;

using System.Drawing.Drawing2D;

using System.Diagnostics;

 

namespace FS_watch

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

            tb_path.Text = Directory.GetCurrentDirectory();

            this.MinimumSize = new System.Drawing.Size(732, 387);

            Control[] cont = { tb_path, bt_search, bt_update, combo, listBox1, bt_expand, bt_open_par, bt_hide, bt_open_explorer, bt_explore_par, lb1 };

            for (int i = 0; i < cont.Length; i++)

                cont[i].TabIndex = i;

            combo.Items.AddRange(new string[] { "Name", "Folders", "Files", "Sizes" });

            combo.SelectedIndex = 0;

            combo.SelectedIndexChanged += delegate(object sender, EventArgs e)

            {

                view();

            };

 

 

            bool inwork = false;

            ListBox[] lbs = { listBox1, listBox2, listBox3, listBox4 };

            for (int i = 0; i < lbs.Length; i++)

                lbs[i].SelectedIndexChanged += delegate(object sender, EventArgs e)

                {

                    if (!inwork)

                    {

                        inwork = true;

                        int ii = -1;

                        for (int j = 0; j < lbs.Length; j++)

                            if (lbs[j] == sender)

                            {

                                ii = j;

                                break;

                            }

                        for (int j = 0; j < lbs.Length; j++)

                            if (j != ii)

                            {

                                lbs[j].SelectedIndex = lbs[ii].SelectedIndex;

                                lbs[j].TopIndex = lbs[ii].TopIndex;

                            }

                        inwork = false;

                    }

                };

        }

 

 

        string[] names;

        long[] folders, files, sizes;

        DirectoryInfo[] children;

 

        private void bt_update_Click(object sender, EventArgs e)

        {

            if (!new fs_search().search(tb_path.Text, out names, out folders, out files, out sizes, out children))

                return;

           

            view();

 

            create_lb();

        }

        private void bt_search_Click(object sender, EventArgs e)

        {

            FolderBrowserDialog fbd = new FolderBrowserDialog();

            if (fbd.ShowDialog()!=DialogResult.OK)

                return;

            tb_path.Text = fbd.SelectedPath;

            bt_update.PerformClick();

        }

        void create_lb()

        {

            listBox1.Items.Clear();

            listBox2.Items.Clear();

            listBox3.Items.Clear();

            listBox4.Items.Clear();

            for (int i = 0; i < names.Length; i++)

                    for (int j = 0; j < names.Length; j++)

                        if (j == map[i])

                        {

                            listBox1.Items.Add(names[i]);

                            write2lb(listBox2, folders[i].ToString("#,0"), 9);

                            write2lb(listBox3, files[i].ToString("#,0"), 9);

                            write2lb(listBox4, sizes[i].ToString("#,0"), 19);

                        }

 

            long[] n = new long[3];

            for (int i = 0; i < names.Length; i++)

            {

                n[0] += folders[i];

                n[1] += files[i];

                n[2] += sizes[i];

            }

            lb1.Text = names.Length.ToString("#,0");

            lb2.Text = n[0].ToString("#,0");

            lb3.Text = n[1].ToString("#,0");

            lb4.Text = n[2].ToString("#,0")+ " B";

 

        }

        void write2lb(ListBox lb, string cont, int place)

        {

            string val = "";

            if (cont.Length < place)

                for (int i = 0; i < place - cont.Length; i++)

                    val += " ";

            val += cont;

            lb.Items.Add(val);

        }

 

        dia d = null;

        long[] parts = null;

 

        int[] map = null;

        void view()

        {

            int sel = combo.SelectedIndex;

            if (!(sel != -1 && names != null && names.Length != 0))

                return;

 

            map = new int[names.Length];

            for (int i = 0; i < names.Length; i++)

                map[i] = i;

 

            if (sel != 0)

            {

                long[] key = new long[names.Length];

                if (sel == 1)

                    Array.Copy(folders, key, names.Length);

                if (sel == 2)

                    Array.Copy(files, key, names.Length);

                if (sel == 3)

                    Array.Copy(sizes, key, names.Length);

 

                for (int i = 0; i < names.Length - 1; i++)

                    for (int j = 0; j < names.Length - 1; j++)

                        if (key[j] > key[j + 1])

                        {

                            key[j] += key[j + 1];

                            key[j + 1] = key[j] - key[j + 1];

                            key[j] -= key[j + 1];

 

                            map[j] += map[j + 1];

                            map[j + 1] = map[j] - map[j + 1];

                            map[j] -= map[j + 1];

                        }

 

            }

            parts = new long[names.Length];

 

            for (int i = 0; i < parts.Length; i++)

            {

                int ii = map[i];

                switch (sel)

                {

                    case 0: parts[i] = 1; break;

                    case 1: parts[i] = folders[ii]; break;

                    case 2: parts[i] = files[ii]; break;

                    case 3: parts[i] = sizes[ii]; break;

                }

            }

            for (int i = 0; i < parts.Length; i++)

                parts[i]++;

 

 

            if (d != null)

                d.Dispose();

 

            d = new dia(this, parts);

            d.Size = new Size(200, 200);

            d.Location = new Point(12, 81);

            d.Parent = this;

 

           

        }

 

 

        public void fk()

        {

            if (hide_next)

            {

                for (int i = 0; i < names.Length; i++)

                    if (i == map[d.get_i_click()])

                    {

                        rem(i);

                        return;

                    }

            }

            for (int i = 0; i < names.Length; i++)

                if (i == map[d.get_i_click()])

                    listBox1.SelectedIndex = i;

        }

 

        bool hide_next = false;

        private void bt_hide_Click(object sender, EventArgs e)

        {

            hide_next = !hide_next;

            bt_hide.BackColor = hide_next ? Color.Green : Color.FromArgb(0, 240, 240, 240);

 

        }

 

        private void lb_SelectedIndexChanged(object sender, EventArgs e)

        {

            if (hide_next)

                rem(listBox1.SelectedIndex);

        }

 

        void rem(int ii)

        {

            string[] x = new string[names.Length - 1];

            long[][] y = new long[3][];

            for (int i = 0; i < y.Length; i++)

                y[i] = new long[names.Length - 1];

            for (int i = 0; i < ii; i++)

            {

                x[i] = names[i];

                y[0][i] = folders[i];

                y[1][i] = files[i];

                y[2][i] = sizes[i];

            }

            for (int i = ii + 1; i < names.Length; i++)

            {

                x[i - 1] = names[i];

                y[0][i - 1] = folders[i];

                y[1][i - 1] = files[i];

                y[2][i - 1] = sizes[i];

            }

 

            names = x;

            folders = y[0];

            files = y[1];

            sizes = y[2];

 

            bt_hide.PerformClick();

 

            view();

            create_lb();

        }

 

        private void bt_open_explorer_Click(object sender, EventArgs e)

        {

            if (listBox1.SelectedIndex != -1)

                Process.Start("explorer.exe", children[listBox1.SelectedIndex].FullName);

        }

 

        private void bt_explore_par_Click(object sender, EventArgs e)

        {

            for (int i = children[0].FullName.Length - 2; i > 0; i--)

                if (children[0].FullName[i] == '\\')

                {

                    Process.Start("explorer.exe", children[0].FullName.Substring(0, i));

                    break;

                }

        }

 

       

 

 

 

    }

    public class dia : Panel

    {

        Form1 ff;

        int max;

        public dia(Form1 ff, long[] parts, int max = 0)

        {

            this.ff = ff;

            this.parts = parts;

            this.max = max;

        }

 

        Panel[] pa = null;

        long[] parts = null;

        protected override void CreateHandle()

        {

            base.CreateHandle();

 

 

 

            //Array.Sort(parts);

            double full = 0;

            foreach (double one in parts)

                full += one;

 

            pa = new Panel[parts.Length];

 

            Point start = new Point(r, 0);

            Point center = new Point(r, r);

            Point p = start;

            for (int i = 0; i < pa.Length; i++)

            {

                pa[i] = new Panel();

 

                using (var gp = new GraphicsPath())

                {

                    bool state = true;

                    if (state)

                        gp.AddLine(center, p);

                    Point old = p;

                    double alpha, begin;

 

                    double sum = 0;

                    for (int j = 0; j < i; j++)

                        sum += parts[j];

                    get_p(sum, full, out begin);

                    p = get_p(parts[i] + sum, full, out alpha);

                    get_p(parts[i], full, out alpha);

 

                    if (!state || true)

                        gp.AddArc(0, 0, 2 * r, 2 * r, (float)begin - 90, (float)alpha);

                    if (!state)

                        gp.AddLine(old, p);

                    if (state)

                        gp.AddLine(p, center);

 

                    pa[i].Size = new Size(r * 2, r * 2);

                    pa[i].Region = new Region(gp);

                }

                System.Threading.Thread.Sleep(1);

 

 

                int range = max;

                Color c1 = Color.Pink;

                Color c2 = Color.FromArgb(255, 0, 176, 240);

 

                double[] part = { c1.R - c2.R, c1.G - c2.G, c1.B - c2.B };

                for (int j = 0; j < part.Length; j++)

                    part[j] /= range;

                int val = (int)parts[i];

                pa[i].BackColor = Color.FromArgb(255, (byte)(c1.R - part[0] * val), (byte)(c1.G - part[1] * val), (byte)(c1.B - part[2] * val));

 

                bool found;

                do

                {

                    found = false;

                    Random ra = new Random();

                    pa[i].BackColor = Color.FromArgb(255, ra.Next(255), ra.Next(255), ra.Next(255));

                    for (int j = 0; j < i; j++)

                        if (pa[j].BackColor == pa[i].BackColor)

                            found = true;

                }

                while (found);

                pa[i].Click += dia_Click;

                pa[i].Parent = this;

            }

        }

        int i_click = -1;

        void dia_Click(object sender, EventArgs e)

        {

            for (int i = 0; i < pa.Length; i++)

                if (sender == pa[i])

                {

                    i_click = i;

                    break;

                }

            ff.fk();

        }

        public int get_i_click()

        {

            return i_click;

 

        }

        int r = 100;

        Point get_p(double part, double full, out double alpha)

        {

            alpha = part * 360 / full;

            double rad = Math.PI * alpha / 180;

            return new Point((int)(Math.Sin(rad) * r) + r, r - (int)(Math.Cos(rad) * r));

        }

 

 

 

 

    }

}

 

 

 

 

// File fs_search.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.IO;

using System.Windows.Forms;

 

namespace FS_watch

{

    public class fs_search

    {

 

        List<int> verz = new List<int>();

        int verz_i = -1;

        public bool search(string path, out string[] names, out  long[] folders, out long[] files, out      long[] sizes, out DirectoryInfo[] children)

        {

            names = null;

            folders = null;

            files = null;

            sizes = null;

            children = null;

 

            verz = new List<int>();

            verz_i = -1;

 

 

            if (!Directory.Exists(path))

            {

                MessageBox.Show("Path does not exist!");

                return false;

 

            }

 

 

            children = new DirectoryInfo(path).GetDirectories();

            names = new string[children.Length];

            folders = new long[children.Length];

            files = new long[children.Length];

            sizes = new long[children.Length];

 

            for (int c = 0; c < children.Length; c++)

            {

                DirectoryInfo di = children[c];

                names[c] = di.Name;

                int n_folders = 0, n_files = 0;

                long size = 0;

                get_files(di, ref n_files, ref size);

                bool goon = true;

 

                do

                {

                    DirectoryInfo[] down = di.GetDirectories();

                    if (down.Length == 0)

                        if (verz_i == -1)

                            goon = false;

                        else

                            goon = godown_or_go_back(ref di, ref n_folders, ref n_files, ref size);

                    else

                    {

                        DirectoryInfo backup = di;

                        try

                        {

                            di = down[0];

                            n_folders++;

                            get_files(di, ref n_files, ref size);

                        }

                        catch

                        {

                            MessageBox.Show("Error @ " + backup.FullName);

                            return false;

                        }

                        verz_i++;

                        if (verz_i == verz.Count)

                            verz.Add(0);

                        else

                            verz[verz_i] = 0;

                    }

                }

                while (goon);

 

                folders[c] = n_folders;

                files[c] = n_files;

                sizes[c] = size;

            }

            return true;

 

        }

        bool godown_or_go_back(ref DirectoryInfo di, ref int n_folders, ref int n_files, ref long size)

        {

            for (; ; )

            {

                string folder = di.FullName;

                for (int i = folder.Length - 1; i > 0; i--)

                    if (folder[i] == '\\')

                    {

                        di = new DirectoryInfo(folder.Substring(0, i));

                        break;

                    }

                DirectoryInfo[] down1 = di.GetDirectories();

 

                if (down1.Length > verz[verz_i] + 1)

                {

                    n_folders++;

                    di = down1[++verz[verz_i]];

                    get_files(di, ref n_files, ref size);

                    return true;

                }

                else

                {

                    verz_i--;

                    if (verz_i == -1)

                        return false;

                }

            }

 

        }

 

        void get_files(DirectoryInfo di, ref int n_files, ref long size)

        {

            FileInfo[] fi = di.GetFiles();

            n_files += fi.Length;

            for (int i = 0; i < fi.Length; i++)

                size += fi[i].Length;

 

 

        }

    }

}