using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.IO;
using Telerik.WebControls;

namespace FileExplorer
{
  public partial class _Default : System.Web.UI.Page
  {
    #region properties

        private string CurrentPath
        {
          get
          {
            return RadTreeView1.SelectedNode == null ?
              tbPath.Text : RadTreeView1.SelectedNode.Value;
          }
        }

        private SearchOption CurrentSearchOption
        {
          get
          {
            return cbSubDirectories.Checked ?
                SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
          }
        }

        #endregion properties

    #region private methods

    private RadTreeNode GetTreeNode(string name, string value, bool isExpanded)
    {
      RadTreeNode node = new RadTreeNode(name);
      node.ImageUrl = "Img/mailfolder.gif";
      node.Expanded = isExpanded;
      node.Value = value;
      return node;
    }

    private string GetImageForExtension(string fileName)
    {
      string image = "File.gif";

      switch (Path.GetExtension(fileName))
      {
        case ".cs": image = "cs.gif"; break;
        case ".css": image = "css.gif"; break;
        case ".html": image = "html.gif"; break;
        case ".resx": image = "resx.gif"; break;
        case ".vb": image = "vb.gif"; break;
        case ".xml": image = "xml.gif"; break;
        case ".ascx":
        case ".aspx": image = "ascx.gif"; break;
        case ".gif":
        case ".jpg": image = "gif.gif"; break;
        case "": image = "mailfolder.gif"; break;
      }
      return image;
    }

    private string[] GetDirectories(string path)
    {
      string[] directories = new string[0];
      try
      {
        directories = Directory.GetDirectories(path, "*.*", this.CurrentSearchOption);
      }
      catch (UnauthorizedAccessException)
      {
        // ignore
      }
      return directories;
    }

    private DataTable GetFileList(string path)
    {
      DataTable fileList = new DataTable();
      fileList.Columns.Add("Name");
      fileList.Columns.Add("Size");
      fileList.Columns.Add("Path");

      DirectoryInfo dir = new DirectoryInfo(path);

      try
      {
        foreach (DirectoryInfo subDir in dir.GetDirectories())
        {
          fileList.Rows.Add(
            new string[] { subDir.Name, "-1", subDir.FullName });
        }

        foreach (FileInfo file in dir.GetFiles())
        {
          fileList.Rows.Add(
            new string[] { file.Name, file.Length.ToString(), file.FullName });
        }
      }
      catch (UnauthorizedAccessException)
      {
        // ignore
      }

      return fileList;
    }

    private LiteralControl GetFramesetElement(string name, string value)
    {
      const string elementFormat = "<label>{0}</label>" +
        "<input class=\"FileInput\" disabled=\"true\" type=\"text\": value=\"{1}\">" +
        "<br>";
      return new LiteralControl(string.Format(elementFormat, name, value));
    }

    private LiteralControl GetLegend(string legend)
    {
      return new LiteralControl(
        string.Format("<legend>{0}</legend>", legend));
    }

    private void UpdateFrameset(HtmlGenericControl frameset, string path)
    {
      FileAttributes attributes = File.GetAttributes(path);

      frameset.Controls.Clear();
      frameset.Controls.Add(
        GetLegend(Path.GetFileNameWithoutExtension(path)));
      frameset.Controls.Add(
        GetFramesetElement("Path", path));
      frameset.Controls.Add(
        GetFramesetElement("Attributes", attributes.ToString()));
      frameset.Controls.Add(
        GetFramesetElement("Created On", File.GetCreationTime(path).ToString()));
      frameset.Controls.Add(
        GetFramesetElement("Last Modified", File.GetLastWriteTime(path).ToString()));
      frameset.Controls.Add(
        GetFramesetElement("Last Access", File.GetLastAccessTime(path).ToString()));
      if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
      {
        try
        {
          string[] files =
            Directory.GetFiles(path, "*.*", this.CurrentSearchOption);
          frameset.Controls.Add(
            GetFramesetElement("File Count", files.Length.ToString()));
        }
        catch
        {
          // ignore access exception
        }
      }
    }

    private void LoadTreeView(RadTreeView treeview)
    {
      treeview.Nodes.Clear();
      RadTreeNode rootNode = GetTreeNode(
        this.CurrentPath, this.CurrentPath, true);
      treeview.Nodes.Add(rootNode);

      BindDirectory(this.CurrentPath, rootNode.Nodes);
    }

    private void BindDirectory(string dirPath, RadTreeNodeCollection nodes)
    {
      if (dirPath == string.Empty)
        return;

      string[] dirs = this.GetDirectories(dirPath);
      foreach (string path in dirs)
      {
        string[] parts = path.Split('\\');
        string name = parts[parts.Length - 1];
        RadTreeNode node = GetTreeNode(name, path, false);

        string[] directories = this.GetDirectories(path);
        if (directories.Length > 0)
        {
          node.ExpandMode = ExpandMode.ServerSide;
        }
        nodes.Add(node);
      }
    }

    #endregion private methods

    #region event handlers

    protected void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack)
      {
        LoadTreeView(RadTreeView1);
      }
    }

    protected void RadTreeView1_NodeClick(object o, RadTreeNodeEventArgs e)
    {
      RadGrid1.DataSource = GetFileList(this.CurrentPath);
      RadGrid1.DataBind();
    }

    protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
    {
      if (e.Item is GridDataItem)
      {
        System.Web.UI.WebControls.Image icon =
          (System.Web.UI.WebControls.Image)e.Item.FindControl("icon");
        icon.ImageUrl = "Img/" +
          GetImageForExtension((string)DataBinder.Eval(e.Item.DataItem, "Name"));
        icon.AlternateText = "icon";
        icon.ImageAlign = System.Web.UI.WebControls.ImageAlign.AbsMiddle;
        icon.Style.Add("vertical-align", "middle");
        icon.BorderWidth = Unit.Pixel(0);

        GridDataItem dataItem = (GridDataItem)e.Item;

        string fileLength = (string)DataBinder.Eval(e.Item.DataItem, "Size");
        if (fileLength != "-1")
          dataItem["Size"].Text = fileLength;
        else
          dataItem["Size"].Text = " ";
      }
    }

    protected void RadTreeView1_NodeExpand(object o, RadTreeNodeEventArgs e)
    {
      if (e.NodeClicked.Nodes.Count == 0)
      {
        BindDirectory(e.NodeClicked.Value, e.NodeClicked.Nodes);
      }
    }

    public void AjaxRequest(object source,
        Telerik.WebControls.AjaxRequestEventArgs e)
    {
      string[] arguments = e.Argument.Split(':');
      string commandName = arguments[0];
      switch (commandName)
      {
        case "RowClick":
          {
            int index = int.Parse(arguments[1]);
            GridDataItem item = RadGrid1.Items[index];
            Label pathLabel = item.FindControl("pathLabel") as Label;
            UpdateFrameset(details, pathLabel.Text);

            break;
          }
        case "Refresh":
          {
            LoadTreeView(RadTreeView1);
            RadGrid1.DataSource = GetFileList(this.CurrentPath);
            RadGrid1.DataBind();
            break;
          }
      }
    }

    #endregion event handlers
  }
}
