using MetadataExtractor;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PictureReposit
{
    public partial class Form1 : Form
    {

        private bool Deleting = false;
        public Form1()
        {
            InitializeComponent();

            RegistryKey PictureHandling = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Tfoman\PictureReposit");
            if (PictureHandling == null)
            {
                txtRootDir.Text = @"D:\Bildlabb\LabRotCat";
            }
            else
            {
                txtRootDir.Text = (string)PictureHandling.GetValue(@"RootMap");
            }

        }

        private void btnFileDialog_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "Välj bild-fil!";
            openFileDialog1.InitialDirectory = "C:\\";
            openFileDialog1.Filter = "Picture files (*.jpg)|*.jpg|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 1;
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.ShowDialog();
            openFileDialog1.Multiselect = false;
            string fName = openFileDialog1.FileName;
            if (fName.Trim() != "")
            {
                int fNamePos = fName.LastIndexOf(@"\") + 1;
                lblFileName.Text = fName.Substring(fNamePos);
                lblPath.Text = fName.Substring(0, fNamePos);
                listLocalFiles();

                for (int i = 0; i < lstPicFiles.Items.Count; i++)
                {
                    if (lstPicFiles.Items[i].ToString() == lblFileName.Text)
                    {
                        lstPicFiles.SelectedIndex = i;
                        break;
                    }
                }

            }
        }

        private void listLocalFiles()
        {
            DirectoryInfo di = new DirectoryInfo(lblPath.Text);
            FileInfo[] files = new string[] { "*.png", "*.jpg", "*.jpeg", "*.img", "*.mov" }
                .SelectMany(i => di.GetFiles(i, SearchOption.AllDirectories))
                .ToArray();

            lstPicFiles.Items.Clear();
            for (int i = 0; i < files.Length; i++)
            {
                lstPicFiles.Items.Add(files[i].Name);
            }

            btnReOrganize.Enabled = true;
        }

        private void lstPicFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!Deleting)
            {
                string fName = ((ListBox)sender).SelectedItem.ToString();
                lblFileName.Text = fName;
                Image actPic = null;
                if (fName.ToUpper().EndsWith(".MOV"))
                {
                    actPic = Image.FromFile("IMG_2994.jpg", true);
                }
                else
                {
                    actPic = Image.FromFile(lblPath.Text + fName, true);
                }
                lblCreated.Text = "Skapad: " + GetOrigCreateDateTimeFromMediaFile(new FileInfo(lblPath.Text + fName)).ToString(); ;
                int w = actPic.Width;
                int h = actPic.Height;
                int pw = pictureBox1.Width;
                int ph = pictureBox1.Height;
                pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
                Bitmap to_bm = new Bitmap((Image)actPic.Clone(), w * ph / h, ph);
                pictureBox1.Image = to_bm;
                actPic = null;

            }
        }


        private void btnReOrganize_Click(object sender, EventArgs e)
        {
            bool slaskDir = false;
            int slaskFilNr = 0;
            string fromPath = lblPath.Text.Trim();
            pbReorgProcess.Visible = true;
            pictureBox1.Visible = false;
            if (txtRootDir.Text.Trim().Substring(txtRootDir.Text.Trim().Length - 1) != @"\")
                txtRootDir.Text = txtRootDir.Text.Trim() + @"\";
            DirectoryInfo di = new DirectoryInfo(txtRootDir.Text);
            if (!di.Exists) di.Create();
            Deleting = true;

            pictureBox1.Image = null;
            pictureBox1.Refresh();
            try
            {
                pbReorgProcess.Maximum = lstPicFiles.Items.Count;
                pbReorgProcess.Minimum = 0;

                for (int i = lstPicFiles.Items.Count - 1; i > -1; i--)
                {
                    pbReorgProcess.Value = lstPicFiles.Items.Count-i;
                    string lFileName = lstPicFiles.Items[i].ToString().Trim();
                    string fName = fromPath + lFileName;
                    lblFileName.Text = fName;
                    FileInfo fi = new FileInfo(fName);
                    string td = GetOrigCreateDateTimeFromMediaFile(fi).ToString();
                    lblCreated.Text = "Skapad: " + td;
                    if (td.Trim() != DateTime.MinValue.ToString())
                    {
                        lblCreated.Text = "Skapad: " + td;
                        td = td.Substring(0, 10);
                        DateTime dttd = DateTime.Parse(td);
                        string subDir1 = dttd.Year.ToString("0000") + "-" + dttd.Month.ToString("00") + @"\";
                        string subDir2 = dttd.Year.ToString("0000") + "_" + dttd.Month.ToString("00") + "_" + dttd.Day.ToString("00") + @"\";
                        DirectoryInfo dis = new DirectoryInfo(di.FullName + subDir1);
                        if (!dis.Exists) dis.Create();
                        DirectoryInfo diss = new DirectoryInfo(dis.FullName + subDir2);
                        if (!diss.Exists) diss.Create();
                        lblPath.Text = diss.FullName;
                        lblFileName.Refresh();
                        lblCreated.Refresh();
                        lblPath.Refresh();
                        fi.CopyTo(diss.FullName + lFileName, true);
                    }
                    else
                    {
                        DirectoryInfo dis = new DirectoryInfo(di.FullName + "NoDateInExif\\");
                        if (!slaskDir)
                        {
                            if (!dis.Exists)
                            {
                                dis.Create();
                                set_Last_number(dis.FullName, 0);
                            }
                            else
                            {
                                slaskFilNr = get_Last_number(dis.FullName);
                            }
                            slaskDir = true;
                        }

                        slaskFilNr++;
                        fi.CopyTo(dis.FullName + slaskFilNr.ToString() + "_" + lFileName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error msg: {ex.Message}");
            }
            finally
            {
                if (slaskFilNr > 0)
                {
                    set_Last_number(di.FullName + "NoDateInExif\\", slaskFilNr);
                }
            }
            lstPicFiles.Items.Clear();
            Deleting = false;
            lblCreated.Text = "";
            lblFileName.Text = "";
            lblPath.Text = "";
            btnReOrganize.Enabled = false;
            if (slaskFilNr > 0)
            {
                set_Last_number(di.FullName + "NoDateInExif\\", slaskFilNr);
            }
            pbReorgProcess.Visible = false;
            pictureBox1.Visible = true;
        }

        private void txtRootDir_TextChanged(object sender, EventArgs e)
        {
            //Software\Tfoman\PictureReposit
            RegistryKey Tfoman = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Tfoman", true);
            RegistryKey PictureHandling = Tfoman.OpenSubKey(@"PictureReposit", true);
            if (PictureHandling == null)
            {
                if (Tfoman == null)
                {
                    Tfoman = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\Tfoman");
                }
                else
                    PictureHandling = Tfoman.CreateSubKey(@"PictureReposit");
            }
            else
            {
                PictureHandling.SetValue(@"RootMap", txtRootDir.Text);
            }
        }

        private int get_Last_number(string path)
        {
            int outPut = 0;
            var lstNrFile = Path.Combine(path, "lastNrFile.txt");
            if (File.Exists(lstNrFile))
            {
                outPut = int.Parse(File.ReadAllText(lstNrFile));
            }
            outPut++;
            return outPut;
        }

        private void set_Last_number(string path, int lastNr)
        {
            var lstNrFile = Path.Combine(path, "lastNrFile.txt");
            var SavedNumber = lastNr.ToString();
            File.WriteAllText(lstNrFile, SavedNumber);
        }

        //------------------------------------------------------------------------
        //  Nya funktioner för hantering av original datum
        //------------------------------------------------------------------------

        DateTime GetOrigCreateDateTimeFromMediaFile(FileInfo file)
        {
            DateTime origDateTime = DateTime.MinValue;
            var creationDate = getCreationDate(file);
            if (creationDate != "")
            {
                if (file.Extension.ToLower() != ".mov")
                {
                    creationDate = prepDateString(creationDate);
                }
                else
                {
                    creationDate = prepMovDateString(creationDate);
                }
                origDateTime = DateTime.Parse(creationDate);
            }
            return origDateTime;
        }


        private string prepMovDateString(string creationDate)
        {
            var x = creationDate.Split(" ");
            return $"{x[0]} {x[2]} {x[1]} {x[4]} {x[3]}";
        }

        private string prepDateString(string creationDate)
        {
            creationDate = creationDate.Replace(" ", "T");
            var x = creationDate.Split("T");
            x[0] = x[0].Replace(":", "-");
            return x[0] + "T" + x[1];
        }

        private string getCreationDate(FileInfo file)
        {

            string output = "";
            switch (file.Extension.ToLower())
            {
                case ".jpg":
                case ".jpeg":
                    {
                        output = getExifValue("Exif IFD0", "Date/Time", file);
                        if (output == "")
                        {
                            output = getExifValue("Exif SubIFD", "Date/Time Original", file);
                        }
                        break;
                    }
                case ".png":
                    {
                        break;
                    }
                case ".mov":
                    {
                        output = getExifValue("QuickTime Movie Header", "Created", file);
                        break;
                    }
            }

            return output;
        }

        private string getExifValue(string key1, string key2, FileInfo fileInfo)
        {
            string output = "";
            foreach (var directory in ImageMetadataReader.ReadMetadata(fileInfo.FullName))
            {
                if (directory.Name == key1)
                {
                    foreach (var tag in directory.Tags)
                    {
                        if (tag.Name == key2)
                        {
                            output = tag.Description;
                        }
                    }
                }
            }
            return output;
        }
    }
}
