/*
 * DlgGenPesPjs.java
 *
 * Created on 23 janvier 2008, 09:52
 */


package fr.gouv.finances.cp.xemelios.plugin.generatorPesPjs;

import fr.gouv.finances.cp.utils.Base64;
import fr.gouv.finances.cp.utils.Pair;
import fr.gouv.finances.cp.utils.xml.NamespaceContextImpl;
import fr.gouv.finances.cp.xemelios.common.config.DocumentModel;
import fr.gouv.finances.cp.xemelios.common.config.DocumentsModel;
import fr.gouv.finances.cp.xemelios.common.config.Loader;
import fr.gouv.finances.cp.xemelios.importers.EtatImporteur;
import fr.gouv.finances.cp.xemelios.ui.MainWindow;
import fr.gouv.finances.cp.xemelios.ui.MainWindow.ImportContent;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.filechooser.FileFilter;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.jdesktop.swingx.action.AbstractActionExt;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 *
 * @author  jp.tessier
 */
public class DlgGenPesPjs extends javax.swing.JDialog {
    
    private JFrame parentWindow;
    private TableModelPJ tableModel = new TableModelPJ();
    private static final String NAMESPACE_PES_ALLER = "http://www.minefi.gouv.fr/cp/helios/pes_v2/Rev0/aller";
    private static final String NAMESPACE_ENCRYPTED_DATA = "http://www.w3.org/2001/04/xmlenc#";
    private static final String NAMESPACE_PES_FACTURE = "http://www.minefi.gouv.fr/cp/helios/pes_v2/facture";
    private Action escapeAction,enterAction;
    private DocumentsModel docModels;
    private DocumentBuilderFactory domFactory;

     
    /** Creates new form DlgGenPesPjs */
    public DlgGenPesPjs(JFrame parent, boolean modal) {
        super(parent, modal);
        parentWindow = parent;
        initComponents();
        if(MainWindow.instance!=null){
            docModels = MainWindow.instance.getDocModels();
        }
        
        /* My initialisations */
        initTextFields();
	tablePjs.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        setLocationRelativeTo(parent);
        domFactory = DocumentBuilderFactory.newInstance();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        onglets = new javax.swing.JTabbedPane();
        PanelGeneral = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        fileToGenerate = new javax.swing.JTextField();
        idPost = new javax.swing.JTextField();
        idColl = new javax.swing.JTextField();
        finess = new javax.swing.JTextField();
        codColl = new javax.swing.JTextField();
        codBudg = new javax.swing.JTextField();
        libCollBudg = new javax.swing.JTextField();
        browse_button = new javax.swing.JButton();
        PanelPieces = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tablePjs = new JTable(){
            public void valueChanged(ListSelectionEvent evt) {
                super.valueChanged(evt);
                showHideButtons(evt);
            }
        };
        AddPJ = new javax.swing.JButton();
        editPJ = new javax.swing.JButton();
        deletePJ = new javax.swing.JButton();
        close_button = new javax.swing.JButton();
        save_button = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Générateur de flux PES PJ");

        onglets.setEnabled(false);
        onglets.setMaximumSize(new java.awt.Dimension(1024, 768));
        onglets.setMinimumSize(new java.awt.Dimension(300, 300));

        jLabel1.setText("Fichier à générer");

        jLabel2.setText("Identifiant du poste");

        jLabel3.setText("Identifiant Collectivité");

        jLabel4.setText("Finess Juridique");

        jLabel5.setText("Code Collectivité");

        jLabel6.setText("Code Budget");

        jLabel7.setText("Libellé Collectivité Budget");

        fileToGenerate.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                fileToGenerateCaretUpdate(evt);
            }
        });

        idPost.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                idPostCaretUpdate(evt);
            }
        });

        codColl.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                codCollCaretUpdate(evt);
            }
        });

        codBudg.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                codBudgCaretUpdate(evt);
            }
        });

        browse_button.setText("...");
        browse_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browse_buttonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout PanelGeneralLayout = new org.jdesktop.layout.GroupLayout(PanelGeneral);
        PanelGeneral.setLayout(PanelGeneralLayout);
        PanelGeneralLayout.setHorizontalGroup(
            PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(PanelGeneralLayout.createSequentialGroup()
                .add(49, 49, 49)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(jLabel7)
                    .add(jLabel2)
                    .add(jLabel3)
                    .add(jLabel4)
                    .add(jLabel5)
                    .add(jLabel6)
                    .add(jLabel1))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(idPost, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                    .add(idColl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                    .add(finess, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                    .add(codColl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                    .add(codBudg, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                    .add(libCollBudg, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, PanelGeneralLayout.createSequentialGroup()
                        .add(fileToGenerate, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 272, Short.MAX_VALUE)
                        .add(18, 18, 18)
                        .add(browse_button)))
                .addContainerGap())
        );
        PanelGeneralLayout.setVerticalGroup(
            PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(PanelGeneralLayout.createSequentialGroup()
                .add(27, 27, 27)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel1)
                    .add(browse_button)
                    .add(fileToGenerate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(12, 12, 12)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel2)
                    .add(idPost, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel3)
                    .add(idColl, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel4)
                    .add(finess, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel5)
                    .add(codColl, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel6)
                    .add(codBudg, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(PanelGeneralLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel7)
                    .add(libCollBudg, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(39, Short.MAX_VALUE))
        );

        onglets.addTab("Généralités", PanelGeneral);

        tablePjs.setModel(tableModel);
        tablePjs.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tablePjsMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(tablePjs);

        AddPJ.setText("Ajouter");
        AddPJ.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AddPJActionPerformed(evt);
            }
        });

        editPJ.setText("Editer");
        editPJ.setEnabled(false);
        editPJ.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editPJActionPerformed(evt);
            }
        });

        deletePJ.setText("Supprimer");
        deletePJ.setEnabled(false);
        deletePJ.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deletePJActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout PanelPiecesLayout = new org.jdesktop.layout.GroupLayout(PanelPieces);
        PanelPieces.setLayout(PanelPiecesLayout);
        PanelPiecesLayout.setHorizontalGroup(
            PanelPiecesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(PanelPiecesLayout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE)
                .add(18, 18, 18)
                .add(PanelPiecesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(deletePJ, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
                    .add(editPJ, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
                    .add(AddPJ, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE))
                .addContainerGap())
        );
        PanelPiecesLayout.setVerticalGroup(
            PanelPiecesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, PanelPiecesLayout.createSequentialGroup()
                .add(51, 51, 51)
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 221, Short.MAX_VALUE)
                .add(33, 33, 33))
            .add(org.jdesktop.layout.GroupLayout.TRAILING, PanelPiecesLayout.createSequentialGroup()
                .addContainerGap(104, Short.MAX_VALUE)
                .add(AddPJ)
                .add(27, 27, 27)
                .add(editPJ)
                .add(27, 27, 27)
                .add(deletePJ)
                .add(78, 78, 78))
        );

        onglets.addTab("Pièces Justificatives", PanelPieces);

        close_button.setText("Fermer");
        close_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                close_buttonActionPerformed(evt);
            }
        });

        save_button.setText("Enregistrer");
        save_button.setEnabled(false);
        save_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                save_buttonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(onglets, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap())
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(close_button)
                        .add(18, 18, 18)
                        .add(save_button)
                        .add(14, 14, 14))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(onglets, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(save_button)
                    .add(close_button))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    
    private void fileToGenerateCaretUpdate(javax.swing.event.CaretEvent evt) {                                           
        doCheck();
    }                                          

    private void idPostCaretUpdate(javax.swing.event.CaretEvent evt) {                                   
        doCheck();
    }                                  

    private void codCollCaretUpdate(javax.swing.event.CaretEvent evt) {                                    
        doCheck();
    }                                   

    private void codBudgCaretUpdate(javax.swing.event.CaretEvent evt) {                                    
        doCheck();
    }                                   

    private void AddPJActionPerformed(java.awt.event.ActionEvent evt) {                                      
        DlgMakePJ makePj = new DlgMakePJ(parentWindow, true);
        makePj.setIdCollIdPostCodBud(idColl.getText(),idPost.getText(),codColl.getText(),codBudg.getText());
        if(makePj.run()) {
            tableModel.add(makePj.getPiece_justificative());
        }
    }                                     

    private void editPJActionPerformed(java.awt.event.ActionEvent evt) {                                       
        editPJ();
    }                                      

    private void deletePJActionPerformed(java.awt.event.ActionEvent evt) {                                         
        tableModel.remove(tablePjs.getSelectedRow());
    }                                        

    private void close_buttonActionPerformed(java.awt.event.ActionEvent evt) {                                             
        this.dispose();
    }                                            

    private void save_buttonActionPerformed(java.awt.event.ActionEvent evt) {                                            
        saveFluxPESPJ();
    }                                           

    private void browse_buttonActionPerformed(java.awt.event.ActionEvent evt) {                                              
        JFileChooser fc = new JFileChooser();
        
            fc.addChoosableFileFilter(new FileFilter() {

                public boolean accept(File f) {
                    return f.isDirectory() || f.getName().toUpperCase().endsWith("XML");
                }

                public String getDescription() {
                    return "Document XML";
                }
            });
      
        int reponse = fc.showOpenDialog(this);
        if(reponse==JFileChooser.APPROVE_OPTION) {
            fileToGenerate.setText(fc.getSelectedFile().getAbsolutePath().toUpperCase().contains(".XML")==true?fc.getSelectedFile().getAbsolutePath():fc.getSelectedFile().getAbsolutePath()+".xml");
        }
    }                                             

    private void tablePjsMouseClicked(java.awt.event.MouseEvent evt) {                                      
         if(tablePjs.getSelectedRow() != -1 && evt.getClickCount() == 2 && evt.getButton() == MouseEvent.BUTTON1){
            editPJ();
        }
    }                                     
    
    private void editPJ(){
        DlgMakePJ dlgMakePJ = new DlgMakePJ(parentWindow,true);
        int rowSeleted = tablePjs.getSelectedRow();
        if(dlgMakePJ.runEdit(tableModel.getData(rowSeleted))) {
            tableModel.refresh();
        }        
    }
    
    private void saveFluxPESPJ(){
        if(formIsValid()){
            try {
                startVentilateur();
                setPropertiesGeneratorPESPJs();
                Document doc = createDOMdoc();

                // Ecriture du DOM dans un fichier
                TransformerFactory tf = TransformerFactory.newInstance();
                
                Transformer trans = tf.newTransformer();
                Properties props = new Properties();
                props.setProperty(OutputKeys.ENCODING,"ISO-8859-1");
                props.setProperty(OutputKeys.INDENT,"yes");
                props.setProperty(OutputKeys.METHOD,"xml");
                trans.setOutputProperties(props);
                
                trans.transform(new DOMSource(doc),new StreamResult(new File(fileToGenerate.getText())));
                    
                stopVentilateur();
                if (MainWindow.instance != null) {
                    int response = JOptionPane.showConfirmDialog(parentWindow, "Le flux PES PJ à bien été généré.\n\nDésirez vous l'importer ?", "Importation du flux PES PJ généré", JOptionPane.YES_NO_OPTION);
                    if (JOptionPane.YES_OPTION == response) {
                        importer(docModels.getDocumentById("PES_Aller"), new Pair(idColl.getText(), libCollBudg.getText()), new Pair(codBudg.getText(), libCollBudg.getText()), new File(fileToGenerate.getText()));
                        this.setVisible(false);
                    }
                } else {
                    JOptionPane.showMessageDialog(parentWindow, "Le flux PES PJ à bien été généré.", "Génération du flux PES PJ", JOptionPane.OK_OPTION);
                }

                resetDialog();
            } catch (TransformerException ex) {
                Logger.getLogger(DlgGenPesPjs.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    } 
    
      private void importer(DocumentModel dm,Pair coll,Pair budg,File f) {
        try {
            Class clazz = Class.forName(dm.getImportClass());
            Object obj = clazz.newInstance();
            if(!(obj instanceof EtatImporteur)) {
                JOptionPane.showMessageDialog(MainWindow.instance,"Cette classe n'est pas un importeur.\nLe fichier de configuration qui vous a été livré est certainement invalide.\nVeuillez contacter votre fournisseur.\n","Erreur",JOptionPane.ERROR_MESSAGE);
                return;
            }
            EtatImporteur ei = (EtatImporteur)obj;
            ei.setDocument(dm,coll,budg);
            ArrayList<File> array = new ArrayList<File>();
            array.add(f);
            ImportContent fToImport = new ImportContent();
            fToImport.setFilesToImport(array);
            
            MainWindow.instance.doImport(ei,fToImport,dm,true);
            
        } catch(Exception ex) {
            ex.printStackTrace();
        } finally {
            
        }
    }
    
    protected DocumentsModel getDocumentsInfosGenPesPjs(String repertoires) {
        DocumentsModel ret = null;
        try {
            ret = Loader.getDocumentsInfos(repertoires);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        return ret;
    }
      
    private void setPropertiesGeneratorPESPJs(){
        FileOutputStream fos = null;
        try {
            File f = new File(System.getProperty("user.home"),"xemelios-PJ-generator.properties");
            System.out.println("fichier de proprietes dans : "+f.getAbsolutePath());
           
            Properties props = new Properties();

            if(f.exists()){
                FileInputStream fis = new FileInputStream(f);
                props.load(fis);
                fis.close();
            }
            
            fos = new FileOutputStream(f);
                
            props.setProperty("idpost", idPost.getText());
            props.setProperty("idcoll", idColl.getText());
            props.setProperty("finess", finess.getText());
            props.setProperty("codcoll", codColl.getText());
            props.setProperty("codbudg", codBudg.getText());
            props.setProperty("libcodbudg", libCollBudg.getText());
            
            props.store(fos,"");
            
            fos.flush();
            fos.close();

        } catch (IOException ex) {
            //Logger.getLogger(DlgGenPesPjs.class.getName()).log(Level.FATAL, null, ex);
            ex.printStackTrace();
        }
    }   
    
    private void resetDialog(){
        for(int i=0;i<tableModel.getRowCount();i++){
                tableModel.remove(i);
        }
        onglets.setSelectedIndex(0);
        fileToGenerate.setText("");
        onglets.setEnabled(false);
        doCheck();
    }
    
    private void showHideButtons(ListSelectionEvent evt){
        if(evt.getFirstIndex() >= 0 && tablePjs.getSelectedRow() != -1){
           editPJ.setEnabled(true); 
           deletePJ.setEnabled(true); 
        }else{
           editPJ.setEnabled(false); 
           deletePJ.setEnabled(false); 
        }
    }
    
    private Document createDOMdoc() {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.newDocument();

            Element root = doc.createElementNS(NAMESPACE_PES_ALLER,"n:PES_Aller");
            
            root.setAttribute("xmlns:n",NAMESPACE_PES_ALLER);
            //root.setAttribute("xmlns:enc",NAMESPACE_ENCRYPTED_DATA);
            
            doc.appendChild(root);

            createEnveloppe(doc);
            createEntetePES(doc);
            if(tableModel.getRowCount()>0){
                createPES_PJ(doc);
            }
                
            return doc;

        } catch (ParserConfigurationException ex) {
            //Logger.getLogger(DlgGenPesPjs.class.getName()).log(Level.FATAL, null, ex);
            ex.printStackTrace();
        }
        return null;
    }
    
    private void createEnveloppe(Document doc){
        Element enveloppe = doc.createElementNS("","Enveloppe");
        
        Element parametre = doc.createElementNS("","Parametres");
        
        Element version = doc.createElementNS("","Version");
        version.setAttribute("V","01");
        
        Element typeFic = doc.createElementNS("","TypFic");
        typeFic.setAttribute("V","PES_PJ");
        
        Element nomFic = doc.createElementNS("","NomFic");
        nomFic.setAttribute("V",new File(fileToGenerate.getText()).getName());
        
        parametre.appendChild(version);
        parametre.appendChild(typeFic);
        parametre.appendChild(nomFic);
        enveloppe.appendChild(parametre);
        
        doc.getChildNodes().item(0).appendChild(enveloppe);
    }
    
    private void createEntetePES(Document doc){
        Element entetePES = doc.createElementNS("","EnTetePES");
        
        Element dteStr = doc.createElementNS("","DteStr");
        dteStr.setAttribute("V",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        
        Element idPoste=null;
        if(idPost.getText().length()!=0){
            idPoste = doc.createElementNS("","IdPost");
            idPoste.setAttribute("V",idPost.getText());
        }
                
        Element idCollec=null;
        if(idColl.getText().length()!=0){
            idCollec = doc.createElementNS("","IdColl");
            idCollec.setAttribute("V",idColl.getText());
        }
        
        Element finJur=null;
        if(finess.getText().length()!=0){
            finJur = doc.createElementNS("","FinJur");
            finJur.setAttribute("V",finess.getText());
        }
        
        Element codCollec=null;
        if(codColl.getText().length()!=0){
            codCollec = doc.createElementNS("","CodCol");
            codCollec.setAttribute("V",codColl.getText());
        }
        
        Element codBud=null;
        if(codBudg.getText().length()!=0){
            codBud = doc.createElementNS("","CodBud");
            codBud.setAttribute("V",codBudg.getText());        
        }
        
        Element libelleColBud=null;
        if(libCollBudg.getText().length()!=0){
            libelleColBud = doc.createElementNS("","LibelleColBud");
            libelleColBud.setAttribute("V",libCollBudg.getText());  
        }
        
        
        entetePES.appendChild(dteStr);
        if(idPoste!=null)entetePES.appendChild(idPoste);
        if(idCollec!=null)entetePES.appendChild(idCollec);
        if(finJur!=null)entetePES.appendChild(finJur);
        if(codCollec!=null)entetePES.appendChild(codCollec);
        if(codBud!=null)entetePES.appendChild(codBud);
        if(libelleColBud!=null)entetePES.appendChild(libelleColBud);
        
        doc.getChildNodes().item(0).appendChild(entetePES);
    }
    
    private void createPES_PJ(Document doc){
        try {
            Element PES_PJ = doc.createElementNS("","PES_PJ");
            
            Element entetePES_PJ = doc.createElementNS("","EnTetePES_PJ");
            Element idVer = doc.createElementNS("","IdVer");
            idVer.setAttribute("V", "1");
            entetePES_PJ.appendChild(idVer);

            PES_PJ.appendChild(entetePES_PJ);

            createPJs(doc,PES_PJ);

            doc.getChildNodes().item(0).appendChild(PES_PJ);
        } catch (IOException ex) {
            //Logger.getLogger(DlgGenPesPjs.class.getName()).log(Level.FATAL, null, ex);
            ex.printStackTrace();
        }
    }
    
    private void createPJs(Document doc,Element pes_pj) throws IOException{
        Vector<Element> vpce = new Vector<Element>();
        Element contenu;
        
        for(int i = 0;i<tableModel.getRowCount();i++){
            PJ pj = tableModel.getData(i);
            contenu = doc.createElementNS("","Contenu");
            Element pce = doc.createElementNS("","PJ");
            
            // Si ce n'est pas une facture, compression de la pj et encodage en base64 de son contenu
            if (!(pj.getTypePJ().contains("Facture"))) {
                
                Element fichier = doc.createElementNS("","Fichier");
                fichier.setAttributeNS("","MIMEType",pj.getPjFile().getName().substring(pj.getPjFile().getName().length()-3,pj.getPjFile().getName().length()));
                // Creation d'un inputStream sur la PJ
                FileInputStream fis = new FileInputStream(pj.getPjFile());
                
                // Creation du gzip et d'un outputStream
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                GZIPOutputStream gzo = new GZIPOutputStream(baos);
                
                // Lecture de la PJ et remplissage du gzip
                byte[] bTmp = new byte[2048];
                int read = 0;
                do {
                    read = fis.read(bTmp);
                    if (read > 0) {
                        gzo.write(bTmp, 0, read);
                    }
                } while (read > 0);

                fis.close();
                gzo.finish();
                gzo.flush();
                gzo.close();
                
                //System.out.println(Base64.encodeBytes(baos.toByteArray(),true));
                Text txt = doc.createTextNode(Base64.encodeBytes(baos.toByteArray(),true));
                fichier.appendChild(txt);
                
                baos.close();
                
                contenu.appendChild(fichier);
                pce.appendChild(contenu);
                
            } else {
                try {
                    // Creation d'un InputStream pour lire la PJ
                    FileInputStream fis = new FileInputStream(pj.getPjFile());
                   
                    // Parssage de la PJ
//                    DOMParser domp = new DOMParser();
//                    domp.parse(new InputSource(fis));
                          
                    DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
                    Document document = domBuilder.parse(new InputSource(fis));
                    
                    // on vérifie que c'est bien un PES_Facture
                    XPathFactory xpf = XPathFactory.newInstance();
                    XPath xp = xpf.newXPath();
                    NamespaceContextImpl ns = new NamespaceContextImpl();
                    ns.addMapping("", NAMESPACE_PES_FACTURE);
                    ns.addMapping("n", NAMESPACE_PES_FACTURE);
                    xp.setNamespaceContext(ns);
                    Element pesFacture = (Element)xp.evaluate("/n:PESFacture", document,XPathConstants.NODE);
                    if(pesFacture==null) throw new SAXException("ce n'est pas un PES Facture");
                    Node node = doc.adoptNode(pesFacture);
                    
                    // Ajout de la PJ
                    contenu.appendChild(node);
                    pce.appendChild(contenu);
                    
                } catch(ParserConfigurationException pcEx) {
                    Logger.getLogger(DlgGenPesPjs.class.getName()).log(Level.SEVERE,"while instanciating new dom parser",pcEx);
                } catch (Exception ex) {
                    //Logger.getLogger(DlgGenPesPjs.class.getName()).log(Level.FATAL, null, ex);
                    //ex.printStackTrace();
                    // ce n'est pas un fichier XML, on le met alors en binaire
                    Element fichier = doc.createElementNS("","Fichier");
                    fichier.setAttributeNS("","MIMEType",pj.getPjFile().getName().substring(pj.getPjFile().getName().length()-3,pj.getPjFile().getName().length()));
                    // Creation d'un inputStream sur la PJ
                    FileInputStream fis = new FileInputStream(pj.getPjFile());

                    // Creation du gzip et d'un outputStream
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    GZIPOutputStream gzo = new GZIPOutputStream(baos);

                    // Lecture de la PJ et remplissage du gzip
                    byte[] bTmp = new byte[2048];
                    int read = 0;
                    do {
                        read = fis.read(bTmp);
                        if (read > 0) {
                            gzo.write(bTmp, 0, read);
                        }
                    } while (read > 0);

                    fis.close();
                    gzo.finish();
                    gzo.flush();
                    gzo.close();

                    //System.out.println(Base64.encodeBytes(baos.toByteArray(),true));
                    Text txt = doc.createTextNode(Base64.encodeBytes(baos.toByteArray(),true));
                    fichier.appendChild(txt);

                    baos.close();

                    contenu.appendChild(fichier);
                    pce.appendChild(contenu);
                }
            }
            
            // Creation des éléments fils de la PES_PJ
            Element idUnique = doc.createElementNS("","IdUnique");
            idUnique.setAttribute("V",pj.getIdentifiant());
            
            Element nomPJ = doc.createElementNS("","NomPJ");
            nomPJ.setAttribute("V",pj.getPjFile().getName());
            
            Element typePJ = doc.createElementNS("","TypePJ");
            typePJ.setAttribute("V",pj.getTypePJ().split(" - ")[0]);
            
            Element desc = doc.createElementNS("","Description");
            desc.setAttribute("V",pj.getDescription());
            
            pce.appendChild(idUnique);
            pce.appendChild(nomPJ);
            pce.appendChild(typePJ);
            pce.appendChild(desc);
            
            createRefsComptas(doc,pj,pce);
            
            vpce.add(pce);
        }
        for(Element e:vpce){
            pes_pj.appendChild(e);
        }
    }
    
    private void createRefsComptas(Document doc,PJ pj,Element pce){
        for(RefCompta rc:pj.getVRefsComptas()){
            Element refCompta = doc.createElementNS("","RefCompta");
            
            Element domaine = doc.createElementNS("","Domaine");
            domaine.setAttribute("V",rc.getDomaine().split(" - ")[0]);
            
            Element exer = doc.createElementNS("","Exercice");
            exer.setAttribute("V",rc.getExercice().toString());
            
            
            Element typObj = doc.createElementNS("","TypeObjet");
            typObj.setAttribute("V",rc.getTypePiece().key);
            
            Element id = doc.createElementNS("","Identifiant");
            id.setAttribute("V",rc.getNumPiece().toString());
            
            Element complId;
            if(rc.getNumLignePiece().length()!=0){
                complId = doc.createElementNS("","ComplementIdentifiant");
                complId.setAttribute("V",rc.getNumLignePiece().toString());
            }else{
                complId=null;
            }
            
            Element codProd;
            if(rc.getCodeProduit().length()!=0){
                codProd = doc.createElementNS("","CodProd");
                codProd.setAttribute("V",rc.getCodeProduit());
            }else{
                codProd=null;
            }            
            
            Element idTiers;
            if(rc.getIdTiers().length()!=0){
                idTiers = doc.createElementNS("","IdTiers");
                idTiers.setAttribute("V",rc.getIdTiers());
            }else{
                idTiers=null;
            }
            
            refCompta.appendChild(domaine);
            refCompta.appendChild(exer);
            refCompta.appendChild(typObj);
            refCompta.appendChild(id);
            if(complId!=null)refCompta.appendChild(complId);
            if(codProd!=null)refCompta.appendChild(codProd);
            if(idTiers!=null)refCompta.appendChild(idTiers);
            
            pce.appendChild(refCompta);
        }
    }
    
    private void initTextFields() {
        String configFileName = System.getProperty("user.home");
        
        File f = new File(configFileName,"xemelios-PJ-generator.properties");
            
        if(f.exists()){
            Properties props = new Properties();
            System.out.println("in initTextFields()");
            try {
                props.load(new FileInputStream(f));
                
                idPost.setText(props.getProperty("idpost"));
                idColl.setText(props.getProperty("idcoll"));
                finess.setText(props.getProperty("finess"));
                codColl.setText(props.getProperty("codcoll"));
                codBudg.setText(props.getProperty("codbudg"));
                libCollBudg.setText(props.getProperty("libcollbudg"));
            } catch (FileNotFoundException ex) {
                System.out.println("Fichier " + configFileName + " introuvable!");
            } catch (IOException ex) {
                ex.getMessage();
            }
        }
        
        doCheck();
    }
    
    private void doCheck(){
        if (fileToGenerate.getText().length() > 0 && idPost.getText().length() > 0 && codColl.getText().length() > 0 && codBudg.getText().length() > 0) {
           onglets.setEnabled(true);
           save_button.setEnabled(true);
        } else {
           onglets.setEnabled(false);
           save_button.setEnabled(false);
        }
    }
    
    private boolean formIsValid(){
        String message = "";
        JTextField jtf=null;
        if(!(fileToGenerate.getText().toUpperCase().endsWith(".XML"))){
            message = "Le nom du fichier est incorrect.\nIl doit se terminer pas .XML";
            jtf = fileToGenerate;
        }else if(idPost.getText().length() > 7){
            message = "L'identifiant du poste ne peut excéder 7 caractères.";
            jtf = idPost;
        }else if(idPost.getText().length() == 0){
            message = "L'identifiant du poste est obligatoire.";
            jtf = idPost;
        }else if(codColl.getText().length() == 0){
            message = "Le code de la collectivité est obligatoire.";
            jtf = codColl;
        }else if(codColl.getText().length() > 3){
            message = "Le code de la collectivité ne peut excéder 3 caractères.";
            jtf = codColl;
        }else if(!(codColl.getText().matches("[0-9a-zA-Z]*"))){
            message = "Le code de la collectivité ne peut contenir que les caractères suivants:\n\n" +
                        "Des chiffres de 0 à 9\n" +
                        "Des lettres de a à z ou de A à Z";
            jtf = codColl;
        }else if(codBudg.getText().length() == 0){
            message = "Le code du budget est obligatoire.";
            jtf = codBudg;
        }else if(codBudg.getText().length() > 2){
            message = "Le code du budget ne peut excéder 2 caractères.";
            jtf = codBudg;
        }else if(!(codBudg.getText().matches("[0-9a-zA-Z]*"))){
            message = "Le code du budget ne peut contenir que les caractères suivants:\n\n" +
                        "Des chiffres de 0 à 9\n" +
                        "Des lettres de a à z ou de A à Z";
            jtf = codBudg;
        } else {
            return true;
        }
        JOptionPane.showMessageDialog(this,message,"Erreur de saisie d'informations",JOptionPane.ERROR_MESSAGE);
        if(onglets.getSelectedIndex() == 1){
            onglets.setSelectedIndex(0);
        }
        jtf.requestFocus();
        return false;
    }

    public void stopVentilateur() {
        getGlassPane().setVisible(false);
    }
    
    public void startVentilateur() {
        getGlassPane().setVisible(true);
    }
        
    public void run() {
        setVisible(true);
    }
    
    @Override
    protected JRootPane createRootPane() {    
        KeyStroke ksEsc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
        KeyStroke ksEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0);
        
	JRootPane rp = new JRootPane();
        escapeAction = new AbstractActionExt("Fermer") {
		    /**
             * Comment for <code>serialVersionUID</code>
             */
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent evt) {
		        setVisible(false);
            }

            public void itemStateChanged(ItemEvent e) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

      	};
        
        enterAction = new AbstractActionExt("Save") {
		    /**
             * Comment for <code>serialVersionUID</code>
             */
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent evt) {
		        saveFluxPESPJ();
		    }

            public void itemStateChanged(ItemEvent e) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

        	};
	rp.registerKeyboardAction(escapeAction,"TOTOTOTO",ksEsc,JComponent.WHEN_IN_FOCUSED_WINDOW);
        rp.registerKeyboardAction(enterAction,"TOTOTOTO",ksEnter,JComponent.WHEN_IN_FOCUSED_WINDOW);
	return rp;
    }
        
    // Variables declaration - do not modify                     
    private javax.swing.JButton AddPJ;
    private javax.swing.JPanel PanelGeneral;
    private javax.swing.JPanel PanelPieces;
    private javax.swing.JButton browse_button;
    private javax.swing.JButton close_button;
    private javax.swing.JTextField codBudg;
    private javax.swing.JTextField codColl;
    private javax.swing.JButton deletePJ;
    private javax.swing.JButton editPJ;
    private javax.swing.JTextField fileToGenerate;
    private javax.swing.JTextField finess;
    private javax.swing.JTextField idColl;
    private javax.swing.JTextField idPost;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField libCollBudg;
    private javax.swing.JTabbedPane onglets;
    private javax.swing.JButton save_button;
    private javax.swing.JTable tablePjs;
    // End of variables declaration                   
    
}
