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

namespace zComp.Analyst
{
    public class EvaluatorInstructionSet : EvaluatorInstructionBase
    {
        private List<EvaluatorInstructionBase> _instructionsList = new List<EvaluatorInstructionBase>();

        protected override void Parse()
        {
            InstructionsList.Clear();

            if (string.IsNullOrWhiteSpace(Expression))
                return;

            if (!_expression.TrimEnd().EndsWith(";"))
                _expression = _expression + ";";

            int parenthesisCounter = 0;
            int bracketCounter = 0;
            bool betweenQuotes = false;
            int expressionStart = 0;
            string currentExpression;

            for (int i = 0; i < Expression.Length; i++)
            {
                char car = Expression[i];

                if (car == '(' && !betweenQuotes)
                    parenthesisCounter++;
                else
                    if (car == ')' && !betweenQuotes)
                        parenthesisCounter--;
                    else
                        if (car == '{' && !betweenQuotes)
                            bracketCounter++;
                        else
                            if (car == '}' && !betweenQuotes)
                            {
                                bracketCounter--;
/*                                if (bracketCounter == 0)
                                {
                                    currentExpression = Expression.Substring(expressionStart, i - expressionStart).Trim();

                                    if (currentExpression.StartsWith("{") && currentExpression.EndsWith("}"))
                                    {
                                        currentExpression = currentExpression.Substring(1, currentExpression.Length - 2);

                                        if (!string.IsNullOrWhiteSpace(currentExpression.Trim()))
                                        {
                                            var parsedInstruction = new EvaluatorInstructionSet(currentExpression);
                                            InstructionsList.Add(parsedInstruction);
                                        }

                                        i++;
                                        expressionStart = i;
                                        betweenQuotes = false;
                                    }
                                }*/
                            }
                            else
                                if (car == ';' && !betweenQuotes && parenthesisCounter == 0 && bracketCounter == 0)
                                {
                                    currentExpression = Expression.Substring(expressionStart, i - expressionStart);

                                    if (!string.IsNullOrWhiteSpace(currentExpression.Trim()))
                                    {
                                        var parsedInstruction = new EvaluatorUniqueInstruction(currentExpression);

                                        if (parsedInstruction.MembersList.Count == 1)
                                            InstructionsList.Add(parsedInstruction.MembersList[0]);
                                        else
                                            InstructionsList.Add(parsedInstruction);
                                    }

                                    i++;
                                    expressionStart = i;
                                    betweenQuotes = false;
                                }
                                else
                                    if (car == ScriptRunnerEnvironment.DefaultQuote)
                                        betweenQuotes = !betweenQuotes;
            }
        }

        public EvaluatorInstructionSet(string script)
            : base(script)
        {
        }

        public override object Evaluate(Evaluator evaluator, object root)
        {
            object result = null;
            foreach (var instruction in InstructionsList)
                result = instruction.Evaluate(evaluator, root);
            return result;
        }

        public List<EvaluatorInstructionBase> InstructionsList
        {
            get
            {
                return _instructionsList;
            }
        }
    }

}
