using System;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace MKVTest
{
    /* Call mkvpropedit.exe
     * Edit "Title" detail property: --edit info --set "title=%TITLE%" %FILE%
     * Edit video track one: --edit track:v1 --set "name(or language)="%VAR%" %FILE%
     * Edit audio track one: --edit track:a1 --set "name(or language)="%VAR%" %FILE%
     * To add simply replace "--set" with "--add".
     */
    public partial class Form1 : Form
    {
        public static string Language = "eng";
        private static readonly ContextMenuStrip menu = new ContextMenuStrip();

        public Form1()
        {
            InitializeComponent();
            inputFilesListView.ItemSelectionChanged += UpdateFilePropPrediction;
            inputFilesListView.MouseClick += ShowMenu;
            this.Resize += Form1_Resize;

            var item = new ToolStripMenuItem
            {
                Name = "RemoveItem",
                Text = @"Remove"
            };
            menu.Items.Add(item);

            var inputColumn = new ColumnHeader()
            {
                Text = @"Files",
                Name = @"HeaderColumn",
                Width = inputFilesListView.Width - 10
            };
            inputFilesListView.Columns.Add(inputColumn);
        }

        private void ShowMenu(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (inputFilesListView.FocusedItem.Bounds.Contains(e.Location) == true)
                {
                    menu.Show(Cursor.Position);
                }
            }
        }

        private void UpdateFilePropPrediction(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            var info = new MkvFileInfo();
            var file = info.GetAttributes(e.Item.Name);
            flowLayoutPanel1.Controls.Clear();
            flowLayoutPanel1.Invalidate();

            var titleLabel = new Label()
            {
                Parent = flowLayoutPanel1,
                Text = @"Current Title: " + file.SegementInformation?.Title,
                AutoSize = true
            };

            flowLayoutPanel1.Container?.Add(titleLabel);

            var videoTrackNumber = 1;
            var audioTrackNumber = 1;

            foreach (var fileTrack in file.Tracks)
            {
                if (fileTrack.Type == MkvTrack.TrackType.Video)
                {
                    var nameLabel = new Label
                    {
                        AutoSize = true,
                        Text = @"Track:v" + videoTrackNumber + @" Name: " + fileTrack.Name,
                        Parent = flowLayoutPanel1
                    };

                    var languageLabel = new Label
                    {
                        AutoSize = true,
                        Text = @"Track:v" + videoTrackNumber + @" Language: " + fileTrack.Language,
                        Parent = flowLayoutPanel1
                    };
                    videoTrackNumber++;
                    if (flowLayoutPanel1.Container != null)
                    {
                        flowLayoutPanel1.Container.Add(nameLabel);
                        flowLayoutPanel1.Container.Add(languageLabel);
                    }
                }

                if (fileTrack.Type == MkvTrack.TrackType.Audio)
                {
                    var nameLabel = new Label
                    {
                        AutoSize = true,
                        Text = @"Track:a" + audioTrackNumber + @" Name: " + fileTrack.Name,
                        Parent = flowLayoutPanel1
                    };
                    var languageLabel = new Label
                    {
                        AutoSize = true,
                        Text = @"Track:a" + audioTrackNumber + @" Language: " + fileTrack.Language,
                        Parent = flowLayoutPanel1
                    };
                    audioTrackNumber++;
                    if (flowLayoutPanel1.Container != null)
                    {
                        flowLayoutPanel1.Container.Add(nameLabel);
                        flowLayoutPanel1.Container.Add(languageLabel);
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private string GetEpisodeName(string text)
        {
            var s = new StringBuilder();
            var hyphenCount = 0;
            var index = 0;
            var fileExtensionStartPoint = text.LastIndexOf(".", StringComparison.InvariantCulture);
            foreach (var c in text)
            {
                if (c == '-' && hyphenCount != 2)
                {
                    hyphenCount++;
                    index++;
                    continue;
                }

                if (hyphenCount == 2)
                {
                    if (c == '.' && index == fileExtensionStartPoint)
                    {
                        break;
                    }
                    s.Append(c);
                }

                index++;
            }

            return s.ToString().Trim();
        }

        private void ListFiles(string folderPath)
        {
            var dir = new DirectoryInfo(folderPath);
            var files = dir.GetFiles("*.mkv", SearchOption.TopDirectoryOnly);
            foreach (var file in files)
            {
                var node = new ListViewItem()
                {
                    Tag = true,         //Assume the file needs to be updated.
                    Name = file.FullName,
                    Text = file.Name
                };
                inputFilesListView.Items.Add(node);
            }

            if (inputFilesListView.Items.Count > 0)
            {
                applyChangesButton.Enabled = true;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var d = new FolderBrowserDialog();
            if (d.ShowDialog() == DialogResult.OK)
            {
                ClearForm();
                ListFiles(d.SelectedPath);             
            }
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            inputFilesListView.Columns[0].Width = inputFilesListView.Width - 10;
        }

        private void applyChangesButton_Click(object sender, EventArgs e)
        {

            foreach (ListViewItem node in inputFilesListView.Items)
            {
                //Check to see if the item has been modified.
                if (node.Tag == null || (bool) node.Tag == false) continue;
                if (!File.Exists(node.Name)) continue;
                var command = "/C mkvpropedit.exe --edit info --set \"title=" + GetEpisodeName(node.Text) +
                              "\" --edit track:v1 --set \"name=" + GetEpisodeName(node.Text) +
                              "\" --edit track:v1 --set \"language=eng\" --edit track:a1 --set \"name=English\" --edit track:a1 --set \"language=eng\" \"" + node.Name + "\" > temp.txt";
                var process = new System.Diagnostics.Process();
                var startInfo = new System.Diagnostics.ProcessStartInfo
                {
                    WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal,
                    FileName = "cmd.exe",
                    Arguments = command
                };
                process.StartInfo = startInfo;
                process.Start();
                while (!process.HasExited)
                {

                }
                if (process.ExitCode == 0) continue;
                var error = File.ReadAllLines("temp.txt");
                MessageBox.Show(@"Error on node: " + node.Text + (error.Length > 0 ? Environment.NewLine + error[0] : string.Empty));
                break;
            }

            File.Delete("temp.txt");
        }

        private void ClearForm()
        {
            inputFilesListView.Items.Clear();
            flowLayoutPanel1.Controls.Clear();
            flowLayoutPanel1.Invalidate();
        }

        private void debugToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var s = new SerializeMkvInfo();
            var xml = s.SerializeFile("C:\\Users\\Crypto\\Documents\\Source Control\\mkvbatcheditor\\MKVTest\\info.txt");
            File.WriteAllLines("C:\\Users\\Crypto\\Desktop\\1234Testing.txt", xml.ToArray());
        }
    }
}
