using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using GlobalScope;

namespace GoldenEye
{
    public partial class GoldenEye : Form
    {
        public GoldenEye()
        {
            InitializeComponent();
        }

        Image _ImgImported;
        Point _DragStart = new Point(0, 0); // Point on screen
        Boolean _IsLeftMouseDrag = false;
        String _Filename;
        Double _Percentage;

        private Boolean _CalledByUpdater = false;
        private String _FileFromCommandLine = "";
        

        Color _SelectionColor = Color.OrangeRed;
        Color _SelectingColor = Color.Yellow;

        Color _ColorThresholdBar = Color.Yellow;


        Color _ColorIn = Color.Lime;
        Color _ColorOut = Color.Red;
        Color _ColorBackColor = Color.Black;
        Color _ColorAboveThreshold;
        Color _ColorBelowThreshold;


        Selection _Selection;
        Int32 _Threshold = 0;
        Int32[,] _GrayscaleValues;
        Int32[] _Occurences;


        private void GoldenEye_Load(object sender, EventArgs e)
        {
            // Center screen
            this.Location = new Point((int)Math.Round((Screen.PrimaryScreen.Bounds.Width - this.Size.Width) / 2.0), (int)Math.Round((Screen.PrimaryScreen.Bounds.Height - this.Size.Height) / 2.0));

            // Hide text
            lblPercentAbove.Text = "";
            lblSavedAs.Text = "";

            // Preset colors
            _ColorAboveThreshold = _ColorIn;
            _ColorBelowThreshold = _ColorOut;




            // Running locally?
            System.Reflection.Assembly ass = System.Reflection.Assembly.GetEntryAssembly();
            string exe = System.IO.Path.GetFullPath(ass.Location);

            if (exe.ToLower().Contains("silicium") || !exe.ToLower().Contains("c:"))
            {
                if (exe.ToLower().Contains("debug"))
                {
                    // Globals.PathToServerVersion = @"\\silicium\rel group\EMPLOYEES\WIM\Software\VrijgaveSystemen\VrijgaveSystemen\bin\Debug";
                }
                else
                {
                    MessageBox.Show("You can only run " + Globals.SoftwareDescription + " locally!", Globals.SoftwareDescription, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
            }


            // Register usage
            Globals.RegisterUser(Globals.SoftwareDescription + " (v" + Globals.BuildVersion + ")");


            #region Check for availability of update for Updater
            String updaterPathServer = Globals.PathToServerVersion + "\\" + Globals.UpdaterExeFile;
            String updaterPathLocal = Globals.CurrentDir + "\\" + Globals.UpdaterExeFile;

            if (File.Exists(updaterPathServer))
            {
                FileInfo infoServer = new FileInfo(updaterPathServer);
                FileInfo infoLocal = new FileInfo(updaterPathLocal);

                // Update if required
                if (infoLocal.LastWriteTimeUtc < infoServer.LastWriteTimeUtc)
                {
                    try
                    {
                        File.Copy(updaterPathServer, updaterPathLocal, true);
                        System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("A newer version of " + Globals.UpdaterModuleDescription + " was found on the server, but automatic update could not be executed. Please try again or update manually!\n\n" + ex.Message, "Version", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            else
            {
                MessageBox.Show("Server could not be accessed to check for version of the Updater! Please try again or update manually if necessary!", "Version", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            #endregion Check for availability of update for Updater



            #region Check for availability of update for software
            if (File.Exists(Globals.PathToServerVersion + "\\" + Globals.FileNameOfSoftware))
            {
                FileInfo infoServer = new FileInfo(Globals.PathToServerVersion + "\\" + Globals.FileNameOfSoftware);
                System.Reflection.Assembly a = System.Reflection.Assembly.GetEntryAssembly();
                string currentExe = System.IO.Path.GetFullPath(a.Location);
                FileInfo infoCurrent = new FileInfo(currentExe);

                // Update if required and if program is not called by updater
                if (infoCurrent.LastWriteTimeUtc < infoServer.LastWriteTimeUtc)
                {
                    if (_CalledByUpdater)
                    {
                        MessageBox.Show("A newer version was found on the server, but automatic update was already executed. Please try again or update manually if necessary!", "Version", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        try
                        {
                            string basedir = System.IO.Path.GetDirectoryName(a.Location);
                            string command = basedir + "\\" + Globals.UpdaterExeFile;
                            System.Diagnostics.Process.Start(command, Globals.LegalUpdateKeyWord + Globals.SpaceOut(_FileFromCommandLine));
                            Application.Exit();
                        }
                        catch
                        {
                            MessageBox.Show("A newer version was found on the server, but automatic update could not be executed. Please try again or update manually!", "Version", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                }
            }
            #endregion Check for availability of update for software







        }


        private void pbox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point curr = ((Control)sender).PointToScreen(new Point(e.X, e.Y));
                _DragStart = new Point(curr.X, curr.Y);
                _IsLeftMouseDrag = true;

                // Relative to pbox
                _DragStart = new Point(e.X, e.Y);
            }

            if (e.Button == MouseButtons.Right)
                ColorPicker(new Point(e.X, e.Y));

        }
        private void pboxResult_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
                if (_Threshold < 0)
                    ColorPicker(new Point(e.X, e.Y));
        }

        private void ColorPicker(Point P)
        {
            if (_Selection == null)
                return;

            Point pp = CanvasToImg(P);
            if (_Selection.IsInEllipse(pp))
            {
                int x1 = Math.Max(0, pp.X - 3);
                int x2 = Math.Min( pp.X + 3, _GrayscaleValues.GetLength(0));
                int y1 = Math.Max(0,pp.Y - 3);
                int y2 = Math.Min(pp.Y + 3, _GrayscaleValues.GetLength(1));
                int n = 0;
                int sum = 0;

                for (int x = x1; x <= x2; x++)
                {
                    for (int y = y1; y <= y2; y++)
                    {
                        sum += _GrayscaleValues[pp.X, pp.Y];
                        n++;
                    }
                }
                _Threshold = (int)Math.Round((double)sum / (double)n, 0);
                Perform();
            }
        }



        private void pbox_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && _IsLeftMouseDrag)
            {
                _IsLeftMouseDrag = false;

                // Remove rectangle from pbox
                pboxOriginal.Refresh();

                // Area has no width or has no height            
                if (_DragStart.X == e.X || _DragStart.Y == e.Y)
                    return; // No drag occured


                this.Cursor = Cursors.WaitCursor;


                // Create Selection
                Point curr = ((Control)sender).PointToClient(new Point(Control.MousePosition.X, Control.MousePosition.Y));
                Point currImg = CanvasToImg(curr);
                Point dragStartImg = CanvasToImg(_DragStart);
                int dx = dragStartImg.X - currImg.X;
                int dy = dragStartImg.Y - currImg.Y;
                int a = (int)Math.Abs(Math.Round(Math.Sqrt(2) * dx));
                int b = (int)Math.Abs(Math.Round(Math.Sqrt(2) * dy));
                int leftX = dragStartImg.X - a;
                int topY = dragStartImg.Y - b;
                int width = 2 * a;
                int height = 2 * b;

                Rectangle r = new Rectangle(leftX, topY, width, height);
                _Selection = new Selection(r);
                _Threshold = -1;
                lblPercentAbove.Text = "";



                _GrayscaleValues = GrayScaleValues();
                _Occurences = Occurences();

                DrawSelection();
                DrawHistogram();

                this.Cursor = Cursors.Default;
            }
        }


        private void pbox_Paint(object sender, PaintEventArgs e)
        {
            if (_IsLeftMouseDrag)
            {
                Point curr = ((Control)sender).PointToClient(new Point(Control.MousePosition.X, Control.MousePosition.Y));
                Rectangle r;

                #region Create r
                int leftX, width;
                int topY, height;
                double dx = _DragStart.X - curr.X;
                double dy = _DragStart.Y - curr.Y;
                int a = (int)Math.Round(Math.Sqrt(2) * dx);
                int b = (int)Math.Round(Math.Sqrt(2) * dy);
                leftX = _DragStart.X - a;
                topY = _DragStart.Y - b;
                width = 2 * a;
                height = 2 * b;
                r = new Rectangle(leftX, topY, width, height);
                #endregion

                Pen pen = new Pen(_SelectingColor, 1);
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                e.Graphics.DrawEllipse(pen, r);
            }
        }


        private void pbox_MouseMove(object sender, MouseEventArgs e)
        {
            if (_IsLeftMouseDrag)
                pboxOriginal.Refresh();
        }


        private void DrawSelection()
        {
            pboxOriginal.Image = (Image)_ImgImported.Clone();
            
            



            
#warning Error here with indexed pixels
            Graphics graphicsO = Graphics.FromImage(pboxOriginal.Image);





            int t = (int)Math.Ceiling((float)_ImgImported.Width / (float)pboxOriginal.Width);

            Pen pen = new Pen(_SelectionColor, t);
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
            graphicsO.DrawEllipse(pen, _Selection.R);

            Brush brush = new SolidBrush(_SelectionColor);
            Rectangle center = new Rectangle(_Selection.Center.X - t * 2, _Selection.Center.Y - t * 2, t * 4, t * 4);
            graphicsO.FillEllipse(brush, center);

            pboxOriginal.Refresh();
            graphicsO.Dispose();

            Bitmap bmp = new Bitmap(_ImgImported.Width, _ImgImported.Height);
            Graphics graphicsR = Graphics.FromImage(bmp);
            graphicsR.Clear(pnlResult.BackColor);
            TextureBrush tBrush = new TextureBrush(_ImgImported);
            graphicsR.FillEllipse(tBrush, _Selection.R);
            pboxResult.Image = bmp;
            lblSavedAs.Text = "";
            graphicsR.Dispose();
        }


        // Return array with size of image with grayscale values.
        // Only convert selected region surrounded by margin.
        private int[,] GrayScaleValues()
        {
            // When converting from RGB to grayscale, it is said that specific weights to channels R, G, and B ought to be applied. 
            // These weights are: 0.2989, 0.5870, 0.1140.

            int[,] r = new int[_ImgImported.Width, _ImgImported.Height];
            int margin = 20;
            Bitmap bmp = new Bitmap(_ImgImported);
            int x1 = Math.Max(0, _Selection.x1 - margin);
            int x2 = Math.Min(_Selection.x2 + margin, bmp.Width);
            int y1 = Math.Max(0, _Selection.y1 - margin);
            int y2 = Math.Min(_Selection.y2 + margin, bmp.Height);

            List<int> occGray = new List<int>();
            List<int> occR = new List<int>();
            List<int> occG = new List<int>();
            List<int> occB = new List<int>();

            for (int x = x1; x < x2; x++)
            {
                for (int y = y1; y < y2; y++)
                {
                    Color c = bmp.GetPixel(x, y);
                    



                    int v = (int)Math.Floor(0.2989 * c.R + 0.5870 * c.G + 0.1140 * c.B);
                    r[x, y] = v;

                    //if(!occR.Contains(c.R))
                    //    occR.Add(c.R);
                    //if (!occG.Contains(c.G))
                    //    occG.Add(c.G);
                    //if (!occB.Contains(c.B))
                    //    occB.Add(c.B);
                    //if (!occGray.Contains(v))
                    //    occGray.Add(v);
                }
            }
            return r;
        }


        private Int32[] Occurences()
        {
            int[] occurences = new Int32[256];

            // Occurrence of gray pixel value in selection
            int x1 = Math.Max(0, _Selection.x1);
            int x2 = Math.Min(_Selection.x2, _GrayscaleValues.GetLength(0));
            int y1 = Math.Max(0, _Selection.y1);
            int y2 = Math.Min(_Selection.y2, _GrayscaleValues.GetLength(1));


            for (int x = x1; x < x2; x++)
            {
                for (int y = y1; y < y2; y++)
                {
                    if (_Selection.IsInEllipse(new Point(x, y)))
                    {
                        // int pix = _GrayscaleValues[x, y];
                        // occurences[pix]++;
                        occurences[_GrayscaleValues[x, y]]++;
                    }
                }
            }
            return occurences;
        }


        private void DrawHistogram()
        {
            Bitmap bmp = new Bitmap(pboxHist.Width, pboxHist.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.Clear(Color.White);

            float f = (float)bmp.Height / (float)_Occurences.Max();
            for (int i = 255; i >= 0; i--)
            {
                float xx1 = i * ((float)bmp.Width / 256);
                float xx2 = (i + 1) * ((float)bmp.Width / 256);
                float v = (float)bmp.Height - (float)_Occurences[i] * f;
                RectangleF rect = new RectangleF(xx1, v, xx2 - xx1, bmp.Height);

                // Background
                Brush b = new SolidBrush(Color.FromArgb(i, i, i));
                g.FillRectangle(b, new RectangleF(xx1, 0, xx2 - xx1, bmp.Height));

                // Profile
                Brush profileBrush;
                if (_Threshold < 1)
                    profileBrush = new SolidBrush(_ColorBelowThreshold);
                else if (i > _Threshold)
                    profileBrush = new SolidBrush(_ColorAboveThreshold);
                else
                    profileBrush = new SolidBrush(_ColorBelowThreshold);
                g.FillRectangle(profileBrush, rect);
            }

            pboxHist.Image = bmp;
        }


        private void pboxHist_MouseClick(object sender, MouseEventArgs e)
        {
            if (_Selection == null)
                return;

            this.Cursor = Cursors.WaitCursor;
            _Threshold = (int)Math.Round((double)e.X / (double)pboxHist.Width * 256);
            Perform();
            this.Cursor = Cursors.Default;
        }


        private void Perform()
        {
            pboxHist.Refresh();
            _Percentage = Math.Round(ApplyThreshold(), 1);
            if (rbtnCuAl.Checked)
                lblPercentAbove.Text = string.Format("Cu-Al: IMC {0:0.0}%", _Percentage);
            else
                lblPercentAbove.Text = string.Format("Au-Al: IMC {0:0.0}%", 100 - _Percentage);
            DrawHistogram();
        }



        private Point CanvasToImg(Point P)
        {
            double scalingX = (double)pboxOriginal.Width / (double)_ImgImported.Width;
            double scalingY = (double)pboxOriginal.Height / (double)_ImgImported.Height;

            int x = (int)Math.Round(P.X / scalingX);
            int y = (int)Math.Round(P.Y / scalingY);
            return new Point(x, y);
        }


        private Point ImgToCanvas(Point P)
        {
            double scalingX = (double)pboxOriginal.Width / (double)_ImgImported.Width;
            double scalingY = (double)pboxOriginal.Height / (double)_ImgImported.Height;

            int x = (int)Math.Round(P.X * scalingX);
            int y = (int)Math.Round(P.Y * scalingY);
            return new Point(x, y);
        }


        private void pboxHist_Paint(object sender, PaintEventArgs e)
        {
            if (_Threshold > 0)
            {
                float x = (float)pboxHist.Width / 256 * (float)_Threshold;

                PointF p1 = new PointF(x, 0);
                PointF p2 = new PointF(x, pboxHist.Height);

                Pen pen = new Pen(_ColorThresholdBar, 2);
                e.Graphics.DrawLine(pen, p1, p2);
            }
        }


        private Double ApplyThreshold()
        {
            int x1 = Math.Max(0, _Selection.x1);
            int x2 = Math.Min(_Selection.x2, _GrayscaleValues.GetLength(0));
            int y1 = Math.Max(0, _Selection.y1);
            int y2 = Math.Min(_Selection.y2, _GrayscaleValues.GetLength(1));

            int total = 0;
            int above = 0;

            Bitmap bmp = new Bitmap(_ImgImported);
            Graphics g = Graphics.FromImage(bmp);
            g.Clear(_ColorBelowThreshold);


            double cX = (double)_Selection.Center.X;
            double cY = (double)_Selection.Center.Y;
            double a = Math.Pow(_Selection.Width / 2, 2);
            double b = Math.Pow(_Selection.Height / 2, 2);
            for (int x = x1; x < x2; x++)
            {
                for (int y = y1; y < y2; y++)
                {
                    if (_Selection.IsInEllipse(new Point(x, y)))
                    {
                        total++;
                        if (_GrayscaleValues[x, y] > _Threshold)
                        {
                            bmp.SetPixel(x, y, _ColorAboveThreshold);
                            above++;
                        }
                    }
                }
            }

            pboxResult.Image = bmp;



            Bitmap bmpR;
            Graphics graphicsR;

            if (cboxOriginalInBG.Checked)
            {
                bmpR = new Bitmap(_ImgImported);
                graphicsR = Graphics.FromImage(bmpR);
            }
            else
            {
                bmpR = new Bitmap(_ImgImported.Width, _ImgImported.Height);
                graphicsR = Graphics.FromImage(bmpR);
                graphicsR.Clear(_ColorBackColor);
            }

            TextureBrush tBrush = new TextureBrush(bmp);
            graphicsR.FillEllipse(tBrush, _Selection.R);

            pboxResult.Image = bmpR;
            lblSavedAs.Text = "";
            graphicsR.Dispose();
            return 100 * (double)above / (double)total;
        }


        private void pnlOriginal_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            try
            {
                // On 12 Nov 2015 Niels Keupink reported an unhandeld exception while selection a region.
                // System.Exception: A Graphics object cannot be created from an image that has an indexed pixel format.
                // Origninal code:
                //     _ImgImported = Image.FromFile(files[0]);
                // was replaced by:
                Bitmap bm = (Bitmap)System.Drawing.Image.FromFile(files[0], true);
                Bitmap tmp = new Bitmap(bm.Width, bm.Height);
                Graphics grPhoto = Graphics.FromImage(tmp);
                grPhoto.DrawImage(bm, new Rectangle(0, 0, tmp.Width, tmp.Height), 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel);
                grPhoto.Dispose();
                _ImgImported = (Image)tmp;
                _Filename = files[0];
            }
            catch (Exception ex)
            {
                MessageBox.Show("Could not load image file!\n\n" + ex.Message, "Select image", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Reset values
            _Threshold = -1;
            _Occurences = null;
            _Selection = null;
            _GrayscaleValues = null;
            pboxOriginal.Image = null;
            lblSavedAs.Text = "";
            pboxResult.Image = null;
            pboxHist.Image = null;



            // Show image
            pboxOriginal.Image = _ImgImported;

            // Scale picture boxes to image
            pboxOriginal.Width = 600;
            pboxOriginal.Height = 553;
            double scalingX = (double)pboxOriginal.Width / (double)_ImgImported.Width;
            double scalingY = (double)pboxOriginal.Height / (double)_ImgImported.Height;
            int h = pboxOriginal.Height;
            int w = pboxOriginal.Width;
            if (scalingY > scalingX)
                h = (int)Math.Floor((double)_ImgImported.Height * scalingX);
            else
                w = (int)Math.Floor((double)_ImgImported.Width * scalingY);
            pboxOriginal.Width = w;
            pboxOriginal.Height = h;
            pboxResult.Width = w;
            pboxResult.Height = h;
            pboxOriginal.Visible = true;

            // Center pbox
            int x = (int)Math.Floor(((double)pnlOriginal.Width - (double)pboxOriginal.Width) / 2);
            int y = (int)Math.Floor(((double)pnlOriginal.Height - (double)pboxOriginal.Height) / 2);
            pboxOriginal.Location = new Point(x, y);
            pboxResult.Location = new Point(x, y);




            //   pnlOriginal.AllowDrop = false;
        }


        private void pnlOriginal_DragEnter(object sender, DragEventArgs e)
        {
            // make sure they're actually dropping files (not text or anything else)
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (files.Length == 1)
                {
                    string ext = new FileInfo(files[0]).Extension.ToLower();
                    if (ext == ".jpg" || ext == ".bmp")
                        e.Effect = DragDropEffects.All;
                }
            }
            else
                e.Effect = DragDropEffects.None;
        }




        private void rbtn_CheckedChanged(object sender, EventArgs e)
        {

            if (rbtnCuAl.Checked)
            {
                _ColorAboveThreshold = _ColorIn;
                _ColorBelowThreshold = _ColorOut;
            }
            else
            {
                _ColorAboveThreshold = _ColorOut;
                _ColorBelowThreshold = _ColorIn;
            }


            if (_Selection == null || _Threshold < 0)
                return;

            this.Cursor = Cursors.WaitCursor;

            Perform();
            this.Cursor = Cursors.Default;


        }

        private void cboxOriginalInBG_CheckedChanged(object sender, EventArgs e)
        {
            if (_Selection == null || _Threshold < 0)
                return;

            this.Cursor = Cursors.WaitCursor;
            Perform();
            this.Cursor = Cursors.Default;
        }


        private void btnSave_Click(object sender, EventArgs e)
        {
            if (_Selection == null)
                return;
            if (_Threshold < 0)
                return;


            FileInfo fi = new FileInfo(_Filename);
            string path = fi.DirectoryName;
            string ext = fi.Extension;
            string file = fi.Name.Replace(fi.Extension, "");
            string resultFile = path + "\\" + file + string.Format("_C{0:00}", _Percentage) + ext;

            try
            {
                if (File.Exists(resultFile))
                {
                    sfd.FileName = new FileInfo(resultFile).Name;
                    sfd.InitialDirectory = path;
                    sfd.Filter = String.Format("{0}|*{1}", ext.Replace(".", "").ToUpper(), ext);
                    sfd.Title = "Save";
                    DialogResult dr = sfd.ShowDialog();
                    if (dr != DialogResult.OK)
                        return;
                    resultFile = sfd.FileName;
                }
                pboxResult.Image.Save(resultFile, _ImgImported.RawFormat);
                lblSavedAs.Text = String.Format("Saved as {0}", new FileInfo(resultFile).Name);
                lblSavedAs.Location = new Point(pnlResult.Width + pnlResult.Location.X - lblSavedAs.Width, lblSavedAs.Location.Y);

            }
            catch (Exception ex)
            {
                MessageBox.Show("Could not save image file!\n\n" + ex.Message, "Save", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }



        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.F1)
            {
                lblSource.Text = "(Release on server folder " + Globals.PathToServerVersion + ")"; 
                
                // Build info
                System.Reflection.Assembly ass = System.Reflection.Assembly.GetEntryAssembly();
                string exe = Path.GetFullPath(ass.Location);
                DateTime d = new FileInfo(exe).LastWriteTimeUtc;
                lblBuild.Text = String.Format("GoldenEye\nMaser Engineering b.v.\nW.D.T. Booij\nBuild v{0:0000}{1:00}{2:00}", d.Year, d.Month, d.Day);
                lblHelp.BackColor = pnlHelp.BackColor;
                pnlHelp.Dock = DockStyle.Fill;
                pnlHelp.Visible = true;
                pnlHelp.BringToFront();
                return true;    // indicate that you handled this keystroke
            }

            // Call the base class
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void btnCloseHelp_Click(object sender, EventArgs e)
        {
            pnlHelp.Visible = false;
        }


        private void pictureBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(@"\\silicium\projects\2015\P151091\sub2");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Could not open folder!\n\n" + ex.Message, "Source folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }


    }
}
