using System;
using System.Collections;
using GoldParser;

namespace Orbiter.Multiplayer
{
    public class SyntaxNode:IEnumerable
    {
        #region Fields
        private string content;
        private SyntaxNode[] childs;
        private int ruleIndex;
        private Rule rule;
        private Symbol symbol;
        private int symbolIndex;
        #endregion

        /// <summary>
        /// Returns the rule index.
        /// </summary>
        protected int RuleIndex
        {
            get { return ruleIndex; }
        }

        /// <summary>
        /// Returns the symbol index.
        /// </summary>
        protected int SymbolIndex
        {
            get { return symbolIndex; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SyntaxNode"/> class.
        /// </summary>
        public SyntaxNode(Rule rule, SyntaxNode[] nodes)
        {
            this.rule = rule;
            ruleIndex = rule.Index;
            symbol = rule.NonTerminal;
            symbolIndex = symbol.Index;
            childs = nodes;
        }

        public Symbol Symbol
        {
            get { return symbol; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SyntaxNode"/> class.
        /// </summary>
        public SyntaxNode(Symbol symbol, string content)
        {
            ruleIndex = -1;
            this.symbol = symbol;
            symbolIndex = symbol.Index;
            this.content = content;
        }
        
        /// <summary>
        /// Gets the content.
        /// </summary>
        /// <value>The content</value>
        public string Content
        {
            get { return content; }
        }

        /// <summary>
        /// Gets the count of the child nodes.
        /// </summary>
        /// <value>The count</value>
        public int Count
        {
            get
            {
                if (childs != null)
                    return childs.Length;
                else
                    return 0;
            }
        }

        public Rule Rule
        {
            get { return rule; }
        }

        /// <summary>
        /// Gets the <see cref="SyntaxNode"/> at the specified index.
        /// </summary>
        /// <value>The SyntaxNode</value>
        protected SyntaxNode this[int index]
        {
            get
            {
                if (childs != null && index < childs.Length) return childs[index];
                throw new SystemException("Index "+index+" of SyntaxNode is invalid!");
            }
        }

        public IEnumerator GetEnumerator()
        {
            return childs.GetEnumerator();
        }
        
        protected SyntaxNode Trimmed
        {
            get
            {
                SyntaxNode result = this;
                while (result.Count > 0) result = result[0];//Trim parsing
                return result;
            }
        }
    }
}
