package ProjectData.SapforData.Loops;
import Common.UI.Themes.VisualiserFonts;
import Common.Utils.Index;
import ProjectData.Files.DBProjectFile;
import ProjectData.Messages.Message;
import ProjectData.SapforData.FileObjectWithMessages;
import ProjectData.SapforData.Functions.FuncCall;

import java.util.Vector;
public class Loop extends FileObjectWithMessages {
    private final int lineNumAfterLoop;
    private final int perfectLoop;
    private final boolean hasOutGoto;
    private final boolean hasPrints;
    private final boolean hasNonRectIters;
    //
    private final int childCount;
    public LoopState loopState;
    public Vector<FileObjectWithMessages> children = new Vector<>();
    public Loop(String[] packedLoopInfo, Index idx, DBProjectFile father_in) {
        file = father_in.name;
        int calls = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        for (int k = 0; k < calls; ++k) {
            String c_name = packedLoopInfo[idx.Inc()];
            int c_line = Integer.parseInt(packedLoopInfo[idx.Inc()]);
            children.add(new FuncCall(father_in, c_name, c_line));
        }
        line = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        lineNumAfterLoop = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        perfectLoop = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        hasOutGoto = (Integer.parseInt(packedLoopInfo[idx.Inc()]) == 1);
        hasPrints = (Integer.parseInt(packedLoopInfo[idx.Inc()]) == 1);
        childCount = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        int state = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        switch (state) {
            case 1:
                loopState = LoopState.GoodLoop;
                break;
            case 2:
                loopState = LoopState.BadLoop;
                break;
            default:
                loopState = LoopState.Loop;
                break;
        }
        hasNonRectIters = (Integer.parseInt(packedLoopInfo[idx.Inc()]) == 1);
        if (hasNonRectIters)
            children.add(new NonRectIter(father_in, line));
        ////-------------------------------------------------------------------------------
        //   число внешних переходов
        int e_gotos = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        for (int k = 0; k < e_gotos; ++k) {
            int c_line = Integer.parseInt(packedLoopInfo[idx.Inc()]);
            children.add(new EGoto(father_in, c_line));
        }
        //число внутренних переходов
        int i_gotos = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        for (int k = 0; k < i_gotos; ++k) {
            int c_line = Integer.parseInt(packedLoopInfo[idx.Inc()]);
            children.add(new IGoto(father_in, c_line));
        }
        //число операторов печати
        int IO = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        for (int k = 0; k < IO; ++k) {
            int c_line = Integer.parseInt(packedLoopInfo[idx.Inc()]);
            children.add(new IO(father_in, c_line));
        }
        //число операторов останова (STOPб PAUSE)
        int stop = Integer.parseInt(packedLoopInfo[idx.Inc()]);
        for (int k = 0; k < stop; ++k) {
            int c_line = Integer.parseInt(packedLoopInfo[idx.Inc()]);
            children.add(new Stop(father_in, c_line));
        }
        //--------------------------------------------------------------------------------
        for (int i = 0; i < childCount; ++i) {
            Loop nextChild = new Loop(packedLoopInfo, idx, father_in);
            children.add(nextChild);
        }
        father_in.AllLoops.put(line, this);
        //нельзя использовать конструктор с параметрами из за особеностей распаковки.
        CheckMessagesPresence();
    }
    @Override
    public String TypeKey() {
        return loopState.toString();
    }
    @Override
    public String Description() {
        return "цикл";
    }
    @Override
    public boolean HasMessage(Message message) {
        return (message.line >= line) && (message.line < lineNumAfterLoop);
    }
    @Override
    public String toString() {
        return super.toString() + ((perfectLoop > 1) ? (" тесная вложенность " + perfectLoop) : "");
    }
    @Override
    public VisualiserFonts getFont() {
        return loopState.getFont();
    }
}
