using System;
using System.Collections;

namespace LLNet.Utils
{
	/// <summary>
	/// Summary description for QueryParams.
	/// </summary>
	public class QueryParams : ArrayList 
	{
		public class PredefinedTags 
		{
			//comodine Tags
			public static string AllToolbarsTag = " &&ToolbarFilter&& &&AdvancedToolbarTag&& &&OrderByToolbarTag&&";
			public static string ToolbarTag = " &&ToolbarFilter&& ";
			public static string DetailRelationTag = " &&DetailRelationTag&& ";
            public static string AdvancedToolbarTag = " &&AdvancedToolbarTag&& ";
			public static string OrderByToolbarTag = " &&OrderByToolbarTag&& ";
            public static string PosToolbarTag = " &&PosToolbarTag&& ";
            public static string RepToolbarTag = " &&RepToolbarTag&& ";
            
		}

        
		public QueryParams() : base()
		{
		}

		public int AddReplaceParam(string pTag, string pValue)
		{
			return Add(new ReplaceParam(pTag,pValue));
		}

		public int AddOrderByParam(string pTag, string pValue)
		{
			return Add(new OrderByParam(pTag,pValue));
		}

		public int AddRecursiveConditionParam(string pTag, string pLogicalOperator, string pColumnName, string pArithmeticalOperator, string pParamValue)
		{
			return Add(new RecursiveConditionParam(pTag,pLogicalOperator,pColumnName,pArithmeticalOperator,pParamValue));
		}

		public int ReplaceConditionParam(string pTag, string pValue)
		{
			return Add(new ReplaceConditionParam(pTag,pValue));
		}

		public int AddParamBase(object pParamBase)
		{
			return Add(pParamBase);
		}
		
		public new QueryParams Clone()
		{
			QueryParams result = new QueryParams();
			foreach (ParamBase pb in this)
			{
				result.AddParamBase(pb);
			}
			return result;
		}

		public ParamBase Find(string pTag)
		{
			foreach(ParamBase param in this)
			{
				if (param.Tag == pTag)
					return param;
			}
			
			return null;
		}

		public string ReplaceParams(string sql)
		{
			foreach(Utils.ParamBase param in this)
			{
                
				sql = param.Replace(sql);
			}
			
			foreach(Utils.ParamBase param in this)
			{
				    if (param.Tag.Trim().StartsWith("&&") && param.Tag.Trim().EndsWith("&&"))
				{
					sql = sql.Replace(param.Tag.Trim()," ");
				}
				else
				{
					sql = sql.Replace("&&" + param.Tag + "&&"," ");
				}
			}

			if (sql.IndexOf("&&") != -1)
			{
				throw new Exception("Faltan parámetros por substituir", new Exception(sql));
			}

			 return sql;
		}

		public string ToXML()
		{
			System.Xml.XmlDocument docto = new System.Xml.XmlDocument();
			System.Xml.XmlNode node = docto.CreateElement("root"); 
			docto.AppendChild(node);
			for(int i = 0; i < this.Count; i++)
			{
				LLNet.Utils.ParamBase paramBase = (LLNet.Utils.ParamBase)this[i];
				node.AppendChild(paramBase.ToXML(docto));
			}
			return docto.InnerXml; 
		}

		public void LoadFromXML(string xml)
		{
		//-- Creamos el documento
			System.Xml.XmlDocument docto = new System.Xml.XmlDocument();
			docto.LoadXml(xml);
		//-- Validamos
			if (docto.ChildNodes.Count > 0)
			{
			//-- Declaracion de variables
				System.Xml.XmlNode node = docto.FirstChild;
			//-- Limpiamos la lista
				this.Clear();
			//-- Recorremos todos los parametros
				foreach(System.Xml.XmlNode param in node.ChildNodes)
				{
					string strTipo = param.Attributes["tipo"].Value;
					LLNet.Utils.ParamBase paramBase = (LLNet.Utils.ParamBase)Activator.CreateInstance( Type.GetType(strTipo),  new object[] { param } );
					Add(paramBase);
				}
			}
		}

	}
}