/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2007 JP.Tessier - jean-philippe.tessier@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package fr.gouv.finances.cp.xemelios.controls;

import fr.gouv.finances.cp.xemelios.controls.models.ControlModel;
import fr.gouv.finances.dgfip.utils.Pair;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;

/**
 * public Anomalie(String idAnomalie,String controleID,String controleLibelle,String docID,String etatID,String elementID,String elementLibelle,String message,String regle,String severity,XPath xPathNameSpacise,Vector<String> xslParams)
 * 
 * @param idAnomalie 
 * @param controleID
 * @param controleLibelle
 * @param docID
 * @param etatID
 * @param elementImportable
 * @param elementEnAnomalie
 * @param message
 * @param regle
 * @param severity
 * @param xPath
 * @param xslParams
 */
public class Anomalie implements Comparable<Anomalie> {

    public static final String ANOMALY_NS_URI = "http://projets.admisource.gouv.fr/xemelios/namespaces#anomally";
    private String idAnomalie, // id auto generer avec IdGenerator
            controleID, // id du controle
            controleLibelle, // libelle du controle (dans le fichier de config).A recuperer par l'intermediaire du DocumentControlModel
            documentID, // id du document importé. A recuperer par l'intermediaire du DocumentControlModel
            etatID, // id de l'etat sur lequel porte l'anomalie.
            elementImportable, // balise (element importable)
            idElementImportable,// numéro de l'element importable sur lequel l'anomalie porte (obligatoire)
            elementEnAnomalie, // le localName (nom de la balise xml au moment de la creation de l'ano) du startElement
            libelleLien, // libelle du lien afficher pour l'anomalie dans l'affichage du rapport
            message, // message du controle.A recuperer par l'intermediaire du DocumentControlModel
            regle, // règle du controle.A recuperer par l'intermediaire du DocumentControlModel
            severity, // severity du controle.A recuperer par l'intermediaire du DocumentControlModel
            xPath;	// xpath car une fois importer il faut pointer sur les éléments
    private Hashtable<String, Object> xslParams; // Hashtable< id du paramètre , valeur du paramètre >
    private ArrayList<Node> nodes;
    private boolean visible = true;

    public Anomalie(String idAnomalie,
            String controleID,
            String controleLibelle,
            String docID,
            String etatID,
            String elementImportable,
            String idElementImportable,
            String elementEnAnomalie,
            String libelleLien,
            String message,
            String regle,
            String severity,
            String xPath,
            Hashtable<String, Object> xslParams) {
        this.idAnomalie = idAnomalie;
        this.controleID = controleID;
        this.controleLibelle = controleLibelle;
        this.documentID = docID;
        this.etatID = etatID;
        this.elementImportable = elementImportable;
        this.idElementImportable = idElementImportable;
        this.elementEnAnomalie = elementEnAnomalie;
        this.libelleLien = libelleLien;
        this.message = message;
        this.regle = regle;
        this.severity = severity;
        this.xPath = xPath;
        this.xslParams = xslParams;
        this.nodes = new ArrayList<Node>();
    }

    public Anomalie(String idAnomalie,
            ControlModel ctrl,
            String docID,
            String etatID,
            String elementImportable,
            String idElementImportable,
            String elementEnAnomalie,
            String libelleLien,
            String message,
            String regle,
            String severity,
            String xPath,
            Hashtable<String, Object> xslParams) {
        this.idAnomalie = idAnomalie;
        this.controleID = ctrl.getId();
        this.controleLibelle = ctrl.getLibelle();
        this.documentID = docID;
        this.etatID = etatID;
        this.elementImportable = elementImportable;
        this.idElementImportable = idElementImportable;
        this.elementEnAnomalie = elementEnAnomalie;
        this.libelleLien = libelleLien;
        this.message = message;
        this.regle = regle;
        this.severity = severity;
        this.xPath = xPath;
        this.xslParams = xslParams;
        this.nodes = new ArrayList<Node>();
    }

    public void addNode(Node node) {
        nodes.add(node);
    }

    public void addAll(Collection<Node> node) {
        this.nodes.addAll(node);
    }

    public String getSeverity() {
        return severity;
    }

    public Collection<Node> getNodes() {
        return nodes;
    }

    public String getControleID() {
        return controleID;
    }

    public void setControleID(String controleID) {
        this.controleID = controleID;
    }

    public String getControleLibelle() {
        return controleLibelle;
    }

    public void setControleLibelle(String controleLibelle) {
        this.controleLibelle = controleLibelle;
    }

    public String getDocumentID() {
        return documentID;
    }

    public void setDocumentID(String documentID) {
        this.documentID = documentID;
    }

    public String getelementImportable() {
        return elementImportable;
    }

    public void setelementImportable(String elementImportable) {
        this.elementImportable = elementImportable;
    }

    public String getelementEnAnomalie() {
        return elementEnAnomalie;
    }

    public void setelementEnAnomalie(String elementEnAnomalie) {
        this.elementEnAnomalie = elementEnAnomalie;
    }

    public String getEtatID() {
        return etatID;
    }

    public void setEtatID(String etatID) {
        this.etatID = etatID;
    }

    public String getIdAnomalie() {
        return idAnomalie;
    }

    public void setIdAnomalie(String idAnomalie) {
        this.idAnomalie = idAnomalie;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getRegle() {
        return regle;
    }

    public void setRegle(String regle) {
        this.regle = regle;
    }

    public String getXPath() {
        return xPath;
    }

    public void setxPath(String pathNameSpacise) {
        xPath = pathNameSpacise;
    }

    public Hashtable<String, Object> getXslParams() {
        return xslParams;
    }

    public void setXslParams(Hashtable<String, Object> xslParams) {
        this.xslParams = xslParams;
    }

    public void setSeverity(String severity) {
        this.severity = severity;
    }

    public String getElementEnAnomalie() {
        return elementEnAnomalie;
    }

    public void setElementEnAnomalie(String elementEnAnomalie) {
        this.elementEnAnomalie = elementEnAnomalie;
    }

    public String getElementImportable() {
        return elementImportable;
    }

    public void setElementImportable(String elementImportable) {
        this.elementImportable = elementImportable;
    }

    public String getIdElementImportable() {
        return idElementImportable;
    }

    public void setIdElementImportable(String idElementImportable) {
        this.idElementImportable = idElementImportable;
    }

    public String getLibelleLien() {
        return libelleLien;
    }

    public void setLibelleLien(String libelleLien) {
        this.libelleLien = libelleLien;
    }

    /**
     * @param other other doit être de type Anomalie !
     */
    public int compareTo(Anomalie other) {
        String id1 = ((Anomalie) other).getControleID();
        String id2 = this.getControleID();

        return id1.compareTo(id2);
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public void marshall(RapportWriter writer) {
        writer.openElement("Anomalie");
        writer.writeElement("Id", new Pair("V", getIdAnomalie()));
        writer.writeElement("Visibility", new Pair("V", isVisible() ? "visible" : "hidden"));
        writer.writeElement("IdCtrl", new Pair("V", getControleID()));
        writer.writeElement("LibelleCtrl", new Pair("V", getControleLibelle()));
        writer.writeElement("EtatId", new Pair("V", getEtatID()));
        writer.writeElement("ElementImportable", new Pair("V", getelementImportable()));
        writer.writeElement("IdElementImportable", new Pair("V", getIdElementImportable()));
        writer.writeElement("ElementEnAnomalie", new Pair("V", getelementEnAnomalie()));
        writer.writeElement("LibelleLien", new Pair("V", getLibelleLien()));

        writer.openElement("Message");
        writer.writeData("<![CDATA[");
        try {
            writer.getWriter().getWriter().write(getMessage());
        } catch(IOException ioEx) {
            // ignored
        }
        writer.writeData("]]>");
        writer.closeElement("Message");

        writer.openElement("Regle");
        writer.writeData("<![CDATA[");
        try {
            writer.getWriter().getWriter().write(getRegle());
        } catch(IOException ioEx) {
            // ignored
        }
        writer.writeData("]]>");
        writer.closeElement("Regle");

        writer.writeElement("Severity", new Pair("V", getSeverity()));
        if (getXPath() != null) {
            writer.writeElement("XPath", new Pair("V", getXPath()));
        }
        if (getXslParams() != null && getXslParams().size() > 0) {
            for (String key : getXslParams().keySet()) {
                String value = getXslParams().get(key).toString();
                writer.openElement("XslParam");
                writer.writeElement("Key", new Pair("V", key));
                writer.writeElement("Value", new Pair("V", value));
                writer.closeElement("XslParam");
            }
        }
        writer.closeElement("Anomalie");
    }
}
