using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MySQL.Grt;
using MySQL.Utilities;
using MySQL.GUI.Workbench.Plugins;

namespace MySQL.GUI.Workbench.Plugins.Wb
{
  public partial class WBPluginAddonManagerPages : WizardPluginPages
  {
    private Wb_addon_manager addonMan;
    String guid;
    String version;

    public WBPluginAddonManagerPages(WizardPlugin wizard)
      : base(wizard)
    {
      InitializeComponent();

      addonMan = new Wb_addon_manager(wizard.GrtManager);

      AddPage(rootMenuPanel,
        null,
        null,
        null,
        null,
        null,
        "Install/Uninstall",
        "Choose action to perform.");

      AddPage(installSelectionPanel,
        InitializeInstallSelectionPage,
        null,
        ProcessInstallSelectionPage,
        null,
        IsInstallSelectionPageToBeSkipped,
        "Specify addon",
        "Specify addon to install by providing its URL.");

      AddPage(installPanel,
        InitializeInstallPage,
        null,
        null,
        null,
        IsInstallPageToBeSkipped,
        "Install",
        "Install chosen addon.");

      AddPage(uninstallSelectionPanel,
        InitializeUninstallSelectionPage,
        null,
        ProcessUninstallSelectionPage,
        null,
        IsUninstallSelectionPageToBeSkipped,
        "Select addon(s)",
        "Select addon(s) to uninstall.");

      AddPage(uninstallPanel,
        InitializeUninstallPage,
        CleanupUninstallPage,
        null,
        null,
        IsUninstallPageToBeSkipped,
        "Uninstall",
        "Uninstall chosen addon(s).");
    }

    private void PrepareTask(PageTask pageTask)
    {
      addonMan.task_msg_cb(pageTask.ProcessTaskMsg);
      addonMan.task_progress_cb(pageTask.ProcessTaskProgress);
      addonMan.task_fail_cb(pageTask.ProcessTaskFail);
      addonMan.task_finish_cb(pageTask.ProcessTaskFinish);
    }

    #region InstallSelection

    private String InitializeInstallSelectionPage()
    {
      toolTip1.SetToolTip(addonDirLinkLabel, addonMan.directory_page_url());
      return "";
    }

    private String IsInstallSelectionPageToBeSkipped()
    {
      return installRB.Checked ? "" : "1";
    }

    private void addonListPanel_DragDrop(object sender, DragEventArgs e)
    {
      String data = e.Data.GetData(DataFormats.Text) as String;
      if (null != data)
        addonManifestUrlTB.Text = data;
    }

    private void addonListPanel_DragEnter(object sender, DragEventArgs e)
    {
      String data = e.Data.GetData(DataFormats.Text) as String;
      if (null != data)
        e.Effect = DragDropEffects.Link;
    }

    private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
      System.Diagnostics.Process.Start(addonMan.directory_page_url());
    }

    #endregion InstallSelection


    #region Install

    private String LoadManifests()
    {
      addonMan.load_manifest_from_url(addonManifestUrlTB.Text, ref guid, ref version);
      return "";
    }

    private String DownloadPackages()
    {
      cancelDownloadBtn.Enabled = true;
      addonMan.start_download(guid, version);
      return "";
    }

    private String InstallPackages()
    {
      addonMan.install(guid, version);
      return "";
    }

    private void AfterDownload(PageTask pageTask)
    {
      cancelDownloadBtn.Enabled = false;
    }

    private String InitializeInstallPage()
    {
      pageTasks.Setup(installResultLabel, null);

      cancelDownloadBtn.Enabled = false;

      installLogTextBox.Text = "";
      downloadProgressDetailsLabel.Text = "";
      downloadProgressBar.Minimum = 0;
      downloadProgressBar.Maximum = 100;

      pageTasks.Add(
        false,
        false,
        "Loading manifest(s)...",
        loadManifestsLabel,
        installStageLabel,
        installResultLabel,
        installPanel,
        installLogTextBox,
        PrepareTask,
        LoadManifests,
        null,
        null,
        null,
        null);

      pageTasks.Add(
        true,
        false,
        "Downloading package(s)...",
        downloadPackagesLabel,
        installStageLabel,
        installResultLabel,
        installPanel,
        installLogTextBox,
        PrepareTask,
        DownloadPackages,
        AfterDownload,
        AfterDownload,
        downloadProgressBar,
        downloadProgressDetailsLabel);

      pageTasks.Add(
        false,
        false,
        "Installing package(s)...",
        installPackagesLabel,
        installStageLabel,
        installResultLabel,
        installPanel,
        installLogTextBox,
        PrepareTask,
        InstallPackages,
        null,
        null,
        null,
        null);

      return pageTasks.Exec();
    }

    private String ProcessInstallSelectionPage()
    {
      String errMsg = "";
      if (0 == addonManifestUrlTB.Text.Length)
        errMsg = "Addon URL was not specified.";
      return errMsg;
    }

    private String IsInstallPageToBeSkipped()
    {
      return installRB.Checked ? "" : "1";
    }

    private void cancelDownloadBtn_Click(object sender, EventArgs e)
    {
      addonMan.cancel_download();
    }

    #endregion Install


    #region UninstallSelection

    private void ReloadInstalledAddonsList()
    {
      //! todo: run async
      installedAddonsLV.Items.Clear();

      List<String> installedAddonsGuids = new List<String>();
      List<String> installedAddonsNames = new List<String>();
      addonMan.get_installed_addons(ref installedAddonsGuids, ref installedAddonsNames);
      for (int n = 0; n < installedAddonsGuids.Count; ++n)
        installedAddonsLV.Items.Add(installedAddonsGuids[n], installedAddonsNames[n], -1);
    }

    private String InitializeUninstallSelectionPage()
    {
      ReloadInstalledAddonsList();
      return "";
    }

    private String ProcessUninstallSelectionPage()
    {
      String errMsg = "";
      if (0 == installedAddonsLV.SelectedItems.Count)
        errMsg = "Addon was not selected.";
      return errMsg;
    }

    private String IsUninstallSelectionPageToBeSkipped()
    {
      return uninstallRB.Checked ? "" : "1";
    }

    #endregion UninstallSelection


    #region Uninstall

    private String UninstallPackages()
    {
      foreach (ListViewItem item in installedAddonsLV.SelectedItems)
      {
        String addonGuid = item.Name;
        addonMan.uninstall(addonGuid);
      }
      return "";
    }

    private String InitializeUninstallPage()
    {
      pageTasks.Setup(uninstallResultLabel, null);

      uninstallLogTextBox.Text = "";
      uninstallProgressDetailsLabel.Text = "";
      uninstallProgressBar.Minimum = 0;
      uninstallProgressBar.Maximum = 100;

      pageTasks.Add(
        false,
        false,
        "Uninstalling package(s)...",
        uninstallPackagesLabel,
        uninstallStageLabel,
        uninstallResultLabel,
        uninstallPanel,
        uninstallLogTextBox,
        PrepareTask,
        UninstallPackages,
        null,
        null,
        uninstallProgressBar,
        uninstallProgressDetailsLabel);

      return pageTasks.Exec();
    }

    private String CleanupUninstallPage()
    {
      ReloadInstalledAddonsList();
      return "";
    }

    private String IsUninstallPageToBeSkipped()
    {
      return uninstallRB.Checked ? "" : "1";
    }

    #endregion Uninstall

  }
}