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


using CategoryTheory;
using DiagramUI;
using FormulaEditor;
using FormulaEditorUI;

namespace DataPerformerUI
{
	public class PanelFormula : Panel
	{
		private char var;
		private Control control;
		private Button button;
		private string formulaString;
		private MathFormulaDrawable formula;
		private Rectangle formulaRect;
		private Image bkgnd;
		private Pen linePen = new Pen(Color.Black);
		private Brush bkBrush = new SolidBrush(Color.Gray);
		private Brush rBrush = new SolidBrush(Color.FromArgb(216, 203, 187));
		private Brush blackBrush = new SolidBrush(Color.Black);
		private Font font = new Font("Times", MathSymbolFactory.Sizes[0], FontStyle.Bold | FontStyle.Italic);
		private Point pointFormula;
		private string variables;
		//		private string cap;
		private string[,] sub;
        private string[] symbols;
        private static string[] staticSymbols;
		public PanelFormula(string cap, Control control, int width, int height, string variables, 
			bool deriv, string[,] sub, string[] symbols)
		{
            if (symbols == null)
            {
                this.symbols = staticSymbols;
            }
            else
            {
                if (symbols[0] != null)
                {
                    this.symbols = symbols;
                }
            }
			this.var = cap[0];
			this.sub = sub;
			this.control = control;
			this.variables = variables;
			Width = width;
			Height = height;
			bkgnd = new Bitmap(width, height);
			Graphics g = Graphics.FromImage(bkgnd);
			g.FillRectangle(bkBrush, 0, 0, width, height);
			g.DrawRectangle(linePen, 0, 0, width - 1, height - 1);
			Paint += new PaintEventHandler(onPaint);
			button = new Button();
			button.Width = 150;
			button.Text = ResourceService.Resources.GetResourceString("Edit");
			button.Left = 20;
			int center = height / 2;
			button.Top = center - button.Height / 2;
			Controls.Add(button);
			button.Click += new EventHandler(onClick);
			int shift = -10;
			int w = (int)g.MeasureString(cap, font).Width;
			int left = button.Left + button.Width + 30;
			g.DrawString(cap + " =", font, blackBrush, left, center + shift);
			if (deriv)
			{
				g.DrawString(".", font, blackBrush, left, center + shift - font.Height - 3);
			}
			left += 60 + w;
			formulaRect = new Rectangle(left, 5, width - left - 5, height - 10);
			center = formulaRect.Top + formulaRect.Height / 2;
			pointFormula = new Point(left + 30, center);
		}
		public char Variable
		{
			get
			{
				return var;
			}
		}

		public string Formula
		{
			get
			{
				return formulaString;
			}
			set
			{
				if (value == null)
				{
					return;
				}
				formulaString = value;
				formula = new MathFormulaDrawable(MathFormula.FromString(MathSymbolFactory.Sizes, value), DrawableConverter.Object);
				formula.Position = pointFormula;
				formula.CalculateFullRelativeRectangle();
				formula.CalculatePositions();
				Graphics g = Graphics.FromImage(bkgnd);
				g.FillRectangle(rBrush, formulaRect.Left, formulaRect.Top, formulaRect.Width, formulaRect.Height);
				g.DrawRectangle(linePen, formulaRect.Left, formulaRect.Top, formulaRect.Width, formulaRect.Height);
				formula.Draw(g);
			}
		}

        public static string[] Symbols
        {
            set
            {
                staticSymbols = value;
            }
        }


		private void onPaint(object sender, PaintEventArgs e)
		{
			e.Graphics.DrawImage(bkgnd, 0, 0);
		}

		private void onClick(object sender, System.EventArgs e)
		{
			FormulaEditorForm f = new FormulaEditorForm(variables, sub, symbols);
			if (formulaString != null)
			{
				f.Formula = formulaString;
			}
			Form form = null;
			Control c = this;
			while (true)
			{
				if (c is Form)
				{
					form = c as Form;
					break;
				}
				c = c.Parent;
			}
			f.ShowDialog(form);
			if (!f.Accepted)
			{
				return;
			}
			Formula = f.Formula;
			Refresh();
		}

	}

}
