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

namespace Zelvaci
{
    class Interpreter
    {
        private const String LETTERS = "abcdefghijklmnopqrstuvwxyz";
        private const String DIGITS = "-0123456789";

        private Zelvak z;
        private StreamReader stream;
        private List<String> words;

        public Interpreter(Zelvak z, StreamReader stream) {
            this.z = z;
            this.stream = stream;
            int ch;
            StringBuilder sb = new StringBuilder();
            words = new List<string>();

            //kulaté závorky nepotřebujeme, stačí nám názvy funkcí, parametry a koncové složené závorky
            //(pokud nepoužíváme rozšíření 4 a 5 Chytřejšího želváka)
            while ((ch = stream.Read()) >= 0) {
                if (DIGITS.Contains((char)ch) || LETTERS.Contains((char)ch)) {
                    sb.Append((char)ch);
                }
                else {
                    if (sb.ToString() != "") {
                        words.Add(sb.ToString());
                        Console.WriteLine(sb.ToString());
                    }
                    sb.Length = 0;
                    if ('}'.Equals((char)ch)) {
                        words.Add("}");
                        Console.WriteLine("}");
                    }
                }
            }
        }

        public void Run() {
            int i;
            List<Executable> commands = ReadCommands(0, out i, null);
            foreach (Executable cmd in commands) {
                cmd.Execute(z);
            }
        }

        public List<Executable> ReadCommands(int start, out int end, String endString) {
            List<Executable> commands = new List<Executable>();
            int i;
            for (i = start; i < words.Count; i++) {
                if (words[i].Equals(endString))
                    break;
                if (Command.IsCommand(words[i])) {
                    List<int> parameters = new List<int>();
                    int j = i + 1;
                    while (j < words.Count) {
                        int num;
                        if (int.TryParse(words[j], out num)) {
                            parameters.Add(num);
                        }
                        else break;
                        j++;
                    }
                    commands.Add(new Command(words[i], parameters));
                }else if(Block.IsBlock(words[i])){
                    int parameter;
                    int.TryParse(words[i + 1], out parameter);
                    commands.Add(new Block(words[i], parameter, ReadCommands(i+1, out i, "}")));
                }
            }
            end = i;
            return commands;
        }
    }
}