/*
 * Copyright
 *   2008 axYus - www.axyus.com
 *   2008 C.Marchand - christophe.marchand@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.ui.searchParams;

import fr.gouv.finances.cp.xemelios.common.config.ChampModel;
import fr.gouv.finances.cp.xemelios.common.config.ListeResultatModel;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.DefaultCellEditor;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 *
 * @author  chm
 */
public class PnlSortBy extends javax.swing.JPanel implements CommonDataUpdater {
    private ListeResultatModel lrm;
//    private ArrayList<ChampModel> displayableChamps;
    private Vector<ChampModel> sortableChamps;
    private Vector<ChampTriable> champsTriables;
    private AbstractTableModel tm;
    private JComboBox cbxSortBy;
    
    /** Creates new form PnlSortBy */
    public PnlSortBy(ListeResultatModel lrm) {
        this.lrm=lrm;
        initComponents();
        initData();
        initListeners();
    }
    protected void initListeners() {
        pbUp.setEnabled(false);
        pbDown.setEnabled(false);
//        pbRemoveAll.setEnabled(false);
        pbRemoveOne.setEnabled(false);
//        pbAddAll.setEnabled(false);
        pbAddOne.setEnabled(false);
        lstChamps.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                if(lstChamps.getSelectedIndices().length==0) {
//                    pbAddAll.setEnabled(false);
                    pbAddOne.setEnabled(false);
                } else {
                    pbAddAll.setEnabled(true);
                    pbAddOne.setEnabled(true);
                }
            }
        });
    }
    public void initData() {
        cbxSortBy = new JComboBox(new String[] { "ASC", "DESC"});
        sortableChamps = new Vector<ChampModel>();
        List<ChampModel> champs = lrm.getListeChamps();
        for(ChampModel cm:champs) {
            if(cm.isTriable()) sortableChamps.add(cm);
        }
        champsTriables = new Vector<ChampTriable>();
        String triDefaut = lrm.getTriDefaut();
        String ordreDefaut = lrm.getOrdre();
        String champsTri[] = triDefaut.split(",");
        StringTokenizer to = new StringTokenizer(ordreDefaut,",");
        for(String ch:champsTri) {
            String or = to.nextToken();
            if(or==null) or = "ASC";
            champsTriables.add(new ChampTriable(ch, lrm.getChamps().get(ch).getLibelle(), or));
            sortableChamps.remove(lrm.getChamps().get(ch));
        }
        tm = new TriableTableModel(champsTriables);
        tblChampTries.setModel(tm);
        lstChamps.setListData(sortableChamps);
    }
    public void tableListSelectionChanged(ListSelectionEvent e) {
        if(tblChampTries.getSelectedRows().length==0) {
            pbUp.setEnabled(false);
            pbDown.setEnabled(false);
//            pbRemoveAll.setEnabled(false);
            pbRemoveOne.setEnabled(false);
        } else {
            pbUp.setEnabled(true);
            pbDown.setEnabled(true);
            pbRemoveAll.setEnabled(true);
            pbRemoveOne.setEnabled(true);
        }
    }
    /** 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">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        lstChamps = new javax.swing.JList();
        jScrollPane2 = new javax.swing.JScrollPane();
        tblChampTries = new org.jdesktop.swingx.JXTable() {
            public void valueChanged(ListSelectionEvent e) {
                super.valueChanged(e);
                tableListSelectionChanged(e);
            }
            public TableCellEditor getCellEditor(int row,int column) {
                if(column==0) return super.getCellEditor(row, column);
                else {
                    DefaultCellEditor dce = new DefaultCellEditor(cbxSortBy);
                    cbxSortBy.setSelectedItem(getValueAt(row,column));
                    return dce;
                }
            }
        };
        pbAddAll = new javax.swing.JButton();
        pbAddOne = new javax.swing.JButton();
        pbRemoveOne = new javax.swing.JButton();
        pbRemoveAll = new javax.swing.JButton();
        pbUp = new javax.swing.JButton();
        pbDown = new javax.swing.JButton();

        lstChamps.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(lstChamps);

        tblChampTries.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane2.setViewportView(tblChampTries);

        pbAddAll.setText(">>");
        pbAddAll.setToolTipText("Tout ajouter");
        pbAddAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbAddAllActionPerformed(evt);
            }
        });

        pbAddOne.setText(">");
        pbAddOne.setToolTipText("Ajouter");
        pbAddOne.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbAddOneActionPerformed(evt);
            }
        });

        pbRemoveOne.setText("<");
        pbRemoveOne.setToolTipText("Retirer");
        pbRemoveOne.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbRemoveOneActionPerformed(evt);
            }
        });

        pbRemoveAll.setText("<<");
        pbRemoveAll.setToolTipText("Tout retirer");
        pbRemoveAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbRemoveAllActionPerformed(evt);
            }
        });

        pbUp.setText("^");
        pbUp.setToolTipText("Monter");
        pbUp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbUpActionPerformed(evt);
            }
        });

        pbDown.setText("V");
        pbDown.setToolTipText("Descendre");
        pbDown.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbDownActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 267, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                        .add(org.jdesktop.layout.GroupLayout.TRAILING, pbAddOne, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(org.jdesktop.layout.GroupLayout.TRAILING, pbAddAll, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(org.jdesktop.layout.GroupLayout.TRAILING, pbRemoveAll, 0, 0, Short.MAX_VALUE)
                        .add(org.jdesktop.layout.GroupLayout.TRAILING, pbRemoveOne, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                        .add(org.jdesktop.layout.GroupLayout.TRAILING, pbDown, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(org.jdesktop.layout.GroupLayout.TRAILING, pbUp)))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 187, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
                    .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                        .add(pbAddAll)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(pbAddOne)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(pbRemoveOne)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(pbRemoveAll)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 118, Short.MAX_VALUE)
                        .add(pbUp)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(pbDown)))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void pbUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbUpActionPerformed
        boolean moved = false;
        int[] selectedRows = tblChampTries.getSelectedRows();
        for(int i=0;i<selectedRows.length;i++) {
            int row = selectedRows[i];
            if(row>i) {
                ChampTriable ch = champsTriables.remove(row);
                champsTriables.insertElementAt(ch, row-1);
                moved = true;
            }
        }
        if(moved) {
            tm.fireTableDataChanged();
            for(int i=0;i<selectedRows.length;i++) {
                int row = selectedRows[i];
                if(row>i) {
                    tblChampTries.getSelectionModel().addSelectionInterval(row-1, row-1);
                }
            }
        }
}//GEN-LAST:event_pbUpActionPerformed

    private void pbDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbDownActionPerformed
        // TODO: corriger cette méthode
        
        int[] selectedRows = tblChampTries.getSelectedRows();
        boolean moved = false;
        for(int i=selectedRows.length-1;i>=0;i--) {
            int row = selectedRows[i];
            if(row<champsTriables.size()-i-1) {
                ChampTriable ch = champsTriables.remove(row);
                if(row+1 < champsTriables.size())
                    champsTriables.insertElementAt(ch, row+1);
                else
                    champsTriables.add(ch);
                moved=true;
            }
        }
        if(moved) {
            tm.fireTableDataChanged();
            for(int i=selectedRows.length-1;i>=0;i--) {
                int row = selectedRows[i];
                if(row<champsTriables.size()-i) {
                    tblChampTries.getSelectionModel().addSelectionInterval(row+1, row+1);
                }
            }
        }
    }//GEN-LAST:event_pbDownActionPerformed

    private void pbAddAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbAddAllActionPerformed
        for(ChampModel cm:sortableChamps) {
            ChampTriable ct = new ChampTriable(cm.getId(), cm.getLibelle(), "ASC");
            champsTriables.add(ct);
        }
        sortableChamps.clear();
        lstChamps.setListData(sortableChamps);
        tm.fireTableDataChanged();
    }//GEN-LAST:event_pbAddAllActionPerformed

    private void pbAddOneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbAddOneActionPerformed
        int[] indexes = lstChamps.getSelectedIndices();
        for(int i:indexes) {
            ChampModel cm = sortableChamps.get(i);
            champsTriables.add(new ChampTriable(cm.getId(), cm.getLibelle(),"ASC"));
        }
        for(int i=indexes.length-1;i>=0;i--) sortableChamps.remove(indexes[i]);
        lstChamps.setListData(sortableChamps);
        tm.fireTableDataChanged();
    }//GEN-LAST:event_pbAddOneActionPerformed

    private void pbRemoveOneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbRemoveOneActionPerformed
        int[] indexes = tblChampTries.getSelectedRows();
        for(int i:indexes) {
            ChampTriable ct = champsTriables.get(i);
            ChampModel cm = lrm.getChamps().get(ct.id);
            sortableChamps.add(cm);
        }
        for(int i=indexes.length-1;i>=0;i--) champsTriables.remove(indexes[i]);
        lstChamps.setListData(sortableChamps);
        tm.fireTableDataChanged();
    }//GEN-LAST:event_pbRemoveOneActionPerformed

    private void pbRemoveAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbRemoveAllActionPerformed
        for(ChampTriable ct:champsTriables) {
            ChampModel cm = lrm.getChamps().get(ct.id);
            sortableChamps.add(cm);
        }
        champsTriables.clear();
        lstChamps.setListData(sortableChamps);
        tm.fireTableDataChanged();
    }//GEN-LAST:event_pbRemoveAllActionPerformed

    public void doUpdate() {
        StringBuffer fields = new StringBuffer();
        StringBuffer sorts = new StringBuffer();
        for(ChampTriable ct:champsTriables) {
            fields.append(ct.id).append(",");
            sorts.append(ct.sens).append(",");
        }
        if(fields.length()>0) {
            fields.deleteCharAt(fields.length()-1);
            sorts.deleteCharAt(sorts.length()-1);
        }
        lrm.setTriDefaut(fields.toString());
        lrm.setOrdre(sorts.toString());
    }
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JList lstChamps;
    private javax.swing.JButton pbAddAll;
    private javax.swing.JButton pbAddOne;
    private javax.swing.JButton pbDown;
    private javax.swing.JButton pbRemoveAll;
    private javax.swing.JButton pbRemoveOne;
    private javax.swing.JButton pbUp;
    private org.jdesktop.swingx.JXTable tblChampTries;
    // End of variables declaration//GEN-END:variables
    
    public static class ChampTriable {
        private String id, sens, desc;
        public ChampTriable(String id, String desc, String sens) {
            super();
            this.id=id;
            this.desc=desc;
            this.sens=sens;
        }
        @Override
        public String toString() { return desc; }
    }
    public static class TriableTableModel extends AbstractTableModel {
        private Vector<ChampTriable> champs;
        public TriableTableModel(Vector<ChampTriable> champs) {
//            super(champs,null);
            this.champs=champs;
        }

        @Override
        public String getColumnName(int column) {
            switch(column) {
                case 0: return "Champ";
                case 1: return "Sens";
            }
            return null;
        }

        public int getColumnCount() {
            return 2;
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return column==1;
        }

        public Object getValueAt(int row, int column) {
            ChampTriable ct = champs.get(row);
            switch(column) {
                case 0: return ct.toString();
                case 1: return ct.sens;
            }
            return null;
        }

        public int getRowCount() {
            return champs.size();
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return String.class;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            ChampTriable ct = champs.get(rowIndex);
            ct.sens = aValue.toString();
        }

    }
}
