// Оригинальная версия написана Cristian Forsberg
// и находится по адресу 
//http://www.businessanyplace.net/?p=spfileman


// Переделано и переведено на русский для Windows Mobile 6
// Visual Studio 2008
// Александр Климов

//------------------------------------------------------------------------------
/// <copyright from='2004' to='2005' company='Christian Forsberg'>
///		Copyright (c) Christian Forsberg, chris@businessanyplace.net.
///
///   This program is distributed in the hope that it will be useful,
///   but WITHOUT ANY WARRANTY; without even the implied warranty of
///   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
/// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace FileManager
{
  public delegate void SetNameDelegate(string name);
  public delegate void SetAttributesDelegate(FileAttributes fileAttributes);

  /// <summary>
	/// Главная форма
	/// </summary>
	public class MainForm : System.Windows.Forms.Form
	{
    private const string UPDIR = "..";
    private string path;
    private string clipboardFileName = string.Empty;
    private ClipboardAction clipboardAction = ClipboardAction.None;

    private enum ClipboardAction
    {
      None,
      Cut,
      Copy
    }

    #region Windows Form Designer generated declarations
    private System.Windows.Forms.MainMenu mainMenu;
    private System.Windows.Forms.MenuItem doneMenuItem;
    private System.Windows.Forms.MenuItem menuMenuItem;
    private System.Windows.Forms.MenuItem cutMenuItem;
    private System.Windows.Forms.MenuItem copyMenuItem;
    private System.Windows.Forms.MenuItem pasteMenuItem;
    private System.Windows.Forms.MenuItem deleteMenuItem;
    private System.Windows.Forms.ListView listView;
    private System.Windows.Forms.ColumnHeader itemsColumnHeader;
    private System.Windows.Forms.MenuItem propertiesMenuItem;
    private System.Windows.Forms.MenuItem renameMenuItem;
    private System.Windows.Forms.MenuItem newFolderMenuItem;
    private System.Windows.Forms.MenuItem pasteShortcutMenuItem;
    private System.Windows.Forms.MenuItem aboutMenuItem;
    private System.Windows.Forms.ImageList imageList;
    #endregion

		public MainForm()
		{
			InitializeComponent();
		}

    #region Dispose
    /// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			base.Dispose( disposing );
		}
    #endregion

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.mainMenu = new System.Windows.Forms.MainMenu();
            this.doneMenuItem = new System.Windows.Forms.MenuItem();
            this.menuMenuItem = new System.Windows.Forms.MenuItem();
            this.cutMenuItem = new System.Windows.Forms.MenuItem();
            this.copyMenuItem = new System.Windows.Forms.MenuItem();
            this.pasteMenuItem = new System.Windows.Forms.MenuItem();
            this.pasteShortcutMenuItem = new System.Windows.Forms.MenuItem();
            this.renameMenuItem = new System.Windows.Forms.MenuItem();
            this.deleteMenuItem = new System.Windows.Forms.MenuItem();
            this.newFolderMenuItem = new System.Windows.Forms.MenuItem();
            this.propertiesMenuItem = new System.Windows.Forms.MenuItem();
            this.aboutMenuItem = new System.Windows.Forms.MenuItem();
            this.listView = new System.Windows.Forms.ListView();
            this.itemsColumnHeader = new System.Windows.Forms.ColumnHeader();
            this.imageList = new System.Windows.Forms.ImageList();
            // 
            // mainMenu
            // 
            this.mainMenu.MenuItems.Add(this.doneMenuItem);
            this.mainMenu.MenuItems.Add(this.menuMenuItem);
            // 
            // doneMenuItem
            // 
            this.doneMenuItem.Text = "Выход";
            this.doneMenuItem.Click += new System.EventHandler(this.doneMenuItem_Click);
            // 
            // menuMenuItem
            // 
            this.menuMenuItem.MenuItems.Add(this.cutMenuItem);
            this.menuMenuItem.MenuItems.Add(this.copyMenuItem);
            this.menuMenuItem.MenuItems.Add(this.pasteMenuItem);
            this.menuMenuItem.MenuItems.Add(this.pasteShortcutMenuItem);
            this.menuMenuItem.MenuItems.Add(this.renameMenuItem);
            this.menuMenuItem.MenuItems.Add(this.deleteMenuItem);
            this.menuMenuItem.MenuItems.Add(this.newFolderMenuItem);
            this.menuMenuItem.MenuItems.Add(this.propertiesMenuItem);
            this.menuMenuItem.MenuItems.Add(this.aboutMenuItem);
            this.menuMenuItem.Text = "Меню";
            this.menuMenuItem.Popup += new System.EventHandler(this.menuMenuItem_Popup);
            // 
            // cutMenuItem
            // 
            this.cutMenuItem.Text = "Вырезать";
            this.cutMenuItem.Click += new System.EventHandler(this.cutMenuItem_Click);
            // 
            // copyMenuItem
            // 
            this.copyMenuItem.Text = "Копировать";
            this.copyMenuItem.Click += new System.EventHandler(this.copyMenuItem_Click);
            // 
            // pasteMenuItem
            // 
            this.pasteMenuItem.Text = "Вставить";
            this.pasteMenuItem.Click += new System.EventHandler(this.pasteMenuItem_Click);
            // 
            // pasteShortcutMenuItem
            // 
            this.pasteShortcutMenuItem.Text = "Вставить ярлык";
            this.pasteShortcutMenuItem.Click += new System.EventHandler(this.pasteShortcutMenuItem_Click);
            // 
            // renameMenuItem
            // 
            this.renameMenuItem.Text = "Переименовать";
            this.renameMenuItem.Click += new System.EventHandler(this.renameMenuItem_Click);
            // 
            // deleteMenuItem
            // 
            this.deleteMenuItem.Text = "Удалить";
            this.deleteMenuItem.Click += new System.EventHandler(this.deleteMenuItem_Click);
            // 
            // newFolderMenuItem
            // 
            this.newFolderMenuItem.Text = "Создать папку";
            this.newFolderMenuItem.Click += new System.EventHandler(this.newFolderMenuItem_Click);
            // 
            // propertiesMenuItem
            // 
            this.propertiesMenuItem.Text = "Свойства";
            this.propertiesMenuItem.Click += new System.EventHandler(this.propertiesMenuItem_Click);
            // 
            // aboutMenuItem
            // 
            this.aboutMenuItem.Text = "О программе";
            this.aboutMenuItem.Click += new System.EventHandler(this.aboutMenuItem_Click);
            // 
            // listView
            // 
            this.listView.Columns.Add(this.itemsColumnHeader);
            this.listView.FullRowSelect = true;
            this.listView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
            this.listView.Location = new System.Drawing.Point(-1, -1);
            this.listView.Size = new System.Drawing.Size(178, 182);
            this.listView.SmallImageList = this.imageList;
            this.listView.View = System.Windows.Forms.View.Details;
            this.listView.ItemActivate += new System.EventHandler(this.listView_ItemActivate);
            this.listView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.listView_KeyUp);
            // 
            // itemsColumnHeader
            // 
            this.itemsColumnHeader.Text = "Items";
            this.itemsColumnHeader.Width = 170;
            this.imageList.Images.Clear();
            this.imageList.Images.Add(((System.Drawing.Image)(resources.GetObject("resource"))));
            this.imageList.Images.Add(((System.Drawing.Image)(resources.GetObject("resource1"))));
            // 
            // MainForm
            // 
            this.ClientSize = new System.Drawing.Size(176, 180);
            this.Controls.Add(this.listView);
            this.Menu = this.mainMenu;
            this.Text = "File Manager";
            this.Load += new System.EventHandler(this.MainForm_Load);

    }
		#endregion

    #region Main
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		static void Main() 
		{
			Application.Run(new MainForm());
		}
    #endregion

    private void MainForm_Load(object sender, System.EventArgs e)
    {
        ListViewHelper.SetGradient(listView);
                
        string bs = Path.DirectorySeparatorChar.ToString();

        // В Windows Mobile нет /Storage
        //this.path = bs + "Storage" + bs + "My Documents" + bs; //исправлено
      
        // Устанавливаем начальную папку
        this.path = bs + "My Documents" + bs;
        //path = bs;
        //path = Directory.GetCurrentDirectory();

        // Заполняем список папок и файлов
        fillList();
    }

        /// <summary>
        /// Заполнение ListView списком папок и файлов
        /// </summary>
        private void fillList()
        {
            Cursor.Current = Cursors.WaitCursor;

            // Заполняем ListView списком папок и файлов
            // в выбранной папке
            ListViewItem lvi;
            listView.BeginUpdate();
            listView.Items.Clear();

            // Если не корневая папка
            if(path.Length > 1)
            {
              // Добавляем папку "Вверх"
              lvi = new ListViewItem(UPDIR);
              lvi.ImageIndex = 0;
              listView.Items.Add(lvi);
            }

            // Добавляем папки
            string[] dirs = Directory.GetDirectories(path);
            ArrayList list = new ArrayList(dirs.Length);
            for(int i = 0; i < dirs.Length; i++)
                list.Add(dirs[i]);

            list.Sort(new SimpleComparer());

            foreach(string dir in list)
            {
                lvi = new ListViewItem(Path.GetFileName(dir));
                lvi.ImageIndex = 0;
                listView.Items.Add(lvi);
            }

            // Добавляем файлы
            string[] files = Directory.GetFiles(path);
            list = new ArrayList(files.Length);
            for(int i = 0; i < files.Length; i++)
                list.Add(files[i]);

            list.Sort(new SimpleComparer());

            foreach(string file in list)
            {
                lvi = new ListViewItem(Path.GetFileName(file));
                lvi.ImageIndex = 1;
                listView.Items.Add(lvi);
            }

            listView.EndUpdate();

            if(listView.Items.Count > 0)
            {
                // выделяем первый элемент
                listView.Items[0].Selected = true;
                listView.Items[0].Focused = true;
            }      
            Cursor.Current = Cursors.Default;
          }

        /// <summary>
        /// Навигация по папкам и файлам
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView_ItemActivate(object sender, System.EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
            bool isFolder = lvi.ImageIndex == 0;

            if(lvi.Text == UPDIR)
                {
                    path = path.Substring(0, path.Substring(0, path.Length - 1).LastIndexOf(Path.DirectorySeparatorChar) + 1);
                    fillList();
                }
            else if(isFolder)
                {
                    path += lvi.Text + Path.DirectorySeparatorChar;
                    fillList();
                }
           else
                ShellExecute.Start(path + lvi.Text);

            Cursor.Current = Cursors.Default;
        }

    private void listView_KeyUp(object sender, KeyEventArgs e)
    {
      int i = 0;
      int lineNo = 0;

      if((e.KeyCode == Keys.Left) || (e.KeyCode == Keys.Right))
      {
        e.Handled = true;
        i = ListViewHelper.GetTopIndex(listView);
        lineNo = listView.SelectedIndices[0] - i;
      }
      switch(e.KeyCode)
      {
        case Keys.Right:
          i += 19;
          if(i > listView.Items.Count)
            i = listView.Items.Count - 1;
          break;

        case Keys.Left:
          i -= 10;
          if(i < 0)
            i = 0;
          break;
      }
      if(e.Handled)
      {
        listView.EnsureVisible(i);
        i = ListViewHelper.GetTopIndex(listView) + lineNo;
        Cursor.Current = Cursors.WaitCursor;
        listView.BeginUpdate();
        listView.Items[i].Selected = true;
        listView.Items[i].Focused = true;
        listView.EndUpdate();
        Cursor.Current = Cursors.Default;
      }
    }

    private void doneMenuItem_Click(object sender, System.EventArgs e)
    {
      this.Close();
    }

    private void menuMenuItem_Popup(object sender, System.EventArgs e)
    {
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      bool isFolder = lvi.ImageIndex == 0;
      if(!(lvi.Text == UPDIR))
      {
        if(!isFolder)
        {
          cutMenuItem.Enabled = true;
          copyMenuItem.Enabled = true;
        }
        renameMenuItem.Enabled = true;
        deleteMenuItem.Enabled = true;
        propertiesMenuItem.Enabled = true;
      }

      pasteMenuItem.Enabled = clipboardAction != ClipboardAction.None;
      pasteShortcutMenuItem.Enabled = clipboardAction == ClipboardAction.Copy;
    }

    private void cutMenuItem_Click(object sender, System.EventArgs e)
    {
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      clipboardFileName = path + lvi.Text;
      clipboardAction = ClipboardAction.Cut;
    }

    private void copyMenuItem_Click(object sender, System.EventArgs e)
    {
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      clipboardFileName = path + lvi.Text;
      clipboardAction = ClipboardAction.Copy;
    }

    private void pasteMenuItem_Click(object sender, System.EventArgs e)
    {
      // Если файл существует
      string dest = path + Path.GetFileName(clipboardFileName);
      if(File.Exists(dest))
      {
        if(MessageBox.Show("Файл уже существует, перезаписать?", this.Text,
           MessageBoxButtons.YesNo, MessageBoxIcon.Question,
           MessageBoxDefaultButton.Button2) == DialogResult.Yes)
          File.Delete(dest);
        else
          return;
      }
      // Перемещаем или копируем
      string s = path.Substring(0, path.Length - 1);
      switch(clipboardAction)
      {
        case ClipboardAction.Cut:
          File.Move(clipboardFileName, dest);
          break;

        case ClipboardAction.Copy:
          File.Copy(clipboardFileName, dest, false);
          break;
      }
      clipboardAction = ClipboardAction.None;
      clipboardFileName = string.Empty;
      fillList();
    }

    private void pasteShortcutMenuItem_Click(object sender, System.EventArgs e)
    {
      int i = 2;
      string s = string.Empty;
      string dest;
      while(true)
      {
        dest = path + "Shortcut" + s + " to " + Path.GetFileName(Path.GetFileNameWithoutExtension(clipboardFileName) + ".lnk");
        if(!File.Exists(dest))
          break;
        s = " (" + i.ToString() + ")";
        i++;
      }
      StreamWriter sw = new StreamWriter(dest);
      s = clipboardFileName;
      if(s.IndexOf(" ") > 0)
        s = "\"" + s + "\"";
      s = s.Length.ToString() + "#" + s;
      sw.WriteLine(s);
      sw.Close();
      fillList();
    }

    private void renameMenuItem_Click(object sender, System.EventArgs e)
    {
      Cursor.Current = Cursors.WaitCursor;
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      bool isFolder = lvi.ImageIndex == 0;
      string s;
      if(isFolder)
        s = "папку";
      else
        s = "файл";
      NameForm nameForm = new NameForm(this, "Переименовать " + s, lvi.Text, new SetNameDelegate(SetRename));
      if(nameForm.ShowDialog() == DialogResult.OK)
        fillList();
      listView.Focus();
    }

        /// <summary>
        /// Метод для переименования папки или файла
        /// </summary>
        /// <param name="name">Имя папки или файла</param>
        public void SetRename(string name)
        {
            ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
            bool isFolder = lvi.ImageIndex == 0;
            string itemName = path + lvi.Text;
            string destName = Path.GetDirectoryName(itemName) + Path.DirectorySeparatorChar.ToString() + name;
            
            if(isFolder)
                Directory.Move(itemName, destName);
            else
                File.Move(itemName, destName);
        }

    private void deleteMenuItem_Click(object sender, System.EventArgs e)
    {
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      bool isFolder = lvi.ImageIndex == 0;
      string s = "Are you sure you want to delete " + lvi.Text;
      if(isFolder)
        s += " and all its content";
      s += "?";
      if(MessageBox.Show(s, this.Text,
        MessageBoxButtons.YesNo, MessageBoxIcon.Question,
        MessageBoxDefaultButton.Button2) == DialogResult.Yes)
      {
        if(isFolder)
          Directory.Delete(path + lvi.Text, true);
        else
          File.Delete(path + lvi.Text);
        fillList();
      }
    }

    private void newFolderMenuItem_Click(object sender, System.EventArgs e)
    {
      Cursor.Current = Cursors.WaitCursor;
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      NameForm nameForm = new NameForm(this, "Новая папка", "", new SetNameDelegate(SetNewName));
      if(nameForm.ShowDialog() == DialogResult.OK)
        fillList();
      listView.Focus();
    }

        /// <summary>
        /// Устанавливает новое имя для папки
        /// </summary>
        /// <param name="name">Имя для папки</param>
        public void SetNewName(string name)
        {
            Directory.CreateDirectory(path + name);
        }

    private void propertiesMenuItem_Click(object sender, System.EventArgs e)
    {
      Cursor.Current = Cursors.WaitCursor;
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      FileInfo fi = new FileInfo(path + lvi.Text);
      PropertiesForm propertiesForm = new PropertiesForm(this, fi, new SetNameDelegate(SetRename), new SetAttributesDelegate(SetAttributes));
      if(propertiesForm.ShowDialog() == DialogResult.OK)
        fillList();
      listView.Focus();
    }

    public void SetAttributes(FileAttributes fileAttributes)
    {
      ListViewItem lvi = listView.Items[listView.SelectedIndices[0]];
      bool isFolder = lvi.ImageIndex == 0;
      if(isFolder)
      {
        DirectoryInfo di = new DirectoryInfo(path + lvi.Text);
        di.Attributes = fileAttributes;
      }
      else
      {
        FileInfo fi = new FileInfo(path + lvi.Text);
        fi.Attributes = fileAttributes;
      }
    }


    private void aboutMenuItem_Click(object sender, System.EventArgs e)
    {
      MessageBox.Show("File Manager 1.0\n\nCopyright (c)2005 Christian Forsberg, chris@businessanyplace.net.", "О программе",
        MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);

    }
  }
}
