using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;


namespace bitcasaViewer
{
    public partial class Form1 : Form
    {
        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            if (ongoing)
            {
                MessageBox.Show("now processing...");
                e.Cancel = true;
                return;
            }
            bool folder_flag = false;
            bool file_flag = false;
            downloadToolStripMenuItem.Enabled = false;
            uploadToolStripMenuItem.Enabled = false;
            renameToolStripMenuItem.Enabled = false;
            moveToolStripMenuItem.Enabled = false;
            copyToolStripMenuItem.Enabled = false;
            mkDirToolStripMenuItem.Enabled = false;
            foreach (ListViewItem listitem in listView1.SelectedItems)
            {
                if ((listitem.SubItems[0].Text == ".") || (listitem.SubItems[0].Text == ".."))
                {
                    folder_flag = true;
                    continue;
                }
                try
                {
                    var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
                    if (item.id != "")
                    {
                        file_flag = true;
                        continue;
                    }
                    if (item.category == "folders")
                        folder_flag = true;
                }
                catch { return; }
            }
            if (file_flag && folder_flag)
            {
                return;
            }
            downloadToolStripMenuItem.Enabled = file_flag;
            uploadToolStripMenuItem.Enabled = ((listView1.SelectedItems.Count == 1) && folder_flag);
            renameToolStripMenuItem.Enabled = (listView1.SelectedItems.Count == 1);
            mkDirToolStripMenuItem.Enabled = ((listView1.SelectedItems.Count == 1) && folder_flag);
            if (SelectedFiles.Count < 1)
            {
                moveToolStripMenuItem.Enabled = true;
                moveToolStripMenuItem.Text = "Move ...";
                copyToolStripMenuItem.Enabled = true;
                copyToolStripMenuItem.Text = "Copy ...";
            }
            else
            {
                moveToolStripMenuItem.Enabled = ((listView1.SelectedItems.Count == 1) && folder_flag);
                moveToolStripMenuItem.Text = "Move here";
                copyToolStripMenuItem.Enabled = ((listView1.SelectedItems.Count == 1) && folder_flag);
                copyToolStripMenuItem.Text = "Copy here";
            }
        }

        private async void downloadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 1)
            {
                var fullpath = listView1.SelectedItems[0].SubItems[3].Text;
                string itemname;
                lock (typeof(BitcasaFileInfo))
                {
                    var item = BitcasaFileInfo.dirTree[fullpath];
                    if (item.id == "") return;
                    itemname = item.name;
                }
                saveFileDialog1.FileName = itemname;
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    progress(0);
                    ongoing = true;
                    toolStripStatusLabel1.Text = "downloading... " + itemname;
                    try
                    {
                        var ret = await Task.Run(
                            () =>
                            {
                                lock (bitcasa)
                                    lock (typeof(BitcasaFileInfo))
                                    {
                                        var item = BitcasaFileInfo.dirTree[fullpath];
                                        return bitcasa.download(
                                            item,
                                            saveFileDialog1.FileName,
                                            (int p) => this.BeginInvoke(
                                                (BitcasaServer.delegateProgressBar)(
                                                    (int x) =>
                                                    {
                                                        progress(x);
                                                    }),
                                                new object[] { p }
                                            )
                                        );
                                    }
                            });

                        if (ret)
                        {
                            progress(100);
                        }
                        else
                        {
                            MessageBox.Show("download failed.");
                            progress(0);
                        }
                    }
                    catch
                    {
                        progress(0);
                        throw;
                    }
                    toolStripStatusLabel1.Text = "";
                    ongoing = false;
                }
            }
            if (listView1.SelectedItems.Count > 1)
            {
                if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                {
                    ArrayList targetfulpass = new ArrayList();
                    lock (typeof(BitcasaFileInfo))
                    {
                        foreach (ListViewItem listitem in listView1.SelectedItems)
                        {
                            var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
                            if (item.id == "") continue;

                            targetfulpass.Add(listitem.SubItems[3].Text);
                        }
                    }
                    progress(0);
                    ongoing = true;
                    try
                    {
                        var result = await Task.Run(
                            () =>
                            {
                                lock (bitcasa)
                                {
                                    var path = folderBrowserDialog1.SelectedPath + "\\";
                                    bool ret = true;
                                    foreach (string target in targetfulpass)
                                    {
                                        lock (typeof(BitcasaFileInfo))
                                        {
                                            var item = BitcasaFileInfo.dirTree[target];
                                            this.BeginInvoke((MethodInvoker)(() => toolStripStatusLabel1.Text = "downloading... " + item.name));
                                            ret = bitcasa.download(
                                                item,
                                                path + item.name,
                                                (int p) => this.BeginInvoke(
                                                    (BitcasaServer.delegateProgressBar)(
                                                        (int x) =>
                                                        {
                                                            progress(x);
                                                        }),
                                                    new object[] { p }
                                                )
                                            );
                                            if (!ret) break;
                                        }
                                    }
                                    return ret;
                                }
                            });
                        if (result)
                        {
                            progress(100);
                        }
                        else
                        {
                            MessageBox.Show("download failed.");
                            progress(0);
                        }
                    }
                    catch
                    {
                        progress(0);
                        throw;
                    }
                    toolStripStatusLabel1.Text = "";
                    ongoing = false;
                }
            }
        }

        private async void uploadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (SelectItemToFileinfo().path == "") return;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                progress(0);
                ongoing = true;
                treeView1.Enabled = false;
                listView1.Enabled = false;
                var filename = openFileDialog1.FileName;
                toolStripStatusLabel1.Text = "uploading... " + filename;
                try
                {
                    var ret = await Task.Run(
                        () =>
                        {
                            lock (bitcasa)
                            {
                                lock (typeof(BitcasaFileInfo))
                                {
                                    var item = SelectItemToFileinfo(); 
                                    return bitcasa.upload(
                                        item,
                                        filename,
                                        (int p) => this.BeginInvoke(
                                            (BitcasaServer.delegateProgressBar)(
                                                (int x) =>
                                                {
                                                        if (x < 0)
                                                        {
                                                            toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
                                                        }
                                                        else
                                                        {
                                                            toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
                                                            progress(x);
                                                        }
                                                }),
                                            new object[] { p }
                                        )
                                    );
                                }
                            }
                        });
                    toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
                    if (ret)
                    {
                        progress(100);
                    }
                    else
                    {
                        MessageBox.Show("upload not completed(failed or too slow response).");
                        progress(0);
                    }
                }
                catch
                {
                    progress(0);
                    throw;
                }
                toolStripStatusLabel1.Text = "";
                ongoing = false;
                treeView1.Enabled = true;
                listView1.Enabled = true;
            }
            if (checkBox_reload.Checked)
                reloadview();
        }

        private void mkDirToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lock (typeof(BitcasaFileInfo))
            {
                var item = SelectItemToFileinfo();
                if (item.path == "") return;
                var dialog = new FormInput();
                dialog.LabelText = "enter new name";
                dialog.InputString = "";
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    if (dialog.InputString == item.name) return;
                    if (dialog.InputString == "") return;

                    lock (bitcasa)
                    {
                        if (!bitcasa.mkDir(item, dialog.InputString, this.progress))
                        {
                            MessageBox.Show("AddFolder failed.");
                            return;
                        }
                    }
                }
                if (checkBox_reload.Checked)
                    reloadview();
            }
        }

        private void renameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lock (typeof(BitcasaFileInfo))
            {
                try
                {
                    var seletedItem = listView1.SelectedItems[0];
                    if ((seletedItem.SubItems[0].Text == ".") || (seletedItem.SubItems[0].Text == "..")) return;
                    var item = BitcasaFileInfo.dirTree[seletedItem.SubItems[3].Text];
                    var dialog = new FormInput();
                    dialog.LabelText = "enter new name";
                    dialog.InputString = item.name;
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        if (dialog.InputString == item.name) return;
                        lock (bitcasa)
                        {
                            if (!bitcasa.rename(item, dialog.InputString, this.progress))
                            {
                                MessageBox.Show("Rename failed.");
                                return;
                            }
                        }
                    }
                }
                catch { return; }
                if (checkBox_reload.Checked)
                    reloadview();
            }
        }

        private void pushSelectedList()
        {
            lock (typeof(BitcasaFileInfo))
            {
                foreach (ListViewItem listitem in listView1.SelectedItems)
                {
                    try
                    {
                        var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
                        if (item.name == "") continue;
                        SelectedFiles.Add(item);
                    }
                    catch { continue; }
                }
            }
        }

        private void moveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (SelectedFiles.Count < 1)
            {
                pushSelectedList();
            }
            else
            {
                lock (bitcasa)
                {
                    lock (typeof(BitcasaFileInfo))
                    {
                        var item = SelectItemToFileinfo();
                        if (item.path == "") return;
                        if (!bitcasa.moveitem((BitcasaFileInfo[])SelectedFiles.ToArray(typeof(BitcasaFileInfo)), item, this.progress))
                            MessageBox.Show("Move failed.");
                        SelectedFiles.Clear();
                    }
                }
            }
            if (checkBox_reload.Checked)
                reloadview();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (SelectedFiles.Count < 1)
            {
                pushSelectedList();
            }
            else
            {
                lock (bitcasa)
                {
                    lock (typeof(BitcasaFileInfo))
                    {
                        var item = SelectItemToFileinfo();
                        if (item.path == "") return;
                        if (!bitcasa.copyitem((BitcasaFileInfo[])SelectedFiles.ToArray(typeof(BitcasaFileInfo)), item, this.progress))
                            MessageBox.Show("Copy failed.");
                        SelectedFiles.Clear();
                    }
                }
            }
            if (checkBox_reload.Checked)
                reloadview();
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ArrayList delFiles = new ArrayList();

            lock (typeof(BitcasaFileInfo))
            {
                foreach (ListViewItem listitem in listView1.SelectedItems)
                {
                    if ((listitem.SubItems[0].Text == ".") || (listitem.SubItems[0].Text == "..")) continue;
                    try
                    {
                        var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
                        if (item.name == "") continue;
                        delFiles.Add(item);
                    }
                    catch { continue; }
                }
            }
            lock (bitcasa)
            {
                if (!bitcasa.deleteitem((BitcasaFileInfo[])delFiles.ToArray(typeof(BitcasaFileInfo)), this.progress))
                    MessageBox.Show("Delete failed.");
            }
            if (checkBox_reload.Checked)
                reloadview();
        }
    }
}
