context: using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.IO;
  using System.Text;
  using System.Threading;
  using System.Windows.Forms;
  using DarkMouse.Explorer;
  using DarkMouse.Util;
  
  namespace DarkMouse
  {
      public partial class FormSearch : Form
      {
          static FormSearch _Instance;
          public static FormSearch Instance
          {
              get
              {
                  if (_Instance == null)
                  {
                      _Instance = new FormSearch();
                  }
                  return _Instance;
              }
          }
  
          public delegate void InvokeUIDelegate(params string[] param);
  
          public void InvokeUI(params string[] param)
          {
              if (InvokeRequired)
              {
                  InvokeUIDelegate invokeUIDelegate = new InvokeUIDelegate(InvokeUI);
                  BeginInvoke(invokeUIDelegate, new object[] { param });
                  return;
              }
              switch (param[0])
              {
                  case "Update":
                      lblInfo.Text = param[1];
                      break;
                  case "AddFolder":
                      DirectoryInfo di = new DirectoryInfo(param[1]);
                      ListViewItem lviFolder = new ListViewItem(new string[] { di.Name, "", di.Parent.FullName, di.CreationTime.ToString("yyyy-MM-dd HH:mm:ss") });
                      lviFolder.ImageIndex = 0;
                      listItems.Items.Add(lviFolder);
                      break;
                  case "AddFile":
                      FileInfo fi = new FileInfo(param[1]);
                      ListViewItem lviFile = new ListViewItem(new string[] { fi.Name, FileUtil.GetSizeString(fi.Length, 2), fi.Directory.FullName, fi.CreationTime.ToString("yyyy-MM-dd HH:mm:ss") });
                      try
                      {
                          lviFile.ImageIndex = IconUtil.GetFile(fi.FullName);
                      }
                      catch (Exception)
                      {
                          lviFile.ImageIndex = IconUtil.GetExtension(fi.FullName);
                      }
                      Color bgColor = Color.White;
                      Color fgColor = Color.Black;
                      switch (fi.Extension.ToLower())
                      {
                          case ".png":
                              bgColor = Color.FromArgb(232, 222, 220);
                              break;
                          case ".jpg":
                          case ".jpeg":
                              bgColor = Color.FromArgb(237, 237, 202);
                              break;
                          case ".gif":
                          case ".frames":
                              bgColor = Color.FromArgb(220, 235, 220);
                              break;
                          case ".bmp":
                              bgColor = Color.FromArgb(227, 227, 255);
                              break;
                          case ".zip":
                              fgColor = Color.FromArgb(0, 90, 0);
                              break;
                          default:
                              break;
                      }
                      lviFile.BackColor = bgColor;
                      lviFile.ForeColor = fgColor;
                      listItems.Items.Add(lviFile);
                      break;
                  case "SearchDone":
                      Running = false;
                      SetSearchStatus();
                      lblInfo.Text = "Ready";
                      break;
                  default:
                      break;
              }
          }
  
          bool Running = false;
          bool SearchFile = true, SearchFolder = true;
          string Keyword = "";
          DateTime? From, To;
  
          FormSearch()
          {
              InitializeComponent();
              ddlTarget.SelectedIndex = 0;
          }
  
          private void btnSearch_Click(object sender, EventArgs e)
          {
              if (ItemList.DirPath.Length == 0)
              {
                  MessageBox.Show("Can't search root folder.", "DarkMouse", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                  return;
              }
              if (ddlTarget.SelectedIndex == 1)
              {
                  SearchFolder = false;
              }
              if (ddlTarget.SelectedIndex == 2)
              {
                  SearchFile = false;
              }
              Keyword = tbKeyword.Text;
              DateTime dtFrom, dtTo;
              if (DateTime.TryParse(tbFrom.Text, out dtFrom))
              {
                  From = dtFrom;
              }
              if (DateTime.TryParse(tbFrom.Text, out dtTo))
              {
                  To = dtTo;
              }
              Running = true;
              SetSearchStatus();
              new Thread(WorkThread).Start();
          }
  
          private void btnCancel_Click(object sender, EventArgs e)
          {
              Running = false;
          }
  
          private void btnClear_Click(object sender, EventArgs e)
          {
              listItems.Items.Clear();
              ddlTarget.SelectedIndex = 0;
              tbKeyword.Text = "";
          }
  
          private void listItems_MouseDoubleClick(object sender, MouseEventArgs e)
          {
              if (listItems.SelectedIndices.Count > 0)
              {
                  ListViewItem lvi = listItems.SelectedItems[0];
                  ItemList.Jump(lvi.SubItems[2].Text.TrimEnd('\\') + "\\", false);
                  FormMain.Instance.Select(lvi.SubItems[0].Text);
              }
          }
  
          private void FormSearch_FormClosing(object sender, FormClosingEventArgs e)
          {
              e.Cancel = true;
              Hide();
          }
  
          void SetSearchStatus()
          {
              btnSearch.Enabled = !Running;
              btnCancel.Enabled = Running;
          }
  
          void WorkThread()
          {
              Search(new DirectoryInfo(ItemList.DirPath));
              InvokeUI("SearchDone");
          }
  
          void Search(DirectoryInfo dir)
          {
              foreach (DirectoryInfo sub in dir.GetDirectories())
              {
                  if (!Running)
                  {
                      return;
                  }
                  InvokeUI("Update", sub.FullName);
                  Search(sub);
              }
              if (SearchFolder)
              {
                  foreach (DirectoryInfo di in dir.GetDirectories(Keyword, SearchOption.TopDirectoryOnly))
                  {
                      if (!Running)
                      {
                          return;
                      }
                      if (From.HasValue && di.CreationTime < From.Value)
                      {
                          continue;
                      }
  
gt:                     if (To.HasValue && di.CreationTime > To.Value)