using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace fmtxml
{
	/// 
	/// Summary description for GenToXml.
	/// 
	public class GenToXml
	{
		private StreamWriter strGenXml;
		private string genName;
		private string MyPath;
		private string MyResPath;
		public GenToXml(string nm, string path, string resPath)
		{
			MyPath = path;
			MyResPath = resPath;
			genName = nm;
			try
			{
				OpenFiles();
				ConvertGenToXml();
				CloseFiles();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Genmac name = " + nm, ex.Message);
			}
		}
		public void OpenFiles()
		{
			if (!Directory.Exists(MyResPath + @"\genmacall\convert"))
				Directory.CreateDirectory(MyResPath + @"\genmacall\convert");
			string fnm = MyResPath + @"\genmacall\convert" + @"\" + genName;
			string outnm = fnm.Substring(0,fnm.LastIndexOf(".")) + ".xml";
			strGenXml = new StreamWriter(outnm,false,System.Text.Encoding.ASCII);
		}
		public void CloseFiles()
		{
			strGenXml.Close();
		}
		public void ConvertGenToXml()
		{
			string linein;
			try
			{
				// use regular expressions to read in the genmac C file and convert to XML.
				StreamReader sr = new StreamReader(MyPath + @"\preproc\"+genName);
				linein = sr.ReadToEnd(); 
				sr.Close();
			}
			catch (Exception e) 
			{
				// Let the user know what went wrong.
				MessageBox.Show("File cannot be written " + genName + " error is " + e.Message);
				return;
			}
			if (linein==null)return;
			int indxb = linein.IndexOf("BEGIN");
			string line = linein.Substring(indxb,linein.Length-indxb);
			linein=null;
			// first Find defmac - endmac -> convert these do an element.
			Regex defmacs = new Regex(@"DEFMAC(\s*|.*?)*ENDMAC",RegexOptions.IgnoreCase|RegexOptions.Compiled);
			Match m;
			strGenXml.Write("<" + genName.Substring(0,genName.LastIndexOf(".")) + "_GENMAC>\n");
			for (m = defmacs.Match(line); m.Success; m = m.NextMatch())
			{
				strGenXml.Write("");				
				string mt = line.Substring(m.Index,m.Length);
				//Find the macro name, i.e. DEFMAC(xyz)
				int indxend = mt.IndexOf(")");
				string macname = mt.Substring(7,indxend-7);
				strGenXml.Write(macname+"\n\n");
				// the '+3' is to remove the \n\r also. The -9 is to account for the +3 &
				// also remove the endmac
				string macstr = mt.Substring(indxend+3,mt.Length-indxend-9);
				// take x chars for the name & put out the name & definition.
				string macnocomment = Regex.Replace(macstr, @"(\/\*(\s*|.*?)*\*\/)|(\/\/.*)", "");
				mt = Regex.Replace(macnocomment,";","");
				macnocomment = Regex.Replace(mt,@"\r\n",";");
				mt = Regex.Replace(macnocomment,@";+",";");  // eliminate multiple ';'
				macnocomment = mt;
				if (mt.IndexOf("&")>-1)
					macnocomment = mt.Replace("&","&");
				strGenXml.Write(macnocomment);
				strGenXml.Write("\n\n\n");
			}
			// next find userdef - endmac -> convert these do an element.
			defmacs = new Regex(@"USERDEF(\s*|.*?)*ENDMAC",RegexOptions.IgnoreCase|RegexOptions.Compiled);
			for (m = defmacs.Match(line); m.Success; m = m.NextMatch())
			{
				strGenXml.Write("");				
				string mt = line.Substring(m.Index,m.Length);
				//Find the macro name, i.e. USERDEF(xyz)
				int indxend = mt.IndexOf(")");
				string macname = mt.Substring(8,indxend-8);
				strGenXml.Write(macname+"\n\n\n");
				// the '+3' is to remove the \n\r also. The -9 is to account for the +3 &
				// also remove the endmac
				string macstr = mt.Substring(indxend+3,mt.Length-indxend-9);
				// take x chars for the name & put out the name & definition.
				string macnocomment = Regex.Replace(macstr, @"(\/\*(\s*|.*?)*\*\/)|(\/\/.*)", "");
				mt = Regex.Replace(macnocomment,";","");
				macnocomment = Regex.Replace(mt,@"\r\n",";");
				mt = Regex.Replace(macnocomment,@";+",";");  // eliminate multiple ';'
				macnocomment = mt;
				if (mt.IndexOf("&")>-1)
					macnocomment = mt.Replace("&","&");
				strGenXml.Write(macnocomment);
				strGenXml.Write("\n\n\n");
			}
			// last find static functions - these have macro definitions too.
			Regex defmacf = new Regex(@"static void (\s*|.*?)*}",RegexOptions.IgnoreCase|RegexOptions.Compiled);
			for (m = defmacf.Match(line); m.Success; m = m.NextMatch())
			{
				strGenXml.Write("");
				string mt = line.Substring(m.Index,m.Length);
				//Find the function name, i.e. static void boxx. Parameters are on an different node(int i)
				int indxbeg= mt.IndexOf("(");
				string fnname = mt.Substring(12,indxbeg-12);
				strGenXml.Write(fnname+"\n\"");
				int indxend=mt.IndexOf(")");
				string param = null;
				if (indxend-1==indxbeg)
					param = "none";
				else
					param = mt.Substring(indxbeg+1,indxend-1-indxbeg);
				strGenXml.Write(param+"\"\n\n");
				// now get past the opening curly.
				indxbeg = mt.IndexOf("{");
				string fnstr = mt.Substring(indxbeg+2,mt.Length-indxbeg-3);
				string macnocomment = Regex.Replace(fnstr, @"(\/\*(\s*|.*?)*\*\/)|(\/\/.*)", ""); // matches multi/single line comments: (\/\*(\s*|.*?)*\*\/)|(\/\/.*)
				mt = Regex.Replace(macnocomment,";","");
				macnocomment = Regex.Replace(mt,@"\r\n",";");
				mt = Regex.Replace(macnocomment,@";+",";");
				if (mt.IndexOf("&")>-1)
					mt = mt.Replace("&","&");
				strGenXml.Write(mt);
				strGenXml.Write("\n\n\n");
			}
			
			strGenXml.Write("" + genName.Substring(0,genName.LastIndexOf(".")) + "_GENMAC>");
		}
	}
}