using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using Aga.Controls.Tree;
using MySQL.Grt;
using MySQL.Utilities;

namespace MySQL.GUI.Shell
{
  public delegate bool NewShellDocument(DockContent documentForm);

	/// <summary>
	/// Main Form of the GRT Shell
	/// </summary>
	public partial class GrtShellForm : DockContent
	{
		/// <summary>
		/// The GRT Manager that controlls the GRT
		/// </summary>
		private GrtManager grtManager;

		/// <summary>
		/// The GRT Shell handling the shell interface
		/// </summary>
		private GrtShell grtShell;

		/// <summary>
		/// The individual sub-forms of the GRT Shell
		/// </summary>
		private GrtPromptForm grtPromptForm;
		private GrtValuesForm grtValuesForm;
		private GrtStructsForm grtStructsForm;
		private GrtModulesForm grtModulesForm;
    private GrtFileExplorerForm grtFileExplorerForm;

    private string scriptFilePath;
    public const string newScriptName = "Untitled.lua";

    /// <summary>
    /// Event that informs about new document creation
    /// </summary>
    public event NewShellDocument NewShellDocument;

		/// <summary>
		/// Default constructor that is hidden
		/// </summary>
		private GrtShellForm()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Constructor that takes the GRT Manager and passes it on to the sub-forms it creates
		/// </summary>
		/// <param name="GrtManager">The GRT Manager of the application</param>
		public GrtShellForm(GrtManager GrtManager)
			: this()
		{
			grtManager = GrtManager;
			grtShell = GrtManager.get_shell();			

			// Suspend dock layout to prevent flicker
			grtDockPanel.SuspendLayout(true);
      try
      {

        // Override dock design
        MySQLDockExtender.SetSchema(grtDockPanel);

        // Create sub-forms
        grtPromptForm = new GrtPromptForm(grtManager);
        grtValuesForm = new GrtValuesForm(grtManager);
        grtStructsForm = new GrtStructsForm(grtManager);
        grtModulesForm = new GrtModulesForm(this, grtManager);
        grtFileExplorerForm = new GrtFileExplorerForm(this, grtManager);

        // Set sub-forms to DockRight
        grtModulesForm.Show(grtDockPanel, DockState.DockRightAutoHide);
        grtStructsForm.Show(grtDockPanel, DockState.DockRightAutoHide);
        grtValuesForm.Show(grtDockPanel, DockState.DockRightAutoHide);
        grtFileExplorerForm.Show(grtDockPanel, DockState.DockRightAutoHide);

        // Set PromptForm as main panel
        grtPromptForm.Show(grtDockPanel);
      }
      finally
      {
        // Resume suspended dock layout
        grtDockPanel.ResumeLayout(true, true);
      }

			ActiveControl = grtPromptForm;

      TabText = "GRT Shell";
		}

    public void ExecuteShellCommand(String cmd)
    {
      // Process the command the user entered
      grtShell.process_line_async(cmd);
    }

		/// <summary>
		/// Routine to print shell text output
		/// </summary>
		/// <param name="text">Text to print</param>
		public void PrintShellOutput(String text)
		{
			grtPromptForm.PrintText(text);
		}

		/// <summary>
		/// Routine that prepares the next command by printing the prompt
		/// </summary>
		/// <param name="prompt">The prompt to print</param>
		public void PrepareNextCommand(String prompt)
		{
			grtPromptForm.PrepareNextCommand(prompt);
		}

		/// <summary>
		/// Routine to print an error message
		/// </summary>
		/// <param name="message">The message</param>
		/// <param name="detail">Message details</param>
		public void ErrorCallback(String message, String detail)
		{
			grtPromptForm.PrintText(message);
			grtPromptForm.PrintText(detail);
		}

		/// <summary>
		/// Routine to refresh
		/// </summary>
		public void RefreshGrtTrees()
		{
			grtValuesForm.RefreshTree();
			grtStructsForm.RefreshTree();
			grtModulesForm.RefreshTree();
		}

		/// <summary>
		/// Called to initialize the shell form
		/// </summary>
		public void Initialize()
		{
			RefreshGrtTrees();
			grtPromptForm.RestoreSnippets();
		}

		/// <summary>
		/// Set the current selection on the prompt form
		/// </summary>
		/// <param name="text">The text the current selection should be set to</param>
		public void SetCurrentSelectionText(string text)
		{
			grtPromptForm.SetCurrentSelectionText(text);
		}

		/// <summary>
		/// Performs tasks when the form is closed
		/// </summary>W
		/// <param name="sender">The object sending the event</param>
		/// <param name="e">The event parameter</param>
		private void GrtShellForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			grtPromptForm.StoreSnippets();
		}

    protected override void OnDockStateChanged(EventArgs e)
    {
      grtPromptForm.StoreSnippets();

      base.OnDockStateChanged(e);
    }

		public void GrtShellForm_ResizeEnd(object sender, EventArgs e)
		{
			if (Height > Width / 2)
				grtValuesForm.SetInspectorLayout(Orientation.Vertical);
			else
				grtValuesForm.SetInspectorLayout(Orientation.Horizontal);
		}

		public GrtValuesForm GrtValuesForm
		{
			get { return grtValuesForm; }
		}

    public GrtFileExplorerForm GrtFileExplorerForm
    {
      get { return grtFileExplorerForm; }
    }

    public GrtStructsForm GrtStructsForm
    {
      get { return grtStructsForm; }
    }

    public GrtModulesForm GrtModulesForm
    {
      get { return grtModulesForm; }
    }

		public void ActivateShell()
		{
			grtPromptForm.ActivateShell();
		}

    public void NewDocumentForm(DockContent documentForm)
    {
      if (documentForm is GrtCodeEditor)
      {
        GrtCodeEditor codeEditor = documentForm as GrtCodeEditor;
        if (scriptFilePath != null)
          codeEditor.FilePath = System.IO.Path.Combine(scriptFilePath, newScriptName);
        else
          codeEditor.FilePath = newScriptName;
      }

      if (NewShellDocument != null)
        if (!NewShellDocument(documentForm))
          documentForm.Show();
    }

    public string ScriptFilePath
    {
      get { return scriptFilePath; }
      set { scriptFilePath = value; }
    }

    public void RefreshGrtFileExplorer()
    {
      grtFileExplorerForm.RefreshTree();
    }
	}
}