// ========================================================================
// Copyright 2006 - Volian Enterprises, Inc. All rights reserved.          
// Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
// ------------------------------------------------------------------------
// $Workfile: $     $Revision: $                                           
// $Author: $   $Date: $                                                   
//                                                                         
// $History: $                                                             
// ========================================================================
using System;
using System.IO;
using System.Xml;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Drawing;
using VEPROMS.CSLA.Library;
namespace Config
{
	/// 
	/// PrivateProfile opens a private profile string and stores it's contents in an xml document.
	/// 
	public class PrivateProfile
	{
        #region Log4Net
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        #endregion
		private string ppName;
		private XmlDocument  ppXml;
		private List attr;
		private List ele;
		private XmlNode AddNode(XmlNode xParent, string sName, string sValue )
		{
			XmlNode nd=AddNode(xParent,sName);
			nd.Value=sValue;
			return nd;
		}
		private XmlNode AddNode(XmlNode xParent, string sName)
		{
			XmlNode nd;
			// Add a node
			string tsName = sName.Replace(' ', '_').Replace("applicability", "Applicability").Replace("unit", "Unit");
			nd=xParent.OwnerDocument.CreateNode(System.Xml.XmlNodeType.Element,tsName,"");
			xParent.AppendChild(nd);
			return nd;
		}
		private void AddAttribute(XmlNode xParent, string sName, string sValue)
		{
			XmlNode xa = xParent.Attributes.GetNamedItem(sName);
			// bug fix. 09/15/03
			// If there was a space after an equal sign, that space character
			// was becomming part of the value string (reading the user.CFG file).
			// This was giving us a "Must have semi-colon" error message.
			// We now strip spaces before and after any Attribute that is written.
			sValue = sValue.Trim(' ');
			sName = sName.Replace(' ', '_');
			sName = sName.Replace("\\", "_slash_");
			sName = sName.Replace("/", "_fslash_");
			if (xParent.Name == "color")
			{
				string[] parts = sValue.Split(",".ToCharArray());
				sValue = ColorConfig.FindKnownColor(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2])).ToString();
			}
			// Add an attribute 
			if (sValue == "")
			{
				if (xa != null)
				{
					xParent.Attributes.RemoveNamedItem(sName);
				}
			}
			else
			{
				if (xa == null)
				{
					xa = xParent.OwnerDocument.CreateNode(System.Xml.XmlNodeType.Attribute, sName, "");
					xParent.Attributes.SetNamedItem(xa);
				}
				xa.Value = sValue;
			}
		}
		private XmlNode AddSection(XmlNode xParent, string sSection)
		{
			// get the name. If it's not in the 'migrated elements' list, then
			// preface the name with a 'z'.
			string elename = sSection.Substring(1, sSection.IndexOf("]") - 1);
			while(elename.IndexOf(' ')>-1) elename = elename.Remove(elename.IndexOf(' '),1);
			if (!ele.Contains(elename.ToLower())) elename = 'z' + elename;
            elename = elename.Replace("\\", "_slash_");
			// Add a section [name]
			XmlNode nd = AddNode(xParent, elename);
			//AddAttribute(nd,"name",sSection.Substring(1,sSection.IndexOf("]")-1));
			return nd;
		}
		private XmlNode AddSection_UC(XmlNode xParent, string sSection )
		{
			// Add a section [name]
			string name_uc = sSection.Substring(1,sSection.IndexOf("]")-1).ToUpper() + "__UC";
			XmlNode nd =AddNode(xParent,name_uc);
			// AddAttribute(nd,"name",name_uc);
			return nd;
		}
		private void  AddComment(XmlNode xParent, string sComment)
		{
			
			if(xParent.ChildNodes.Count > 0)
			{
				XmlNode ndlast=xParent.ChildNodes.Item(xParent.ChildNodes.Count-1);
				if(ndlast.Name=="comment")
				{
					XmlNode xa = ndlast.Attributes.GetNamedItem("text");
					xa.Value=xa.Value + "\r\n" + sComment;
					return;
				}
			}
			// Add a comment text
			XmlNode nd =AddNode(xParent,"comment");			
			AddAttribute(nd,"text",sComment);
		}
		private void  AddLine(XmlNode xParent, string sLine)
		{
			// Add a comment text
			XmlNode nd =AddNode(xParent,"line");			
			AddAttribute(nd,"text",sLine);
		}
		private void AddParam(XmlNode xParent, string sParam)
		{		
			int i = sParam.IndexOf("=");		
			// get the name. If it's not in the 'migrated attribute' list, then
			// preface the name with a 'z'.
			string attrname = sParam.Substring(0, i);
			while (attrname.IndexOf(' ') > -1) attrname = attrname.Remove(attrname.IndexOf(' '), 1);
			if (!attr.Contains(attrname.ToLower())) attrname = 'z' + attrname;
			string sValue=sParam.Substring(i+1);
			string sName = attrname.Trim(' ');
			sName = sName.Replace("id", "ID").Replace("name", "Name").Replace("number", "Number").Replace("text", "Text").Replace("other", "Other").Replace("masterdir","MasterDir");
			AddAttribute(xParent, sName, sValue);
		}
		private void AddParam_UC(XmlNode xParent, string sParam)
		{
			int i = sParam.IndexOf("=");
			// add a param name=value
			string sName=sParam.Substring(0,i);
			string sValue=sParam.Substring(i+1);
			//XmlNode nd =AddNode(xParent,"paramUC");
			sName = sName.Trim(' ');
			AddAttribute(xParent, sName, sValue);
			//AddAttribute(nd,"name",sName.ToUpper()+"__UC");
			//AddAttribute(nd,"value",sValue);
		}
		private void LoadXML()
		{
			string sLine;
			ppXml.LoadXml("");// initialize ppXml
			XmlNode  xmlTop=ppXml.DocumentElement;
			XmlNode  xmlNd=ppXml.DocumentElement;
			//XmlNode  xmlNd_UC=ppXml.DocumentElement;
			StreamReader myReader = new StreamReader(ppName);// Open file
			while( (sLine = myReader.ReadLine())!= null)// read line-by-line
			{
				// add structure
				try
				{
					if (sLine.Length > 0)
					{
						switch (sLine.Substring(0, 1))
						{
							case "[":
								xmlNd = AddSection(xmlTop, sLine);
								//xmlNd_UC=AddSection_UC(xmlTop, sLine);
								break;
							case ";":
								//AddComment(xmlNd, sLine);
								break;
							default:
								if (sLine.IndexOf("=") >= 0)
								{
									AddParam(xmlNd, sLine);
									//AddParam_UC(xmlNd_UC, sLine);
								}
								else
								{
									//AddLine(xmlNd, sLine);
								}
								break;
						}
					}
				}
				 catch (Exception ex)
				{
					log.ErrorFormat("error parsing .INI file: {0} - Directory: {1}", ex.Message,ppName);
				}
			}
			myReader.Close();
		}
		public PrivateProfile(string sFileName, List listIni_EleName, List listIni_AttrName)
		{
			ppName=sFileName;
			ppXml= new XmlDocument();
			attr = listIni_AttrName;
			ele = listIni_EleName;
			LoadXML();
		}
		~PrivateProfile()
		{
			// Clean-up
			// 
		}
		public string PrettyNode(XmlNode nd,int level)
		{
			string retval="";
			string prefix=new string(' ',level*2);
			if(nd.ChildNodes.Count > 0)
			{
				retval = prefix + "<" + nd.Name;
				for(int i=0;i";
				for(int i=0;i";
			}
			else
			{
				retval = prefix + "<" + nd.Name;
				for(int i=0;i";
			}
			return retval;
		}
		public string PrettyXML()
		{
			return PrettyNode(ppXml.DocumentElement,0);
		}
		public XmlDocument XML()
		{
			// return XML Document
			return ppXml;
		}
		public override string ToString()
		{
			// return string
			return "";
		}
		public void Save()
		{
			SaveAs(ppName);
		}
		public void SaveAs(string sName)
		{
		}
		public string Attr(string sPath)
		{
			string retval="";
			XmlNode xn = ppXml.SelectSingleNode(sPath);
			if(xn != null)
			{
				string quots = xn.Value;
				if (quots.Substring(0,1)=="\"" && quots.Substring(quots.Length-1,1)=="\"")
					retval = quots.Substring(1,quots.Length-2);
				else
					retval=xn.Value;
			}
			return retval;
		}
		public string Attr(string sSection, string sParameter)
		{
			string findstr = "/ini/sectionUC[@name='" + sSection.ToUpper() + "__UC']/paramUC[@name='" + sParameter.ToUpper() + "__UC']/@value";
			return Attr(findstr);
		}
	}
}