public int FindNextElseOrEndifCommand()
    {
        int index = currentCommandIndex;
        int nestedIfCommandsFound = 0;

        for (int i = index; i < vsnCommands.Count; i++)
        {
            VsnCommand command = vsnCommands[i];

            if (command.GetType() == typeof(IfCommand))
            {
                nestedIfCommandsFound++;
            }

            if (command.GetType() == typeof(EndIfCommand))
            {
                if (nestedIfCommandsFound == 0)
                {
                    return(command.commandIndex);
                }
                else
                {
                    nestedIfCommandsFound -= 1;
                }
            }

            if (command.GetType() == typeof(ElseCommand) &&
                nestedIfCommandsFound == 0)
            {
                return(command.commandIndex);
            }
        }
        return(-1);
    }
    public void ExecuteCurrentCommand()
    {
        VsnCommand currentCommand = vsnCommands[currentCommandIndex];

        Debug.Log(">> " + loadedScriptName + " line " + currentCommand.fileLineId);
        currentCommandIndex++;
        currentCommand.Execute();
    }
    public List <VsnCommand> ParseVSNCommands(string[] lines)
    {
        List <VsnCommand> vsnCommandsFromScript = new List <VsnCommand>();

        int commandNumber = 0;

        for (int i = 0; i < lines.Length; i++)
        {
            string line = lines[i].TrimStart();

            if (line == "\r" || String.IsNullOrEmpty(line))
            {
                continue;
            }

            List <VsnArgument> vsnArguments = new List <VsnArgument>();

            string commandName = Regex.Match(line, "^([\\w\\-]+)").Value;

            MatchCollection valuesMatch = Regex.Matches(line, "[^\\s\"']+|\"[^\"]*\"|'[^']*'");

            List <string> args = new List <string>();

            foreach (Match match in valuesMatch)
            {
                args.Add(match.Value);
            }

            args.RemoveAt(0); // Removes the first match, which is the "commandName"

            foreach (string arg in args)
            {
                VsnArgument vsnArgument = ParseArgument(arg);
                vsnArguments.Add(vsnArgument);
            }

            VsnCommand vsnCommand = InstantiateVsnCommand(commandName, vsnArguments);
            if (vsnCommand != null)
            {
                if (commandName == "waypoint")
                {
                    RegisterWaypoint(new VsnWaypoint(vsnArguments[0].GetReference(), commandNumber));
                }

                vsnCommand.commandIndex = commandNumber;
                vsnCommand.fileLineId   = i + 1;
                commandNumber++;
                vsnCommandsFromScript.Add(vsnCommand);
            }
        }

        return(vsnCommandsFromScript);
    }
    /// <summary>
    /// Iterates through all command classes searching for one with the correct CommandAttribute matching the commandName
    /// </summary>
    /// <returns>The vsn command.</returns>
    /// <param name="commandName">Command name.</param>
    /// <param name="vsnArguments">Vsn arguments.</param>
    private VsnCommand InstantiateVsnCommand(string commandName, List <VsnArgument> vsnArguments)
    {
        foreach (Type type in VsnController.instance.possibleCommandTypes)
        {
            foreach (Attribute attribute in type.GetCustomAttributes(false))
            {
                if (attribute is CommandAttribute)
                {
                    CommandAttribute commandAttribute = (CommandAttribute)attribute;

                    if (commandAttribute.CommandString == commandName)
                    {
                        VsnCommand vsnCommand = Activator.CreateInstance(type) as VsnCommand;
                        vsnCommand.InjectArguments(vsnArguments);

                        if (vsnCommand.CheckSyntax() == false)
                        {
                            string line = commandName + ": ";

                            foreach (VsnArgument c in vsnArguments)
                            {
                                line += c.GetStringValue() + "/" + c.GetReference() + "/" + c.GetNumberValue() + " - ";
                            }
                            Debug.LogError("Invalid syntax for this command: " + line);
                            return(new InvalidCommand());
                        }

                        // TODO add metadata like line number?...

                        return(vsnCommand);
                    }
                }
            }
        }

        Debug.Log("Got a null");
        return(null);
    }