using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;


namespace SoundBoard
{
    public partial class formMain : Form
    {
        //private const int WM_KEYDOWN = 0x100;
        private programDebugConsole debugConsoleWindow = new programDebugConsole();
        private MediaPlayer gMultimediaPlayer = new MediaPlayer();
        private Random randomNum = new Random();
        private ListView listViewEntity = new ListView();
        private string _workingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
        private string[] _soundDirectories;
        private List<List<String>> listViewContents = new List<List<string>>();

        public formMain()
        {
            InitializeComponent();
        }

        private void formMain_Load(object sender, EventArgs e)
        {
            //Build the UI, foreach directory create one TabPage and one ListView object
            try
            {
                CreateUITabs("Working Directory", _workingDirectory);

                _soundDirectories = Directory.GetDirectories(_workingDirectory);
                foreach (string sounds in _soundDirectories)
                {
                    CreateUITabs(Path.GetFileName(sounds), sounds);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\nThis application will now terminate.", "Fatal Error");
                Close();
            }

            //check to see if the listView is empty on form load
            if (soundboardTabControl.SelectedTab.Controls[0].Enabled == true)
            {
                mainMenuFileShowOnDisk.Enabled = true;
                btnRandom.Enabled = true;
            }
            else
            {
                mainMenuFileShowOnDisk.Enabled = false;
                btnRandom.Enabled = false;
            }
            fileSystemWatcherMain.Path = _workingDirectory; //watch in the application's working directory
            fileSystemWatcherMain.IncludeSubdirectories = true; //and watch in the subfolders for changes, but only one layer down from the app's directory
            fileSystemWatcherMain.Created += new FileSystemEventHandler(fileSystemUpdateDetected); //file or folder created
            fileSystemWatcherMain.Deleted += new FileSystemEventHandler(fileSystemUpdateDetected); //file or folder moved or deleted
            fileSystemWatcherMain.Renamed += new RenamedEventHandler(fileSystemUpdateDetected); //for any file changes like file extension changes
            soundboardTabControl.SelectedIndexChanged += new EventHandler(CheckForDisabledListView); //disables or enables the Show on Disk file menu object
            debugConsoleWindow.FormClosing += debugConsoleWindow_FormClosing; //Capture the closing of the form and prevent it, instead hide it
        }

#region event-handlers
        void debugConsoleWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            debugConsoleWindow.HideConsole();
            mainMenuHelpShowConsole.Enabled = true;
            mainMenuHelpShowConsole.Checked = false;
        }

        private void fileSystemUpdateDetected(object sender, FileSystemEventArgs e)
        {
            //perform the UI refresh operation
            RefreshUIControls();
        }
        private void CheckForDisabledListView(object sender, EventArgs e)
        {
            listViewEntity = (ListView)soundboardTabControl.SelectedTab.Controls[0];
            if (listViewEntity.Enabled == false)
            {
                mainMenuFileShowOnDisk.Enabled = false;
                btnRandom.Enabled = false;
            }
            else
            {
                mainMenuFileShowOnDisk.Enabled = true;
                btnRandom.Enabled = true;
            }
        }
#endregion

        private void RefreshUIControls()
        {
            _workingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
            _soundDirectories = Directory.GetDirectories(_workingDirectory);
            soundboardTabControl.SelectedIndexChanged -= new EventHandler(CheckForDisabledListView);

            foreach (TabPage tabPage in soundboardTabControl.TabPages)
            {
                foreach (ListView listView in tabPage.Controls)
                {
                    listView.Dispose();
                }
                tabPage.Dispose();
            }

            listViewContents.Clear();

            CreateUITabs("Working Directory", _workingDirectory);

            foreach (string files in _soundDirectories)
            {
                CreateUITabs(Path.GetFileName(files), files);
            }
            //check to see if the listView is empty
            if (soundboardTabControl.SelectedTab.Controls[0].Enabled == true)
            {
                mainMenuFileShowOnDisk.Enabled = true;
                btnRandom.Enabled = true;
            }
            else
            {
                mainMenuFileShowOnDisk.Enabled = false;
                btnRandom.Enabled = false;
            }
            soundboardTabControl.SelectedIndexChanged += new EventHandler(CheckForDisabledListView);
        }

        private void CreateUITabs(string tabName, string directoryPath)
        {
            //Add tabs dynamically
            int soundControlHeight = soundboardTabControl.Height;
            int soundControlWidth = soundboardTabControl.Width;
            int index = soundboardTabControl.TabCount;
            int fileCount = 0;
            TabPage tab = new TabPage();
            ListView localListView = new ListView();
            string[] columnNames = new string[2]; //Perhaps include a compatibility column to flag files that cause errors?
            string[] files;
            ListViewItem listItemObject;

            //Construct the TabPage and its properties
            tab.Text = tabName; //Display the folder's full name to the user
            tab.Name = tabName.Replace(" ", "") + "Tab"; //create a legal name for the tab's (name) property
            tab.Height = soundControlHeight;
            tab.Height = soundControlWidth;

            //Construct the ListView and its properties
            localListView.Height = soundControlHeight - 25;
            localListView.Width = soundControlWidth - 5;
            localListView.Name = tabName.Replace(" ", "") + "ListView";
            localListView.FullRowSelect = true;
            localListView.MultiSelect = false;
            localListView.GridLines = true;
            localListView.View = View.Details;
            localListView.Activation = ItemActivation.OneClick;
            localListView.TabStop = false;
            localListView.Columns.Add("File Name", 340, HorizontalAlignment.Left);
            localListView.Columns.Add("File Ext", 50, HorizontalAlignment.Left);
            localListView.ItemActivate += new EventHandler((sender, e) => ListViewOnLeftClick(sender, e, localListView));

            files = Directory.GetFiles(directoryPath);
            listViewContents.Add(new List<String>());

            foreach (string file in files)
            {
                switch (Path.GetExtension(file).ToLower())
                {
                    //Only include sound files in the ListView / most commonly supported audio formats in Windows
                    case ".mp3":    //MPEG layer 3
                    case ".wav":    //WAV audio format
                    case ".wma":    //Windows Media Audio
                    case ".mid":    //MIDI - Musical Instrument Digital Interface 
                    case ".ra":     //Real Audio
                    case ".ram":    //Real Audio
                    case ".rm":     //Real Audio
                    case ".ogg":    //OGG audio format
                        columnNames[0] = Path.GetFileNameWithoutExtension(file);
                        columnNames[1] = Path.GetExtension(file);
                        listItemObject = new ListViewItem(columnNames);
                        localListView.Items.Add(listItemObject);
                        listViewContents[index].Add(file);
                        fileCount++;
                        break;
                    default:
                        break;
                }
            }

            if (localListView.Items.Count == 0 && tab.Name == "WorkingDirectoryTab")
            {
                soundboardTabControl.Controls.Add(tab);
                tab.Controls.Add(localListView);
                localListView.Items.Add("No files found in the programs working directory");
                localListView.Enabled = false;
            }
            else if (localListView.Items.Count > 0 && tab.Name == "WorkingDirectoryTab")
            {
                soundboardTabControl.Controls.Add(tab);
                tab.Controls.Add(localListView);
            }
            else if (localListView.Items.Count > 0)
            {
                soundboardTabControl.Controls.Add(tab);
                tab.Controls.Add(localListView);
            }
            else
            {
                //remove the array that represents the tab that was created above because it is empty
                int i = listViewContents.Count;
                listViewContents.RemoveAt(i - 1);
            }
        }

        private void ListViewOnLeftClick(object sender, EventArgs e, ListView listView)
        {
            string fileName;
            string fileExt;
            string fileLocation;

            fileName = listView.SelectedItems[0].SubItems[0].Text;
            fileExt = listView.SelectedItems[0].SubItems[1].Text;

            if (soundboardTabControl.SelectedIndex == 0)
            {
                if (File.Exists(_workingDirectory + "\\" + fileName + fileExt))
                {
                    fileLocation = _workingDirectory + "\\" + fileName + fileExt;
                }
                else
                {
                    return;
                }
            }
            else
            {
                if (File.Exists(_workingDirectory + "\\" + soundboardTabControl.SelectedTab.Text + "\\" + fileName + fileExt))
                {
                    fileLocation = _workingDirectory + "\\" + soundboardTabControl.SelectedTab.Text + "\\" + fileName + fileExt;
                }
                else
                {
                    return;
                }
            }
            gMultimediaPlayer.PlaySoundFile(fileLocation);
        }

        private void btnRandom_Click(object sender, EventArgs e)
        {
            int iterations = (int)randomIterationNumericUpDown.Value;
            listViewEntity = (ListView)soundboardTabControl.SelectedTab.Controls[0];
            GenerateRandomPlayList makePlayList = new GenerateRandomPlayList();
            string[] playList;

            if (mainMenuPlayAll.Checked == true)
            {
                playList = makePlayList.MulitViewPlayList(listViewContents, iterations);

                gMultimediaPlayer.PlayAudioPlaylist(playList);
            }
            else
            {
                playList = makePlayList.SingleViewPlayList(listViewContents, iterations, soundboardTabControl.SelectedIndex);

                gMultimediaPlayer.PlayAudioPlaylist(playList);
            }
        }

        private void loopSelectedSoundCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (loopSelectedSoundCheckBox.Checked == true)
            {
                gMultimediaPlayer.WillLoop = true;
                gMultimediaPlayer.IsLoopBoxCheck = true;
            }
            else
            {
                gMultimediaPlayer.WillLoop = false;
                gMultimediaPlayer.IsLoopBoxCheck = false;
            }
        }

        #region Menu Strip Actions
        private void mainMenuFileShowOnDisk_Click(object sender, EventArgs e)
        {
            listViewEntity = (ListView)soundboardTabControl.SelectedTab.Controls[0];
            string fileName;
            string fileExt;

            try
            {
                fileName = listViewEntity.SelectedItems[0].SubItems[0].Text;
                fileExt = listViewEntity.SelectedItems[0].SubItems[1].Text;

                if (soundboardTabControl.SelectedIndex == 0)
                {
                    if (File.Exists(_workingDirectory + "\\" + fileName + fileExt))
                    {
                        Process.Start("explorer.exe", "/select, \"" + _workingDirectory + "\\" + fileName + fileExt + "\"");
                    }
                }
                else
                {
                    if (File.Exists(_workingDirectory + "\\" + soundboardTabControl.SelectedTab.Text + "\\" + fileName + fileExt))
                    {
                        Process.Start("explorer.exe", "/select, \"" + _workingDirectory + "\\" + soundboardTabControl.SelectedTab.Text + "\\" + fileName + fileExt + "\"");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("No item is selected.", "No File Selected");
            }
        }

        private void mainMenuHelpAbout_Click(object sender, EventArgs e)
        {
            aboutForm aboutDialogForm = new aboutForm();
            aboutDialogForm.ShowDialog();
            aboutDialogForm.Dispose();
        }

        private void mainMenuFileExit_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void mainMenuHelpShowConsole_Click(object sender, EventArgs e)
        {
            debugConsoleWindow.ShowConsole();
            mainMenuHelpShowConsole.Enabled = false;
        }
        #endregion

        //Handles all messages being sent to controls
        //NEEDS IT'S OWN THREAD!
        //public bool PreFilterMessage(ref Message m)
        //{
        //    Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;
        //    bool retVal = false;

        //    if (m.Msg == WM_KEYDOWN)
        //    {
        //        // Handle the keypress          
        //        //Disable the Tab key
        //        if (keyCode.ToString() == "Tab")
        //        {
        //            //Tab key caught, filter out the keystroke
        //            debugConsoleWindow.WriteToConsole("Keystroke seen");
        //            return true;
        //        }
        //    }
        //    return retVal;
        //}
    }
}
