/// <summary>
		/// Wraps a paragraph in a text that possibly contains some markup
		/// </summary>
		/// <returns>
		/// Description of linelayout.
		/// </returns>
		/// <param name='text'>
		/// The text to be wrapped
		/// </param>
		/// <param name='tm'>
		/// The textmesh object that contains information about style and rendering
		/// </param>
		public static IEnumerable<TTFTextInternal.LineLayout> WrapParagraphsExt (string text, TTFText tm)
		{
			float d;
			int lno = 0;
			char[] lseps = new char[] { '\n' };
			char[] wseps = new char[] { ' ' };
			string [] paragraphs = text.Split (lseps);		
			if (paragraphs.Length == 0) {
				yield break;
			}
		
		
			float firstlineoffset = 0;
			if ((tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Right) && (tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Center)) {
				firstlineoffset = tm.FirstLineOffset;
			}
		
			foreach (string paragraph in paragraphs) {		
				System.Collections.Generic.List<TTFTextScriptTextToken> ttstts = new System.Collections.Generic.List<TTFTextScriptTextToken> (ParseScriptText (paragraph));	
				string otext;
			
			
				//string[] words = paragraph.Split(wseps, System.StringSplitOptions.RemoveEmptyEntries);
				int ntexts = 0;
				foreach (TTFTextScriptTextToken t in ttstts) {
					if (!t.is_script)
						ntexts++;
				}
			
				//return new TTFTextInternal.LineLayout(words[0],tm,true);
				if (ntexts == 0) {
					yield return new TTFTextInternal.LineLayout("",tm,true);
					if ((tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Right) && (tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Center)) {
						firstlineoffset = tm.FirstLineOffset;
					}
				} else {
					TTFTextInternal.LineLayout ll = new TTFTextInternal.LineLayout ("", tm, true);	    
				
					foreach (TTFTextScriptTextToken t in ttstts) {			
						if (t.is_script) {
							otext = ll.line;
							EvalEasyMarkUp (tm, t.text, ref ll);
							d = ll.GetDefaultLineWidth (ll.hspacing); // TODO: <- THIS IS WRONG !			
							if (d > (ll.linewidth - firstlineoffset)) {
								ll.RewindLine (otext);
								FinalizeLL (ref ll, firstlineoffset);								
								ll.lineno = lno++;
								yield return ll;
								firstlineoffset = 0;
								ll = new TTFTextInternal.LineLayout ("", tm, true);
								EvalEasyMarkUp (tm, t.text, ref ll);
							}														
						} else {
									
							string[] words = null;
		
							if (tm.CurrentTextStyle.WordSplitMode == TTFText.WordSplitModeEnum.SpaceBased) {
								words = t.text.Split (wseps, System.StringSplitOptions.RemoveEmptyEntries);
							}
						
							if (tm.CurrentTextStyle.WordSplitMode == TTFText.WordSplitModeEnum.Character) {				
								words = new string[t.text.Length];
								int ci = 0;
								foreach (char c in t.text) {
									words [ci] = "" + c;
									ci++;
								}
							}

						
							foreach (string w in words/*t.text.Split(wseps)*/) {
								otext = ll.line;
								if (otext.Length != 0) {
									if (tm.CurrentTextStyle.WordSplitMode == TTFText.WordSplitModeEnum.SpaceBased) {
										ll.AppendText (' ' + w);
									} else {
										ll.AppendText (w);
									}
								} else {
									ll.AppendText (w);								
								}
							
							
							
								d = ll.GetDefaultLineWidth (ll.hspacing); // TODO: <- THIS IS WRONG !			
								if (d > (ll.linewidth - firstlineoffset)) {
									ll.RewindLine (otext);								
									FinalizeLL (ref ll, firstlineoffset);								
									ll.lineno = lno++;
									yield return ll;
									firstlineoffset = 0;
									ll = new TTFTextInternal.LineLayout (w, tm, true);
								} 
							}
						}
					}
		
					// last line
					if ((tm.ParagraphAlignment == TTFText.ParagraphAlignmentEnum.Justified)) {
						ll.align = TTFText.ParagraphAlignmentEnum.Left;
					}
		
					ll.offset = 0;
					if (((ll.align != TTFText.ParagraphAlignmentEnum.Right))		
					&& ((ll.align != TTFText.ParagraphAlignmentEnum.Center))) {
						ll.offset = firstlineoffset;		
					}
				
					ll.ComputeCharacterPositions ();								
					if ((tm.ParagraphAlignment == TTFText.ParagraphAlignmentEnum.Right)) {
						ll.offset = ll.linewidth - ll.GetActualLinewidth ();
					} else {
						if ((tm.ParagraphAlignment == TTFText.ParagraphAlignmentEnum.Center)) {
							ll.offset = (ll.linewidth - ll.GetActualLinewidth ()) / 2;
						} else {
							ll.offset = firstlineoffset;								
						}
					}
					ll.lineno = lno++;
				
					yield return ll;
					if ((tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Right) && (tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Center)) {
						firstlineoffset = tm.FirstLineOffset;
					}		
				}
			
			}
		}
		/// <summary>
		/// Wraps a paragraphs that does not contain any markup.
		/// </summary>
		/// <returns>
		/// The paragraphs simple.
		/// </returns>
		/// <param name='text'>
		/// The Text to be wrapped up.
		/// </param>
		/// <param name='tm'>
		/// The textmesh object associated with it.
		/// </param>
		public static IEnumerable<TTFTextInternal.LineLayout> WrapParagraphsSimple (string text, TTFText tm)
		{	
			// This function proceeds as follow it generates outline adding words one by one
			// if the line becomes too long for the desired textwidth it starts a new line
		 
			float d;
			int lno = 0;
			char[] lseps = new char[] { '\n' };
			char[] wseps = new char[] { ' ' };
			string [] paragraphs = text.Split (lseps);
		
			if (paragraphs.Length == 0) {
				yield break;
			}
			float firstlineoffset = 0;
			if ((tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Right) && (tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Center)) {
				firstlineoffset = tm.FirstLineOffset;
			}
		
			foreach (string paragraph in paragraphs) {
		
			
				string[] words = null;
		
				if (tm.WordSplitMode == TTFText.WordSplitModeEnum.SpaceBased) {
					words = paragraph.Split (wseps, System.StringSplitOptions.RemoveEmptyEntries);
				}	
				if (tm.WordSplitMode == TTFText.WordSplitModeEnum.Character) {				
					words = new string[paragraph.Length];
					int ci = 0;
					foreach (char c in paragraph) {
						words [ci] = "" + c;
						ci++;
					}
				}
			
			
				if (words.Length == 0) {
					yield return new TTFTextInternal.LineLayout("",tm,true);
					if ((tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Right) && (tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Center)) {
						firstlineoffset = tm.FirstLineOffset;
					}
				} else {
						
					TTFTextInternal.LineLayout ll = new TTFTextInternal.LineLayout (words [0], tm, true);
	    
					for (int idx = 1; idx < words.Length; ++idx) {			
						string w = words [idx];
						string otext = ll.line;
						if (tm.WordSplitMode == TTFText.WordSplitModeEnum.SpaceBased) {
							ll.AppendText (" " + w);
						} else {
							ll.AppendText (w);
						}
						
				
						d = ll.GetDefaultLineWidth (ll.hspacing);
			
						if (d > (ll.linewidth - firstlineoffset)) {
							ll.RewindLine (otext);
							ll.offset = 0;
						
							if (((ll.align != TTFText.ParagraphAlignmentEnum.Right))		
					&& ((ll.align != TTFText.ParagraphAlignmentEnum.Center))) {
								ll.offset = firstlineoffset;		
							}
							ll.ComputeCharacterPositions ();
		
							if ((ll.align == TTFText.ParagraphAlignmentEnum.Right)) {
								// Debug.Log(System.String.Format("{0} {1}",ll.linewidth, ll.GetActualLinewidth()));
								ll.offset = ll.linewidth - ll.GetActualLinewidth ();
							} else {
								if ((ll.align == TTFText.ParagraphAlignmentEnum.Center)) {
									ll.offset = (ll.linewidth - ll.GetActualLinewidth ()) / 2;
								} else {
									ll.offset = firstlineoffset;
								}
							}
				
							ll.lineno = lno++;
							yield return ll;
							firstlineoffset = 0;
							ll = new TTFTextInternal.LineLayout (w, tm, true);
				
						} 
					}
		
					// last line
					if ((tm.ParagraphAlignment == TTFText.ParagraphAlignmentEnum.Justified)) {
						ll.align = TTFText.ParagraphAlignmentEnum.Left;
					}
		
					ll.offset = 0;
					if (((ll.align != TTFText.ParagraphAlignmentEnum.Right))		
					&& ((ll.align != TTFText.ParagraphAlignmentEnum.Center))) {
						ll.offset = firstlineoffset;		
					}
				
					ll.ComputeCharacterPositions ();								
					if ((tm.ParagraphAlignment == TTFText.ParagraphAlignmentEnum.Right)) {
						ll.offset = ll.linewidth - ll.GetActualLinewidth ();
					} else {
						if ((tm.ParagraphAlignment == TTFText.ParagraphAlignmentEnum.Center)) {
							ll.offset = (ll.linewidth - ll.GetActualLinewidth ()) / 2;
						} else {
							ll.offset = firstlineoffset;
						}
					
					}
				
					ll.lineno = lno++;
					yield return ll;
					if ((tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Right) && (tm.ParagraphAlignment != TTFText.ParagraphAlignmentEnum.Center)) {
						firstlineoffset = tm.FirstLineOffset;
					}		
				}
			}
		}
		/// <summary>
		/// Subdivide lines into words
		/// </summary>
		/// <returns>
		/// The one per line.
		/// </returns>
		/// <param name='l'>
		/// L.
		/// </param>	
		static IEnumerable<TTFTextInternal.LineLayout> EOnePerWord (TTFTextInternal.LineLayout l)
		{

			char[] seps = new char[] { ' ' };
			string[] words = l.line.Split (seps, System.StringSplitOptions.RemoveEmptyEntries);
		
			int p = 0;
			float sa = 0;
			foreach (string w in words) {			
				int wlen = w.Length;
				int p0 = p;
			
				while (l.line[p] != w[0])
					p++; // <- skipping spaces : BUG TO BE FIXED !
		    
				TTFTextInternal.LineLayout r = new TTFTextInternal.LineLayout (w, l.tm, false);
				r.prevadvance = l.prevadvance + sa;
				if (wlen > 0) {
					r.linewidth = l.GetCharStyle (p).LineWidth;
				}
				r.charadvances = new float[w.Length];
				r.charpositions = new float[w.Length];
				r.charstyleindex = new int[w.Length];
				r.charmetadata = new object[w.Length];
			
				for (int i = 0; i < wlen; i++) {
					r.charadvances [i] = l.charadvances [p + i];	
					r.charpositions [i] = l.charpositions [p + i] - l.charpositions [p0];		
					r.charstyleindex [i] = l.charstyleindex [p + i];	
					r.charmetadata [i] = l.charmetadata [p + i];
				}
			
				if (p + wlen < l.line.Length) {
					r.advancelen = l.charpositions [p + wlen] - l.charpositions [p0];
				} else {
					r.advancelen = l.advancelen - l.charpositions [p0];
				}
				r.lineno = l.lineno;
				yield return r;
				sa += r.advancelen;
				p += wlen;
			}
		}
		/// <summary>
		/// Subdivides line into individual characters
		/// </summary>
		/// <returns>
		/// The one per char.
		/// </returns>
		/// <param name='l'>
		/// L.
		/// </param> 
		static IEnumerable<TTFTextInternal.LineLayout> EOnePerChar (TTFTextInternal.LineLayout l)
		{		
			
			int i = 0;
			float sa = 0;
			foreach (char c in l.line) {
				TTFTextInternal.LineLayout r = new TTFTextInternal.LineLayout ("" + c, l.tm, false);		
				r.charadvances = new float[1];
				r.charpositions = new float[1];												
				r.charstyleindex = new int[1];	
				r.charmetadata = new object[1];
				r.charadvances [0] = l.charadvances [i];	
				r.charpositions [0] = 0;	
				r.charstyleindex [0] = l.charstyleindex [i];	
				r.charmetadata [0] = l.charmetadata [i];
				r.prevadvance = l.prevadvance + sa;
				r.linewidth = l.GetCharStyle (i).LineWidth;
				r.lineno = l.lineno;
				if (i + 1 < l.line.Length) {
					r.advancelen = l.charpositions [i + 1] - l.charpositions [i];
				} else {
					r.advancelen = l.advancelen - l.charpositions [i];					
				}
				yield return r;
				sa += r.advancelen;
			
				i += 1;
			}
		} 
		public static IEnumerable<TTFTextInternal.LineLayout> GenerateTextLayout (string text, TTFText tm)
		{				
			switch (tm.LayoutMode) {
			case TTFText.LayoutModeEnum.No:
				char [] seps = {'\n'};
				int lineno = 0;
				foreach (string s in text.Split(seps)) {
					TTFTextInternal.LineLayout l = new TTFTextInternal.LineLayout (s, tm, true);
					l.offset = 0;
					l.lineno = lineno++;
					l.advancedir = Vector3.right;
					yield return l;
				}
				break;
			case TTFText.LayoutModeEnum.Wrap:
#if TTFTEXT_LITE
			if (tm.DemoMode) {
#endif				
			
				foreach (TTFTextInternal.LineLayout ll in WrapParagraphsSimple(text, tm)) {
					yield return ll;
				}
#if TTFTEXT_LITE
			}
#endif				
				
				break;
			case TTFText.LayoutModeEnum.StyleEnabled:
#if TTFTEXT_LITE
			if (tm.DemoMode) {
#endif				
			
				foreach (TTFTextInternal.LineLayout ll in WrapParagraphsExt(text, tm)) {
					yield return ll;
				}
#if TTFTEXT_LITE
			}
#endif				
				
				break;			
			}
		}