using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Drawing.Text;
using System.IO;
using SpeechLib;

namespace MathSpeakWrite
{
	/// <summary>
	/// A RelDrawingBase an abstract which all drawing Objects (colorboxes, symbols, div, sqrt) 
	/// should implement. It contains virtual or abstract definitions of all the methods which
	/// it's subclasses should need to call on eachother or be called from outside. It is 
	/// Serializable so saving the whole thing should be easy.
	/// </summary>
	
	[Serializable]
	public abstract class RelDrawingBase
	{
		internal RelDrawingBase prev, next;
		internal int parents;
		public int ID;
		public float width, height;
		
		[NonSerialized] public static int nextID = 0;
		[NonSerialized] public static int hbuf=3;
		[NonSerialized] public static Font normal14, normal12, normal10;
		[NonSerialized] public static Font greek14, greek12, greek10;
		[NonSerialized] public static SolidBrush b, b_red;
		[NonSerialized] public static Pen p, p_red;
		[NonSerialized] public static String[] texHexArray, texSymbolArray;
		[NonSerialized] public static String[] mathMLHexArray, mathMLSymbolArray;
		
		/// <summary>
		/// This method sets up all the class variables which are used by the code in this
		/// class and its subclasses. You must call initPFC before using this class or its
		/// subclasses.
		/// </summary>
		public static void initPFC()
		{
			b = new SolidBrush(Color.Black);
			b_red = new SolidBrush(Color.MidnightBlue);
			p = new Pen(b);
			p_red = new Pen(b_red,2);
			normal14 = new Font("Times New Roman", 14);
			greek14 = new Font("Symbol", 14);
			normal12 = new Font("Times New Roman", 12);
			greek12 = new Font("Symbol", 12);
			normal10 = new Font("Times New Roman", 10);
			greek10 = new Font("Symbol", 10);
		}

		/// <summary>
		/// A simple implementation of max which returns the larger of two vars.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static float max(float a, float b)
		{
			return (a>b)? a : b;
		}
		/// <summary>
		/// A simple implementation of max which returns the larger of three vars
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="c"></param>
		/// <returns></returns>
		public static float max(float a, float b, float c)
		{
			if(a > b && a > c)
				return a;
			if(b > a && b > c)
				return b;
			return c;
		}

		/// <summary>
		/// A simple implementation of the min function which returns the smallest of
		/// its four parameters
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="c"></param>
		/// <param name="d"></param>
		/// <returns></returns>
		public static float min(float a, float b, float c, float d)
		{
			if(a <= b && a <= c && a <= d)
				return a;
			else if(b <= a && b <= c && b <= d)
				return b;
			else if(c <= a && c <= b && c <= d)
				return c;
			else
				return d;
		}
		/// <summary>
		/// A simple implementation of the max function which returns the largest of
		/// its four parameters
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="c"></param>
		/// <param name="d"></param>
		/// <returns></returns>
		public static float max(float a, float b, float c, float d)
		{
			if(a >= b && a >= c && a >= d)
				return a;
			else if(b >= a && b >= c && b >= d)
				return b;
			else if(c >= a && c >= b && c >= d)
				return c;
			else
				return d;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="arr"></param>
		/// <param name="parents"></param>
		/// <param name="g"></param>
		/// <returns></returns>
		/*public static RelDrawingBase[] toksToSyms(string[] arr, int parents, Graphics g)
		{
			RelDrawingBase [] allRDBs = new RelDrawingBase[arr.Length];
			RelDrawingBase prev = null;
			int i;

			for(i=0; i < arr.Length; i++)
			{
				if(arr[i] == "@D" || arr[i] == "@d")
					allRDBs[i] = new DivisionRDB(prev, parents);
				else if (arr[i] == "@N" || arr[i] == "@n")
					allRDBs[i] = new NRootRDB(prev,parents);
				else if (arr[i] == "@S" || arr[i] == "@s")
					allRDBs[i] = new SqrtRDB(prev, parents);
				else
					allRDBs[i] = new SymbolRDB(prev, parents, arr[i], g);
				
				if(prev != null)
					prev.next = allRDBs[i];
				prev = allRDBs[i];
			}
			if(i == 0)
				return null;
			return allRDBs;
		}
		*/
		/// <summary>
		/// A specially designed function for taking a string of text and breaking it into 
		/// tokens which the program can recognize. This includes, isolating the
		/// special escape sequences which represent characters in the Symbol font,
		/// finding special escape sequences for creating RDBs (such as squareroot) and 
		/// other various special commands (liked cubed, subscript, etc).
		/// </summary>
		/// <param name="text">A string of text containing tokens delimited by spaces.</param>
		/// <returns></returns>
		private static string[] tokStrings(string text)
		{	
			int i;
			string []arr;
			string presStr="";
			char [] delimiters = {' '};
			ArrayList results = new ArrayList();

			arr = text.Split(delimiters);

			for(i=0; i < arr.Length; i++)
			{
				if(arr[i].Length == 0)
				{}
				else if(arr[i] == "@B" || arr[i] == "@b" || arr[i] == "@u" || arr[i] == "@U" 
					|| arr[i] == "@I" || arr[i] == "@i")
					presStr += arr[i] + " ";
				else if(arr[i] == "@D" || arr[i] == "@d" || arr[i] == "@n" || arr[i] == "@N"
					|| arr[i] == "@S" || arr[i] == "@s" || arr[i] == "@2" || arr[i] == "@3" 
					|| arr[i] == "@O" || arr[i] == "@o" || arr[i] == "@e" || arr[i] == "@E"
					|| arr[i] == "@L" || arr[i] == "@l" || arr[i] == "@P" || arr[i] == "@p")
					results.Add(arr[i]);
				else if(arr[i][0] == '@' && arr[i][1] != 'x')
				{}
				else if(arr[i].Length > 0)
				{
					presStr += arr[i];
					results.Add(presStr);
					presStr = "";
				}
			}

			arr = (string[]) results.ToArray(typeof(string));
			return arr;
		}

		/// <summary>
		/// This function takes a string, the last selected RDB, the currently selected colorbox
		/// and a Graphics g and uses them to create a chain of RDB's which represent the given
		/// string. It returns the last RDB in the chain which is at the same level as the given
		/// colorbox (if no colorbox, same level as the given selectedRDB). This function should insert
		/// the new RDBs into the existing datastructures automatically, based on the pointers in
		/// the selRDB.
		/// </summary>
		/// <param name="text">The text to be parsed and added into the RDB data structure</param>
		/// <param name="sel">The last selected SymbolRDB</param>
		/// <param name="lastCB">The currently selected ColorBox. Null if none was selected.</param>
		/// <returns>Returns the symbol that should be selected</returns>
		public static RelDrawingBase addWithStr(string text, RelDrawingBase sel, ColorBoxRDB lastCB, Graphics g)
		{
			string []arr;
			RelDrawingBase returnme;
			//Create an array of tokens
			arr = tokStrings(text);
		
			if(arr.Length == 0)
				return sel;
			
			ArrayList aL = new ArrayList();

			foreach (string s in arr)
				aL.Add(s);

			returnme = RecAddStr(aL, sel,lastCB,g);
		
			if(returnme != null && lastCB != null)
			{
				if(lastCB.parents != returnme.parents)
					returnme = returnme.listGetParentAtLevel(lastCB.parents);
			}	
			else if(returnme != null && sel !=null && returnme.parents != sel.parents)
				returnme = returnme.listGetParentAtLevel(sel.parents);

			if(lastCB != null && lastCB.next != null)
				returnme.next =  lastCB.next;
			return returnme;
		}
		
		/// <summary>
		/// Parses the ArrayList of strings and creates the next RDB according to the string in strs[0]. This function 
		/// recursively calls itself until strs is empty at which point it will return sel as the next 
		/// object to be selected on the screen.
		/// Strs can contain strings of words, numbers, or commands which start with the symbol '@'.
		/// </summary>
		/// <param name="strs">An ArrayList of Strings to turn into a series of RDBs</param>
		/// <param name="sel">The last selected SymbolRDB</param>
		/// <param name="lastCB">The ColorBox selected, can be old.</param>
		/// <param name="g"></param>
		/// <returns>The next RDB to be selected</returns>
		public static RelDrawingBase RecAddStr(ArrayList strs, RelDrawingBase sel, ColorBoxRDB lastCB, Graphics g)
		{
			RelDrawingBase first = sel;
			ColorBoxRDB nextCB = null;
			int parents = lastCB != null ? lastCB.parents : sel.parents;
			
			if(strs.Count == 0)
				return sel;

			string daStr = (string) strs[0];

			if(daStr == "@D" || daStr == "@d")
				first = new DivisionRDB(sel, parents);
			else if (daStr == "@N" || daStr == "@n")
			{
				first= new NRootRDB(sel,parents);
				nextCB = (ColorBoxRDB)(((NRootRDB)first).rad);
			}
			else if (daStr == "@S" || daStr == "@s")
			{
				first = new SqrtRDB(sel, parents);
				nextCB = (ColorBoxRDB)(((SqrtRDB)first).rad);
			}
			else if(daStr == "@2")
			{
				if(sel != null && sel.GetType() == typeof(SymbolRDB))
					((SymbolRDB)sel).exp = new SymbolRDB(sel, sel.parents+1, "2", g);
			}
			else if(daStr == "@3")
			{
				if(sel != null && sel.GetType() == typeof(SymbolRDB))
					((SymbolRDB)sel).exp = new SymbolRDB(sel, sel.parents+1, "3", g);
			}
			else if(daStr == "@L" || daStr == "@l")
			{
				if(sel.GetType() == typeof(SymbolRDB))
				{
					nextCB = new ColorBoxRDB(sel, 1+sel.parents);
					((SymbolRDB)sel).sub = nextCB;
				}
			}
			else if(daStr == "@P" || daStr == "@p")
			{
				if(sel.GetType() == typeof(SymbolRDB))
				{
					nextCB = new ColorBoxRDB(sel,1+ sel.parents);
					((SymbolRDB)sel).exp=nextCB;
				}
			}
			else if(daStr == "@O" || daStr == "@o")
			{
				
				//if sel is null, create an empty colorbox for top
				if(sel == null)
				{
					DivisionRDB aD;
					first = aD = new DivisionRDB(null, 0);
					nextCB = (ColorBoxRDB) aD.bot;
				}

				//if sel isn't null, stick it in the top
				else
				{
					DivisionRDB aD = new DivisionRDB(sel.prev, sel.parents);
					
					if(sel.prev != null)
						sel.prev.replaceRefFor(sel, aD);
					sel.prev = aD;
					aD.setTop(sel);
					sel.next = new ColorBoxRDB(sel, sel.parents);
					sel.listChangeParents(1, g);

					nextCB = (ColorBoxRDB) aD.bot;
					sel = first = aD;
				}
			}
			else
				first = new SymbolRDB(sel, parents, daStr, g);
			
			if(lastCB == null && sel != first)
				sel.next = first;

			if(lastCB != null && lastCB.prev !=null && first != sel)
				lastCB.prev.replaceRefFor(lastCB, first);
			
			//first.prev = (lastCB != null) ?  lastCB.prev : null;
			strs.RemoveAt(0);
			return RecAddStr(strs, first, nextCB, g);
		}

		/// <summary>
		/// The base constructor of a RelDrawingBase. It cannot be called itself, except from a 
		/// subclass since this class is abstract.
		/// </summary>
		/// <param name="prev">Whatever object is pointing to this one on the left</param>
		/// <param name="num_parents">The number of levels away from the top level this class is</param>
		public RelDrawingBase(RelDrawingBase prev, int num_parents)
		{
			this.prev = prev;
			this.parents = num_parents;
			this.next = null; //Could be overridden later
			this.ID = nextID;
			nextID ++;
		}
		
		/// <summary>
		/// This method instructs an object makesure that all of it's non-prev CBs are
		/// pointing to colorboxes. This method would commonly be used in editing so that
		/// the user is presented with colorboxes for all possible fields of a variable
		/// and can choose one. 
		/// The rules for creating a colorbox require that it is only created if that
		/// neighbor is not already a colorbox. A Colorbox should never point to another
		/// Colorbox.
		/// </summary>
		public virtual void addNeighborCBs()
		{
		}
		
		/// <summary>
		/// Roughly the inverse of the addNeighborCBs method. Removes "extra" colorboxes from a
		/// symbol, that is colorboxes which point to non-null objects such as symbols, division
		/// bars and square roots signs (a colorbox should never point to another colorbox).
		/// Colorboxes which do point to null objects (IE: terminal Colorboxes) are not removed.
		/// [As a rule of thumb, only Colorboxes should able to point to nulls]
		/// </summary>
		public virtual void removeNeighborCBs()
		{

		}

		/// <summary>
		/// The textToParse should contain numeral digits for 1-19
		/// the tens: 20,30... and the modifiers: 100, 1000, 1000000 ...
		/// It can also contain any other words and they will not be affected.
		/// The numbers in the string will be turned into real numbers while the words around 
		/// the number will not be affected. 
		/// </summary>
		/// <param name="textToParse">The string containing the text to translate.</param>
		/// <returns>A new string which is the same as textToParse except that the spoken numbers 
		/// have been translated into their corresponding int values and now match what the 
		/// user intended to speak</returns>
		public static string convertTextToNumbers(String textToParse)
		{

			string[] arr;
			char [] delimiters = {' '};
			arr = textToParse.Split(delimiters);

			string parsedText = "";
			bool includeNumber = false, digitTalk = false, lastWasSingle = false;
			long currentTotalNumber = 0, currentDigits = 0;

			for(int i = 0; i < arr.Length; i++)
			{
				long number = -1;
				try {number = System.Convert.ToInt64(arr[i]);}
				catch{}

				if (number == -1)
				{
					if (includeNumber && !digitTalk)
					{
						currentTotalNumber += currentDigits;
						parsedText += " " + currentTotalNumber.ToString() + " ";
						currentTotalNumber = 0;
						currentDigits = 0;
					}
					includeNumber = false;
					digitTalk = false;
					lastWasSingle = false;
					parsedText += " " + arr[i]+ " ";
				}
				else
				{
					if (number < 10 && lastWasSingle == true)
					{
						if (digitTalk == false)
							parsedText += " " + System.Convert.ToInt32(arr[i-1]);
						digitTalk = true;

					}

					if (number == 1000000000000 || number == 1000000000 || 
						number == 1000000 || number == 1000)
					{
						if (currentDigits == 0)
							currentDigits = 1;
						currentTotalNumber += currentDigits * number;
						currentDigits = 0;
					}
					else if (number == 100)
					{
						if (currentDigits == 0)
							currentDigits = 1;
						currentDigits = currentDigits * 100;
					}
					else if (digitTalk == true)
					{
						parsedText += number;
						includeNumber = false;
						currentTotalNumber = 0;
						currentDigits = 0;
					}
					else 
						currentDigits += number;


					if (number < 10)
						lastWasSingle = true;
					else
						lastWasSingle = false;

					includeNumber = true;

				}
			}

			if (includeNumber && !digitTalk)
			{
				currentTotalNumber += currentDigits;
				parsedText += currentTotalNumber.ToString();
			}

			return parsedText.Trim();
		}
		/// <summary>
		/// Draws just this RDB at the given coords using the Graphics obj which is passed in.
		/// </summary>
		/// <param name="x">Upper Left xcoord</param>
		/// <param name="y">Upper Left ycoord</param>
		/// <param name="g"></param>
		public abstract void draw(float x, float y, Graphics g);
		/// <summary>
		/// A recursive drawing function which not only draws this RDB but all RDBs linked to
		/// it. Since all RDBs are stored in the tree like structure with each pointing to the
		/// next RDB to the left of it, this is really the sane manner of drawing them.
		/// </summary>
		/// <param name="x">Upper Left X Coord</param>
		/// <param name="y">Upper Lett Y Coord</param>
		/// <param name="g"></param>
		public abstract void listDraw(float x, float y, Graphics g);
		/// <summary>
		/// This recursive function determines the combined height of all objects to the left 
		/// of this one. (IE: It should measure the distance from the highest y to the lowest y).
		/// </summary>
		/// <returns></returns>
		public virtual float listHeight()
		{
			float returnme =  lowestY(0)-highestY(0);
			return (returnme < 0) ? 0 : returnme;
		}
		/// <summary>
		/// Returns the highest y coordinate of this+all RDBs to the right
		/// </summary>
		/// <param name="presy">The y coord at which this object should be drawn</param>
		/// <returns></returns>
		public abstract float highestY(float presy);
		/// <summary>
		/// Returns the lowest y coordinate of this+all RDBs to the right.
		/// </summary>
		/// <param name="presy">The y coord at which this obj should be drawn</param>
		/// <returns></returns>
		public abstract float lowestY(float presy);
		/// <summary>
		/// Finds the next element on the left with the given number of elements or fewer.
		/// Looks this RDB's parents field and sees whether it has the given number of parents or
		/// fewer. If it has more, follows the prev pointers back until it finds one with the given
		/// number of parents (or fewer).
		/// </summary>
		/// <param name="targetNumParents">The number of parents for an element which we want found</param>
		/// <returns></returns>
		public virtual RelDrawingBase listGetParentAtLevel(int targetNumParents)
		{
			if(this.parents <= targetNumParents)
				return this;
			else
				return prev.listGetParentAtLevel(targetNumParents);
		}
		/// <summary>
		/// Alters the number of parents of this RDB's and all to the right of it by incrementing 
		/// each RDB's parents by the given delta. A graphics object is also required. 
		/// </summary>
		/// <param name="delta"></param>
		/// <param name="g"></param>
		public virtual void listChangeParents(int delta, Graphics g)
		{
			this.parents += delta;

			if(this.next != null)
				this.next.listChangeParents(delta, g);
		}

		/// <summary>
		/// Returns the distance above the base y coord that this object will extend.
		/// For example, a SymbolRBD will be drawn with it's text at the given y, but 
		/// other items in it's next or exp fields may extend above that y. This function
		/// returns the distance that the largest extends above that y coord.
		/// </summary>
		/// <returns></returns>
		public abstract float listHeightBelowDrawY();
		/// <summary>
		/// Returns the depth below the base y coord that this and all right objects
		/// extend. For instance, if this object is drawn at a location, this method
		/// will return the distance from that location to the lowest.
		/// </summary>
		/// <returns></returns>
		public abstract float listHeightAboveDrawY();
		/// <summary>
		/// This recursive function determines the combined width of all objects to the left of
		/// this one. (IE: It should measure the distance from the left most x to the right most)
		/// </summary>
		/// <returns></returns>
		public abstract float listWidth();
		/// <summary>
		/// Returns a string containing the debugging information of this and all
		/// right colorboxes.
		/// </summary>
		/// <returns></returns>
		public virtual string listDebugStr()
		{
			return this.ToString() + '\n' + ((next != null) ? next.listDebugStr() : "");
		}
		/// <summary>
		/// Converts all RDBs from this symbol right (exp, sub, and next) into a 
		/// Tex interpretation.
		/// </summary>
		/// <returns>A string written in Tex equivalent to the math expression from this Object to the right.</returns>
		public abstract string listConvertToTex();
		/// <summary>
		/// Converts all RDBs from this symbol right (exp, sub, and next) into a 
		/// mathML interpretation.
		/// </summary>
		/// <returns>A string written in mathML equivalent to the math expression from this Object to the right.</returns>
		public abstract string listConvertToMathML();
		/// <summary>
		/// Reads in the two files, texHexArray and texSymbolArray, 
		/// into two public String Arrays. Each line in the file designates a new array entry.
		/// The files can not have more than 200 lines.
		/// The arrays represent the correspondence between the RDB hex representation, and Tex Symbols.
		/// </summary>
		public void readTexArrays()
		{
			texHexArray = new String[200];
			texSymbolArray = new String[200];
			StreamReader sr = new StreamReader("texHexArray.txt");
			String currentLine = "a";

			for (int i = 0; currentLine != null; i++)
			{
				texHexArray[i] = currentLine = sr.ReadLine();
			}
			sr.Close();
			sr = new StreamReader("texSymbolArray.txt");
			currentLine = "a";
			for (int i = 0; currentLine != null; i++)
			{
				texSymbolArray[i] = currentLine = sr.ReadLine();
			}
			sr.Close();
		}
		/// <summary>
		/// Reads in the two files, mathMLHexArray and mathMLSymbolArray, 
		/// into two public String Arrays. Each line in the file designates a new array entry.
		/// The files can not have more than 200 lines.
		/// The arrays represent the correspondence between the RDB hex representation, and MathML Symbols.
		/// </summary>
		public void readMathMLArrays()
		{
			mathMLHexArray = new String[200];
			mathMLSymbolArray = new String[200];
			StreamReader sr = new StreamReader("mathMLHexArray.txt");
			String currentLine = "a";

			for (int i = 0; currentLine != null; i++)
			{
				mathMLHexArray[i] = currentLine = sr.ReadLine();
			}
			sr.Close();
			sr = new StreamReader("mathMLSymbolArray.txt");
			currentLine = "a";
			for (int i = 0; currentLine != null; i++)
			{
				mathMLSymbolArray[i] = currentLine = sr.ReadLine();
			}
			sr.Close();
		}
		/// <summary>
		/// Returns the first objected in an RDB tree. Does this by following the prev pointers 
		/// back to the first object. All objects in an RDB tree should have the same value for
		/// this function
		/// </summary>
		/// <returns></returns>
		public virtual RelDrawingBase listGetRoot()
		{
			RelDrawingBase presObj= this;

			while(presObj.prev != null)
				presObj = presObj.prev;
			return presObj;
		}
		/// <summary>
		/// Inserts the specified symbols right after this RDB and puts the former next RDBs to
		/// the right of that one.
		/// </summary>
		/// <param name="startSym">The left most symbol to insert</param>
		/// <param name="endSym">The right most symbol to insert</param>
		public virtual void insertRDBAfter(RelDrawingBase startSym, RelDrawingBase endSym)
		{
			if(this.next != null)
			{
				endSym.next = this.next;
				this.next.prev = endSym;
			}
			this.next = startSym;
			startSym.prev = this;
		}
		/// <summary>
		/// Searches the fields (ex: next, prev) for a Reference to a given object and replaces
		/// that reference with a reference to a different object. 
		/// </summary>
		/// <param name="initRef">The Object to find and replace</param>
		/// <param name="repRef">The Object to replace the initRef</param>
		public abstract void replaceRefFor(RelDrawingBase initRef, RelDrawingBase repRef);
		/// <summary>
		/// Replaces this RDB with some chained RDBs, whose first and last elements are given.
		/// You can use this method to replace this RDB with another sole RDB by passing that
		/// RDB as both the first and last element.
		/// </summary>
		/// <param name="first"></param>
		/// <param name="last"></param>
		public virtual void replaceSelfWith(RelDrawingBase first, RelDrawingBase last)
		{
			if(this.prev != null)
				this.prev.replaceRefFor(this,first);
			first.prev = this.prev;

			if(this.next != null)
				this.next.prev = last;
			last.next = this.next;
		}
		/// <summary>
		/// Turns on/off the drawing on all neighboring colorboxes but does not actually create or
		/// destroy them as addNeighborCBs and removeNeighborCBs do.
		/// </summary>
		/// <param name="isOn">Set to true if you want CBs on, false if you want them off</param>
		public virtual void toogleNeighborCBDraw(bool isOn)
		{
			/*if(prev != null && prev.GetType() == typeof(ColorBoxRDB))
				((ColorBoxRDB)prev).drawSelf = isOn;*/
			if(next != null && next.GetType() == typeof(ColorBoxRDB))
				((ColorBoxRDB)next).drawSelf = isOn;
		}
		/// <summary>
		/// Returns an object from the RDB tree which was at the specified click coords.
		/// </summary>
		/// <param name="x">The x this obj should be drawn at</param>
		/// <param name="y">The y this obj should be drawn at</param>
		/// <param name="click_x">The x coordinate of the click</param>
		/// <param name="click_y">The y coordinate of the click</param>
		/// <param name="g"></param>
		/// <returns>An RDB at the coords of the click (it's possible to have several)</returns>
		public abstract RelDrawingBase listRDBAtCoords(float x, float y, float click_x, float click_y, Graphics g);
		/// <summary>
		/// Returns true if this object was the one which was clicked on. (Doesn't search whole hierarchy)
		/// </summary>
		/// <param name="x">The x coord this obj is drawn at</param>
		/// <param name="y">The y coord this obj is drawn at</param>
		/// <param name="click_x">The x coord of the click</param>
		/// <param name="click_y">The y coord of the click</param>
		/// <returns></returns>
		public virtual bool wasClickedOn(float x, float y, float click_x, float click_y)
		{
			if((click_x > x) && (click_x < (x+width)))
				if((click_y > y) && (click_y < (y+height)))
					return true;
			return false;
		}

		/// <summary>
		/// Tell this RDB to remove itself from the tree. Does so by telling the previous object to replace
		/// its pointer to this one with the one to this guy's next field.
		/// </summary>
		public virtual void deleteSelf()
		{
			//this.toogleNeighborCBDraw(false);
			this.removeNeighborCBs();
			if(prev != null && next != null)
			{
				prev.replaceRefFor(this, this.next);
				next.prev = this.prev;
			}
			else if(prev !=null && next == null)
			{
				prev.replaceRefFor(this, null);
			}
			else if(next !=null && prev == null)
			{
				next.prev = null;
			}
		}
	}
	
	/// <summary>
	/// This ColorBox class is a subclass of the RelDrawingBase, described above. It is for drawing
	/// ColorBoxes, boxes in which a user clicks to indicate that he wants to insert math at that location.
	/// Like it's superclass, ColorBoxRDB is Serializable for easy transmission and saving.
	/// </summary>
	[Serializable]
	public class ColorBoxRDB: RelDrawingBase
	{
		public bool drawSelf, drawFilled = true;
		/// <summary>
		/// A Constructor for a colorbox, basically the same as that for the superclass. Assumes that 
		/// there is no next RDB object (which is generally the case for ColorBoxRDBs) and that this
		/// colorbox should not initially be drawing itself. Also sets up height and width based on
		/// num_parents.
		/// </summary>
		/// <param name="prev">Whatever object is pointing to this one on the left</param>
		/// <param name="num_parents">The number of levels away from the top level this class is</param>
		public ColorBoxRDB(RelDrawingBase prev, int num_parents)
			:this(prev, num_parents, null )
		{
		}

		/// <summary>
		/// The more detailed ColorBoxRDB constructor. Allows a user supplied next field in addition
		/// to prev and num_parents. Assumes that this colorbox should not by default be drawining
		/// itself. Also, sets up height and width based on num_parents. 
		/// </summary>
		/// <param name="prev">Whatever object is pointing to this one on the left</param>
		/// <param name="num_parents">The number of levels away from the top level this class is</param>
		/// <param name="next">The object on the right which this RDB should point to</param>
		public ColorBoxRDB(RelDrawingBase prev, int num_parents, RelDrawingBase next)
			:base(prev,num_parents)
		{
			this.width = this.height = calcSide(num_parents);
			this.next = next;
			this.drawSelf = false;
		}
		
		/// <summary>
		/// Given the number of parents, returns the length of the sides of the box. (Static method)
		/// </summary>
		/// <param name="parents"></param>
		/// <returns></returns>
		private static float calcSide(float parents)
		{
			if(parents < 2)
				return 24-parents*2;
			else
				return 20;
		}

		/// <summary>
		/// Draws just this colorbox at the given x and y coords.
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <param name="g"></param>
		public override void draw(float x, float y, Graphics g)
		{
			if(drawSelf)
			{
				if(drawFilled)
					g.FillRectangle(b_red, x, y, width, height);
				else
					g.DrawRectangle(p_red, x, y, width, height);
			}
		}

		public override float highestY(float presy)
		{
			if(next == null && drawSelf)
				return presy;
			else if(next == null && !drawSelf)
				return presy + height;
			else
				return Math.Min(presy, next.highestY(presy));
		}

		public override float lowestY(float presy)
		{
			if(next == null && drawSelf)
				return presy + height;
			else if (next == null && !drawSelf)
				return presy;
			else
				return Math.Max(presy, next.lowestY(presy));
		}

		/// <summary>
		/// Draws this colorbox and all RDBs connected to it on the right, recursively starting at
		/// the given coordinates. The given coordinates will be the location of this colorbox, the
		/// coordinates of connected objects are calculated on the fly.
		/// </summary>
		/// <param name="x">X Coord to draw this obj at</param>
		/// <param name="y">Y Coord to draw this obj at</param>
		/// <param name="g"></param>
		public override void listDraw(float x, float y, Graphics g)
		{
			this.draw(x,y,g);
			
			if(next != null && this.drawSelf)
				next.listDraw(x+width+hbuf, y, g);
			else if (next != null)
				next.listDraw(x, y, g);
		}

		public override float listHeightAboveDrawY()
		{
			if(next !=null)
				return Math.Max(0, next.listHeightAboveDrawY());
			else
				return 0;
		}
		
		public override float listHeightBelowDrawY()
		{
			if(next != null)
				return Math.Max(height, next.listHeightBelowDrawY());
			else if(this.drawSelf)
				return height;
			else
				return 0;
		}

		/// <summary>
		/// Returns the width of this obj + all objects to the right of it.
		/// </summary>
		/// <returns></returns>
		public override float listWidth()
		{
			float nextlen=0, thislen=0;

			if(next != null)
				nextlen = next.listWidth();
			if(this.drawSelf)
				thislen = this.width;
			return thislen + nextlen;
			//return max(thislen,nextlen);
		}

		/// <summary>
		/// Converts its next field if present into a 
		/// Tex interpretation.
		/// </summary>
		/// <returns>A string written in Tex equivalent to 
		/// the math expression of the next Object</returns>
		public override string listConvertToTex()
		{
			string texTrans = "";
			if (next != null)
				texTrans = next.listConvertToTex();
			return texTrans;
		}
		/// <summary>
		/// Converts its next field if present into a 
		/// MathML interpretation.
		/// </summary>
		/// <returns>A string written in MathML equivalent to 
		/// the math expression of the next Object</returns>
		public override string listConvertToMathML()
		{
			string MLTrans = "";
			if (next != null)
				MLTrans += next.listConvertToMathML();
			return MLTrans;
		}
		/// <summary>
		/// If the given reference is the next reference, it replaces it. Otherwise it does nothing.
		/// </summary>
		/// <param name="initRef">The reference to the obj to replace</param>
		/// <param name="repRef">The object to replace the initRef with</param>
		public override void replaceRefFor(RelDrawingBase initRef, RelDrawingBase repRef)
		{
			if(initRef == null)
				return;

			if(initRef == next)
			{
				this.next = repRef;
				repRef.prev = this;
			}
		}
		/// <summary>
		/// Returns an object on the right which was clicked on. Requires the render coords of the 
		/// present object, the click coords and a Graphics g.
		/// </summary>
		/// <param name="x">The xcoord to render this CB at </param>
		/// <param name="y">The ycoord to render this CB at</param>
		/// <param name="click_x">The xcoord of the click</param>
		/// <param name="click_y">The ycoord of the click</param>
		/// <param name="g"></param>
		/// <returns></returns>
		public override RelDrawingBase listRDBAtCoords(float x, float y, float click_x, float click_y, Graphics g)
		{
			if(this.wasClickedOn(x,y,click_x, click_y))
				return this;
			else if(next != null)
				return next.listRDBAtCoords(x+width+hbuf,y,click_x,click_y,g);
			else
				return null;
		}
		
		public override string ToString()
		{
			string prevID, nextID;
			prevID = (prev == null) ? "null" : prev.ID.ToString();
			nextID = (next == null) ? "null" : next.ID.ToString();
			return "Colorbox: ID = [" + this.ID + "] drawStatus = [" + this.drawSelf 
				+  "] prev = [" + prevID + "] next = [" + nextID + "]";
		}

		/// <summary>
		/// Returns true this colorbox was the object clicked on, false otherwise.
		/// </summary>
		/// <param name="x">The xcoord to render this CB at</param>
		/// <param name="y">The ycoord to render this CB at</param>
		/// <param name="click_x">The xcoord of the click</param>
		/// <param name="click_y">The ycoord of the click</param>
		/// <returns></returns>
		public override bool wasClickedOn(float x, float y, float click_x, float click_y)
		{
			if(drawSelf)
				return base.wasClickedOn (x, y, click_x, click_y);
			else
				return false;
		}

	}

	[Serializable]
	public class SymbolRDB : RelDrawingBase
	{
		internal string text;
		internal RelDrawingBase exp, sub;
		public Font normalF, greekF;
		
		/// <summary>
		/// Creates a SymbolRBD with the specified RDB, colorbox drawing mode, text
		/// number of parents.
		/// </summary>
		/// <param name="prev">The object to the left that links to this one</param>
		/// <param name="num_parents">The number of RDBs from the top level this one is</param>
		/// <param name="daText">The text of the symbol. It can be the @escape sequence.
		/// It should only be the token for this particular symbol, no chaining symbols
		/// will be created by this function.</param>
		/// <param name="next">The "next" RDB. That is the one on this level that follows
		/// this one.</param>
		/// <param name="sub">The "subscript" RDB. It is below and to the right of this
		/// one.</param>
		/// <param name="exp">The "exponent" RDB. Is is above to the right of this one.
		/// </param>
		/// <param name="CBs">Boolean tells this symbol whether neighboring Colorboxes
		/// should be drawn.</param>
		/// <param name="g"> A windows Graphics drawing object</param>
		public SymbolRDB(RelDrawingBase prev, int num_parents, string daText, RelDrawingBase next,
			RelDrawingBase sub, RelDrawingBase exp, bool CBs, Graphics g)
			:base(prev, num_parents)
		{
			this.next = next;
			this.exp = exp;
			this.sub = sub;
			this.text = daText;

			this.setFonts();
			this.recalcDimensions(g);
			this.toogleNeighborCBDraw(CBs);
		}
		//Creates a SymbolRDB with colorboxes as next,sub and prev, CB drawing off
		/// <summary>
		/// Creates a SymbolRDB with colorboxes put in the next,sub and prev field 
		/// with their drawing turned off.
		/// </summary>
		/// <param name="prev">The colorbox on the right which link to this one.</param>
		/// <param name="num_parents">The number of RDBs from the top level this one is</param>
		/// <param name="daText">The text of the symbol. It can be the @escape sequence.
		/// It should only be the token for this particular symbol, no chaining symbols
		/// will be created by this function.</param>
		/// <param name="g">A windows Graphics drawing object</param>
		public SymbolRDB(RelDrawingBase prev, int num_parents, string daText, Graphics g)
			:this(prev, num_parents, daText, null,null, null, false, g)
		{
			this.next = new ColorBoxRDB(this, num_parents);
			this.exp = new ColorBoxRDB(this, num_parents + 1);
			this.sub = new ColorBoxRDB(this, num_parents +1);
		}
		
		public override void addNeighborCBs()
		{
			if(next != null && next.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB cb = new ColorBoxRDB(this, this.parents);
				this.insertRDBAfter(cb, cb);
			}
			if(exp != null && exp.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB cb = new ColorBoxRDB(this, this.parents+1);
				this.insertRDBExp(cb, cb);
			}
			if(sub != null && sub.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB cb = new ColorBoxRDB(this, this.parents+1);
				this.insertRDBSub(cb, cb);
			}
			this.toogleNeighborCBDraw(true);
		}
		public override void removeNeighborCBs()
		{
			if(next != null && next.GetType() == typeof(ColorBoxRDB) && next.next != null)
			{
				this.next = next.next;
				next.prev = this;
			}
			if(exp != null && exp.GetType() == typeof(ColorBoxRDB) && exp.next != null)
			{
				this.exp = exp.next;
				exp.prev = this;
			}
			if(sub != null && sub.GetType() == typeof(ColorBoxRDB) && sub.next != null)
			{
				this.sub = sub.next;
				sub.prev = this;
			}
			this.toogleNeighborCBDraw(false);
		}

		
		public override void deleteSelf()
		{
			if(next != null && prev != null)
				base.deleteSelf();
			else if(next != null && prev == null)
				next.prev = null;
			else if(prev != null && next == null)
				prev.replaceRefFor(this, new ColorBoxRDB(prev, this.parents));
		}


		/// <summary>
		/// Draws just this symbol at the given x and y coordinates. Not any of the right
		/// symbols.
		/// </summary>
		/// <param name="x">The upper left x coordinate to draw this symbol at</param>
		/// <param name="y">The upper left y coordinate to draw this symbol at</param>
		/// <param name="g">A windows Graphics drawing object</param>
		public override void draw(float x, float y, Graphics g)
		{
			drawAString(g, this.text, FontStyle.Regular, normalF, greekF, x, y);
		}

		public override float highestY(float presy)
		{
			float subHighest, expHighest, nextHighest;

			subHighest = (sub == null) ? calcTopY(presy) : sub.highestY(calcSubY(presy));
			expHighest = (exp == null) ? calcTopY(presy) : exp.highestY(calcExpY(presy));
			nextHighest= (next == null) ? calcTopY(presy) : next.highestY(presy);

			return min(calcTopY(presy), subHighest, expHighest, nextHighest); 
		}

		public override float lowestY(float presy)
		{
			float subLowest, expLowest, nextLowest;

			subLowest = (sub == null) ? calcTopY(presy)+ this.height: sub.lowestY(calcSubY(presy));
			expLowest = (exp == null) ? calcTopY(presy)+ this.height: exp.lowestY(calcExpY(presy));
			nextLowest= (next == null) ? calcTopY(presy)+this.height: next.lowestY(presy);

			return max(calcTopY(presy) + height, subLowest, expLowest, nextLowest); 
		}

		/// <summary>
		/// Draws this symbol, and it's next, exp and sub (the three fields on the right).
		/// Those will in turn recursively draw their right hand neighbors. So this function
		/// can effective draw the entire expression to the right of it. Additional documents
		/// will discuss formatting.
		/// </summary>
		/// <param name="x">The left x coordinate at which to draw *this* symbol. 
		/// Others will be drawn further right as the drawing progresses</param>
		/// <param name="y">The top y coordinate at at which to draw *this* symbol. Exponents 
		/// may be drawn considerably above this and subscripts may be considerably below.
		/// The coordinates of linked RDB will be calculated as the drawing proceeds.</param>
		/// <param name="g">A windows Graphics drawing object</param>
		public override void listDraw(float x, float y, Graphics g)
		{
			recalcDimensions(g);
			draw(x,calcTopY(y), g);	
			//g.DrawRectangle(p, x, calcTopY(y), width, height);

		if(sub != null)
				sub.listDraw(x+width, calcSubY(y), g);
			if(exp != null)
				exp.listDraw(x+width, calcExpY(y), g);
			if(next != null)
				next.listDraw(x + width+ calcExpSubWidth() + hbuf, y, g);
		}
		
		public override void listChangeParents(int delta, Graphics g)
		{
			this.parents += delta;
			this.setFonts();
			this.recalcDimensions(g);
			this.next.listChangeParents(delta,g);
			this.exp.listChangeParents(delta,g);
			this.sub.listChangeParents(delta,g);
		}

		/// <summary>
		/// Examines this and exp,sub and next (all right linked RDBS) to see if a click 
		/// intersected any of their bounding boxes. Returns the first which does.
		/// </summary>
		/// <param name="x">The x coord at which this should be drawn.</param>
		/// <param name="y">The y coord at which this should be drawn.</param>
		/// <param name="click_x">The x coord of the click.</param>
		/// <param name="click_y">The y coord of the click.</param>
		/// <param name="g">A windows Graphics drawing object</param>
		///
		/// <returns></returns>
		public override RelDrawingBase listRDBAtCoords(float x, float y, float click_x, float click_y, Graphics g)
		{
			RelDrawingBase temp;

			if(this.wasClickedOn(x,y,click_x, click_y))
				return this;
			if(this.next != null)
			{
				temp = next.listRDBAtCoords(x+width+calcExpSubWidth()+hbuf, y,click_x,click_y,g);
				if(temp !=null)
					return temp;
			}
			if(this.sub != null)
			{
				temp = sub.listRDBAtCoords(x+width,calcSubY(y),click_x,click_y,g);
				if(temp !=null)
					return temp;
			}
			if(this.exp != null)
			{
				temp = exp.listRDBAtCoords(x+width,calcExpY(y),click_x,click_y,g);
				if(temp !=null)
					return temp;
			}
			return null;
		}

		public override float listHeightAboveDrawY()
		{
			float returnme = this.highestY(0);
			return (returnme < 0) ? (-1 * returnme) : 0;
		}

		public override float listHeightBelowDrawY()
		{
			/*float returnme =  this.listHeight() - this.listHeightAboveDrawY();
			return (returnme < 0) ? 0 : returnme;*/
			return this.lowestY(0);
		}

		public override float listWidth()
		{
			float nwid=0, ewid=0, swid=0;

			//if(next !=null)
			nwid = next.listWidth();
			if(exp != null)
				ewid = exp.listWidth();
			if(sub != null)
				swid = sub.listWidth();

			return this.width + hbuf + nwid+ max(swid, ewid);
		}

		/// <summary>
		/// Returns a string displaying the ID of this and all linked RDBs + similar descriptions
		/// strings for all right (exp, sub and next) RDBs, each on it's own line.
		/// </summary>
		/// <returns></returns>
		public override string listDebugStr()
		{
			return this.ToString()+ '\n'+exp.listDebugStr()+next.listDebugStr()+sub.listDebugStr();
		}

		/// <summary>
		/// Converts all RDBs from this symbol right (exp, sub, and next) into a 
		/// Tex interpretation.
		/// </summary>
		/// <returns>A string written in Tex equivalent to the math expression from this 
		/// Symbol to the right.</returns>
		public override string listConvertToTex()
		{
			string texTrans;
			texTrans = this.textToTex();

			if (exp.listConvertToTex() != "")
				texTrans += "^{" + exp.listConvertToTex() + "}";
			if (sub.listConvertToTex() != "")
				texTrans += "_{" + sub.listConvertToTex() + "}";
			if (next.listConvertToTex() != "")
				texTrans += " " + next.listConvertToTex();

			return texTrans;
		}

		/// <summary>
		/// Converts all RDBs from this symbol right (exp, sub, and next) into a 
		/// MathML interpretation.
		/// </summary>
		/// <returns>A string written in MathML equivalent to the math expression 
		/// from this Symbol to the right.</returns>
		public override string listConvertToMathML()
		{
			string MLTrans = "";
			string subMath = sub.listConvertToMathML();
			string expMath = exp.listConvertToMathML();
		
			if (subMath != "" && expMath != "")
			{
				MLTrans += "<m:msubsup>";
				MLTrans += this.textToMathML();
				MLTrans += "<m:mrow>" + subMath + "</m:mrow>";
				MLTrans += "<m:mrow>" + expMath + "</m:mrow>";
				MLTrans += "</m:msubsup>";
			}
			else if (subMath != "")
			{
				MLTrans += "<m:msub>";
				MLTrans += this.textToMathML();
				MLTrans += "<m:mrow>" + subMath + "</m:mrow>";
				MLTrans += "</m:msub>";
			}
			else if (expMath != "")
			{
				MLTrans += "<m:msup>";
				MLTrans += this.textToMathML();
				MLTrans += "<m:mrow>" + expMath + "</m:mrow>";
				MLTrans += "</m:msup>";
			}
			else
			{
				MLTrans += this.textToMathML();
			}

				MLTrans += next.listConvertToMathML();

			return MLTrans;
		}

		/// <summary>
		/// Takes the text is the object and returns a new string that is the Tex equivalent.
		/// Handles Bold, Italic, and Underline symbols.
		/// </summary>
		/// <returns>A string represented the Tex equivalent of this Symbol's text</returns>
		public string textToTex()
		{
			string texResult = "";
			bool bold = this.isBold();
			bool underline = this.isUnderline();
			bool italic = this.isItalic();
			bool hex = this.isHex();
			bool letters;
			if (hex)
				letters = false;
			else
				letters = this.containsLetters();

			string textToLookup = "";
			if (hex)
				textToLookup = this.getHex();
			else
				textToLookup = this.getText();

			if (bold && !italic)
				texResult += "\\bf{";
			if(!bold && !italic && letters)
				texResult += "\\rm{";
			if (underline)
				texResult += "\\underline{";

			
			string texSymbol = lookupTexSymbol(textToLookup);

			if (texSymbol != null)
				texResult += texSymbol;
			else
				texResult += textToLookup;

			if(underline)
				texResult += "}";
			if(!bold && !italic && letters)
				texResult += "}";
			if(bold && !italic)
				texResult += "}";


			return texResult;
		
		}

		/// <summary>
		/// Takes the text is the object and returns a new string that is the MathML equivalent.
		/// Handles Bold, Italic, and Underline symbols.
		/// </summary>
		/// <returns>A string represented the MathML equivalent of this Symbol's text</returns>
		public string textToMathML()
		{
			string mathMLResult = "";
			bool bold = this.isBold();
			bool underline = this.isUnderline();
			bool italic = this.isItalic();
			bool hex = this.isHex();

			string textToLookup = "";
			if (hex)
				textToLookup = this.getHex();
			else
				textToLookup = this.getText();

			if (bold && !italic)
				mathMLResult += "<m:mstyle fontweight=\"bold\">";
			if (bold && italic)
				mathMLResult += "<m:mstyle fontweight=\"bold\" fontstyle=\"italic\">";
			if (underline)
				mathMLResult += "<m:munder>";

			
			string mathMLSymbol = lookupMathMLSymbol(textToLookup);

			if (mathMLSymbol != null)
				mathMLResult += "<m:mi>" + mathMLSymbol + "</m:mi>";
			else
				mathMLResult += "<m:mi>" + textToLookup + "</m:mi>";

			if(underline)
				mathMLResult += "<m:mo> &#x0332; </m:mo> </m:munder>";
			if(bold)
				mathMLResult += "</m:mstyle>";


			return mathMLResult;
		
		}

		/// <summary>
		/// Looks up the given text in the texHexArray and returns the corresponding symbol
		/// found on the same line in the texSymbolArray.
		/// </summary>
		/// <param name="text">The text to lookup.</param>
		/// <returns>The Tex symbol equivalent.</returns>
		public string lookupTexSymbol(String text)
		{
			for (int i = 0; i < texHexArray.Length; i++)
			{
				if (texHexArray[i] == text)
					return texSymbolArray[i];
			}

			return null;
		}
		/// <summary>
		/// Looks up the given text in the mathMLHexArray and returns the corresponding symbol
		/// found on the same line in the mathMLSymbolArray.
		/// </summary>
		/// <param name="text">The text to lookup.</param>
		/// <returns>The mathML symbol equivalent.</returns>
		public string lookupMathMLSymbol(String text)
		{
			for (int i = 0; i < mathMLHexArray.Length; i++)
			{
				if (mathMLHexArray[i] == text)
					return mathMLSymbolArray[i];
			}

			return null;
		}
		/// <summary>
		/// Searches for '@B' is this Symbol's text to determine if it is Bold.
		/// </summary>
		/// <returns>True if this Symbol is Bold.</returns>
		public bool isBold()
		{
			int test = text.IndexOf("@B");
			int test2 = text.IndexOf("@b");

			if (test == -1 && test2 == -1)
				return false;
			return true;

		}
		/// <summary>
		/// Searches for '@U' is this Symbol's text to determine if it is Underlined.
		/// </summary>
		/// <returns>True if this Symbol is Underlined.</returns>
		public bool isUnderline()
		{
			int test = text.IndexOf("@U");
			int test2 = text.IndexOf("@u");

			if (test == -1 && test2 == -1)
				return false;
			return true;

		}

		/// <summary>
		/// Searches for '@I' is this Symbol's text to determine if it is Italic.
		/// </summary>
		/// <returns>True if this Symbol is Italic.</returns>
		public bool isItalic()
		{
			int test = text.IndexOf("@I");
			int test2 = text.IndexOf("@i");

			if (test == -1 && test2 == -1)
				return false;
			return true;
		}
		/// <summary>
		/// Searches for '@H' is this Symbol's text to determine if it is Hex.
		/// </summary>
		/// <returns>True if this Symbol is Hex.</returns>
		public bool isHex()
		{
			int test = text.IndexOf("@x");
			int test2 = text.IndexOf("@x");

			if (test == -1 && test2 == -1)
				return false;
			return true;

		}

		/// <summary>
		/// Searches this symbol's text to see if any of its characters that are letters.
		/// </summary>
		/// <returns>True if this Symbol contains any letters.</returns>
		public bool containsLetters()
		{
			string testText = this.getText();
			if (testText == null)
				return false;
			
			testText.Trim();

			for(int i = 0; i < testText.Length; i++)
			{
				if (Char.IsLetter(testText, i))
					return true;
			}
			return false;

		}
		/// <summary>
		/// Searches for '@x' in this Symbol's text to find the 2 digit hex number 
		/// that it contains.
		/// </summary>
		/// <returns>Null if this symbol does not contain a hex symbol. Otherwise, it 
		/// returns the 2 digit hex number contained in the Symbol's text.</returns>
		public string getHex()
		{
			int test = text.IndexOf("@x");
			if (test == -1)
				return null;
			else
			{
				return text.Substring(test+2, 2);
			}
			


		}

		/// <summary>
		/// This function creates a new string equivalent to this Symbol's text except that it 
		/// removes any bold, italic, and underline indications, and hex numbers.
		/// </summary>
		/// <returns>A string that contains only the plaintext of this Symbol.</returns>
		public string getText()
		{
			string plaintext = text;
			while (plaintext != null && plaintext.StartsWith("@"))
			{
				if (plaintext[1] == 'x')
					plaintext = plaintext.Remove(0,4);
				else
					plaintext = plaintext.Remove(0,2);
				if (plaintext != null)
					plaintext = plaintext.Trim();
			}

			return plaintext;
		}

		/// <summary>
		/// Searches all fields in this RDB for the given initRef and replaces it with the 
		/// given repRef. Used for changing a ref from the prev, since you don't know
		/// which of the prev's field's an object is in in.
		/// </summary>
		/// <param name="initRef">The reference to search for to replace.</param>
		/// <param name="repRef">The reference to replace initRef with.</param>
		public override void replaceRefFor(RelDrawingBase initRef, RelDrawingBase repRef)
		{
			if(initRef == null)
				return;

			if(initRef == next)
			{
				this.next = repRef;
				repRef.prev = this;
			}
			else if(initRef == exp)
			{
				this.exp = repRef;
				repRef.prev = this;
			}
			else if(initRef == sub)
			{
				this.sub = repRef;
				repRef.prev = this;
			}
		}

		/// <summary>
		/// Orders all right neighboring colorboxes (those in exp, sub and next) to turn their
		/// drawing on/off. Unlike removeNeighborCBs, this is not destructive.
		/// </summary>
		/// <param name="isOn">If true, draws the neighbor CBs, if false, doesn't.</param>
		public override void toogleNeighborCBDraw(bool isOn)
		{
			base.toogleNeighborCBDraw(isOn);
			if(sub != null && sub.GetType() == typeof(ColorBoxRDB))
				((ColorBoxRDB)sub).drawSelf = isOn;
			if(exp != null && exp.GetType() == typeof(ColorBoxRDB))
				((ColorBoxRDB)exp).drawSelf = isOn;
		}

		/// <summary>
		/// Returns a string containing this item's ID and those of all linked RDBs (prev,
		/// sub, exp and next)
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			if(prev !=null)
				return "Symbol: ID = [" + this.ID + "] text = [" + this.text + "] prev = [" + prev.ID + "] next = [" 
					+next.ID + "] exp = [" + exp.ID + "] sub = [" + sub.ID + "]"; 
			else
				return "Symbol: ID = [" + this.ID + "] text = [" + this.text + "] next = [" 
					+next.ID + "] exp = [" + exp.ID + "] sub = [" + sub.ID + "]"; 
		}

		/// <summary>
		/// Returns of the larger of the width of the exponent and the width of the subscript.
		/// Generally used for spacing the next object so that it doesn't overlap the subscript 
		/// or exponent.
		/// </summary>
		/// <returns></returns>
		public float calcExpSubWidth()
		{
			float expw=0, subw=0;

			if(exp != null)
				expw = exp.listWidth();
			if(sub != null)
				subw = sub.listWidth();
			return max(subw, expw);
		}
		/// <summary>
		/// Returns the y coordinate at which the exponent is drawn, given the coord at which
		/// this symbol is drawn.
		/// </summary>
		/// <param name="presy">The coord at which this symbol is drawn.</param>
		/// <returns></returns>
		public float calcExpY(float presy)
		{
			if(exp.GetType() == typeof(ColorBoxRDB))
			{
				if(((ColorBoxRDB) exp).drawSelf)
					return calcTopY(presy) - exp.listHeightBelowDrawY();
				else
					return calcTopY(presy);
			}

			return calcTopY(presy) + (this.height/3) - exp.listHeightBelowDrawY();
		}

		/// <summary>
		/// Returns the y coordinate at which the subscript is drawn, given the coord at which
		/// this symbol is drawn.
		/// </summary>
		/// <param name="presy">The coord at which this symbol is drawn.</param>
		/// <returns></returns>
		public float calcSubY(float presy)
		{
			if(sub.GetType() == typeof(ColorBoxRDB))
			{
				if(((ColorBoxRDB) sub).drawSelf)
					return calcTopY(presy) + this.height + sub.listHeightAboveDrawY();
				else
					return calcTopY(presy) + this.height;
			}
			return calcTopY(presy) + this.height - (this.height/3) + sub.listHeightAboveDrawY();
		}

		/// <summary>
		/// Returns the y coordinate at which the top of this symbol is drawn, given 
		/// the coord at which it was passed by the previous symbol.
		/// </summary>
		/// <param name="presy">The coord which the previous symbol gives as the 
		/// starting point of this Symbol.</param>
		/// <returns></returns>
		public float calcTopY(float presy)
		{
			string hexCode = this.getHex();
				
			//integrals, sumations, products
			//all need to have their placement adjusted according to their height
			if (hexCode == "F2" || hexCode == "E5" || hexCode =="D5")
				return presy - height/2;
			return presy;
		}

		/// <summary>
		/// Takes a given RDB(s) and sticks places it(them) in the exponent field. If there
		/// already is an exponent, the new RDB(s) becomes the first element(s) of the exponent 
		/// and the old exponent is chained into the next field.
		/// </summary>
		/// <param name="first">The first RDB to insert, will always be the first element of the
		/// exponent.</param>
		/// <param name="last">The last RDB to insert, will have the old exponent after it</param>
		public void insertRDBExp(RelDrawingBase first, RelDrawingBase last)
		{
			if(this.exp != null)
			{
				last.next = this.exp;
				this.exp.prev = last;
			}
			this.exp = first;
			first.prev = this;
		}
		/// <summary>
		/// Takes a given RDB(s) and sticks places it(them) in the subscript field. If there
		/// already is an subscript, the new RDB(s) becomes the first element(s) of the sub 
		/// and the old subscript is chained into the next field.
		/// </summary>
		/// <param name="first">The first RDB to insert, will always be the first element of the
		/// subscript.</param>
		/// <param name="last">The last RDB to insert, will have the old subscript after it</param>
		public void insertRDBSub(RelDrawingBase first, RelDrawingBase last)
		{
			if(this.sub != null)
			{
				last.next = this.sub;
				this.sub.prev = last;
			}
			this.sub = first;
			first.prev = this;
		}

		/// <summary>
		/// If turnOn is true, this Symbol will be made bold by adding a '@B' to 
		/// its text string. Otheriwse the '@B's in the text string will be recursively 
		/// removed until the Symbol is no longer bold. 
		/// </summary>
		/// <param name="g"></param>
		/// <param name="turnOn">Indicates whether or not to make this symbol bold.</param>
		public void makeBold(Graphics g, bool turnOn)
		{
			if (turnOn) //addbold
				this.setString("@B " + this.text, g);
			else //remove bold label
			{
				int test = text.IndexOf("@B");
				int test2 = text.IndexOf("@b");

				if (test != -1)
					this.setString(this.text.Remove(test, 3), g);

				else if (test2 != -1)
					this.setString(this.text.Remove(test2, 3), g);
			}

			if(this.isBold() && !turnOn)
				makeBold(g, turnOn);
			return;			

		}
		/// <summary>
		/// If turnOn is true, this Symbol will be made italic by adding a '@I' to 
		/// its text string. Otheriwse the '@I's in the text string will be recursively 
		/// removed until the Symbol is no longer italic. 
		/// </summary>
		/// <param name="g"></param>
		/// <param name="turnOn">Indicates whether or not to make this symbol italic.</param>
		public void makeItalic(Graphics g, bool turnOn)
		{
			if (turnOn) //additalic
				this.setString("@I " + this.text, g);
			else //remove italic label
			{
				int test = text.IndexOf("@I");
				int test2 = text.IndexOf("@i");

				if (test != -1)
					this.setString(this.text.Remove(test, 3), g);

				else if (test2 != -1)
					this.setString(this.text.Remove(test2, 3), g);
			}
			if(this.isItalic() && !turnOn)
				makeItalic(g, turnOn);
			return;	

		}
		/// <summary>
		/// If turnOn is true, this Symbol will be underlined by adding a '@U' to 
		/// its text string. Otheriwse the '@U's in the text string will be recursively 
		/// removed until the Symbol is no longer underlined. 
		/// </summary>
		/// <param name="g"></param>
		/// <param name="turnOn">Indicates whether or not to underline this symbol.</param>
		public void makeUnderline(Graphics g, bool turnOn)
		{
			if (turnOn) //addUnderline
				this.setString("@U " + this.text, g);
			else //remove underline label
			{
				int test = text.IndexOf("@U");
				int test2 = text.IndexOf("@u");

				if (test != -1)
					this.setString(this.text.Remove(test, 3), g);

				else if (test2 != -1)
					this.setString(this.text.Remove(test2, 3), g);
			}
			if(this.isUnderline() && !turnOn)
				makeUnderline(g, turnOn);
			return;	
		}

		/// <summary>
		/// Recalculates the current dimensions of this Symbol and updates 
		/// the width and height fields. 
		/// </summary>
		/// <param name="g"></param>
		public void recalcDimensions(Graphics g)
		{
			width = strWidth(g, text, normalF, greekF);
			height = strHeight(g, text, normalF, greekF);
		}
		/// <summary>
		/// Changes the text of this symbol to the given token. We cannot simply change
		/// a text field because width (and height) must be recalculated.
		/// </summary>
		/// <param name="s">String token for this symbol</param>
		/// <param name="g"></param>

		public void setString(string s, Graphics g)
		{
			this.text = s;
			this.width = strWidth(g, text, normalF, greekF);
			this.height = strHeight(g, text, normalF, greekF);
		}
		public void setFonts()
		{
			if(parents == 0)
			{
				normalF = normal14; 
				greekF = greek14; 
			}
			else if (parents == 1)
			{ 
				normalF = normal12;
				greekF = greek12; 
			}
			else
			{ 
				normalF = normal10; 
				greekF = greek10; 
			}
		}
		//returns the first and last Symbols in the list in returned array
		/// <summary>
		/// Takes an array of string tokens and produces a set of symbols to represent them.
		/// It returns them chained in eachother's next fields. Returns a two element array,
		/// containing the first and last elements of the chain, all others chain be accessed
		/// using the next and prev field.
		/// </summary>
		/// <param name="s">String tokens to change into symbols</param>
		/// <param name="num_parents">The number of parents the created symbols have</param>
		/// <param name="g"></param>
		/// <returns>A two element array containing the first and last symbols in the 
		/// produced chain.</returns>
		public static SymbolRDB[] stringsToSymbols(string[] s, int num_parents, Graphics g)
		{
			if(s.Length <= 0)
				return null;

			SymbolRDB first = new SymbolRDB(null, num_parents, s[0], g);
			SymbolRDB pres;
			SymbolRDB[] returnme = new SymbolRDB[2];
			int i;
			
			pres = first;
			for(i=1; i < s.Length; i++)
			{
				pres.next = new SymbolRDB(pres, num_parents, s[i], g);
				pres = (SymbolRDB) pres.next;
			}

			returnme[0] = first;
			returnme[1] = pres;
			return returnme;
		}
		/// <summary>
		/// Returns the maximum height of the given string in the given Fonts (automatically
		/// changes greek letters and symbols into the GreekF).
		/// </summary>
		/// <param name="g"></param>
		/// <param name="s">The string, can contain escape sequences for greek/math.</param>
		/// <param name="normalF">Font for normal text</param>
		/// <param name="greekF">Font for symbols and greek</param>
		/// <returns>The height of the string</returns>
		public float strHeight(Graphics g, string s, Font normalF, Font greekF)
		{
			/*int i;
			for(i=0; i < s.Length; i++)
				if(s[i] == '\\')
					return g.MeasureString(s, greekF).Height;
			return g.MeasureString(s, normalF).Height;*/

			return max(normalF.Height, greekF.Height, this.height);
		}
		/// <summary>
		/// Returns the length of the given string in the given Fonts (automatically 
		/// changes greek letters and symbols into Greek F).
		/// </summary>
		/// <param name="g"></param>
		/// <param name="s">The string, can contain escape sequences for greek/math</param>
		/// <param name="normalF">Font for normal text.</param>
		/// <param name="greekF">Font for symbols and greek</param>
		/// <returns>The width of the string</returns>
		public float strWidth(Graphics g, string s, Font normalF, Font greekF)
		{
			return this.strWidthRec(g, s, FontStyle.Regular, normalF, greekF, 0);
		}
		/// <summary>
		/// A helper function for strWidth. Uses a style and presx which change on each
		/// recursion.
		/// </summary>
		/// <param name="g"></param>
		/// <param name="s">The string (can contain escape sequences)</param>
		/// <param name="useStyle">The present style</param>
		/// <param name="normalF">The regular font</param>
		/// <param name="greekF">The math/symbol font</param>
		/// <param name="presx">The xcoord at which this symbol is</param>
		/// <returns>The x coord of the last symbol</returns>
		public float strWidthRec(Graphics g, string s, FontStyle useStyle, Font normalF,
			Font greekF, float presx)
		{
			if(s.Length == 0)
				return presx;

			string hexCode = this.getHex();
			float pixelFontSize = -1;
				
			//integrals, sumations, products
			//all need to have their height adjusted according to what follows them
			if ((hexCode == "F2" || hexCode == "E5" || hexCode == "D5") && next!=null && sub != null && exp!=null)
			{
				pixelFontSize = max(next.listHeight(),sub.listHeight() + exp.listHeight() + 20);
				pixelFontSize = min(pixelFontSize, 150,150,150); //the symbol looks bad if its print to large
				height = pixelFontSize;					 //150 pixels is the max height
			}

			if(s[0] == '@')
			{
				//Followed by x and two digit hex values for symbolic
				if(s[1] == 'x')
				{
					if(s.Length < 4)
						return 0;

					int hexcode = (int) (Convert.ToUInt32(s[2].ToString(), 16) * 16 + 
						Convert.ToUInt32(s[3].ToString(), 16));
					char hexchar = (char) hexcode;
					Font drawFont;
					if (pixelFontSize != -1)
						drawFont = new Font(greekF.Name, pixelFontSize, useStyle, System.Drawing.GraphicsUnit.Pixel);
					else
						drawFont = new Font(greekF.Name, greekF.SizeInPoints, useStyle);

					presx += charWidth(hexchar, g, drawFont);
					return strWidthRec(g, s.Substring(4), useStyle, normalF, greekF, presx);
				}
				
				else
				{
					//Followed by Bold, Underline, Italics
					if(s[1] == 'b' || s[1] == 'B')
						useStyle |= FontStyle.Bold;
					if(s[1] == 'u' || s[1] == 'U')
						useStyle |= FontStyle.Underline;
					if(s[1] == 'i' || s[1] == 'I')
						useStyle |= FontStyle.Italic;
					if(s.Length > 3)
						return strWidthRec(g, s.Substring(3), useStyle, normalF, greekF, presx);
					else 
						return 0;
				}
			}
			else
			{
				Font drawFont;
					if (pixelFontSize != -1)
						drawFont = new Font(normalF.Name, pixelFontSize, useStyle, System.Drawing.GraphicsUnit.Pixel);
					else
						drawFont = new Font(normalF.Name, normalF.SizeInPoints, useStyle);
				presx += charWidth(s[0], g, drawFont);
				if(s[0] == ' ')
					useStyle = FontStyle.Regular;
				return strWidthRec(g, s.Substring(1), useStyle, normalF, greekF, presx);
			}
		}
		/// <summary>
		/// Returns the width of an individual character in the given Font.
		/// </summary>
		/// <param name="aChar">The character to measure</param>
		/// <param name="g">The Graphics G</param>
		/// <param name="f">The font</param>
		/// <returns>Width of the character in the font</returns>
		public static float charWidth(char aChar, Graphics g, Font f)
		{
			if(aChar != ' ')
				return g.MeasureString(aChar.ToString(), f).Width-5;
			else
				return g.MeasureString(aChar.ToString(), f).Width;
		}

		/// <summary>
		/// Draws a string at the given coordinates using the given styles, fonts.
		/// </summary>
		/// <param name="g">A Graphics G</param>
		/// <param name="s">The string to draw</param>
		/// <param name="useStyle">Present Style (can change on recursions)</param>
		/// <param name="normalF">The font for normal letters/numbers</param>
		/// <param name="greekF">The font for greek/math</param>
		/// <param name="presx">The xcoord to draw the first letter of the string</param>
		/// <param name="y">The y coord to draw the string</param>
		/// <returns>The coord of the final letter of the font.</returns>
		public float drawAString(Graphics g, string s, FontStyle useStyle, Font normalF, Font greekF,
			float presx, float y)
		{
			if(s.Length == 0)
				return presx;

			string hexCode = this.getHex();
			float pixelFontSize = -1;
				
			//integrals, sumations, products
			//all need to have their height adjusted according to what follows them
			if ((hexCode == "F2" || hexCode == "E5" || hexCode =="D5")&& next!=null && sub != null && exp!=null)
			{
				pixelFontSize = max(next.listHeight(),sub.listHeight() + exp.listHeight()+20);
				pixelFontSize = min(pixelFontSize, 150,150,150); //the symbol looks bad if its print to large
				height = pixelFontSize;					 //150 pixels is the max height
			}


			if(s[0] == '@')
			{
				//Followed by x and two digit hex values for symbolic
				if(s[1] == 'x')
				{
					int hexcode = (int) (Convert.ToUInt32(s[2].ToString(), 16) * 16 + 
						Convert.ToUInt32(s[3].ToString(), 16));
					char hexchar = (char) hexcode;
					Font drawFont;
					if (pixelFontSize != -1)
						drawFont = new Font(greekF.Name, pixelFontSize, useStyle, System.Drawing.GraphicsUnit.Pixel);
					else
						drawFont = new Font(greekF.Name, greekF.SizeInPoints, useStyle);

					g.DrawString(hexchar.ToString(), drawFont, b, presx, y);
					presx += charWidth(hexchar, g, drawFont);
					return drawAString(g, s.Substring(4), useStyle, normalF, greekF, presx, y);
				}
				
				else
				{
					//Followed by Bold, Underline, Italics
					if(s[1] == 'b' || s[1] == 'B')
						useStyle |= FontStyle.Bold;
					if(s[1] == 'u' || s[1] == 'U')
						useStyle |= FontStyle.Underline;
					if(s[1] == 'i' || s[1] == 'I')
						useStyle |= FontStyle.Italic;
					if(s.Length > 3)
						return drawAString(g, s.Substring(3), useStyle, normalF, greekF, presx, y);
					else
						return 0;
				}
			}

			else
			{


				Font drawFont;
				if (pixelFontSize != -1)
					drawFont = new Font(normalF.Name, pixelFontSize, useStyle, System.Drawing.GraphicsUnit.Pixel);
				else
					drawFont = new Font(normalF.Name, normalF.SizeInPoints, useStyle);

				g.DrawString(s[0].ToString(), drawFont, b, presx, y);
				presx += charWidth(s[0], g, drawFont);
				if(s[0] == ' ')
					useStyle = FontStyle.Regular;
				return drawAString(g, s.Substring(1), useStyle, normalF, greekF, presx, y);
			}
		}
		/// <summary>
		/// Returns true if the click_x and click_y lie within this Objects boundaries
		/// given the x, and y as this Object's starting point.
		/// </summary>
		/// <param name="x">The x coordinate which this Object starts at.</param>
		/// <param name="y">The y coordinate which this Object starts at.</param>
		/// <param name="click_x">The x coordinate of the mouse click.</param>
		/// <param name="click_y">The y coordinate of the mouse click.</param>
		/// <returns></returns>
		public override bool wasClickedOn(float x, float y, float click_x, float click_y)
		{
			return base.wasClickedOn(x, calcTopY(y), click_x, click_y);
		}

	}
	[Serializable]
	public class DivisionRDB : RelDrawingBase
	{
		internal RelDrawingBase top, bot;
		public static float vbuf = hbuf;
		
		/// <summary>
		/// The main constructor for a division bar. It creates a division bar from the given RDBs, and parents
		/// </summary>
		/// <param name="prev">The Previous RDB (the RDB on the left which links to this one)</param>
		/// <param name="num_parents">The number of levels this is from the root</param>
		/// <param name="topRDB">The RDB to put on the top of the division bar</param>
		/// <param name="botRDB">The RDB to put on the bottom of the division bar</param>
		public DivisionRDB(RelDrawingBase prev, int num_parents, RelDrawingBase topRDB, RelDrawingBase botRDB, 
			RelDrawingBase next)
			:base(prev, num_parents)
		{
			this.top = topRDB;
			this.bot = botRDB;
			this.next = next;
		}

		/// <summary>
		/// This constructor creates an empty DivisionRDB with the given previous RDB and parents.
		/// </summary>
		/// <param name="prev">The Previous RDB (the one on the left which links to this one)</param>
		/// <param name="num_parents">The number of levels this is from the root</param>
		public DivisionRDB(RelDrawingBase prev, int num_parents)
			:this(prev, num_parents, null, null, null)
		{
			/*this.top = new ColorBoxRDB(this, num_parents +1);
			this.bot = new ColorBoxRDB(this, num_parents +1);
			this.next = new ColorBoxRDB(this, num_parents);*/
			this.addNeighborCBs();
			this.removeNeighborCBs();
		}

		/// <summary>
		/// Returns the coordinate at which the top RDB should be drawn, given the y for this divRDB.
		/// </summary>
		/// <param name="presy">The drawing y coord for the division bar</param>
		/// <returns></returns>
		public float calcTopY(float presy)
		{
			return calcLineY(presy) -top.listHeightBelowDrawY() - vbuf;
		}

		/// <summary>
		/// Returns upper the coordinate at which the actual division line should be drawn given 
		/// the present y coordinate.
		/// </summary>
		/// <param name="presy">The drawing y coordinate for the object</param>
		/// <returns></returns>
		public float calcLineY(float presy)
		{

			/*			float topheight;
						topheight = top.listHeight();
						return presy+ topheight + vbuf;*/

			//if(prev !=null && prev.GetType() != typeof(DivisionRDB))
				return presy + 8;
			//return presy;
		}

		/// <summary>
		/// Returns the upper Y coordinate at which the next RDB, the one after the divRDB should be drawn
		/// given the drawing y coordinate for the div RDB
		/// </summary>
		/// <param name="presy">The drawing y coordinate for this object</param>
		/// <returns></returns>
		public float calcNextY(float presy)
		{
			return presy;
		}

		/// <summary>
		/// Returns the upper y coordinate at which to draw the bottom RDB, given the drawing y for the whole RDB.
		/// </summary>
		/// <param name="presy">The present y coordinate for this object</param>
		/// <returns></returns>
		public float calcBotY(float presy)
		{
			return calcLineY(presy) + bot.listHeightAboveDrawY() + vbuf;
		}
		/// <summary>
		/// Returns the left x coordinate at which to draw the top RDB, given the present x coord.
		/// </summary>
		/// <param name="presx">The drawing X coord for this object</param>
		/// <returns></returns>
		public float calcTopX(float presx)
		{
			float topwid, botwid;
			topwid = top.listWidth();
			botwid = bot.listWidth();
			if(topwid >= botwid)
				return presx+hbuf;
			else
				return (botwid - topwid) / 2 + hbuf + presx;
		}

		/// <summary>
		/// Returns the left x coord at which to draw the bottom RDB. 
		/// </summary>
		/// <param name="presx">The present drawing x coordinate for this object.</param>
		/// <returns></returns>
		public float calcBotX(float presx)
		{
			float topwid, botwid;
			topwid = top.listWidth();
			botwid = bot.listWidth();
			if(botwid >= topwid)
				return presx+hbuf;
			else
				return (topwid - botwid) / 2 + hbuf + presx;
		}
		/// <summary>
		/// Returns the left x coordinate at which to draw the item following this div box,
		/// given this object's drawing coords.
		/// </summary>
		/// <param name="presx">The present x coordinate at which to draw this object</param>
		/// <returns></returns>
		public float calcNextX(float presx)
		{
			return presx + this.width + hbuf;
		}

		/// <summary>
		/// This function takes into account changes in the top and bottom RDBs and uses them
		/// to recompute the height and width of this division RDB. Unlike symbol RDBs, division
		/// RBDs have dimensions which reflect the size of their contents.
		/// </summary>
		public void recalcDimensions()
		{
			this.width = 3 * hbuf + max(top.listWidth(), bot.listWidth());
			this.height = 2 * vbuf + top.listHeight() + bot.listHeight();
		}

		/// <summary>
		/// Used to place a new bot at the bot of the division RDB. We cannot simply set a field
		/// since the width and height of the divisionRDB must be recalculated to reflect the
		/// new RDB.
		/// </summary>
		/// <param name="newBot"></param>
		public void setBot(RelDrawingBase newBot)
		{
			this.bot = newBot;
			newBot.prev = this;
			recalcDimensions();
		}

		/// <summary>
		/// Used to place a new top at the top of the division RDB. We cannpt simply set a field
		/// since the width and height of the division RDB must be recalculated to reflect the
		/// new RDB.
		/// </summary>
		/// <param name="newTop"></param>
		public void setTop(RelDrawingBase newTop)
		{
			this.top = newTop;
			newTop.prev = this;
			recalcDimensions();
		}

		/// <summary>
		/// If they do not already exist, creates colorboxes for top, bot and next to allow for
		/// editting and turns their drawSelves on. 
		/// </summary>
		public override void addNeighborCBs()
		{
			if(top == null || top.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB newtop = new ColorBoxRDB(this, this.parents +1);
				
				if(this.top != null)
				{
					newtop.next = this.top;
					this.top.prev = newtop;
				}
				
				this.top = newtop;
			}
			if(bot == null || bot.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB newbot = new ColorBoxRDB(this, this.parents+1);
				
				if(this.bot != null)
				{
					newbot.next = this.bot;
					this.bot.prev = newbot;
				}
				
				this.bot = newbot;
			}
			if(next == null || next.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB newnext = new ColorBoxRDB(this, this.parents);
				
				if(this.next != null)
				{
					newnext.next = this.next;
					this.next.prev = newnext;
				}
				
				this.next = newnext;
			}
			this.toogleNeighborCBDraw(true);
		}

		/// <summary>
		/// Removes "unneeded" colorboxes for the top, bot and next. That is, if they are non-terminal
		/// they are removed. If they are terminal they are left but turned off.
		/// </summary>
		public override void removeNeighborCBs()
		{
			if(top !=null && top.GetType() == typeof(ColorBoxRDB) && top.next != null)
			{
				this.top = this.top.next;
				this.top.prev = this;
			}
			if(bot !=null && bot.GetType() == typeof(ColorBoxRDB) && bot.next != null)
			{
				this.bot = this.bot.next;
				this.bot.prev = this;
			}
			if(next !=null && next.GetType() == typeof(ColorBoxRDB) && next.next != null)
			{
				this.next = this.next.next;
				this.next.prev = this;
			}
			this.toogleNeighborCBDraw(false);
		}

		/// <summary>
		/// Draws the division bar's line only. It does NOT draw the top or bottom.
		/// </summary>
		/// <param name="x">X Coord at which to draw the DivisionRDB</param>
		/// <param name="y">Y Coord at which to draw this DivisionRDB</param>
		/// <param name="g"></param>
		public override void draw(float x, float y, Graphics g)
		{
			recalcDimensions();
			float starty = calcLineY(y);
			
			//		g.DrawRectangle(p, x, top.highestY(calcTopY(y)), width, height);
			g.DrawLine(p,x,starty,x+width, starty);
		}

		/// <summary>
		/// Of this contents of the division RDB and all following RDBs, returns the highest Y coord
		/// given that the division RDB is being drawn at the specified y coord.
		/// </summary>
		/// <param name="presy">The y coord at which the division RDB should be drawn</param>
		/// <returns></returns>
		public override float highestY(float presy)
		{
			float botHighest, topHighest, nextHighest;
			
			this.recalcDimensions();

			topHighest = (top == null) ? presy : top.highestY(calcTopY(presy));
			botHighest = (bot == null) ? presy : bot.highestY(calcBotY(presy));
			nextHighest= (next == null) ? presy : next.highestY(calcNextY(presy));

			return min(presy, topHighest, botHighest, nextHighest); 
		}
		/// <summary>
		/// Of the contents of this divisionRBD and all following RBDs, returns the lowest Y coord
		/// given that the division RDB is being draw at the specified y coord.
		/// </summary>
		/// <param name="presy">The y coord at which this division RDB should be drawn</param>
		/// <returns></returns>
		public override float lowestY(float presy)
		{
			float botLowest, topLowest, nextLowest;
	
			this.recalcDimensions();

			topLowest = (top == null) ? presy: top.lowestY(calcTopY(presy));
			botLowest = (bot == null) ? presy: bot.lowestY(calcBotY(presy));
			nextLowest= (next == null) ? presy: next.lowestY(calcNextY(presy));

			return max(topLowest, botLowest, nextLowest); 
		}

		public override void listChangeParents(int delta, Graphics g)
		{
			this.parents += delta;
			this.top.listChangeParents(delta,g);
			this.bot.listChangeParents(delta,g);
			this.next.listChangeParents(delta,g);
			this.recalcDimensions();
		}

		/// <summary>
		/// Returns a string containing the ID of this div RDB and it's prev, next, top and bottom + 
		/// the similar strings of all RDBs contained in the top, bot and next fields, seperated by
		/// new lines.
		/// </summary>
		/// <returns></returns>
		public override string listDebugStr()
		{
			return this.ToString() + "\n" + top.listDebugStr() + bot.listDebugStr() + next.listDebugStr();
		}

		/// <summary>
		/// Converts all RDBs from this symbol right (top, bot, and next) into a 
		/// Tex interpretation.
		/// </summary>
		/// <returns>A string written in Tex equivalent to the math expression 
		/// from this Object to the right.</returns>
		public override string listConvertToTex()
		{
			string texTrans;

			texTrans = "\\frac{" + top.listConvertToTex() + "}{" + bot.listConvertToTex()
				+ "}";
			if (next.listConvertToTex() != "")
				texTrans += " " + next.listConvertToTex();

			return texTrans;
		}

		/// <summary>
		/// Converts all RDBs from this symbol right (top, bot, and next) into a 
		/// MathML interpretation.
		/// </summary>
		/// <returns>A string written in MathML equivalent to the math expression 
		/// from this Object to the right.</returns>
		public override string listConvertToMathML()
		{
			string MLTrans;
			MLTrans = "<m:mfrac>";

			MLTrans += "<m:mrow>" + top.listConvertToMathML() + "</m:mrow>";
			MLTrans += "<m:mrow>" + bot.listConvertToMathML() + "</m:mrow>";

			MLTrans += "</m:mfrac>";
			MLTrans += next.listConvertToMathML();

			return MLTrans;
		}
		/// <summary>
		/// Draws this RDB at the given coords, including it's top, bottom and next members and 
		/// recursively. 
		/// </summary>
		/// <param name="x">X Coord at which to draw this RDB</param>
		/// <param name="y">Y Coord at which to draw this RDB</param>
		/// <param name="g"></param>
		public override void listDraw(float x, float y, Graphics g)
		{
			this.draw(x,y,g);
			top.listDraw(calcTopX(x),calcTopY(y), g);
			bot.listDraw(calcBotX(x), calcBotY(y), g);
			next.listDraw(calcNextX(x), calcNextY(y), g);
		}
		
		/// <summary>
		/// The distance between a drawing y coord passed into listDraw and the highest point that 
		/// would be drawn.
		/// </summary>
		/// <returns></returns>
		public override float listHeightAboveDrawY()
		{
			/*			if(prev != null)
							return top.listHeight() + vbuf + prev.height/2;
						else
							return top.listHeight() + vbuf + 8;*/
			return -1 * this.highestY(0);
		}

		/// <summary>
		/// This distance between a drawing y coord passed into this listDraw and the lowest point
		/// that would be drawn
		/// </summary>
		/// <returns></returns>
		public override float listHeightBelowDrawY()
		{
			/*	if(prev !=null)
					return bot.listHeight() + vbuf + prev.height/2;
				else
					return bot.listHeight() + vbuf + 8; */
			return this.listHeight() - this.listHeightAboveDrawY();
		}
		/// <summary>
		/// The total width of the DivisionRDB + all next fields. 
		/// </summary>
		/// <returns></returns>
		public override float listWidth()
		{
			recalcDimensions();
			return this.width+hbuf+next.listWidth();
		}
		/// <summary>
		/// Tells us if a given RDB linked to this one as part of the next, top and bot fields or this
		/// divRBD itself (only if none of the others were clicked on) was clicked on.
		/// </summary>
		/// <param name="x">The x coord at which to draw this one</param>
		/// <param name="y">The y coord at which to draw this one</param>
		/// <param name="click_x">The x coord of the click</param>
		/// <param name="click_y">The y coord of the click</param>
		/// <param name="g"></param>
		/// <returns></returns>
		public override RelDrawingBase listRDBAtCoords(float x, float y, float click_x, float click_y, Graphics g)
		{
			RelDrawingBase temp;

			if(this.next != null)
			{
				temp = next.listRDBAtCoords(calcNextX(x),calcNextY(y),click_x,click_y, g);
				if(temp !=null)
					return temp;
			}
			if(this.top != null)
			{
				temp = top.listRDBAtCoords(calcTopX(x),calcTopY(y),click_x,click_y, g);
				if(temp !=null)
					return temp;
			}
			if(this.bot != null)
			{
				temp = bot.listRDBAtCoords(calcBotX(x),calcBotY(y),click_x,click_y, g);
				if(temp !=null)
					return temp;
			}
			if(this.wasClickedOn(x,y,click_x,click_y))
				return this;
			return null;
		}

		/// <summary>
		/// Looks up the given reference and searches the next, top and bot fields for it. If it is there,
		/// it is replaced by the repRef
		/// </summary>
		/// <param name="initRef">The reference to search for, if found replaced with repRef</param>
		/// <param name="repRef">If the initRef is found, it is replaced with this</param>
		public override void replaceRefFor(RelDrawingBase initRef, RelDrawingBase repRef)
		{
			if(initRef == null)
				return;

			if(initRef == next)
			{
				this.next = repRef;
				repRef.prev = this;
			}
			else if(initRef == top)
			{
				this.top = repRef;
				repRef.prev = this;
			}
			else if(initRef == bot)
			{
				this.bot = repRef;
				repRef.prev = this;
			}
		}
		
		/// <summary>
		/// Returns a string containing the ID of this RDB plus, the ID's of it's prev, next, top and bottom
		/// neighbors.
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			string prevID = (prev != null)? prev.ID.ToString() : "null";
			string topID = (top != null) ? top.ID.ToString() : "null";
			string botID = (bot != null) ? bot.ID.ToString() : "null";
			string nextID = (next != null) ? next.ID.ToString() : "null";

			return "Division Bar, ID = [" + this.ID + "] prev = [" + prevID + "] top = [" + topID + "] bot = ["  
				+botID+"] next = ["+nextID+"]";
		}

		/// <summary>
		/// Looks at top, bot and next and sees if they are colorboxes. If so, there drawing is turned off.
		/// Unliked removeColorboxes, this function is not destructive.
		/// </summary>
		/// <param name="isOn"></param>
		public override void toogleNeighborCBDraw(bool isOn)
		{
			if(next !=null && next.GetType() == typeof(ColorBoxRDB))
				((ColorBoxRDB)next).drawSelf = isOn;
			if(bot !=null && bot.GetType() == typeof(ColorBoxRDB))
			{
				((ColorBoxRDB)bot).drawSelf = true;
				((ColorBoxRDB)bot).drawFilled = isOn;
			}
			if(top !=null && top.GetType() == typeof(ColorBoxRDB))
			{
				((ColorBoxRDB)top).drawSelf = true;
				((ColorBoxRDB)top).drawFilled = isOn;
			}
		}

		/// <summary>
		/// Returns true if the click_x and click_y lie within this Objects boundaries
		/// given the x, and y as this Object's starting point.
		/// </summary>
		/// <param name="x">The x coordinate which this Object starts at.</param>
		/// <param name="y">The y coordinate which this Object starts at.</param>
		/// <param name="click_x">The x coordinate of the mouse click.</param>
		/// <param name="click_y">The y coordinate of the mouse click.</param>
		/// <returns></returns>
		public override bool wasClickedOn(float x, float y, float click_x, float click_y)
		{
			return base.wasClickedOn(x, top.highestY(calcTopY(y)), click_x, click_y);
		}

	}

	[Serializable]
	public class NRootRDB : RelDrawingBase
	{
		internal RelDrawingBase rad, deg;
		public static float vbuf=hbuf;
		
		/// <summary>
		/// Constructs a NthRootRBD with the given previous, parents, next, radicand and degree fields
		/// </summary>
		/// <param name="prev">The previous RDB (the one on the left) which link to this one</param>
		/// <param name="num_parents">The number of levels this RDB is from the top</param>
		/// <param name="next">The RBD which should follow this one after it drawn</param>
		/// <param name="radicand">The quantity being rooted</param>
		/// <param name="degree">The degree of the root (ex: 3 = cube root, 4 = forth root)</param>
		public NRootRDB(RelDrawingBase prev, int num_parents, RelDrawingBase next, RelDrawingBase radicand, 
			RelDrawingBase degree)
			:base(prev, num_parents)
		{	
			rad = radicand;
			deg = degree;
			this.next = next;
			this.toogleNeighborCBDraw(false);
		}

		/// <summary>
		/// A simplier constructor for the NthRootRDB, automatically creates the next, radicand and 
		/// degree fields as colorboxes, requiring only the previous RDB and num_parents.
		/// </summary>
		/// <param name="prev">The previous RDB (the one on the left) which link to this one</param>
		/// <param name="num_parents">The number of levels this RDB is from the top</param>
		public NRootRDB(RelDrawingBase prev, int num_parents)
			:base(prev, num_parents)
		{
			rad = new ColorBoxRDB(this, num_parents+1);
			deg = new ColorBoxRDB(this, num_parents + 4);
			next = new ColorBoxRDB(this, num_parents);
			this.toogleNeighborCBDraw(false);
		}

		/// <summary>
		/// Returns the x coordinate at which the very first segment of the root actaul sign should be drawn, 
		/// based on the given x. This is often not the same as x because of the leading degree field.
		/// </summary>
		/// <param name="presx">The x coord where the nthRootRDB should be drawn</param>
		/// <returns></returns>
		public float calcSeg1X(float presx)
		{
			return (height/8 > (deg.listWidth() - height/8)) ? presx :
				presx + deg.listWidth()-height/8;
			//return presx + deg.listWidth() - height/8;
		}
		/// <summary>
		/// Returns the y coordinate of the top line of square root based on the given y coord at which
		/// to start drawing the nthRootRDB.
		/// </summary>
		/// <param name="presy">The y coord for drawing this RDB</param>
		/// <returns></returns>
		public float calcSeg3Y(float presy)
		{
			return presy - (rad.listHeightAboveDrawY() + vbuf);
		}
		
		/// <summary>
		/// Returns the width of the radicand and the associated border.
		/// </summary>
		/// <returns></returns>
		public float calcInsideWidth()
		{
			return rad.listWidth() + 2 * hbuf;
		}
		/// <summary>
		/// Returns the width of the "lead" that is, the part of the nthRootRDB before the
		/// radicand, the degree field and the first two segments of the root sign.
		/// </summary>
		/// <returns></returns>
		public float calcLeadWidth()
		{
			return max(height/4, deg.listWidth());
		}

		/// <summary>
		/// Returns the left x coord at which the radical drawing should start, given 
		/// the left coord at which the drawing of the RDB should start.
		/// </summary>
		/// <param name="presx">The left x coord for drawing this RDB</param>
		/// <returns></returns>
		public float calcRadX(float presx)
		{
			return calcLeadWidth()+hbuf + presx;
		}
		/// <summary>
		/// Returns the upper y coordinate at which drawing the radical should start,
		/// given the upper y coord for drawing the RDB.
		/// </summary>
		/// <param name="presy">The y coord at which the RDB should be drawn.</param>
		/// <returns></returns>
		public float calcRadY(float presy)
		{
			return presy;
		}
		/// <summary>
		/// Returns the left x coordinate at which drawing the degree should start
		/// given the left x coord for drawing the RDB.
		/// </summary>
		/// <param name="presx">The left x coord for drawing this RDB</param>
		/// <returns></returns>
		public float calcDegX(float presx)
		{
			return presx;
		}
		/// <summary>
		/// Returns the upper y coord at which drawing the degree should start
		/// given the upper y coord for drawing thisRDB.
		/// </summary>
		/// <param name="presy">The y coord for drawing this RDB</param>
		/// <returns></returns>
		public float calcDegY(float presy)
		{
			return calcSeg3Y(presy) + height/2 - deg.listHeightBelowDrawY();
		}
		/// <summary>
		/// Returns the left x coord at which the next RDB can be drawn, given the 
		/// left x coordinate for drawing this nthRootRDB.
		/// </summary>
		/// <param name="presx">The left x coord for drawing this RDB</param>
		/// <returns></returns>
		public float calcNextX(float presx)
		{
			return presx + width + hbuf;
		}
		/// <summary>
		/// Returns the upper y coord at which the next RDB can be drawn, given the
		/// upper y coordinate for drawing this nthRootRDB.
		/// </summary>
		/// <param name="presy">The y coord for drawing this RDB</param>
		/// <returns></returns>
		public float calcNextY(float presy)
		{
			return presy;
		}

		/// <summary>
		/// Updates the width and height fields in this object to reflect changes
		/// in the degree and radicand fields.
		/// </summary>
		public void recalcDimensions()
		{
			this.height = vbuf + rad.listHeight();
			this.width = calcInsideWidth() + calcLeadWidth();
		}

		/// <summary>
		/// Adds colorboxes if they don't exist to the radicand, degree and next fields.
		/// Then, turns on all neighboring colorboxes.
		/// </summary>
		public override void addNeighborCBs()
		{
			if(deg == null || deg.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB newDeg = new ColorBoxRDB(this, this.parents+4);

				if(this.deg !=null)
				{
					newDeg.next = this.deg;
					this.deg.prev = newDeg;
				}
				this.deg = newDeg;
			}
			if(rad == null || rad.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB newRad = new ColorBoxRDB(this, this.parents);

				if(this.rad !=null)
				{
					newRad.next = this.rad;
					this.rad.prev = newRad;
				}
				this.rad = newRad;
			}
			if(next == null || next.GetType() != typeof(ColorBoxRDB))
			{
				ColorBoxRDB newNext = new ColorBoxRDB(this, this.parents);

				if(this.next !=null)
				{
					newNext.next = this.next;
					this.next.prev = newNext;
				}
				this.next = newNext;
			}
			this.toogleNeighborCBDraw(true);
		}

		/// <summary>
		/// Turns off all neighboring colorboxes (in the case of a nthRootRDB, that sometimes means 
		/// just changing them to outline draw) and removes colorboxes which are extraneous. That is,
		/// colorboxes which are linked to non-null objects. We commonly remove colorboxes when an
		/// RDB is deselected.
		/// </summary>
		public override void removeNeighborCBs()
		{
			if(deg != null && deg.GetType() ==typeof(ColorBoxRDB) && deg.next != null)
			{
				this.deg=this.deg.next;
				this.deg.prev = this;
			}
			if(rad != null && rad.GetType() ==typeof(ColorBoxRDB) && rad.next != null)
			{
				this.rad=this.rad.next;
				this.rad.prev = this;
			}
			if(next != null && next.GetType() ==typeof(ColorBoxRDB) && next.next != null)
			{
				this.next=this.next.next;
				this.next.prev = this;
			}
			toogleNeighborCBDraw(false);
		}
		
		/// <summary>
		/// Draws the actual root sign using the given coords for drawing the whole RBD.
		/// This function does NOT draw the degree, radicand or next fields, just the 
		/// mathematical sign for root.
		/// </summary>
		/// <param name="x">This RDB's left drawing x coord</param>
		/// <param name="y">This RDB's upper drawing y coord</param>
		/// <param name="g"></param>
		public override void draw(float x, float y, Graphics g)
		{
			recalcDimensions();

			//Draw Seg1
			float s3starty = calcSeg3Y(y);
			float s1startx, s1starty, s1endx, s1endy;
			s1startx = calcSeg1X(x); 
			s1starty = s3starty + 2 * height /3;
			s1endx = s1startx + height/8; 
			s1endy = s3starty+height;
			g.DrawLine(p, s1startx, s1starty, s1endx, s1endy);

			//Draw Seg2
			float s2startx, s2starty, s2endx, s2endy;
			s2startx = s1endx;
			s2starty = s1endy;
			s2endy = s3starty;
			s2endx = s2startx + height / 8;
			g.DrawLine(p, s2startx,s2starty, s2endx, s2endy);

			//Draw Seg3
			float s3startx, s3endx, s3endy;
			s3startx = s2endx;
			s3endx = s3startx + this.calcInsideWidth();
			s3endy = s3starty;
			g.DrawLine(p, s3startx, s3starty, s3endx, s3endy);
		}
		
		/// <summary>
		/// Returns the highest Y coordinate drawn by either this nthRootRDB, it's deg field
		/// or any next objects following it, given the y coord at which this nthRootRDB is
		/// be drawn.
		/// </summary>
		/// <param name="presy">The y coord at which this RDB is drawn</param>
		/// <returns></returns>
		public override float highestY(float presy)
		{
			float topH, degH, nextH;
			
			this.recalcDimensions();

			topH = calcSeg3Y(presy);
			degH = (deg == null) ? topH : deg.highestY(calcDegY(presy));
			nextH = (next == null) ? topH : next.highestY(calcNextY(presy));
			return min(topH, topH, degH, nextH);
		}

		/// <summary>
		/// Returns the lowest Y coord drawn by this nthRootRDB, it's radicand, or any next objects 
		/// following it, given the y coord at which this nthRootRDB is to be drawn.
		/// </summary>
		/// <param name="presy">The y coord at which this RDB is drawn</param>
		/// <returns></returns>
		public override float lowestY(float presy)
		{
			float topL, radL, nextL;
			
			this.recalcDimensions();
			topL = calcSeg3Y(presy) + height;
			radL = (rad == null) ? topL : rad.lowestY(calcRadY(presy));
			nextL = (next ==null) ? topL : next.lowestY(calcNextY(presy));

			return max(topL, radL, nextL, topL);
		}

		public override void listChangeParents(int delta, Graphics g)
		{
			this.parents += delta;
			this.rad.listChangeParents(delta, g);
			this.deg.listChangeParents(delta,g);
			this.next.listChangeParents(delta,g);
			this.recalcDimensions();
		}

		/// <summary>
		/// Draw's this nthRootRDB's symbol, it's degree and radicand in their appropriate places,
		/// and all following next objects.
		/// </summary>
		/// <param name="x">The left most x coord at which this RDB should be drawn</param>
		/// <param name="y">The drawing y coordinate for drawing this RDB</param>
		/// <param name="g"></param>
		public override void listDraw(float x, float y, Graphics g)
		{
			draw(x,y,g);
			rad.listDraw(calcRadX(x), calcRadY(y), g);
			deg.listDraw(calcDegX(x), calcDegY(y), g);
			next.listDraw(calcNextX(x), calcNextY(y), g);
		}
		/// <summary>
		/// Returns a string with this RDB's ID, it's prev, next, deg and rad's IDs and similar 
		/// strings for the next,deg and rad fields, seperated by line breaks.
		/// </summary>
		/// <returns></returns>
		public override string listDebugStr()
		{
			return this.ToString() + "\n" + deg.listDebugStr() + "\n" + rad.listDebugStr()
				+ "\n" + next.listDebugStr() + "\n";
		}

		/// <summary>
		/// Converts all RDBs from this symbol right (rad, deg, and next) into a 
		/// Tex interpretation.
		/// </summary>
		/// <returns>A string written in Tex equivalent to the math expression 
		/// from this Object to the right.</returns>
		public override string listConvertToTex()
		{
			string texTrans;

			texTrans = "\\sqrt[" + deg.listConvertToTex() + "]{" + rad.listConvertToTex() 
				+ "}";
			if (next.listConvertToTex() != "")
				texTrans += " " + next.listConvertToTex();

			return texTrans;
		}
		/// <summary>
		/// Converts all RDBs from this symbol right (rad, deg, and next) into a 
		/// MathML interpretation.
		/// </summary>
		/// <returns>A string written in MathML equivalent to the math expression 
		/// from this Object to the right.</returns>
		public override string listConvertToMathML()
		{
			string MLTrans;
			MLTrans = "<m:mroot>";

			MLTrans += "<m:mrow>" + rad.listConvertToMathML() + "</m:mrow>";
			MLTrans += "<m:mrow>" + deg.listConvertToMathML() + "</m:mrow>";
			MLTrans += "</m:mroot>";

			MLTrans += next.listConvertToMathML();

	

			return MLTrans;
		}
		/// <summary>
		/// Returns the distance from this nthRootRDB's drawing y coordinate to the highest
		/// y coord of this RDB, or it's deg or next fields.
		/// </summary>
		/// <returns></returns>
		public override float listHeightAboveDrawY()
		{
			return -1 * highestY(0);
		}

		/// <summary>
		/// Returns the distance from this nthRootRDB's drawing y coordinate to the lowest
		/// y coord of this RDB, or it's rad or next fields.
		/// </summary>
		/// <returns></returns>
		public override float listHeightBelowDrawY()
		{
			return lowestY(0);
		}

		/// <summary>
		/// Returns the width of this nthRootRBD + all that of all following RDBs.
		/// </summary>
		/// <returns></returns>
		public override float listWidth()
		{
			recalcDimensions();
			return calcNextX(0) + next.listWidth(); 
		}

		/// <summary>
		/// Checks this RDB's deg, rad and next fields (recursively) to see if anyone clicked on them, if not
		/// it then checks itself. It returns the first RDB it found that was clicked on.
		/// </summary>
		/// <param name="x">The left x coord at which this RBD should be drawn</param>
		/// <param name="y">The y coord at which this RDB should be drawn</param>
		/// <param name="click_x">The x coord of the click</param>
		/// <param name="click_y">The y coord of the click</param>
		/// <param name="g"></param>
		/// <returns></returns>
		public override RelDrawingBase listRDBAtCoords(float x, float y, float click_x, float click_y, Graphics g)
		{
			
			if(deg != null)
			{
				RelDrawingBase temp;
				temp = deg.listRDBAtCoords(calcDegX(x), calcDegY(y), click_x, click_y, g);
				if(temp != null)
					return temp;
			}
			if(rad != null)
			{
				RelDrawingBase temp;
				temp = rad.listRDBAtCoords(calcRadX(x), calcRadY(y), click_x, click_y, g);
				if(temp != null)
					return temp;
			}
			if(next != null)
			{
				RelDrawingBase temp;
				temp = next.listRDBAtCoords(calcNextX(x), calcNextY(y), click_x, click_y, g);
				if(temp != null)
					return temp;
			}
			if(this.wasClickedOn(x,y,click_x, click_y))
				return this;
			return null;
		}

		/// <summary>
		/// Searches this nthRootRDB's next, rad and deg fields for the given initRef. If it is
		/// found, it is replaced with the given repRef.
		/// </summary>
		/// <param name="initRef">The reference to look for an replace with the repRef</param>
		/// <param name="repRef">The reference which replaces the initRef</param>
		public override void replaceRefFor(RelDrawingBase initRef, RelDrawingBase repRef)
		{
			if(initRef == null)
				return;
			if(deg == initRef)
				deg = repRef;
			else if(rad == initRef)
				rad = repRef;
			else if(next == initRef)
				next = repRef;
		}
		
		/// <summary>
		/// A string which describes the NthRootRBD, providing it's ID and the ID's of it's connected
		/// RDBs, prev, next, rad and deg.
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
		
			if(prev != null)
				return "NRoot: [" + ID + "] prev = [" + prev.ID + "] deg = [" + deg.ID + "] rad = [" 
					+rad.ID+ "] next = [" +next.ID + "]";
			else
				return "NRoot: [" + ID + "] deg = [" + deg.ID + "] rad = [" 
					+rad.ID+ "] next = [" +next.ID + "]";
		}

		/// <summary>
		/// Turns the drawing on and off the associated next, rad and deg fields. In the case of this particular
		/// class. There must be a rad field. So, when the rad field would otherwise be unoccupied, it is drawn as
		/// a red outline instead of the full read colorbox.
		/// </summary>
		/// <param name="isOn">Set to true if you want colorboxes (filled colorboxes) on, else false</param>
		public override void toogleNeighborCBDraw(bool isOn)
		{
			if(next.GetType() == typeof(ColorBoxRDB))
			{
				((ColorBoxRDB)next).drawSelf = isOn;
			}
			if(rad.GetType()  == typeof(ColorBoxRDB))
			{
				((ColorBoxRDB)rad).drawSelf = true;
				((ColorBoxRDB)rad).drawFilled = isOn;
			}
			if(deg.GetType() == typeof(ColorBoxRDB))
			{
				((ColorBoxRDB)deg).drawSelf = isOn;
			}
			recalcDimensions();
		}
	}

	[Serializable]
	public class SqrtRDB : NRootRDB
	{
		public SqrtRDB(RelDrawingBase prev, int num_parents, RelDrawingBase next, RelDrawingBase radicand)
			:base(prev, num_parents, next, radicand, null)
		{
			deg = new ColorBoxRDB(this, num_parents +4);
		}
		
		public SqrtRDB(RelDrawingBase prev, int num_parents)
			:base(prev, num_parents)
		{
			rad = new ColorBoxRDB(this, num_parents+1);
			deg = new ColorBoxRDB(this, num_parents + 4);
		}

		public override void listDraw(float x, float y, Graphics g)
		{
			draw(x,y,g);
			rad.listDraw(calcRadX(x), calcRadY(y), g);
			next.listDraw(calcNextX(x), calcNextY(y), g);
		}
		/// <summary>
		/// Converts all RDBs from this symbol right (rad, and next) into a 
		/// Tex interpretation.
		/// </summary>
		/// <returns>A string written in Tex equivalent to the math expression 
		/// from this Object to the right.</returns>
		public override string listConvertToTex()
		{
			string texTrans;
			texTrans = "\\sqrt{" + rad.listConvertToTex() + "}";

			if (next.listConvertToTex() != "")
				texTrans += " " + next.listConvertToTex();
			
			return texTrans;
		}

		/// <summary>
		/// Converts all RDBs from this symbol right (rad and next) into a 
		/// MathML interpretation.
		/// </summary>
		/// <returns>A string written in MathML equivalent to the math expression 
		/// from this Object to the right.</returns>
		public override string listConvertToMathML()
		{
			string MLTrans;
			MLTrans = "<m:msqrt>";

			MLTrans += rad.listConvertToMathML();
			MLTrans += "</m:msqrt>";

			MLTrans += next.listConvertToMathML();

	

			return MLTrans;
		}
	}
}
