/* ////////////////////////////////////////////////////////////////
*   
*   In the Name of Allah
*   
*   DICTIONARYFORMIDS-CREATOR
*   
*   This file is part of DictionaryForMIDs-Creator
*   Copyright (C) 2012 Karim Mahamane Karimou
*   DictionaryForMIDs-Creator is a GUI wrapper around various
*   DictionaryForMIDs tools, among others we have
*   DictdToDictionaryForMIDs, DictionaryGeneration,
*   JarCreator and BitmapFontGenerator.
*   
*   DictionaryForMIDs-Creator 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.
*   
*   DictionaryForMIDs-Creator 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 DictionaryForMIDs-Creator;
*   if not, write to the Free Software Foundation, Inc.,
*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*   
* //////////////////////////////////////////////////////////////// */


package de.kugihan.DfMCreator.utils;

import de.kugihan.DfMCreator.DfMCreatorMain;
import de.kugihan.dictionaryformids.dictgen.DictionaryGeneration;
import de.kugihan.dictionaryformids.general.DictionaryException;
import edu.hws.eck.mdb.I18n;
import java.awt.Cursor;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;


public class CheckCSVFileIntegrity extends javax.swing.JFrame implements PropertyChangeListener {
    
    // Variables used by checkCsvFileFormat()
    public static String csv_file_name;
    public static String encoding;
    public static char sepChar;
    public static int numOfLang;

    // variable that holds lets us know if the job is done
    private boolean done;
    
    // the actual task tha will be carried on
    Task csvCheck;
    
    /**
     * Creates new form CheckCSVFileIntegrity
     */
    public CheckCSVFileIntegrity() {
        initComponents();
    }

    /**
     * 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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel2 = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        checkButton = new javax.swing.JButton();
        browseButton = new javax.swing.JButton();
        numLang = new javax.swing.JComboBox();
        progressBar = new javax.swing.JProgressBar();
        tarea = new javax.swing.JTextField();
        sep = new javax.swing.JComboBox();
        enc = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setResizable(false);
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanel2.setLayout(new java.awt.GridBagLayout());

        jPanel1.setLayout(new java.awt.GridBagLayout());

        checkButton.setText(I18n.tr("check")); // NOI18N
        checkButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel1.add(checkButton, gridBagConstraints);

        browseButton.setText(I18n.tr("browse")); // NOI18N
        browseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        jPanel1.add(browseButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(jPanel1, gridBagConstraints);

        numLang.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }));
        numLang.setSelectedIndex(0);
        numLang.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                numLangItemStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(numLang, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        jPanel2.add(progressBar, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.ipadx = 250;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(tarea, gridBagConstraints);

        sep.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Tab", "Carriage Return", "Form Feed", "Comma", "Semi-Colon", "Colon" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(sep, gridBagConstraints);

        enc.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "UTF-8", "ISO-8859-1", "US-ASCII" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(enc, gridBagConstraints);

        jLabel1.setText(I18n.tr("availableLangs")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(jLabel1, gridBagConstraints);

        jLabel2.setText(I18n.tr("sepChars")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(jLabel2, gridBagConstraints);

        jLabel3.setText(I18n.tr("charEncoding")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(jLabel3, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.gridheight = 7;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(jPanel2, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void numLangItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_numLangItemStateChanged
        
    }//GEN-LAST:event_numLangItemStateChanged

    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
        String s = openFile(false);
        if (!"".equals(s)){
            tarea.setText(s);
        }
    }//GEN-LAST:event_browseButtonActionPerformed

    private void checkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkButtonActionPerformed
        checkCSVFileIntegrity();
    }//GEN-LAST:event_checkButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
       
        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
               // new CheckCSVFileIntegrity().setVisible(true);
            }
        });
    }
    
    public static CheckCSVFileIntegrity getCSVCheckWin(){
        return new CheckCSVFileIntegrity();
    }

    private void checkCSVFileIntegrity() {
        if ("".equals(tarea.getText())){
            try {
                throw new FileNotFoundException(I18n.tr("textFieldIsEmpty"));
            } catch (FileNotFoundException ex) {
                DfMCreatorMain.printAnyMsg(ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
        checkButton.setEnabled(false);
        browseButton.setEnabled(false);
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        done = false;
        // creating the task
        csvCheck = new Task();
        // running the task
        csvCheck.execute();
        csvCheck.addPropertyChangeListener(this);
        progressBar.setValue(csvCheck.getProgress());
    }

    
    class Task extends SwingWorker<Void, Void>{

        @Override
        protected Void doInBackground() throws Exception {
            try {
                csv_file_name = tarea.getText();
                encoding = enc.getSelectedItem().toString();
                numOfLang = Integer.parseInt(numLang.getSelectedItem().toString());
                String sep_Char = sep.getSelectedItem().toString();
               
		if (sep_Char.equals(I18n.tr("tab"))){
		    sepChar = '\t';
		} else if ( sep_Char.equals(I18n.tr("carRe"))){
		    sepChar ='\r';
		} else if (sep_Char.equals(I18n.tr("formFeed"))){
		    sepChar = '\f';
		} else if (sep_Char.equals(I18n.tr("comma"))){
		    sepChar = ',';
		} else if (sep_Char.equals(I18n.tr("semiColon"))){
		    sepChar = ';';
		} else if (sep_Char.equals(I18n.tr("colon"))){
		    sepChar = ':';
		} else {
		    sepChar = '\t';
		}        
                
                checkCsvFileFormat(csv_file_name, encoding, sepChar, numOfLang);
            } catch (DictionaryException | IOException ex) {
                System.out.println(ex.getMessage());
            }
            return null;
        }
        
        @Override
        protected void done(){
            done = true;
            Toolkit.getDefaultToolkit().beep();
            checkButton.setEnabled(true);
            browseButton.setEnabled(true);
            setCursor(null);
            progressBar.setIndeterminate(false);
            progressBar.setValue(progressBar.getMinimum());
        }    
    }
    
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (!done) {
            int progress = csvCheck.getProgress();
            if (progress == 0) {
                progressBar.setStringPainted(false);
                progressBar.setIndeterminate(true);
            }
            else {
                progressBar.setIndeterminate(false); 
                progressBar.setString(null);
                progressBar.setValue(progress);
            }            
        }
    }
    
    /**
     * checkCsvFileFormat() Copied from DictionaryGeneration in order
     * to adapt it to the GUI DfM-Creator. Checks a CSV file's integrity.
     * @param csvFileName the input csv-file's name.
     * @throws DictionaryException
     * @throws IOException 
     */
    public static void checkCsvFileFormat(String csvFileName, String encoding, char sepChar, int numLang) throws DictionaryException, IOException {
	System.out.println(I18n.tr("checking.msg", new Object[] {csvFileName}));
	InputStreamReader csvFile = new InputStreamReader(new FileInputStream(csvFileName), encoding);
	String csvFileLine;
	int lineCounter = 0;
	String splitCharacter = String.valueOf(sepChar);
	while ((csvFileLine = DictionaryGeneration.readLineFromReader(csvFile)) != null) {
		++lineCounter;
		// check if number of separator characters is correct
		int numberOfSeparatorCharacters = csvFileLine.split(splitCharacter).length - 1;
		if (numberOfSeparatorCharacters != (numLang -1)) {
		            String s = I18n.tr("numOfSepCharIncorrect", new Object[] {lineCounter, numberOfSeparatorCharacters, (numLang -1)});
                    DfMCreatorMain.printAnyMsg(s, I18n.tr("fileFormatIncorrectTitle"), JOptionPane.ERROR_MESSAGE);
                       
                    throw new DictionaryException(I18n.tr("fileFormatIsIncorrect"));
		}
	}
	csvFile.close();
	DfMCreatorMain.printAnyMsg(I18n.tr("done.Checking"),
                                 I18n.tr("done.Bang"), JOptionPane.INFORMATION_MESSAGE);
    }
    
    private String openFile(boolean dirsOnly) {
        String filename;
	JFileChooser chooser = new JFileChooser();
	if (dirsOnly) {
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
	} else {
            chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        }
	int valueReturned = chooser.showOpenDialog(this);
	if (valueReturned == JFileChooser.APPROVE_OPTION){
            filename = chooser.getSelectedFile().getAbsolutePath();
            return filename;
        }
        else {
            return "";
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browseButton;
    private javax.swing.JButton checkButton;
    private javax.swing.JComboBox enc;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JComboBox numLang;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JComboBox sep;
    private javax.swing.JTextField tarea;
    // End of variables declaration//GEN-END:variables
}
