using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.CodeDom.Compiler;

using Icarus.Utilities.UI;

namespace Icarus.Scripting
{
	/// <summary>
	/// Summary description for ScriptingConsole.
	/// </summary>
	public class ScriptingConsole : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Panel pnl_Controls;
		private System.Windows.Forms.Button btn_ExecuteScript;
		private System.Windows.Forms.TextBox txt_Script;
		private System.Windows.Forms.RichTextBox txt_Output;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		private System.Windows.Forms.OpenFileDialog dlg_OpenScript;
		private System.Windows.Forms.MainMenu m_MainMenu;
		private System.Windows.Forms.MenuItem mi_File;
		private System.Windows.Forms.MenuItem mi_Open;
		private System.Windows.Forms.MenuItem mi_LoadLevel;
		private System.Windows.Forms.OpenFileDialog dlg_LoadLevel;

		/// <summary>
		/// This is a text writer that outputs the stuff to the console textbox.
		/// </summary>
		private TextBoxWriter m_ConsoleWriter;

		/// <summary>
		/// Gets the console text writer.
		/// </summary>
		public System.IO.TextWriter ConsoleWriter 
		{
			get { return m_ConsoleWriter; }
		}

        /// <summary>
        /// Initialize the Scripting Console
        /// </summary>
		public ScriptingConsole()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			m_ConsoleWriter = new TextBoxWriter(txt_Output);
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#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()
		{
			this.pnl_Controls = new System.Windows.Forms.Panel();
			this.txt_Script = new System.Windows.Forms.TextBox();
			this.btn_ExecuteScript = new System.Windows.Forms.Button();
			this.txt_Output = new System.Windows.Forms.RichTextBox();
			this.dlg_OpenScript = new System.Windows.Forms.OpenFileDialog();
			this.m_MainMenu = new System.Windows.Forms.MainMenu();
			this.mi_File = new System.Windows.Forms.MenuItem();
			this.mi_Open = new System.Windows.Forms.MenuItem();
			this.mi_LoadLevel = new System.Windows.Forms.MenuItem();
			this.dlg_LoadLevel = new System.Windows.Forms.OpenFileDialog();
			this.pnl_Controls.SuspendLayout();
			this.SuspendLayout();
			// 
			// pnl_Controls
			// 
			this.pnl_Controls.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.pnl_Controls.Controls.Add(this.txt_Script);
			this.pnl_Controls.Controls.Add(this.btn_ExecuteScript);
			this.pnl_Controls.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.pnl_Controls.Location = new System.Drawing.Point(0, 346);
			this.pnl_Controls.Name = "pnl_Controls";
			this.pnl_Controls.Size = new System.Drawing.Size(632, 100);
			this.pnl_Controls.TabIndex = 0;
			// 
			// txt_Script
			// 
			this.txt_Script.AcceptsReturn = true;
			this.txt_Script.AcceptsTab = true;
			this.txt_Script.AllowDrop = true;
			this.txt_Script.AutoSize = false;
			this.txt_Script.Location = new System.Drawing.Point(8, 8);
			this.txt_Script.Multiline = true;
			this.txt_Script.Name = "txt_Script";
			this.txt_Script.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
			this.txt_Script.Size = new System.Drawing.Size(528, 80);
			this.txt_Script.TabIndex = 1;
			this.txt_Script.Text = "";
			// 
			// btn_ExecuteScript
			// 
			this.btn_ExecuteScript.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
			this.btn_ExecuteScript.Location = new System.Drawing.Point(544, 8);
			this.btn_ExecuteScript.Name = "btn_ExecuteScript";
			this.btn_ExecuteScript.Size = new System.Drawing.Size(75, 80);
			this.btn_ExecuteScript.TabIndex = 0;
			this.btn_ExecuteScript.Text = "Execute";
			this.btn_ExecuteScript.Click += new System.EventHandler(this.btn_ExecuteScript_Click);
			// 
			// txt_Output
			// 
			this.txt_Output.DetectUrls = false;
			this.txt_Output.Font = new System.Drawing.Font("Lucida Console", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.txt_Output.Location = new System.Drawing.Point(8, 8);
			this.txt_Output.Name = "txt_Output";
			this.txt_Output.ReadOnly = true;
			this.txt_Output.Size = new System.Drawing.Size(616, 312);
			this.txt_Output.TabIndex = 1;
			this.txt_Output.Text = "";
			// 
			// dlg_OpenScript
			// 
			this.dlg_OpenScript.AddExtension = false;
			this.dlg_OpenScript.Filter = "All Supported Script Files (*.cs, *.js, *.vb)|*.cs;*.js;*.vb";
			this.dlg_OpenScript.Title = "Execute Script File";
			// 
			// m_MainMenu
			// 
			this.m_MainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					   this.mi_File});
			// 
			// mi_File
			// 
			this.mi_File.Index = 0;
			this.mi_File.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					this.mi_Open,
																					this.mi_LoadLevel});
			this.mi_File.Text = "File";
			// 
			// mi_Open
			// 
			this.mi_Open.Index = 0;
			this.mi_Open.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
			this.mi_Open.Text = "Open Script";
			this.mi_Open.Click += new System.EventHandler(this.mi_Open_Click);
			// 
			// mi_LoadLevel
			// 
			this.mi_LoadLevel.Index = 1;
			this.mi_LoadLevel.Shortcut = System.Windows.Forms.Shortcut.CtrlL;
			this.mi_LoadLevel.Text = "Load Level";
			this.mi_LoadLevel.Click += new System.EventHandler(this.mi_LoadLevel_Click);
			// 
			// dlg_LoadLevel
			// 
			this.dlg_LoadLevel.Filter = "XML Level File (*.xml)|*.xml";
			this.dlg_LoadLevel.Title = "Load Icarus Level";
			// 
			// ScriptingConsole
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(632, 446);
			this.ControlBox = false;
			this.Controls.Add(this.txt_Output);
			this.Controls.Add(this.pnl_Controls);
			this.MaximizeBox = false;
			this.MaximumSize = new System.Drawing.Size(640, 480);
			this.Menu = this.m_MainMenu;
			this.MinimizeBox = false;
			this.MinimumSize = new System.Drawing.Size(640, 480);
			this.Name = "ScriptingConsole";
			this.ShowInTaskbar = false;
			this.Text = "Scripting Console";
			this.pnl_Controls.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		private void ReportCompilationErrors(CompilerErrorCollection errors)
		{
			if (errors != null)
			{
				Console.Error.WriteLine("Script Compilation Failed...");
				foreach (CompilerError e in errors) { Console.Error.WriteLine("{0}", e); }
				Console.Error.WriteLine("");
			}
		}

		private void btn_ExecuteScript_Click(object sender, System.EventArgs ea)
		{
			btn_ExecuteScript.Enabled = false;
			txt_Script.ReadOnly = true;

			CompilerErrorCollection errors = ScriptManager.Instance.ExecuteScript(txt_Script.Text);
			ReportCompilationErrors(errors);
			if (errors == null) { txt_Script.Text = ""; }
			
			txt_Script.ReadOnly = false;
			btn_ExecuteScript.Enabled = true;
		}

		private void mi_Exit_Click(object sender, System.EventArgs e)
		{
			Application.Exit();
		}

		private void mi_Open_Click(object sender, System.EventArgs e)
		{
			DialogResult result = dlg_OpenScript.ShowDialog(this);
			if (result == DialogResult.OK) 
			{
				string filename = dlg_OpenScript.FileName;
				ReportCompilationErrors(ScriptManager.Instance.ExecuteFile(filename));
			}
		}

		private void mi_LoadLevel_Click(object sender, System.EventArgs e)
		{
			DialogResult result = dlg_LoadLevel.ShowDialog(this);
			if (result == DialogResult.OK) 
			{
				string filename = dlg_LoadLevel.FileName;
				txt_Script.Text = String.Format("Icarus.Logic.GameEngine.Instance.PushState(new TuxHunter.GameStates.GameplayState(Icarus.Logic.LevelLoader.Instance.LoadLevelXML(\"{0}\")));", filename.Replace("\\", "/"));
			}
		}
	}
}
