using System.ComponentModel;
using System.ComponentModel.Design;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Configuration.Assemblies;
using System.Xml;


using FormulaEditor;

namespace FormulaEditorUI
{
	/// <summary>
	/// Summary description for FormulaEditorForm.
	/// </summary>
	public class FormulaEditorForm : System.Windows.Forms.Form, IFormula
	{
		/*private static Hah resources =
			FormsDiagramUI.FormDiagramUI.ControlResources;*/
		private System.ComponentModel.Container components = null;
		private System.Windows.Forms.Button buttonOK;
		private System.Windows.Forms.Button buttonCancel;
		private FormulaEditorPanel panel;
		private System.Windows.Forms.MenuItem menuItemFile;
		private System.Windows.Forms.MenuItem menuItemOpen;
		private System.Windows.Forms.MenuItem menuItemSaveAs;
		private System.Windows.Forms.MainMenu mainMenuEditor;
		private System.Windows.Forms.OpenFileDialog openFileDialogEditor;
		private System.Windows.Forms.SaveFileDialog saveFileDialogEditor;
		private System.Windows.Forms.MenuItem menuItemSep;
		private System.Windows.Forms.MenuItem menuItemDatabase;
		private System.Windows.Forms.MenuItem menuItemDatabaseLoad;
		private System.Windows.Forms.MenuItem menuItemDatabaseSave;
		private System.Windows.Forms.MenuItem menuItemOpenDatabase;
		private System.Windows.Forms.MenuItem menuItemSaveImage;
		private System.Windows.Forms.SaveFileDialog saveFileDialogImage;
		private bool accepted = false;
        protected string[] symbols;

		public FormulaEditorForm() 
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
			ResourceService.Resources.LoadControlResources(this);
			panel = new FormulaEditorPanel();
			panel.Left = 0;
			panel.Top = 0;
			panel.Width = 1200;
			panel.Height = 500;
			Controls.Add(panel);
			panel.Prepare();
			this.KeyUp += panel.Performer.KeyUpEventHandler;
			this.KeyPress += panel.Performer.KeyPressEventHandler;
			openFileDialogEditor.InitialDirectory = 
				ResourceService.Resources.CurrentDirectory + "\\Functions";
			saveFileDialogEditor.InitialDirectory = openFileDialogEditor.InitialDirectory;
			
			//if (EMDatabaseInterface.DatabaseClient.Service == null)
			//{
			//	menuItemDatabase.Visible = false;
			//}
		}

		public FormulaEditorForm(string s, string[,] sub, string[] symbols)
		{
			InitializeComponent();
			ResourceService.Resources.LoadControlResources(this);
            this.symbols = symbols;
			panel = new FormulaEditorPanel();
			panel.Left = 0;
			panel.Top = 0;
			panel.Width = 1200;
			panel.Height = 500;
			Controls.Add(panel);
			panel.Prepare(s, 4, sub, symbols);
			openFileDialogEditor.InitialDirectory = 
				ResourceService.Resources.CurrentDirectory + "\\Functions";
			saveFileDialogEditor.InitialDirectory = openFileDialogEditor.InitialDirectory;
	/*		
			if (EMDatabaseInterface.DatabaseClient.Service == null)
			{
				menuItemDatabase.Visible = false;
			}*/
		}


		public string Formula
		{
			get
			{
				return panel.Performer.FormulaString;
			}
			set
			{
               panel.Performer.SetFormula(value, MathSymbolFactory.Sizes);
                panel.Performer.DrawFormula();
			}
		}

		public static Image CreateImage(string formula)
		{
			Image im = new Bitmap(10, 10);
			Graphics g = Graphics.FromImage(im);
			SimpleSymbolDrawable.Prepare(new int[] {8, 6, 5, 4}, g);
			MathFormulaDrawable f = new MathFormulaDrawable(MathFormula.FromString(new int[] {8, 6, 5, 4}, formula), DrawableConverter.Object);
			f.CalculateFullRelativeRectangle();
			Rectangle r = f.FullRelativeRectangle;
			Point p = new Point(10, -r.Y);
			f.Position = p;
			f.CalculatePositions();
			im = new Bitmap(r.Width + 20, r.Height);
			Brush brush = new SolidBrush(Color.White);
			g = Graphics.FromImage(im);
			g.FillRectangle(brush, 0, 0, im.Width, im.Height);
			f.Draw(g);
			SimpleSymbolDrawable.Prepare(MathSymbolFactory.Sizes, g);
			g.Dispose();
			return im;
		}

		public bool Accepted
		{
			get
			{
				return accepted;
			}
		}

		/// <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()
		{
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(FormulaEditorForm));
			this.buttonOK = new System.Windows.Forms.Button();
			this.buttonCancel = new System.Windows.Forms.Button();
			this.mainMenuEditor = new System.Windows.Forms.MainMenu();
			this.menuItemFile = new System.Windows.Forms.MenuItem();
			this.menuItemOpen = new System.Windows.Forms.MenuItem();
			this.menuItemSep = new System.Windows.Forms.MenuItem();
			this.menuItemSaveAs = new System.Windows.Forms.MenuItem();
			this.menuItemSaveImage = new System.Windows.Forms.MenuItem();
			this.menuItemDatabase = new System.Windows.Forms.MenuItem();
			this.menuItemOpenDatabase = new System.Windows.Forms.MenuItem();
			this.menuItemDatabaseLoad = new System.Windows.Forms.MenuItem();
			this.menuItemDatabaseSave = new System.Windows.Forms.MenuItem();
			this.openFileDialogEditor = new System.Windows.Forms.OpenFileDialog();
			this.saveFileDialogEditor = new System.Windows.Forms.SaveFileDialog();
			this.saveFileDialogImage = new System.Windows.Forms.SaveFileDialog();
			this.SuspendLayout();
			// 
			// buttonOK
			// 
			this.buttonOK.Location = new System.Drawing.Point(368, 528);
			this.buttonOK.Name = "buttonOK";
			this.buttonOK.TabIndex = 0;
			this.buttonOK.TabStop = false;
			this.buttonOK.Text = "Accept";
			this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
			// 
			// buttonCancel
			// 
			this.buttonCancel.Location = new System.Drawing.Point(512, 528);
			this.buttonCancel.Name = "buttonCancel";
			this.buttonCancel.TabIndex = 1;
			this.buttonCancel.TabStop = false;
			this.buttonCancel.Text = "Cancel";
			this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
			// 
			// mainMenuEditor
			// 
			this.mainMenuEditor.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																						   this.menuItemFile,
																						   this.menuItemDatabase});
			// 
			// menuItemFile
			// 
			this.menuItemFile.Index = 0;
			this.menuItemFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																						 this.menuItemOpen,
																						 this.menuItemSep,
																						 this.menuItemSaveAs,
																						 this.menuItemSaveImage});
			this.menuItemFile.Text = "File";
			// 
			// menuItemOpen
			// 
			this.menuItemOpen.Index = 0;
			this.menuItemOpen.Text = "Open";
			this.menuItemOpen.Click += new System.EventHandler(this.menuItemOpen_Click);
			// 
			// menuItemSep
			// 
			this.menuItemSep.Index = 1;
			this.menuItemSep.Text = "-";
			// 
			// menuItemSaveAs
			// 
			this.menuItemSaveAs.Index = 2;
			this.menuItemSaveAs.Text = "Save as";
			this.menuItemSaveAs.Click += new System.EventHandler(this.menuItemSaveAs_Click);
			// 
			// menuItemSaveImage
			// 
			this.menuItemSaveImage.Index = 3;
			this.menuItemSaveImage.Text = "Save formula image";
			this.menuItemSaveImage.Click += new System.EventHandler(this.menuItemSaveImage_Click);
			// 
			// menuItemDatabase
			// 
			this.menuItemDatabase.Index = 1;
			this.menuItemDatabase.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																							 this.menuItemOpenDatabase,
																							 this.menuItemDatabaseLoad,
																							 this.menuItemDatabaseSave});
			this.menuItemDatabase.Text = "Database";
			// 
			// menuItemOpenDatabase
			// 
			this.menuItemOpenDatabase.Index = 0;
			this.menuItemOpenDatabase.Text = "View Database";
			this.menuItemOpenDatabase.Click += new System.EventHandler(this.menuItemOpenDatabase_Click);
			// 
			// menuItemDatabaseLoad
			// 
			this.menuItemDatabaseLoad.Index = 1;
			this.menuItemDatabaseLoad.Text = "Load";
			this.menuItemDatabaseLoad.Click += new System.EventHandler(this.menuItemDatabaseLoad_Click);
			// 
			// menuItemDatabaseSave
			// 
			this.menuItemDatabaseSave.Index = 2;
			this.menuItemDatabaseSave.Text = "Save";
			this.menuItemDatabaseSave.Click += new System.EventHandler(this.menuItemDatabaseSave_Click);
			// 
			// openFileDialogEditor
			// 
			this.openFileDialogEditor.Filter = "Function files |*.xml";
			// 
			// saveFileDialogEditor
			// 
			this.saveFileDialogEditor.Filter = "Function files |*.xml";
			// 
			// saveFileDialogImage
			// 
			this.saveFileDialogImage.Filter = "Gif |*.gif";
			// 
			// FormulaEditorForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(1280, 573);
			this.Controls.Add(this.buttonCancel);
			this.Controls.Add(this.buttonOK);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Menu = this.mainMenuEditor;
			this.Name = "FormulaEditorForm";
			this.Text = "Formula Editor";
			this.ResumeLayout(false);

		}
		#endregion


		private void buttonOK_Click(object sender, System.EventArgs e)
		{
			try
			{
				MathFormula formula = panel.Performer.Formula;
				//MathFormula f = formula.FullTransform;
				//new ObjectFormulaTree(f, ElementaryFunctionsCreator.Object);
			}
			catch (System.Exception ex)
			{
				MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				//DiagramUI.DefaultForm.ShowError(this, ex);
				return;
			}
			accepted = true;
			Dispose();
		}

		private void buttonCancel_Click(object sender, System.EventArgs e)
		{
			Dispose();
		}
		private void loadXml(string filename)
		{
			try
			{
				/*XmlDocument doc = new XmlDocument();
				/*XmlReader reader = new XmlTextReader(filename);
				doc.Load(reader);
				reader.Close();
				XmlElement el = doc.GetElementsByTagName("Function")[0] as XmlElement;
				Formula = el.Attributes["Formula"].Value;*/
                /*doc.Load(filename);
                XmlCDataSection s = doc.DocumentElement.FirstChild as XmlCDataSection;*/
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
                    formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                Stream stream = File.OpenRead(filename);
                MathFormula f = formatter.Deserialize(stream) as MathFormula;
                stream.Close();
                f.Post();
                Formula = f.FormulaString;
			}
			catch (System.Exception ex)
			{
				MessageBox.Show(this, ex.Message);
			}
		}
		private void saveXml(string filename)
		{
		/*	XmlDocument doc = new XmlDocument();
			doc.LoadXml("<?xml version=\"1.0\"?>" + "<Root>" + "</Root>");
            XmlCDataSection section = doc.CreateCDataSection("Data");
            section.InnerText = Formula;
            doc.DocumentElement.AppendChild(section);
            doc.Save(filename);
			/*XmlElement element = doc.CreateElement("Function");
			XmlAttribute f = doc.CreateAttribute("Formula");
			f.Value = Formula;
			element.Attributes.Append(f);
			XmlNode nl = doc.DocumentElement;
			nl.AppendChild(element);
			if (doc != null)
			{
				XmlWriter writer = new XmlTextWriter(filename, new System.Text.UTF8Encoding());
				doc.WriteContentTo(writer);
				writer.Flush();
				writer.Close();
			}*/
            //doc.WriteTo(.WriteContentTo(.WriteTo(.WriteContentTo(

            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            string s = Formula;
            byte[] b = new byte[s.Length];
            for (int i = 0; i < b.Length; i++)
            {
                b[i] = (byte)s[i];
            }

            Stream stream = File.OpenWrite(filename);
            stream.Write(b, 0, b.Length);
            stream.Close();
		}

		private void menuItemOpen_Click(object sender, System.EventArgs e)
		{
			if (openFileDialogEditor.ShowDialog(this) != DialogResult.OK)
			{
				return;
			}
			loadXml(openFileDialogEditor.FileName);
			Refresh();
		}

		private void menuItemSaveAs_Click(object sender, System.EventArgs e)
		{
			if (saveFileDialogEditor.ShowDialog(this) != DialogResult.OK)
			{
				return;
			}
			saveXml(saveFileDialogEditor.FileName);
		}

        private void menuItemDatabaseLoad_Click(object sender, System.EventArgs e)
        {
/*
            EMDatabaseInterface.FormDataBaseFormula form =
                new EMDatabaseInterface.FormDataBaseFormula((int)EMDatabaseInterface.FormulaDataMode.Load, new FormulaDrawing());
            form.ShowDialog(this);
            if (form.Accepted)
            {
                Formula = form.Formula;
            }
            Refresh();*/
        }

        private void menuItemDatabaseSave_Click(object sender, System.EventArgs e)
		{
			try
			{
				MathFormula formula = panel.Performer.Formula;
                new ObjectFormulaTree(formula.FullTransform, ElementaryFunctionsCreator.Object);
			}
			catch (System.Exception ex)
			{
				MessageBox.Show(this, ex.Message);
				return;
			}
/*
			EMDatabaseInterface.FormDataBaseFormula form =
                new EMDatabaseInterface.FormDataBaseFormula((int)EMDatabaseInterface.FormulaDataMode.Save, new FormulaDrawing());
			form.Formula = this.Formula;
			form.ShowDialog(this);*/
		}

		private void menuItemOpenDatabase_Click(object sender, System.EventArgs e)
		{
			
		/*	EMDatabaseInterface.FormDataBaseFormula form = 
				new EMDatabaseInterface.FormDataBaseFormula((int)EMDatabaseInterface.FormulaDataMode.Look, new FormulaDrawing());
			form.ShowDialog(this);
		*/}

		private void menuItemSaveImage_Click(object sender, System.EventArgs e)
		{
			if (saveFileDialogImage.ShowDialog(this) != DialogResult.OK)
			{
				return;
			}
			Image im = CreateImage(panel.Performer.Formula.FormulaString);
			im.Save(saveFileDialogImage.FileName, System.Drawing.Imaging.ImageFormat.Gif);
		}

	}
}
