context: /*
   
   * Author:	Bob Limnor (info@limnor.com)
   * Project: Limnor Studio
   * Item:	Visual Expression Display and Edit
   * License: GNU General Public License v3.0
   
   */
  /*
   * All rights reserved by Longflow Enterprises Ltd
   * 
   * Formula Editor
   */
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Drawing;
  using System.Xml;
  using System.Windows.Forms;
  using System.ComponentModel;
  using System.Collections;
  using System.CodeDom;
  using MathExp.RaisTypes;
  using System.Drawing.Design;
  using System.Reflection;
  using ProgElements;
  using VPL;
  using System.Xml.Serialization;
  using System.Collections.Specialized;
  using System.Globalization;
  
  namespace MathExp
  {
  
  	public enum EnumIncludeReturnPorts { Inport, OutPort, Both, None }
  	/// <summary>
  	/// an item in a group
  	/// </summary>
  	public class MathExpItem
  	{
  		#region fields and constructors
  		private MathExpGroup _mathOwner;
  		private IMathExpression _exp;
  		private Point _pos;
  		private Size _size;
  		private object _portSelection;
  		private bool _useCompileType;
  		private RaisDataType _compileType;
  		public MathExpItem(MathExpGroup owner)
  		{
  			if (owner == null)
  				throw new MathException("owner cannot be null when creating MathExpItem");
  			_mathOwner = owner;
  		}
  		#endregion
  		#region Methods
  		public virtual void Copy(MathExpItem target)
  		{
  			target.Name = Name;
  			target.Description = Description;
  			target.Location = Location;
  			target.Size = Size;
  			if (_exp != null)
  			{
  				target.MathExpression = (IMathExpression)_exp.Clone();
  			}
  		}
  		public virtual MathExpItem Clone(MathExpGroup owner)
  		{
  			MathExpItem obj = new MathExpItem(owner);
  			Copy(obj);
  			obj.MathExpression.ContainerMathItem = obj;
  			return obj;
  		}
  		void setVariableAsLocalById(int id)
  		{
  			VariableList vs = MathExpression.FindAllInputVariables();
  			for (int i = 0; i < vs.Count; i++)
  			{
  				if (vs[i].ID == id)
  				{
  					vs[i].IsLocal = true;
  				}
  			}
  		}
  		public CodeExpression ReturnCodeExpression(IMethodCompile method)
  		{
  			IProgramEntity pe = this.MathExpression as IProgramEntity;
  			if (pe != null)
  			{
  				return pe.ReturnCodeExpression(_portSelection, method);
  			}
  			CodeExpression ce = this.MathExpression.ReturnCodeExpression(method);
  			return ce;
  		}
  		public string ReturnJavaScriptCodeExpression(StringCollection methodCode)
  		{
  			return CreatejavaScript(methodCode);
  		}
  		public string CreatejavaScript(StringCollection code)
  		{
  			IProgramEntity pe = this.MathExpression as IProgramEntity;
  			if (pe != null)
  			{
  				return pe.CreateJavaScript(_portSelection, code);
  			}
  			return this.MathExpression.CreateJavaScript(code);
  		}
  		public string CreatePhpScript(StringCollection code)
  		{
  			IProgramEntity pe = this.MathExpression as IProgramEntity;
  			if (pe != null)
  			{
  				return pe.CreatePhpScript(_portSelection, code);
  			}
  			return this.MathExpression.CreatePhpScript(code);
  		}
  		/// <summary>
  		/// this method is used for copy/paste
  		/// </summary>
  		public void ReCreateDefaultPorts()
  		{
  			PortCollection ports = this.GetAllPorts();
  			for (int i = 0; i < ports.Count; i++)
  			{
  				UInt32 id = ports[i].PortID;
  				UInt32 idNew = MathNodeVariable.GetNewID();
  				this.MathExpression.ReplaceVariableID(id, idNew);
  				ports[i].LinkedPortID = 0;
  				((DrawingVariable)ports[i].Label).Variable.ResetID(idNew);
  				if (ports[i] is LinkLineNodeInPort)
  				{
  					ports[i].SetPrevious(new LinkLineNode(ports[i], null));
  					((Control)ports[i].PrevNode).Location = ports[i].DefaultNextNodePosition();
  				}
  				else
  				{
  					ports[i].SetNext(new LinkLineNode(null, ports[i]));
  					((Control)ports[i].NextNode).Location = ports[i].DefaultNextNodePosition();
  				}
  			}
  		}
  		/// <summary>
  		/// this method is used for copy/paste
  		/// </summary>
  		public void CreateLinkLines()
  		{
  			PortCollection ports = this.GetAllPorts();
  			ports.CreateLinkLines();
  		}
  		/// <summary>
  		/// this method is used for copy/paste
  		/// </summary>
  		/// <returns></returns>
  		public Control[] GetPortControls()
  		{
  			PortCollection ports = this.GetAllPorts();
  			List<Control> cs = new List<Control>();
  			for (int k = 0; k < ports.Count; k++)
  			{
  				cs.Add(ports[k].Label);
  				if (ports[k] is LinkLineNodeInPort)
  				{
  					LinkLineNode l = ports[k];
  					while (l != null)
  					{
  						cs.Add(l);
  						l = (LinkLineNode)l.PrevNode;
  					}
  				}
  				else if (ports[k] is LinkLineNodeOutPort)
  				{
  					LinkLineNode l = ports[k];
  					while (l != null)
  					{
  						cs.Add(l);
  						l = (LinkLineNode)l.NextNode;
  					}
  				}
  			}
  			Control[] a = new Control[cs.Count];
  			cs.CopyTo(a);
  			return a;
  		}
  		/// <summary>
  		/// called before compiling
  		/// </summary>
  		public void PrepareForCompile(IMethodCompile method)
  		{
  			MathExpression.PrepareForCompile(method);
  		}
  		public void PrepareDrawInDiagram()
  		{
  			if (_exp != null)
  			{
  				_exp.PrepareDrawInDiagram();
  			}
  		}
  		public void SetDesignServiceProvider(IDesignServiceProvider provider)
  		{
  			MathNode.RegisterGetGlobalServiceProvider(this, provider);
  			if (_exp != null)
  			{
  				_exp.SetServiceProvider(provider);
  			}
  		}
  		public XmlDocument GetXmlDocument()
  		{
  			if (_exp != null)
  			{
  				return _exp.GetXmlDocument();
  			}
  			return null;
  		}
  		#endregion
  		#region Properties
  		[Browsable(false)]
  		public bool IsValid
  		{
  			get
  			{
  				if (_exp != null)
  				{
  					return _exp.IsValid;
  				}
  				return true;
  			}
  		}
  		[Browsable(false)]
  		public bool ContainLibraryTypesOnly
  		{
  			get
  			{
  				if (_exp != null)
  					return _exp.ContainLibraryTypesOnly;
  				return true;
  			}
  		}
  		[Browsable(false)]
  		public bool UseCompileType
  		{
  			get
  			{
  				return _useCompileType;
  			}
  			set
  			{
  				_useCompileType = value;
  			}
  		}
  		[Browsable(false)]
  		public RaisDataType CompileDataType
  		{
  			get
  			{
  				return _compileType;
  			}
  			set
  			{
  				_compileType = value;
  			}
  		}
  		[Browsable(false)]
  		public RaisDataType ActualCompiledDataType
  		{
  			get
  			{
  				if (_exp != null)
  					return _exp.ActualCompileDataType;
  				return new RaisDataType();
  			}
  		}
  		[Browsable(false)]
  		public MathExpGroup Parent
  		{
  			get
  			{
  				return _mathOwner;
  			}
  		}
  
  		public IMathExpression MathExpression
  		{
  			get
  			{
  				if (_exp == null)
  				{
  					_exp = new MathNodeRoot();
  					_exp.ContainerMathItem = this;
  				}
  				return _exp;
  			}
  			set
  			{
  				_exp = value;
  				_exp.ContainerMathItem = this;
  			}
  		}
  		public MathExpItem GetItemByID(UInt32 id)
  		{
  			_portSelection = null;
  			if (MathExpression.GetVariableByID(id) != null)
  			{
  				return this;
  			}
  			IProgramEntity pe = MathExpression as IProgramEntity;
  			if (pe != null)
  			{
  				if (pe.ProgEntity != null)
  				{
  					ProgramOutPort[] outports = pe.ProgEntity.Outports;
  					if (outports != null)
  					{
  						for (int i = 0; i < outports.Length; i++)
  						{
  							if (outports[i].PortID == id)
  							{
  								_portSelection = outports[i];
  								return this;
  							}
  						}
  					}
  					ProgramInPort[] inports = pe.ProgEntity.Inports;
  					if (inports != null)
  					{
  						for (int i = 0; i < inports.Length; i++)
  						{
  							if (inports[i].PortID == id)
  							{
  								_portSelection = inports[i];
  								return this;
  							}
  						}
  					}
  				}
  			}
  			return null;
  		}
  		/// <summary>
  		/// get all input ports and optionally output port.
  		/// </summary>
  		/// <param name="returnPortType"></param>
  		/// <returns></returns>
  		public PortCollection GetAllPorts()
  		{
  			PortCollection ports;
  			if (this.MathExpression is MathExpGroup)
  			{
  				ports = ((MathExpGroup)this.MathExpression).GetAllPorts(true);
  			}
  			else
  			{
  				ports = new PortCollection();
  			}
  			return ports;
  		}
  
  		public Point Location
  		{
  			get
  			{
  				return _pos;
  			}
  			set
  			{
  				_pos = value;
  			}
  		}
  
  		public Size Size
  		{
  			get
  			{
  				return _size;
  			}
  			set
  			{
  				_size = value;
  			}
  		}
  
  		public string Name
  		{
  			get
  			{
  				if (this.MathExpression != null)
  					return this.MathExpression.Name;
  				return "";
  			}
  			set
  			{
  				if (this.MathExpression != null)
  				{
  					this.MathExpression.Name = value;
  				}
  			}
  		}
  		public string TraceItemName()
  		{
  			System.Text.StringBuilder sb = new StringBuilder();
  			sb.Append(" MathItem for expression ");
  			if (MathExpression == null)
  			{
  				sb.Append("null");
  			}
  			else
  			{
  				sb.Append(MathExpression.GetType().Name);
  				sb.Append(" name:'");
  				sb.Append(MathExpression.Name);
  				sb.Append("'");
  			}
  			return sb.ToString();
  		}
  		public string TraceInfo
  		{
  			get
  			{
  				if (_exp != null)
  				{
  					return TraceItemName() + " " + _exp.TraceInfo;
  				}
  				return TraceItemName() + " null expression ";
  			}
  		}
  		public string Description
  		{
  			get
  			{
  				if (this.MathExpression != null)
  					return this.MathExpression.Description;
  				return "";
  			}
  			set
  			{
  
gt: 				if (this.MathExpression != null)