/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE":
 * I wrote this file. As long as you retain this notice you can do
 * whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return - Sebastian Roll
 * ----------------------------------------------------------------------------
 */
 
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
 
namespace FileSystemWatch
{
   /// <summary>
   /// Modal Window with two DataGridViews.
   /// User can include/exclude directories from watching here.
   /// </summary>
   partial class EditDirectoriesWindow : Form
   {
      // handle to caller
      // we must inform caller on new directory include/exclude list
      // i.e. this window is closing and user has edited some paths.
      MainWindow parentForm = null;
      // the directories
      PathContainer pathsToInclude = null;
      PathContainer pathsToExclude = null;
 
      // ctor
      public EditDirectoriesWindow(MainWindow caller, PathContainer include, PathContainer exclude)
      {
         InitializeComponent();
         // overtake given parameters to private member variables
         parentForm = caller;
         pathsToInclude = include;
         pathsToExclude = exclude;
      }
 
      // this window is presented
      // -> show all directories in DataGridViews
      // --> directories were loaded from configFile on startUp by main window form
      private void EditDirectoriesWindow_Load(object sender, EventArgs e)
      {
         // set text for both first default rows
         // (seems to be not applied from visual studio designer (bug?))
         dataGridViewPathsInclude.Rows[0].Cells["ColumnButtonDirOpnDlg"].Value = "Open...";
         dataGridViewPathsExclude.Rows[0].Cells["ColumnOpenButton"].Value = "Open...";
 
         foreach (String s in pathsToInclude.paths)
         {
            int i = dataGridViewPathsInclude.Rows.Add();
            dataGridViewPathsInclude.Rows[i].Cells[0].Value = s;
         }
         foreach (String s in pathsToExclude.paths)
         {
            int i = dataGridViewPathsExclude.Rows.Add();
            dataGridViewPathsExclude.Rows[i].Cells[0].Value = s;
         }
      }
 
      // take over user edits
      // validate if user entered a path to a directory
      // do not close window until all paths are valid
      // if all is OK: safe paths to config file and close window 
      // and notify main window to rebuild its FSW-array
      private void buttonOK_Click(object sender, EventArgs e)
      {
         // reset and fill includeDirectory container
         pathsToInclude.clear();
         // iterate all includeDirectories
         for (int i = 0; i < dataGridViewPathsInclude.RowCount - 1; i++)
         {
            // get the directory string
            Object o = dataGridViewPathsInclude.Rows[i].Cells[0].Value;
            if (o != null)
            {
               String folderName = o.ToString();
               bool validFolderName = false;
 
               // check if directory exists
               try
               {
                  validFolderName = Directory.Exists(folderName);
               }
               catch (Exception exp)
               {
                  MessageBox.Show("Cannot apply inlude path: " + folderName + "\n" + exp.Message, "FSW Error");
                  dataGridViewPathsInclude.ClearSelection();
                  dataGridViewPathsInclude.Rows[i].Selected = true;
                  return;
               }
 
               if (!validFolderName)
               {
                  // directory does not exist
                  MessageBox.Show("Cannot apply include path: " + folderName, "FSW Error");
                  dataGridViewPathsInclude.ClearSelection();
                  dataGridViewPathsInclude.Rows[i].Selected = true;
                  return;
               }
 
               // append string to directory-container
               pathsToInclude.add(folderName);
            }
         }
 
         // reset and fill excludeDirectory container
         pathsToExclude.clear();
         // iterate all includeDirectories
         for (int i = 0; i < dataGridViewPathsExclude.RowCount - 1; i++)
         {
            // get the directory string
            Object o = dataGridViewPathsExclude.Rows[i].Cells[0].Value;
            if (o != null)
            {
               String folderName = o.ToString();
               bool validFolderName = false;
 
               // check if directory exists
               try
               {
                  validFolderName = Directory.Exists(folderName);
               }
               catch (Exception exp)
               {
                  MessageBox.Show("Cannot apply exclude path: " + folderName + "\n" + exp.Message, "FSW Error");
                  dataGridViewPathsExclude.ClearSelection();
                  dataGridViewPathsExclude.Rows[i].Selected = true;
                  return;
               }
 
               if (!validFolderName)
               {
                  // directory does not exist
                  MessageBox.Show("Cannot apply exclude path: " + folderName, "FSW Error");
                  dataGridViewPathsExclude.ClearSelection();
                  dataGridViewPathsExclude.Rows[i].Selected = true;
                  return;
               }
 
               // append string to directory-container
               pathsToExclude.add(folderName);
            }
         }
 
         // inform caller to rebuild its FileSystemWatchers
         parentForm.rebuildFileSystemWatchersList(pathsToInclude);
         // store directories to file
         pathsToInclude.safe("FSWPathsInclude.txt");
         // store directories to file
         pathsToExclude.safe("FSWPathsExclude.txt");
 
         // hide this window
         Close();
      }
 
      // discard user edits and close window
      private void buttonCancel_Click(object sender, EventArgs e)
      {
         Close();
      }
 
      // user clicked include-dataGridView cell
      private void dataGridViewPathsInclude_CellContentClick(object sender, DataGridViewCellEventArgs e)
      {
         // check if user clicked the open... button
         if (e.ColumnIndex == 1 && e.RowIndex >= 0)
         {
            // yes, show the "browse folder dialog"
            DialogResult result = folderBrowserDialog1.ShowDialog();
            // user confirmed selected path?
            if (result == DialogResult.OK)
            {
               // get the path
               String s = folderBrowserDialog1.SelectedPath;
               if (s != "")
               {
                  // first, add a new row. user can enter another path there afterwards
                  dataGridViewPathsInclude.Rows.Add();
                  // set path-text for this row
                  dataGridViewPathsInclude.Rows[e.RowIndex].Cells["ColumnEditPath"].Value = s;
               }
            }
         }
      }
 
      // called whenever a row is added to the include-dataGridView
      private void dataGridViewPathsInclude_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
      {
         // set text for open... button
         dataGridViewPathsInclude.Rows[e.RowIndex].Cells["ColumnButtonDirOpnDlg"].Value = "Open...";
      }
 
      // user clicked exclude-dataGridView cell
      private void dataGridViewPathsExclude_CellContentClick(object sender, DataGridViewCellEventArgs e)
      {
         // check if user clicked the open... button
         if (e.ColumnIndex == 1 && e.RowIndex >= 0)
         {
            // yes, show the "browse folder dialog"
            DialogResult result = folderBrowserDialog1.ShowDialog();
            // user confirmed selected path?
            if (result == DialogResult.OK)
            {
               // get the path
               String s = folderBrowserDialog1.SelectedPath;
               if (s != "")
               {
                  // first, add a new row. user can enter another path there afterwards
                  dataGridViewPathsExclude.Rows.Add();
                  // set path-text for this row
                  dataGridViewPathsExclude.Rows[e.RowIndex].Cells["dataGridViewTextBoxColumn1"].Value = s;
               }
            }
         }
      }
 
      // called whenever a row is added to the exclude-dataGridView
      private void dataGridViewPathsExclude_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
      {
         // set text for open... button
         dataGridViewPathsExclude.Rows[e.RowIndex].Cells["ColumnOpenButton"].Value = "Open...";
      }
   }
}