PageRenderTime 45ms CodeModel.GetById 10ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/WikiDocGenerator/MainWindow.xaml.cs

http://yet-another-music-application.googlecode.com/
C# | 892 lines | 657 code | 115 blank | 120 comment | 184 complexity | aa11eaead4db299a9e10516ab9f76858 MD5 | raw file
  1using System;
  2using System.Collections;
  3using System.Collections.Generic;
  4using System.Linq;
  5using System.IO;
  6using System.Text;
  7using System.Text.RegularExpressions;
  8using System.Windows;
  9using System.Windows.Controls;
 10using System.Windows.Data;
 11using System.Windows.Documents;
 12using System.Windows.Input;
 13using System.Windows.Media;
 14using System.Windows.Media.Imaging;
 15using System.Windows.Navigation;
 16using System.Xml;
 17using Microsoft.Win32;
 18
 19namespace WikiDocGenerator
 20{
 21	/// <summary>
 22	/// Interaction logic for MainWindow.xaml
 23	/// </summary>
 24	public partial class MainWindow : Window
 25    {
 26        #region Members
 27
 28        List<Class> classes = new List<Class>();
 29		List<Enum> enums = new List<Enum>();
 30		List<Delegate> delegates = new List<Delegate>();
 31
 32        #endregion
 33
 34        #region Constructor
 35
 36        /// <summary>
 37        /// 
 38        /// </summary>
 39        public MainWindow()
 40		{
 41			//InitializeComponent();
 42			//Match m2 = r.Match(text2);
 43			//Match m3 = r.Match(text3);
 44
 45			//MessageBox.Show("Match on 1: " + m1.Success + "\nMatch on 2: " + m2.Success + "\nMatch on 3: " + m3.Success);
 46
 47			//Close();
 48
 49			string file = @"H:\Development\Stoffi\trunk\Application\bin\Debug\Stoffi.XML";
 50			Read(file);
 51			Close();
 52		}
 53
 54        #endregion
 55
 56        #region Methods
 57
 58        #region Private
 59
 60        /// <summary>
 61        /// 
 62        /// </summary>
 63        /// <param name="filename"></param>
 64        private void Read(string filename)
 65		{
 66			XmlTextReader xmlReader = new XmlTextReader(filename);
 67			xmlReader.WhitespaceHandling = WhitespaceHandling.None;
 68
 69			xmlReader.Read();
 70			xmlReader.Read();
 71			xmlReader.Read();
 72			xmlReader.Skip();
 73
 74			int i = 0;
 75
 76			if (xmlReader.Name == "members")
 77			{
 78				List<Entity> entities = new List<Entity>();
 79				Hashtable classTable = new Hashtable();
 80				xmlReader.Read();
 81				while (!(xmlReader.Name == "members" && xmlReader.NodeType == XmlNodeType.EndElement))
 82				{
 83					i++;
 84					ReadMember(xmlReader, entities);
 85					xmlReader.Read();
 86					//if (i > 3) break;
 87				}
 88				foreach (Entity e in entities)
 89				{
 90					if (e.Name.StartsWith("XamlGeneratedNamespace") ||
 91						e.Name.StartsWith("Stoffi.Properties.")) continue;
 92
 93					if (e is Class)
 94					{
 95						string[] name = ParseName(e.Name);
 96						e.Name = name[0];
 97						classTable[name[0]] = e;
 98					}
 99				}
100				foreach (Entity e in entities)
101				{
102					if (e.Name.StartsWith("XamlGeneratedNamespace") ||
103						e.Name.StartsWith("Stoffi.Properties.")) continue;
104
105					if (e is Method)
106					{
107						string[] name = ParseName(e.Name, true);
108						e.Name = name[1];
109						Class c = classTable[name[0]] as Class;
110						c.Methods.Add(e as Method);
111					}
112					else if (e is Delegate)
113					{
114						string[] name = ParseName(e.Name, true);
115						if (name[1] == null)
116						{
117							e.Name = name[0];
118							delegates.Add(e as Delegate);
119						}
120						else
121						{
122							e.Name = name[1];
123							Class c = classTable[name[0]] as Class;
124							c.Delegates.Add(e as Delegate);
125						}
126					}
127					else if (e is Event)
128					{
129						string[] name = ParseName(e.Name, true);
130						e.Name = name[1];
131						Class c = classTable[name[0]] as Class;
132						c.Events.Add(e as Event);
133					}
134					else if (e is Field)
135					{
136						string[] name = ParseName(e.Name, true);
137						e.Name = name[1];
138						Class c = classTable[name[0]] as Class;
139						c.Fields.Add(e as Field);
140					}
141					else if (e is Property)
142					{
143						string[] name = ParseName(e.Name, true);
144						e.Name = name[1];
145						Class c = classTable[name[0]] as Class;
146						c.Properties.Add(e as Property);
147					}
148					else if (!(e is Class))
149					{
150						Console.WriteLine("Unknown type of entity: " + e.Name);
151					}
152				}
153
154				foreach (DictionaryEntry o in classTable)
155				{
156					Class c = o.Value as Class;
157
158					if (c.Fields.Count > 0 && c.Methods.Count == 0 && c.Events.Count == 0 && c.Properties.Count == 0)
159					{
160						Enum e = new Enum();
161						e.Name = c.Name;
162						e.Summary = c.Summary;
163						e.SeeAlsos = c.SeeAlsos;
164						e.Remarks = c.Remarks;
165
166						foreach (Field f in c.Fields)
167						{
168							Value v = new Value();
169							v.Name = f.Name;
170							v.Summary = f.Summary;
171							v.SeeAlsos = f.SeeAlsos;
172							v.Remarks = f.Remarks;
173							e.Values.Add(v);
174						}
175						enums.Add(e);
176					}
177					else
178					{
179						foreach (Method m in c.Methods)
180						{
181							if (m.Name.StartsWith("#cctor") || m.Name.StartsWith("#ctor"))
182								c.Constructor = m;
183							else if (m.Name == "Finalize")
184								c.Destructor = m;
185						}
186						c.Methods.Remove(c.Constructor);
187						c.Methods.Remove(c.Destructor);
188						classes.Add(c);
189					}
190				}
191
192				Generate();
193			}
194			else
195			{
196				Console.WriteLine("Expected element <members> but got <" + xmlReader.Name + "> instead");
197			}
198		}
199
200        /// <summary>
201        /// 
202        /// </summary>
203        /// <param name="name"></param>
204        /// <param name="hasParent"></param>
205        /// <returns></returns>
206		private string[] ParseName(string name, bool hasParent = false)
207		{
208			//if (name.StartsWith("Stoffi.Utilities."))
209			//    name = name.Remove(0, "Stoffi.Utilities.".Length);
210
211			if (name.StartsWith("Stoffi."))
212				name = name.Remove(0, "Stoffi.".Length);
213
214			string[] ret = new string[2];
215			int p = name.IndexOf('.');
216			if (hasParent && p >= 0)
217			{
218				ret[0] = name.Substring(0, p);
219				ret[1] = name.Substring(p+1);
220			}
221			else ret[0] = name;
222			return ret;
223		}
224
225        /// <summary>
226        /// 
227        /// </summary>
228        /// <param name="xmlReader"></param>
229        /// <param name="entities"></param>
230		private void ReadMember(XmlTextReader xmlReader, List<Entity> entities)
231		{
232			if (xmlReader.Name == "member" && xmlReader.NodeType == XmlNodeType.Element)
233			{
234				string[] nameFields = xmlReader.GetAttribute(0).Split(':');
235
236				Entity e;
237				Entity e1 = new Delegate();
238
239				if (nameFields[0] == "F")
240					e = new Field();
241				else if (nameFields[0] == "T")
242				{
243					e = new Class();
244				}
245				else if (nameFields[0] == "E")
246					e = new Event();
247				else if (nameFields[0] == "M")
248					e = new Method();
249				else if (nameFields[0] == "P")
250					e = new Property();
251				else
252				{
253					Console.WriteLine("Member '" + nameFields[1] + "' is of unknown type: " + nameFields[0]);
254					return;
255				}
256
257				e.Name = nameFields[1];
258				//Console.WriteLine("####### MEMBER: " + e.Name + " ###############");
259
260				xmlReader.Read();
261				while (!(xmlReader.Name == "member" && xmlReader.NodeType == XmlNodeType.EndElement))
262				{
263					if (xmlReader.NodeType == XmlNodeType.Element)
264					{
265						string tag = xmlReader.Name;
266						string value = "";
267						string name = "";
268
269						if (xmlReader.HasAttributes)
270							name = xmlReader.GetAttribute(0);
271
272						value = ReadTag(xmlReader);
273
274						if (tag.ToLower() == "summary")
275							e.Summary = value;
276						else if (tag.ToLower() == "seealso")
277							e.SeeAlsos.Add(value);
278						else if (tag.ToLower() == "remarks")
279							e.Remarks.Add(value);
280
281						else if (tag.ToLower() == "param" && e is Method)
282							((Method)e).Params[name] = value;
283						else if (tag.ToLower() == "typeparam" && e is Method)
284							((Method)e).TypeParam = value;
285						else if (tag.ToLower() == "returns" && e is Method)
286							((Method)e).Return = value;
287
288						else if (tag.ToLower() == "param" && e is Delegate)
289							((Delegate)e).Params[name] = value;
290						else if (tag.ToLower() == "typeparam" && e is Delegate)
291							((Delegate)e).TypeParam = value;
292						else if (tag.ToLower() == "returns" && e is Delegate)
293							((Delegate)e).Return = value;
294
295						else if (tag.ToLower() == "param" && e is Class)
296						{
297							e1.Name = e.Name;
298							e1.Summary = e.Summary;
299							e1.SeeAlsos = e.SeeAlsos;
300							e1.Remarks = e.Remarks;
301							e = e1;
302							((Delegate)e).Params[name] = value;
303						}
304						else if (tag.ToLower() == "typeparam" && e is Class)
305						{
306							e1.Name = e.Name;
307							e1.Summary = e.Summary;
308							e1.SeeAlsos = e.SeeAlsos;
309							e1.Remarks = e.Remarks;
310							e = e1;
311							((Delegate)e).TypeParam = value;
312						}
313						else if (tag.ToLower() == "returns" && e is Class)
314						{
315							e1.Name = e.Name;
316							e1.Summary = e.Summary;
317							e1.SeeAlsos = e.SeeAlsos;
318							e1.Remarks = e.Remarks;
319							e = e1;
320							((Delegate)e).Return = value;
321						}
322						else
323							Console.WriteLine(nameFields[1] + " has invalid member: " + tag + " = " + value);
324					}
325					xmlReader.Read();
326				}
327
328				entities.Add(e);
329			}
330			else
331			{
332				Console.WriteLine("Expected element <member> but got <" + xmlReader.Name + "> instead");
333			}
334		}
335
336        /// <summary>
337        /// 
338        /// </summary>
339        /// <param name="xmlReader"></param>
340        /// <returns></returns>
341		private string ReadTag(XmlTextReader xmlReader)
342		{
343			string name = xmlReader.Name;
344			string value = "";
345			//Console.WriteLine("Reading tag: " + name + "\t\tEmpty: " + xmlReader.IsEmptyElement);
346
347			if (xmlReader.IsEmptyElement)
348			{
349				if (xmlReader.HasAttributes)
350					value = xmlReader.GetAttribute(0);
351			}
352			else
353			{
354				xmlReader.Read();
355				while (!(xmlReader.Name == name && xmlReader.NodeType == XmlNodeType.EndElement))
356				{
357					if (xmlReader.NodeType == XmlNodeType.Text)
358						value += xmlReader.Value;
359					else if (xmlReader.NodeType == XmlNodeType.Element)
360					{
361						if (xmlReader.IsEmptyElement)
362						{
363							value += "<" + xmlReader.Name;
364							if (xmlReader.HasAttributes)
365								while (xmlReader.MoveToNextAttribute())
366									value += String.Format(" {0}=\"{1}\"", xmlReader.Name, xmlReader.Value);
367							value += "/>";
368						}
369						else
370						{
371							value += "<" + xmlReader.Name + ">";
372							value += ReadTag(xmlReader);
373							value += "</" + xmlReader.Name + ">";
374						}
375					}
376					else if (xmlReader.NodeType == XmlNodeType.EndElement)
377					{
378						value += "</" + xmlReader.Name + ">";
379					}
380
381					xmlReader.Read();
382				}
383			}
384			return value;
385		}
386
387        /// <summary>
388        /// 
389        /// </summary>
390		private void Generate()
391		{
392			foreach (Class c in classes)
393			{
394				Console.WriteLine("Go: " + c.Name);
395
396				if (c.Name == "YouTubePlayerInterface")
397					Console.WriteLine("Stop!");
398
399				Directory.CreateDirectory("output");
400				StreamWriter sw = File.CreateText(Path.Combine("output", c.Name + "Class.wiki"));
401				
402				sw.WriteLine("#summary Class specification of " + c.Name);
403				sw.WriteLine("#labels Doc-Class");
404
405				sw.WriteLine("= Overview =");
406				sw.WriteLine(FixInformation(c, c, false));
407				sw.WriteLine("<wiki:toc/>");
408				sw.WriteLine("----");
409
410				if (c.Constructor != null)
411				{
412					sw.WriteLine("= Constructor =");
413					sw.WriteLine("||`" + FixMethodName(c.Name, c.Constructor.Name, c.Constructor.Params) + "`||");
414					sw.WriteLine("");
415					foreach (DictionaryEntry o in c.Constructor.Params)
416						sw.WriteLine(" _" + (o.Key as string) + ": " + (o.Value as string) + "_\n");
417					sw.WriteLine(FixInformation(c, c.Constructor));
418				}
419
420				if (c.Destructor != null)
421				{
422					sw.WriteLine("= Destructor =");
423					sw.WriteLine("||`" + FixMethodName(c.Name, c.Destructor.Name, c.Destructor.Params) + "`||");
424					foreach (DictionaryEntry o in c.Destructor.Params)
425						sw.WriteLine(" _" + (o.Key as string) + ": " + (o.Value as string) + "_\n");
426					sw.WriteLine(FixInformation(c, c.Destructor));
427				}
428
429				if (c.Fields.Count > 0 || c.Properties.Count > 0)
430				{
431					sw.WriteLine("= Members =");
432
433					if (c.Fields.Count > 0)
434					{
435						sw.WriteLine("== Fields ==");
436						sw.WriteLine("");
437						foreach (Field f in c.Fields)
438						{
439							sw.WriteLine("===" + EscapeCamelLink(f.Name) + "===");
440							sw.WriteLine("");
441							sw.WriteLine(FixInformation(c, f));
442						}
443					}
444
445					if (c.Properties.Count > 0)
446					{
447						sw.WriteLine("== Properties ==");
448						sw.WriteLine("");
449						foreach (Property p in c.Properties)
450						{
451							sw.WriteLine("===" + EscapeCamelLink(p.Name) + "===");
452							sw.WriteLine("");
453							sw.WriteLine(FixInformation(c, p));
454						}
455					}
456				}
457
458				if (c.Methods.Count > 0)
459				{
460					sw.WriteLine("= Methods =");
461					sw.WriteLine("");
462					foreach (Method m in c.Methods)
463					{
464						sw.WriteLine("===" + EscapeCamelLink(StripMethodName(m.Name)) + "===");
465						sw.WriteLine("");
466						sw.WriteLine("||`" + FixMethodName(c.Name, m.Name, m.Params) + "`||");
467						sw.WriteLine("");
468						foreach (DictionaryEntry o in m.Params)
469							sw.WriteLine(" _" + (o.Key as string) + ": " + (o.Value as string) + "_\n");
470						sw.WriteLine(FixInformation(c, m));
471					}
472				}
473
474				if (c.Delegates.Count > 0)
475				{
476					sw.WriteLine("= Delegates =");
477					sw.WriteLine("");
478					foreach (Delegate d in c.Delegates)
479					{
480						sw.WriteLine("===" + EscapeCamelLink(StripMethodName(d.Name)) + "===");
481						sw.WriteLine("");
482						sw.WriteLine("||`" + FixMethodName(c.Name, d.Name, d.Params) + "`||");
483						sw.WriteLine("");
484						foreach (DictionaryEntry o in d.Params)
485							sw.WriteLine(" _" + (o.Key as string) + ": " + (o.Value as string) + "_\n");
486						sw.WriteLine(FixInformation(c, d));
487					}
488				}
489
490				if (c.Events.Count > 0)
491				{
492					sw.WriteLine("= Events =");
493					sw.WriteLine("");
494					foreach (Event e in c.Events)
495					{
496						sw.WriteLine("===" + EscapeCamelLink(e.Name) + "===");
497						sw.WriteLine("");
498						sw.WriteLine(FixInformation(c, e));
499					}
500				}
501				sw.Close();
502			}
503
504			foreach (Enum e in enums)
505			{
506				Directory.CreateDirectory("output");
507				StreamWriter sw = File.CreateText(Path.Combine("output", e.Name + "Enum.wiki"));
508
509				sw.WriteLine("#summary Enum specification of " + e.Name);
510				sw.WriteLine("#labels Doc-Enum");
511				sw.WriteLine("= Overview =");
512				sw.WriteLine(FixInformation(e, e, false));
513				sw.WriteLine("<wiki:toc/>");
514				sw.WriteLine("----");
515
516				if (e.Values.Count > 0)
517				{
518					sw.WriteLine("= Values =");
519					sw.WriteLine("");
520					foreach (Value v in e.Values)
521					{
522						sw.WriteLine("==" + v.Name + "==");
523						sw.WriteLine(FixInformation(e, v));
524					}
525				}
526				sw.Close();
527			}
528
529			foreach (Delegate e in delegates)
530			{
531				Directory.CreateDirectory("output");
532				StreamWriter sw = File.CreateText(Path.Combine("output", e.Name + "Delegate.wiki"));
533
534				sw.WriteLine("#summary Delegate specification of " + e.Name);
535				sw.WriteLine("#labels Doc-Delegate");
536				sw.WriteLine("= Overview =");
537				sw.WriteLine(FixInformation(e, e, false));
538				sw.WriteLine("<wiki:toc/>");
539				sw.WriteLine("----");
540
541				sw.WriteLine("");
542				sw.WriteLine("||`" + FixMethodName("", e.Name, e.Params) + "`||");
543				sw.WriteLine("");
544				foreach (DictionaryEntry o in e.Params)
545					sw.WriteLine(" _" + (o.Key as string) + ": " + (o.Value as string) + "_\n");
546				sw.Close();
547			}
548		}
549
550        /// <summary>
551        /// 
552        /// </summary>
553        /// <param name="str"></param>
554        /// <returns></returns>
555		private string EscapeCamelLink(string str)
556		{
557			if (HasCamelCase(str)) return "!" + str;
558			else return str;
559		}
560
561        /// <summary>
562        /// 
563        /// </summary>
564        /// <param name="p"></param>
565        /// <param name="e"></param>
566        /// <param name="returnToTop"></param>
567        /// <returns></returns>
568		private string FixInformation(Entity p, Entity e, bool returnToTop = true)
569		{
570			string txt = ParseForLinks(FixSummary(e.Summary)) + "\n\n";
571
572			if (e.Remarks.Count > 0) txt += "\n";
573			foreach (string remark in e.Remarks)
574				txt += " _Remark: " + ParseForLinks(remark) + "_\n\n";
575
576			if (e.SeeAlsos.Count > 0) txt += "\n";
577			foreach (string seealso in e.SeeAlsos)
578				txt += " _See also: " + ParseSeeAlso(seealso) + "_\n\n";
579
580			if (returnToTop)
581			{
582				txt += "[" + p.Name + (p is Class ? "Class":"Enum") + "#Overview Return to top]\n\n<br/>";
583			}
584
585			return txt;
586		}
587
588        /// <summary>
589        /// 
590        /// </summary>
591        /// <param name="str"></param>
592        /// <returns></returns>
593		private bool HasCamelCase(string str)
594		{
595			string pat = @"^[A-Z]+.*[a-z]+.*[A-Z].*[a-z]+";
596
597			Regex r = new Regex(pat, RegexOptions.None);
598
599			Match m = r.Match(str);
600			return m.Success;
601		}
602
603        /// <summary>
604        /// 
605        /// </summary>
606        /// <param name="summary"></param>
607        /// <returns></returns>
608		private string FixSummary(string summary)
609		{
610			summary = summary.Trim();
611			summary = summary.Replace("            ", "");
612			summary = summary.Replace("1)", "  #");
613			summary = summary.Replace("2)", "  #");
614			summary = summary.Replace("3)", "  #");
615			summary = summary.Replace("4)", "  #");
616			summary = summary.Replace("5)", "  #");
617			summary = summary.Replace("6)", "  #");
618			summary = summary.Replace("7)", "  #");
619			summary = summary.Replace("8)", "  #");
620			summary = summary.Replace("9)", "  #");
621
622			return summary;
623		}
624
625        /// <summary>
626        /// 
627        /// </summary>
628        /// <param name="cname"></param>
629        /// <param name="method"></param>
630        /// <param name="args"></param>
631        /// <returns></returns>
632		private string FixMethodName(string cname, string method, Hashtable args)
633		{
634			string name = method;
635			string arguments = "";
636
637			if (name.EndsWith(")"))
638			{
639				List<string> pnames = new List<string>();
640				foreach (DictionaryEntry o in args)
641					pnames.Add(o.Key as string);
642				string paras = "";
643
644				name = method.Substring(0, method.IndexOf('('));
645				paras = method.Substring(method.IndexOf('(') + 1);
646				paras = paras.Substring(0, paras.Length - 1);
647
648				string[] para = paras.Split(',');
649				int i=0;
650				foreach (string ptype in para)
651				{
652					arguments += ptype.Substring(ptype.LastIndexOf('.') + 1) + " " + pnames[i++] + ", ";
653				}
654
655				arguments = arguments.Substring(0, arguments.Length - 2);
656			}
657
658			return name.Replace("Finalize", "~" + cname).Replace("#cctor", cname).Replace("#ctor", cname) + "(" + arguments + ")";
659		}
660
661        /// <summary>
662        /// 
663        /// </summary>
664        /// <param name="mname"></param>
665        /// <returns></returns>
666		private string StripMethodName(string mname)
667		{
668			if (mname.Contains('(')) return mname.Substring(0, mname.IndexOf('('));
669			else return mname;
670		}
671
672        /// <summary>
673        /// 
674        /// </summary>
675        /// <param name="str"></param>
676        /// <returns></returns>
677		private string ParseSeeAlso(string str)
678		{
679			if (!str.Contains(':')) return str;
680
681			string type = str.Substring(0, str.IndexOf(':'));
682			str = str.Substring(str.IndexOf(':')+1);
683
684			if (str.Contains('(')) str = str.Substring(0, str.IndexOf('('));
685
686			int i = str.LastIndexOf('.');
687			if (i < 0) return str;
688
689			string parent = str.Substring(0, i);
690			string name = str.Substring(i + 1);
691
692			if (parent.StartsWith("Stoffi.Utilities."))
693				parent = parent.Remove(0, "Stoffi.Utilities.".Length);
694
695			else if (parent.StartsWith("Stoffi."))
696				parent = parent.Remove(0, "Stoffi.".Length);
697
698			if (type == "T")
699			{
700				foreach (Class c in classes)
701					if (c.Name == name) return "[" + c.Name + "Class " + name + "]";
702				foreach (Enum e in enums)
703					if (e.Name == name) return "[" + e.Name + "Enum " + name + "]";
704				return "[" + parent + "." + name + " " + parent + "." + name + "]";
705			}
706
707			string lstr = name + " " + name;
708			if (type == "M") lstr += "()";
709
710			foreach (Class c in classes)
711				if (c.Name == parent) return "[" + c.Name + "Class#" + lstr + "]";
712			foreach (Enum e in enums)
713				if (e.Name == parent) return "[" + e.Name + "Enum#" + lstr + "]";
714			return "[" + parent + "." + name + " " + parent + "." + name + "]";
715		}
716
717        /// <summary>
718        /// 
719        /// </summary>
720        /// <param name="str"></param>
721        /// <returns></returns>
722		private string ParseForLinks(string str)
723		{
724			if (str.Length <= 0) return str;
725
726			string ret = "";
727			foreach (string word in str.Split(new char[3] { ' ', '.', ','}))
728			{
729				string parsedWord = Linkalize(word);
730				if (parsedWord == word && HasCamelCase(parsedWord)) parsedWord = "!" + parsedWord;
731				ret += " " + parsedWord;
732			}
733			return ret.Substring(1);
734		}
735
736        /// <summary>
737        /// 
738        /// </summary>
739        /// <param name="str"></param>
740        /// <returns></returns>
741		private string Linkalize(string str)
742		{
743			foreach (Class c in classes)
744			{
745				if (c.Name == str) return "[" + c.Name + "Class " + str + "]";
746				foreach (Field f in c.Fields)
747					if (f.Name == str) return "[" + c.Name + "Class#" + f.Name + " " + str + "]";
748				foreach (Property p in c.Properties)
749					if (p.Name == str) return "[" + c.Name + "Class#" + p.Name + " " + str + "]";
750				foreach (Method m in c.Methods)
751					if (StripMethodName(m.Name) == str) return "[" + c.Name + "Class#" + StripMethodName(m.Name) + " " + str + "]";
752				foreach (Event e in c.Events)
753					if (e.Name == str) return "[" + c.Name + "Class#" + e.Name + " " + str + "]";
754			}
755			foreach (Enum e in enums)
756			{
757				if (e.Name == str) return "[" + e.Name + "Enum " + str + "]";
758				foreach (Value v in e.Values)
759					if (v.Name == str) return "[" + e.Name + "Enum#" + v.Name + " " + str + "]";
760			}
761			return str;
762		}
763
764        #endregion
765
766        #region Event handlers
767
768        /// <summary>
769        /// 
770        /// </summary>
771        /// <param name="sender"></param>
772        /// <param name="e"></param>
773        private void StartButton_Click(object sender, RoutedEventArgs e)
774		{
775			OpenFileDialog dlg = new OpenFileDialog();
776			Nullable<bool> result = dlg.ShowDialog();
777			if (result == true)
778			{
779				Read(dlg.FileName);
780			}
781		}
782
783        #endregion
784
785        #endregion
786
787        #region Classes
788
789        /// <summary>
790        /// 
791        /// </summary>
792		class Entity
793        {
794            #region Members
795
796            public string Name;
797			public string Summary;
798			public List<string> SeeAlsos = new List<string>();
799			public List<string> Remarks = new List<string>();
800
801            #endregion
802        }
803
804        /// <summary>
805        /// 
806        /// </summary>
807		class Class : Entity
808        {
809            #region Members
810
811            public List<Property> Properties = new List<Property>();
812			public Method Constructor = null;
813			public Method Destructor = null;
814			public List<Method> Methods = new List<Method>();
815			public List<Delegate> Delegates = new List<Delegate>();
816			public List<Event> Events = new List<Event>();
817			public List<Field> Fields = new List<Field>();
818
819            #endregion
820        }
821
822        /// <summary>
823        /// 
824        /// </summary>
825		class Field : Entity
826		{
827		}
828
829        /// <summary>
830        /// 
831        /// </summary>
832		class Event : Entity
833		{
834		}
835
836        /// <summary>
837        /// 
838        /// </summary>
839		class Property : Entity
840		{
841		}
842
843        /// <summary>
844        /// 
845        /// </summary>
846		class Method : Entity
847        {
848            #region Members
849
850            public string Return;
851			public string TypeParam;
852			public Hashtable Params = new Hashtable();
853
854            #endregion
855        }
856
857        /// <summary>
858        /// 
859        /// </summary>
860		class Enum : Entity
861        {
862            #region Members
863
864            public List<Value> Values = new List<Value>();
865
866            #endregion
867        }
868
869        /// <summary>
870        /// 
871        /// </summary>
872		class Value : Entity
873		{
874        }
875
876		/// <summary>
877		/// 
878		/// </summary>
879		class Delegate : Entity
880		{
881			#region Members
882
883			public string Return;
884			public string TypeParam;
885			public Hashtable Params = new Hashtable();
886
887			#endregion
888		}
889
890        #endregion
891    }
892}