/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package targets.mips;

import API.MiddlewareInterface;
import common.Block;
import common.Code;
import common.Instruction;
import common.Label;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 *
 * @author EUGENIO CARVALHO
 */
public class MipsUpdateAddressMiddleware implements MiddlewareInterface {

    protected HashMap<String, Boolean> updateOffsetShift = new HashMap<String, Boolean>() {
        {
            put("beq", true);
            put("bne", true);
            put("blez", true);
            put("bltz", true);
            put("bgez", true);
            put("bgtz", true);
        }
    };

    public MipsUpdateAddressMiddleware() {
    }

    @Override

    public void Exec(Code c, LinkedHashMap<String, MiddlewareInterface> cp) throws Exception {
        Long offset = 0L;
        Label label;
        for (Map.Entry<String, Block> x : c.Blocks().entrySet()) {
            for (Instruction inst : x.getValue().Instructions()) {

                // Atualziza o offset das instruições de branch
                if (!updateOffsetShift.containsKey(inst.Get("inst"))) {
                    continue;
                }
//                System.out.println("UPDATE ADDRESS: " + inst.Get("label") + " c.labels:" + c.labels);
                label = c.labels.get(inst.Get("label"));
//                offset = Integer.parseInt(def.get(0));
//                offset = Integer.parseInt(def.get(1).split(""));

//                System.out.println("Offset:" + +"----" +);
//                offset = Integer.parseInt(def.get(0));
//                offset = ((offset - inst.GetInt("global.position")) / 4) - 1;
//                System.out.println("LABEL:"
//                        + label.GetGlobalPosition()
//                        + "/"
//                        + Utils.FormatNum(label.GetGlobalPosition(), "hex")
//                        + "/"
//                        + inst.GetInt("global.position")
//                        + "/"
//                        + Utils.FormatNum(inst.GetInt("global.position"), "hex")
//                );
                offset = ((label.GetGlobalPosition() - inst.GetInt("global.position")) / 4) - 1;

//                System.out.println("OffsetCalculado:" + offset);
                inst.Set("offset", offset);
            }
        }

//        System.out.println("Labels:" + c.labels);
//        String[] parts;
//        int index;
        // Update address of labels
//        for (Map.Entry<String, ArrayList<String>> entry : c.labels.entrySet()) {
//            ArrayList<String> labeldata = entry.getValue();
//            labeldata.set(0, (Integer.parseInt(labeldata.get(0)) * 4) + "");
//            try {
//                parts = labeldata.get(1).split("(\\+)");
//                if (parts.length > 1) {
//                    index = Integer.parseInt(parts[1]);
//                    labeldata.set(1, parts[0] + "+" + (index * 4));
//                }
//            } catch (Exception e) {
//            }
//        }
    }

}
// atualiza o indice da instrução de pc + 4
//                if (inst.isNumber("global.position")) {
//                    inst.Set("block.position", inst.GetInt("block.position") * 4);
//                    inst.Set("global.position", inst.GetInt("global.position") * 4);
//                } else if (inst.eq("type", "label")) {
//                    // atualiza o endereco dos labels
//                    inst.Set("reference.position", inst.GetInt("reference.position") * 4);
//                    inst.Set("global.reference.position", inst.GetInt("global.reference.position") * 4);
//                }
