package _VisualDVM.ProjectData.SapforData.Arrays;
import Common.Utils.Index;
import Common.Utils.IntegerPairJson;
import Common.Utils.Pair;
import _VisualDVM.ProjectData.SapforData.Regions.ParallelRegion;
import com.google.gson.annotations.Expose;

import java.math.BigInteger;
import java.util.Vector;
public class AlignRule {
    @Expose
    public String packedAlignArrayAddress;
    @Expose
    public String packedAlignWithAddress;
    @Expose
    public Vector<IntegerPairJson> alignRule;
    @Expose
    public Vector<AlignRuleWidthJson> alignRuleWith = new Vector<>();
    //----
    public BigInteger alignArray_address;
    public BigInteger alignWith_address;
    public ParallelRegion parent_region = null;
    public AlignRule(String[] splited, Index idx) {
        alignArray_address = new BigInteger((splited[idx.Inc()]));
        alignWith_address = new BigInteger(splited[idx.Inc()]);
        int alignRule_size = Integer.parseInt((splited[idx.Inc()]));
        alignRule = new Vector<>(alignRule_size);
        for (int i = 0; i < alignRule_size; ++i) {
            int first = Integer.parseInt(splited[idx.Inc()]);
            int second = Integer.parseInt(splited[idx.Inc()]);
            alignRule.add(new IntegerPairJson(first, second));
        }
        int alignRuleWith_size = Integer.parseInt(splited[idx.Inc()]);
        alignRuleWith = new Vector<>(alignRuleWith_size);
        for (int k = 0; k < alignRuleWith_size; ++k) {
            int dimNum = Integer.parseInt(splited[idx.Inc()]);
            int a = Integer.parseInt(splited[idx.Inc()]);
            int b = Integer.parseInt(splited[idx.Inc()]);
            alignRuleWith.add(new AlignRuleWidthJson(dimNum, a, b));
        }
    }
    private static Pair<String, String> convertDigitToPositive(int digit) {
        String buf = "";
        String sign = " + ";
        if (digit < 0) {
            sign = " - ";
            int val = -digit;
            buf += String.valueOf(val);
        } else
            buf += String.valueOf(digit);
        return new Pair<>(sign, buf);
    }
    public void Init() {
        //--
        alignArray_address = new BigInteger(packedAlignArrayAddress);
        alignWith_address = new BigInteger(packedAlignWithAddress);
        //--
        packedAlignArrayAddress = null;
        packedAlignWithAddress = null;
    }
    public ProjectArray getAlignArray() {
        return parent_region.arraysMap.get(alignArray_address);
    }
    public ProjectArray getAlignWith() {
        return parent_region.arraysMap.get(alignWith_address);
    }
    String genStringExpr(String letter, int a, int b) {
        String retVal = "";
        if (a == 0 && b == 0)
            retVal = "*";
        else if (b == 0) {
            if (a == 1)
                retVal = letter;
            else {
                Pair<String, String> digit2 = convertDigitToPositive(a);
                if (digit2.getKey() == " - ")
                    retVal = "(-" + digit2.getValue() + ")" + " * " + letter;
                else retVal = digit2.getValue() + " * " + letter;
            }
        } else {
            Pair<String, String> digit1 = convertDigitToPositive(b);
            if (a == 1)
                retVal = letter + digit1.getKey() + digit1.getValue();
            else {
                Pair<String, String> digit2 = convertDigitToPositive(a);
                if (digit2.getKey() == " - ")
                    retVal = "(-" + digit2.getValue() + ")" + " * " + letter + digit1.getKey() + digit1.getValue();
                else
                    retVal = digit2.getValue() + " * " + letter + digit1.getKey() + digit1.getValue();
            }
        }
        return retVal;
    }
    public int GetLenString() {
        String val = "";
        val += getAlignArray().shortName + "(";
        for (int i = 0; i < alignRule.size(); ++i) {
            val += genStringExpr(ProjectArray.alignNames[i], alignRule.get(i).getKey(), alignRule.get(i).getValue());
            if (i != alignRule.size() - 1)
                val += ",";
        }
        val += ") ";
        return val.length();
    }
    public Pair<String, String> GenRule(int maxArrayStringLen) {
        getAlignArray().ac_current.clear();
        getAlignArray().ac_new.clear();
        getAlignArray().spaces_shift = "";
        //------------------------------------------------------------>>>
        getAlignArray().align_template = getAlignWith();
        getAlignArray().parent_region = parent_region;
        //------------------------------------------------------------>>>
        String retVal = "";
        String arrayString = "";
        retVal += getAlignArray().TypeString() + " ";
        arrayString += getAlignArray().shortName + "(";
        for (int i = 0; i < alignRule.size(); ++i) {
            arrayString += genStringExpr(ProjectArray.alignNames[i], alignRule.get(i).getKey(), alignRule.get(i).getValue());
            if (i != alignRule.size() - 1)
                arrayString += ",";
        }
        arrayString += ") ";
        for (int i = 0; i < maxArrayStringLen - arrayString.length(); ++i) {
            getAlignArray().spaces_shift += " ";
        }
        retVal += getAlignArray().spaces_shift;
        retVal += arrayString;
        String bracket_open = "(";
        String bracket_close = ")";

        /*
        if (getAlignWith().isTemplFlag > 0)
        {
            bracket_open = "[";
            bracket_close = "]";
        }
         */
        retVal += "→ " + getAlignWith().shortName + bracket_open;
        Vector<String> alignEachDim = new Vector<>(getAlignWith().dimSize);
        for (int i = 0; i < alignEachDim.capacity(); ++i)
            alignEachDim.add("*");
        for (int i = 0; i < alignRuleWith.size(); ++i) {
            if (alignRuleWith.get(i).getDimNum() != -1) {
                alignEachDim.set(alignRuleWith.get(i).getDimNum(),
                        genStringExpr(ProjectArray.alignNames[i], alignRuleWith.get(i).getA(), alignRuleWith.get(i).getB()));
                //коэццициенты находятся здесь!!------------------------------------------------------------------->>
                getAlignArray().ac_current.put(i,
                        new Dimension(i,
                                alignRuleWith.get(i).getA(),
                                alignRuleWith.get(i).getB()
                        ));
            } else getAlignArray().ac_current.put(i, new Dimension(i));
        }
        for (int i = 0; i < alignEachDim.size(); ++i) {
            retVal += alignEachDim.get(i);
            if (i != getAlignWith().dimSize - 1)
                retVal += ",";
        }
        retVal += bracket_close;// + String_.wands(alignArray.Id.ToString());
        return new Pair<>(getAlignWith().shortName, retVal);
    }
}
