/*
 * 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 API;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import template.TemplateCtx;

/**
 *
 * @author Eugenio
 */
public class RegistroBase implements template.TemplateCtx {

    protected HashMap<String, String> attr;
    protected HashMap<String, ArrayList<String>> lists;

    public Instruction parent;
    public Instruction next;
    public Instruction prev;

    public RegistroBase() {
        lists = new LinkedHashMap<>();
        attr = new LinkedHashMap<>();
    }

    public void addList(String nome, ArrayList<String> lista) {
        lists.put(nome, lista);
    }

    public boolean existeLista(String nome) {
        return lists.containsKey(nome);
    }

    public void addInList(String nome, String value) {
        getList(nome).add(value);
    }

    public ArrayList<String> getList(String nome) {
        if (!existeLista(nome)) {
            lists.put(nome, new ArrayList<String>());
        }
        return lists.get(nome);
    }

    public void setParent(Instruction n) {
        parent = n;
    }

    public String G(String attrib) {
        return attr.containsKey(attrib) ? attr.get(attrib) : "";
    }

    public String get(String attrib, String orValue) {
        String val = G(attrib);
        return (val.equals("")) ? orValue : val;
    }

    public String format(String f) {
        String value = "";
        for (Map.Entry<String, String> entry : this.getProps().entrySet()) {
            value = entry.getValue() != null ? entry.getValue() : "NULL";
            f = f.replaceAll("\\{" + entry.getKey() + "\\}", value);
        }
        return f;
    }

    @Override
    public TemplateCtx Set(String id, String value) {
        S(id, value);
        return this;
    }

    public RegistroBase S(String attrib, String value) {
        attr.put(attrib, value);
        return this;
    }

    public boolean testAndSet(String atributo, String cmp, String valor) {
        if (eq(atributo, cmp)) {
            S(atributo, valor);
            return true;
        }
        return false;
    }

    public boolean contem(String atributo, String part) {
        if (!Has(atributo)) {
            return false;
        }
        return G(atributo).contains(part);
    }

    @Override
    public String toString() {
        String reg = "";
        for (Map.Entry<String, String> entry : attr.entrySet()) {
            String string = entry.getKey();
            String string1 = entry.getValue();
            reg += "\t" + string + ":" + string1 + ",\n";
        }
        return ":\n" + reg;

    }

    public void somar(String atributo, int i) {
        if (!Has(atributo)) {
            set(atributo, i);
        } else {
            try {
                int nu = getInt(atributo);
                set(atributo, nu + i);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public RegistroBase set(String attrib, int valor) {
        S(attrib, "" + valor);
        return this;
    }

    public String getText() {
        return G("value");
    }

    public String getRegistroClass() {
        return G("class");
    }

    public String getValorOuVazio(String string) {
        return (attr.containsKey(string)) ? attr.get(string) : "";
    }

    public boolean Has(String at) {
        return attr.containsKey(at);
    }

    public HashMap<String, String> getProps() {
        return attr;
    }

    public void del(String atrib) {
        attr.remove(atrib);
    }

    public int getInt(String atributo) throws Exception {
        String l = "";
        try {
            l = G(atributo);
            return Integer.parseInt(l);
        } catch (Exception e) {
            throw new Exception("[ID:" + G("id") + "]O atributo {" + atributo + ":'" + l + "'} não é inteiro");
        }
    }

    public boolean eq(String attrib, String value) {
        if (!attr.containsKey(attrib)) {
            return false;
        }
        return attr.get(attrib).equals(value);
    }

    public boolean in(String atributo, String[] valores) {
        if (!attr.containsKey(atributo)) {
            return false;
        }

        boolean in = false;

        for (String valor : valores) {
            if (attr.get(atributo).equals(valor)) {
                in = true;
                break;
            }
        }

        return in;
    }

    public boolean diferente(String atributo, String valor) {
        return !attr.get(atributo).equals(valor);
    }

    /**
     * Verifica Se um dado atributo é numerico.
     *
     * @param atributo
     * @return
     */
    public boolean isNumber(String atributo) {
        try {
            Integer.parseInt(G(atributo).replaceAll("\\s*", ""));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Copia o dado do regiStro r com atributio Fonte para regiStro atual
     * mantendo o nome do atributo
     *
     * @param atribs Fonte
     * @param r
     */
    public void copiar(String atrib, RegistroBase r) {
        S(atrib, r.G(atrib));
    }

    /**
     * Copia o dado do regiStro r com atributio Fonte para o atributo deStino no
     * regiStro atual
     *
     * @param atribs Fonte
     * @param atribd DeStino
     * @param r
     */
    public void copiar(String atribs, String atribd, RegistroBase r) {
        S(atribd, r.G(atribs));
    }

}
