/* This file was generated by SableCC's ObjectMacro. */

package org.sablecc.objectmacro.codegeneration.java.macro;

import java.util.*;

public class MSetInternal
        extends Macro {

    private DSeparator ParamNameSeparator;

    private DBeforeFirst ParamNameBeforeFirst;

    private DAfterLast ParamNameAfterLast;

    private DNone ParamNameNone;

    final List<String> list_ParamName;

    final Context ParamNameContext = new Context();

    final StringValue ParamNameValue;

    private DSeparator ContextSeparator;

    private DBeforeFirst ContextBeforeFirst;

    private DAfterLast ContextAfterLast;

    private DNone ContextNone;

    final List<String> list_Context;

    final Context ContextContext = new Context();

    final StringValue ContextValue;

    private DSeparator SetParamsSeparator;

    private DBeforeFirst SetParamsBeforeFirst;

    private DAfterLast SetParamsAfterLast;

    private DNone SetParamsNone;

    final List<Macro> list_SetParams;

    final Context SetParamsContext = new Context();

    final MacroValue SetParamsValue;

    private Map<Context, StringValue> list_VarName = new LinkedHashMap<>();

    MSetInternal(
            Macros macros) {

        setMacros(macros);
        this.list_ParamName = new LinkedList<>();
        this.list_Context = new LinkedList<>();
        this.list_SetParams = new LinkedList<>();
        this.list_VarName = new LinkedHashMap<>();

        this.ParamNameValue
                = new StringValue(this.list_ParamName, this.ParamNameContext);
        this.ContextValue
                = new StringValue(this.list_Context, this.ContextContext);
        this.SetParamsValue
                = new MacroValue(this.list_SetParams, this.SetParamsContext);
    }

    MSetInternal(
            String pParamName,
            String pContext,
            List<Macro> pSetParams,
            Macros macros) {

        setMacros(macros);
        this.list_ParamName = new LinkedList<>();
        this.list_Context = new LinkedList<>();
        this.list_SetParams = new LinkedList<>();
        this.list_VarName = new LinkedHashMap<>();

        this.ParamNameValue
                = new StringValue(this.list_ParamName, this.ParamNameContext);
        this.ContextValue
                = new StringValue(this.list_Context, this.ContextContext);
        this.SetParamsValue
                = new MacroValue(this.list_SetParams, this.SetParamsContext);
        if (pSetParams != null) {
            addAllSetParams(pSetParams);
        }

        if (pParamName != null) {
            addParamName(pParamName);
        }
        if (pContext != null) {
            addContext(pContext);
        }
    }

    public void addAllParamName(
            List<String> strings) {

        if (this.macros == null) {
            throw ObjectMacroException.parameterNull("ParamName");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }
        for (String string : strings) {
            if (string == null) {
                throw ObjectMacroException.parameterNull("ParamName");
            }

            this.list_ParamName.add(string);
        }
    }

    public void addParamName(
            String string) {

        if (string == null) {
            throw ObjectMacroException.parameterNull("ParamName");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        this.list_ParamName.add(string);
    }

    public void addAllContext(
            List<String> strings) {

        if (this.macros == null) {
            throw ObjectMacroException.parameterNull("Context");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }
        for (String string : strings) {
            if (string == null) {
                throw ObjectMacroException.parameterNull("Context");
            }

            this.list_Context.add(string);
        }
    }

    public void addContext(
            String string) {

        if (string == null) {
            throw ObjectMacroException.parameterNull("Context");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        this.list_Context.add(string);
    }

    public void addAllSetParams(
            List<Macro> macros) {

        if (macros == null) {
            throw ObjectMacroException.parameterNull("SetParams");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        int i = 0;

        for (Macro macro : macros) {
            if (macro == null) {
                throw ObjectMacroException.macroNull(i, "SetParams");
            }

            if (getMacros() != macro.getMacros()) {
                throw ObjectMacroException.diffMacros();
            }

            verifyTypeSetParams(macro);
            this.list_SetParams.add(macro);
            this.children.add(macro);
            Macro.cycleDetector.detectCycle(this, macro);

            i++;
        }
    }

    void verifyTypeSetParams(
            Macro macro) {

        macro.apply(new InternalsInitializer("SetParams") {

            @Override
            void setParamRef(
                    MParamRef mParamRef) {

            }

            @Override
            void setStringValueArg(
                    MStringValueArg mStringValueArg) {

            }
        });
    }

    public void addSetParams(
            MParamRef macro) {

        if (macro == null) {
            throw ObjectMacroException.parameterNull("SetParams");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        if (getMacros() != macro.getMacros()) {
            throw ObjectMacroException.diffMacros();
        }

        this.list_SetParams.add(macro);
        this.children.add(macro);
        Macro.cycleDetector.detectCycle(this, macro);
    }

    public void addSetParams(
            MStringValueArg macro) {

        if (macro == null) {
            throw ObjectMacroException.parameterNull("SetParams");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        if (getMacros() != macro.getMacros()) {
            throw ObjectMacroException.diffMacros();
        }

        this.list_SetParams.add(macro);
        this.children.add(macro);
        Macro.cycleDetector.detectCycle(this, macro);
    }

    void setVarName(
            Context context,
            StringValue value) {

        if (value == null) {
            throw new RuntimeException("value cannot be null here");
        }

        this.list_VarName.put(context, value);
    }

    private String buildParamName() {

        StringBuilder sb = new StringBuilder();
        List<String> strings = this.list_ParamName;

        int i = 0;
        int nb_strings = strings.size();

        for (String string : strings) {

            sb.append(string);
            i++;
        }

        return sb.toString();
    }

    private String buildContext() {

        StringBuilder sb = new StringBuilder();
        List<String> strings = this.list_Context;

        int i = 0;
        int nb_strings = strings.size();

        for (String string : strings) {

            sb.append(string);
            i++;
        }

        return sb.toString();
    }

    private String buildSetParams() {

        StringBuilder sb = new StringBuilder();
        Context local_context = this.SetParamsContext;
        List<Macro> macros = this.list_SetParams;

        int i = 0;
        int nb_macros = macros.size();
        String expansion = null;

        for (Macro macro : macros) {
            expansion = macro.build(local_context);

            sb.append(expansion);
            i++;
        }

        return sb.toString();
    }

    private String buildVarName(
            Context context) {

        StringValue stringValue = this.list_VarName.get(context);
        return stringValue.build();
    }

    StringValue getParamName() {

        return this.ParamNameValue;
    }

    StringValue getContext() {

        return this.ContextValue;
    }

    MacroValue getSetParams() {

        return this.SetParamsValue;
    }

    private StringValue getVarName(
            Context context) {

        return this.list_VarName.get(context);
    }

    private void initSetParamsInternals(
            Context context) {

        for (Macro macro : this.list_SetParams) {
            macro.apply(new InternalsInitializer("SetParams") {

                @Override
                void setParamRef(
                        MParamRef mParamRef) {

                }

                @Override
                void setStringValueArg(
                        MStringValueArg mStringValueArg) {

                }
            });
        }
    }

    private void initParamNameDirectives() {

    }

    private void initContextDirectives() {

    }

    private void initSetParamsDirectives() {

    }

    @Override
    void apply(
            InternalsInitializer internalsInitializer) {

        internalsInitializer.setSetInternal(this);
    }

    @Override
    String build(
            Context context) {

        CacheBuilder cache_builder = this.cacheBuilders.get(context);

        if (cache_builder == null) {
            cache_builder = new CacheBuilder();
        }
        else if (cache_builder.getExpansion() == null) {
            throw new InternalException("Cycle detection detected lately");
        }
        else {
            return cache_builder.getExpansion();
        }

        this.cacheBuilders.put(context, cache_builder);
        List<String> indentations = new LinkedList<>();

        initSetParamsInternals(context);

        initParamNameDirectives();
        initContextDirectives();
        initSetParamsDirectives();

        StringBuilder sb0 = new StringBuilder();

        sb0.append("m");
        sb0.append(buildVarName(context));
        sb0.append(".set");
        sb0.append(buildParamName());
        sb0.append("(");
        sb0.append(buildContext());
        sb0.append(", ");
        sb0.append(buildSetParams());
        sb0.append(");");
        cache_builder.setExpansion(sb0.toString());
        return sb0.toString();
    }

    private void setMacros(
            Macros macros) {

        if (macros == null) {
            throw new InternalException("macros cannot be null");
        }

        this.macros = macros;
    }
}
