//Enum Express

using System;

namespace JXC_MIS.MyClass
{
	public enum EnumExpress
	{
		Add,//加号
		Dec,//减号
		Mul,//乘号
		Div,//除号
		Sin,//正玄
		Cos,//余玄
		Tan,//正切
		ATan,//余切
		Sqrt,//平方根
		Pow,//求幂
		None,//无
	}
	/// <summary>
	/// ClsExpress 算数表达式解析。
	/// </summary>
	public class ClsExpressDeal
	{
		public ClsExpressDeal()
		{
			//
			// TODO: 在此处添加构造函数逻辑
			//
  
		}
		private double CalculateExpress(string strExpression)
		{
   
			string strTemp="";
			string strTempB="";
			string strOne="";
			string strTwo="";
			double ReplaceValue=0;
			string sChar;//负号和正号
			while (strExpression.Substring(1,strExpression.Length-1).IndexOf("+")!=-1 || strExpression.Substring(1,strExpression.Length-1).IndexOf("-")!=-1 
				|| strExpression.Substring(1,strExpression.Length-1).IndexOf("*")!=-1 || strExpression.Substring(1,strExpression.Length-1).IndexOf("/")!=-1)
			{

				sChar=strExpression.Substring(0,1);//负号和正号
				if (sChar=="+" || sChar=="-" ) sChar=sChar;else sChar="";
				//判断运算优先级别
				if (strExpression.IndexOf("*")!=-1 || strExpression.IndexOf("/")!=-1)
				{
					for (int i=1;i<strExpression.Length;i++)
					{
						switch (strExpression.Substring(i,1))
						{
							case "*":
								strTemp=strExpression.Substring(strExpression.IndexOf("*")+1,strExpression.Length-strExpression.IndexOf("*")-1);
								strTempB=strExpression.Substring(0,strExpression.IndexOf("*"));
								strOne=sChar+strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
								strOne=strOne.Trim();
								strTwo=strTemp.Substring(0,GetNextPos(strTemp));
								ReplaceValue=Convert.ToDouble(GetExpType(strOne))*Convert.ToDouble(GetExpType(strTwo));
								strExpression=strExpression.Replace(strOne+"*"+strTwo,ReplaceValue.ToString());
								break;
							case "/":
								strTemp=strExpression.Substring(strExpression.IndexOf("/")+1,strExpression.Length-strExpression.IndexOf("/")-1);
								strTempB=strExpression.Substring(0,strExpression.IndexOf("/"));
								strOne=sChar+strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
								strOne=strOne.Trim();
								strTwo=strTemp.Substring(0,GetNextPos(strTemp));
								ReplaceValue=Convert.ToDouble(GetExpType(strOne))/Convert.ToDouble(GetExpType(strTwo));
								strExpression=strExpression.Replace(strOne+"/"+strTwo,ReplaceValue.ToString());
								break;
							default:
								break;
						}
					}
					}
				//判断运算优先级别
				if (strExpression.IndexOf("+")!=-1 || strExpression.IndexOf("-")!=-1)
				{
					for (int i=1;i<strExpression.Length;i++)
					{
						sChar=strExpression.Substring(0,1);//负号和正号
						if (sChar=="+" || sChar=="-" ) sChar=sChar;else sChar="";

						switch (strExpression.Substring(i,1))
						{
							case "+":
								strTemp=strExpression.Substring(strExpression.IndexOf("+")+1,strExpression.Length-strExpression.IndexOf("+")-1);
								strTempB=strExpression.Substring(0,strExpression.IndexOf("+"));
								strOne=sChar+strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
								strOne=strOne.Trim();
								strTwo=strTemp.Substring(0,GetNextPos(strTemp));
								ReplaceValue=Convert.ToDouble(GetExpType(strOne))+Convert.ToDouble(GetExpType(strTwo));
								strExpression=strExpression.Replace(strOne+"+"+strTwo,ReplaceValue.ToString());
								break;
							case "-":
								strTemp=strExpression.Substring(strExpression.IndexOf("-")+1,strExpression.Length-strExpression.IndexOf("-")-1);
								strTempB=strExpression.Substring(0,strExpression.IndexOf("-"));
								strOne=sChar+strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
								strOne=strOne.Trim();
								strTwo=strTemp.Substring(0,GetNextPos(strTemp));
								ReplaceValue=Convert.ToDouble(GetExpType(strOne))-Convert.ToDouble(GetExpType(strTwo));
								strExpression=strExpression.Replace(strOne+"-"+strTwo,ReplaceValue.ToString());
								break;
							default:
								break;
						}
					}	 
				}
			}
   
			return Convert.ToDouble(strExpression);
		}
  
		private double CalculateExExpress(string strExpression,EnumExpress ExpressType)
		{
			double retValue=0;
			switch(ExpressType)
			{
				case EnumExpress.Sin:
					retValue=Math.Sin(Convert.ToDouble(strExpression));
					break;
				case EnumExpress.Cos:
					retValue= Math.Cos(Convert.ToDouble(strExpression));
					break;
				case EnumExpress.Tan:
					retValue= Math.Tan(Convert.ToDouble(strExpression));
					break;
				case EnumExpress.ATan:
					retValue= Math.Atan(Convert.ToDouble(strExpression));
					break;
				case EnumExpress.Sqrt:
					retValue= Math.Sqrt(Convert.ToDouble(strExpression));
					break;
				case EnumExpress.Pow:
					retValue= Math.Pow(Convert.ToDouble(strExpression),2);
					break;
			}
			if (retValue==0) return Convert.ToDouble(strExpression);
			return retValue;
		}
		private int GetNextPos(string strExpression)
		{
			int[] ExpPos=new int[4];
			ExpPos[0]=strExpression.IndexOf("+");
			ExpPos[1]=strExpression.IndexOf("-");
			ExpPos[2]=strExpression.IndexOf("*");
			ExpPos[3]=strExpression.IndexOf("/");
			int tmpMin=strExpression.Length;
			for (int count=1;count<=ExpPos.Length;count++)
			{
				if (tmpMin>ExpPos[count-1] && ExpPos[count-1]!=-1)
				{
					tmpMin=ExpPos[count-1];
				}
			}

			return tmpMin;
   
		}
		private int GetPrivorPos(string strExpression)
		{
			int[] ExpPos=new int[4];
			ExpPos[0]=strExpression.LastIndexOf("+");
			ExpPos[1]=strExpression.LastIndexOf("-");
			ExpPos[2]=strExpression.LastIndexOf("*");
			ExpPos[3]=strExpression.LastIndexOf("/");
			int tmpMax=-1;
			for (int count=1;count<=ExpPos.Length;count++)
			{
				if (tmpMax<ExpPos[count-1] && ExpPos[count-1]!=-1)
				{
					tmpMax=ExpPos[count-1];
				}
			}

			return tmpMax;
   
		}
		/// <summary>
		/// 字符串相加连接
		/// </summary>
		/// <param name="strExpression"></param>
		/// <returns></returns>
		public string CharAddChar(string strExpression)
		{
			string[] ArrSplit=strExpression.Split('&');
			string strResult="";
			int j=ArrSplit.Length ;
			for (int i=0;i<j;i++)
			{
             strResult=strResult+ArrSplit[i];
			}
			return strResult;
		}
		public string SpiltExpression(string strExpression)
		{
			string strTemp="";
			string strExp="";

			while (strExpression.IndexOf("(")!=-1)
			{
				strTemp=strExpression.Substring(strExpression.LastIndexOf("(")+1,strExpression.Length-strExpression.LastIndexOf("(")-1);
				strExp=strTemp.Substring(0,strTemp.IndexOf(")"));
				strExpression=strExpression.Replace("("+strExp+")",CalculateExpress(strExp).ToString());

			}
			if(strExpression.IndexOf("+")!=-1 || strExpression.IndexOf("-")!=-1 
				|| strExpression.IndexOf("*")!=-1 || strExpression.IndexOf("/")!=-1)
			{
				strExpression=CalculateExpress(strExpression).ToString();
			}
			return strExpression;
		}
  
		private string GetExpType(string strExpression)
		{
			strExpression=strExpression.ToUpper();
			if (strExpression.IndexOf("SIN")!=-1)
			{
				return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.Sin).ToString();
			}
			if (strExpression.IndexOf("COS")!=-1)
			{
				return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("S")+1,strExpression.Length-1-strExpression.IndexOf("S")),EnumExpress.Cos).ToString();
			}
			if (strExpression.IndexOf("TAN")!=-1)
			{
				return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.Tan).ToString();
			}
			if (strExpression.IndexOf("ATAN")!=-1)
			{
				return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.ATan).ToString();
			}
			if (strExpression.IndexOf("SQRT")!=-1)
			{
				return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("T")+1,strExpression.Length-1-strExpression.IndexOf("T")),EnumExpress.Sqrt).ToString();
			}
			if (strExpression.IndexOf("POW")!=-1)
			{
				return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("W")+1,strExpression.Length-1-strExpression.IndexOf("W")),EnumExpress.Pow).ToString();
			}
			return strExpression;
		}












	}










}
