using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PosStart
{
    /// <summary>
    /// It is a summary Description for XmlBase
    /// <para>(XmlBase에 대한 요약 설명입니다.)</para>
    /// </summary>
    public class XmlBase
    {
        private string m_strInput = "";										// 받은 데이타보관

        /// <summary>
        /// Initializes new instance of Constructor, XmlBase Class.
        /// <para>(Constructor, XmlBase 클래스의 새 인스턴스를 초기화합니다.)</para>
        /// </summary>
        public XmlBase()
        {
            //
            // TODO: 여기에 생성자 논리를 추가합니다.

        }
        /// <summary>
        /// Initializes new instance of Constructor, XmlBase Class.
        /// <para>(Constructor, XmlBase 클래스의 새 인스턴스를 초기화합니다.)</para>
        /// </summary>
        /// <param name="pStrInput">입력 데이타 - Input Data</param>
        public XmlBase(string pStrInput)
        {
            // 입력된 데이타를 보관합니다
            //**************************************************************************************
            m_strInput = pStrInput.Trim();
        }

        /// <summary>
        /// Parses Message and returns it as Hashtable format of Message
        /// <para>(메세지를 파싱하여 Message의 Hashtable 형태로 리턴)</para>
        /// </summary>
        public CmMessage ParserStart()
        {
            try
            {
                // 한 라인을 읽어서 데이타가 없으면 종료합니다.
                //**************************************************************************************
                string strNewLine = ReadNewLine();
                if (strNewLine == null) return null;


                // XML의 시작 Tag에 사용된 이름이 없습니다.
                //**************************************************************************************
                int iLpos = strNewLine.IndexOf("<");
                int iRpos = strNewLine.IndexOf(">", iLpos);
                strNewLine = strNewLine.Substring(iLpos + 1, iRpos - iLpos - 1);
                if (strNewLine == "") return null;


                // 시작 Tag의 이름을 이용하여 메세지를 만들어서 Parsing을 시작합니다.
                //**************************************************************************************
                CmMessage rtnMessage = new CmMessage(strNewLine);
                ParsingNewLine(rtnMessage);


                // Parsing한 메세지를 리턴합니다.
                //**************************************************************************************
                return rtnMessage;
            }
            catch
            {
                return null;
            }
        }


        /// <summary>
        /// Reads 1 line from the first to \n, and returns it after removing blanks, etc.
        /// <para>(처음부터 \n까지 1라인을 읽어서 공백등을 제거하고 리턴)</para>
        /// </summary>
        private string ReadNewLine()
        {
            string strNewLine = null;
            // 마지막 라인을 체크하여 종료를 리턴
            //**************************************************************************************
            if (m_strInput == null || m_strInput.Length == 0) return null;


            // 마지막 라인부터 1라인을 읽어서 보관합니다.
            //**************************************************************************************
            //m_intLineNum++;
            int intPos = m_strInput.IndexOf("\n");
            if (intPos < 0)													// 마지막 데이타
            {
                strNewLine = m_strInput.Trim();								// 읽은 라인
                m_strInput = null;											// 파일끝 설정
            }
            else
            {
                strNewLine = m_strInput.Substring(0, intPos).Trim();		// 읽은 라인
                m_strInput = m_strInput.Substring(intPos + 1);				// 파일의 남은라인들
            }


            // 빈줄이거나 "//" 주석으로 시작되면 새로운 라인을 읽습니다.
            //**************************************************************************************
            if (strNewLine.Length <= 2 || strNewLine.Substring(0, 2) == "//")
            {
                strNewLine = ReadNewLine();
            }
            return strNewLine;
        }


        /// <summary>
        /// Parses values of "&lt;" and"/&gt;" and saves them into Message Hashtable
        /// <para>("&lt;"와 "/&gt;"의 값을 Parsing하여 Message Hashtable에 보관)</para>
        /// </summary>
        private void ParsingNewLine(CmMessage msgParent)
        {
            while (true)
            {
                // 1 라인씩 Parsing 하여 Message에 보관합니다.
                //**********************************************************************************
                string strNewLine = ReadNewLine();
                if (strNewLine == null) return;								// Parsing 정상종료


                // 1 라인씩 Parsing 하여 Message에 보관합니다.
                //**********************************************************************************
                int intStaKeyLeft = strNewLine.IndexOf("<");				// <strStaKey>
                int intEndKeyLeft = strNewLine.IndexOf("</");				// </strEndKey>


                if (intEndKeyLeft < 0)										// <strStaKey> 형태
                {
                    int intStaKeyRight = strNewLine.IndexOf(">", Math.Max(0, intStaKeyLeft));
                    string strStaKey = strNewLine.Substring(intStaKeyLeft + 1, intStaKeyRight - intStaKeyLeft - 1);

                    CmMessage msgChild = new CmMessage(strStaKey);
                    ParsingNewLine(msgChild);
                    msgParent.MakeMessage(msgChild.MessageName, msgChild);
                }
                else if (intStaKeyLeft == intEndKeyLeft)					// </strEndKey> 형태
                {
                    int intEndKeyRight = strNewLine.IndexOf(">", Math.Max(0, intEndKeyLeft));
                    string strEndKey = strNewLine.Substring(intEndKeyLeft + 2, intEndKeyRight - intEndKeyLeft - 2);

                    if (msgParent.MessageName != strEndKey)				// 부모 메시지 Head Tag와 다르면 에러
                    {
                        // ConsoleNx.WriteLine("CuParser Error : Mismatched 1 !!! StartTag=<"+msgParent.MessageName+"> EndTag=</"+strEndKey+">, Line Number="+m_intLineNum);
                    }
                    break;													// XML 대분류 종료
                }
                else														// <strStaKey>strValue</strEndKey> 형대
                {
                    int intStaKeyRight = strNewLine.IndexOf(">", Math.Max(0, intStaKeyLeft));
                    int intEndKeyRight = strNewLine.IndexOf(">", Math.Max(0, intEndKeyLeft));
                    string strValue = strNewLine.Substring(intStaKeyRight + 1, intEndKeyLeft - intStaKeyRight - 1);
                    string strStaKey = strNewLine.Substring(intStaKeyLeft + 1, intStaKeyRight - intStaKeyLeft - 1);
                    string strEndKey = strNewLine.Substring(intEndKeyLeft + 2, intEndKeyRight - intEndKeyLeft - 2);

                    if (strStaKey != strEndKey)								// 시작 Tag와 종료 Tag가 다르면 에러
                    {
                        // ConsoleNx.WriteLine("CuParser Error : Mismatched 2 !!! StartTag=<"+strStaKey+"> EndTag=</"+strEndKey+">, Line Number="+m_intLineNum);
                    }
                    msgParent.MakeMessage(strStaKey, strValue);
                }
            }
        }
    }
}
