/*
 * NotesAccessory.java
 *
 * Created on August 7, 2008, 3:30 PM
 */
package usda.weru.weps.reports;

import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileReader;
import de.schlichtherle.truezip.file.TFileWriter;
import java.awt.Cursor;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.apache.log4j.Logger;
import usda.weru.weps.RunFileData;
import usda.weru.weps.reports.query.NotesResultSet;
import net.sf.jasperreports.view.JRSaveContributor;
import net.sf.jasperreports.view.save.JRPrintSaveContributor;
import javax.swing.filechooser.FileFilter;
import net.sf.jasperreports.engine.JRException;

/**
 *
 * @author  joelevin
 */
public class SummaryAccessory extends javax.swing.JPanel implements ReportViewerListener {

    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = Logger.getLogger(SummaryAccessory.class);

    /**
     *
     */
    public static final String PROP_MODIFIED = "modified";

    /**
     *
     */
    public static final String PROP_READING = "reading";

    /**
     *
     */
    protected boolean c_reading;

    /**
     *
     */
    protected TFile c_notesFile;

    /**
     *
     */
    protected TFile c_warningsFile;

    /**
     *
     */
    protected int c_notesHashcode;

    /**
     *
     */
    protected boolean c_modified;

    /**
     *
     */
    protected ReportPack c_pack;
    
    private JRViewerBean viewer;
    
    private String pdfPath;

    /** Creates new form NotesAccessory
     * @param pack 
     */
    public SummaryAccessory(ReportPack pack, ReportViewer inViewer) {
        initComponents();
        c_pack = pack;

        notesTextArea.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                updateModified();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateModified();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateModified();
            }

            private void updateModified() {
                setModified((notesTextArea.getText().hashCode() != c_notesHashcode));
            }
        });
        updateFileReference();
        viewer = inViewer.getBean();
        
        String path = inViewer.getpath();
        pdfPath = path + "\\run.pdf";

    }

    private void updateFileReference() {
        if (c_pack.getConnection() != null) {
            TFile[] files = c_pack.getConnection().getRunFiles();
            if (files != null && files.length > 0) {
                c_notesFile = new TFile(files[0], RunFileData.NotesFileName);
                c_warningsFile = new TFile(files[0], RunFileData.WarningsFile);
                readNotes();
                readWarnings();
                return;
            }
        }
        c_notesFile = null;
        readNotes();
        readWarnings();
    }

    /**
     *
     * @param modified
     */
    public void setModified(boolean modified) {
        boolean old = c_modified;
        c_modified = modified;
        firePropertyChange(PROP_MODIFIED, old, c_modified);
        saveButton.setEnabled(c_notesFile != null && c_modified);
    }

    /**
     *
     * @return
     */
    public boolean isModified() {
        return c_modified;
    }

    /**
     *
     * @param reading
     */
    protected void setReading(boolean reading) {
        if (reading) {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        } else {
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
        boolean old = c_reading;
        c_reading = reading;
        firePropertyChange(PROP_READING, old, c_reading);
    }

    /**
     *
     * @return
     */
    public boolean isReading() {
        return c_reading;
    }

    /**
     *
     */
    public void readWarnings() {
        warningsTextArea.setText("");
        if (c_warningsFile != null && c_warningsFile.exists()) {
            if (!warningsPanel.isAncestorOf(tabPane)) {
                tabPane.add(warningsPanel);
                tabPane.setTitleAt(tabPane.indexOfComponent(warningsPanel), "Warnings");
            }
            BufferedReader in = null;
            try {
                in = new BufferedReader(new TFileReader(c_warningsFile));

                StringBuilder buffer = new StringBuilder();
                boolean first = true;
                String line;
                while ((line = in.readLine()) != null) {
                    if (!first) {
                        buffer.append("\n");
                    }
                    buffer.append(line);
                    first = false;
                }

                warningsTextArea.setText(buffer.toString());
            } catch (IOException ioe) {
                LOGGER.error("Error reading warnings file: " + c_warningsFile.getAbsolutePath(), ioe);
                warningsTextArea.setText("Error reading warnings file.");
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        LOGGER.error("Error closing warnings file: " + c_warningsFile.getAbsolutePath(), e);
                    }
                }
            }
        } else {
            tabPane.remove(warningsPanel);
        }
    }

    /**
     *
     */
    public void readNotes() {

        notesTextArea.setText("");
        if (c_notesFile != null && c_notesFile.exists()) {
            BufferedReader in = null;
            try {
                setReading(true);
                in = new BufferedReader(new TFileReader(c_notesFile));

                StringBuilder buffer = new StringBuilder();
                boolean first = true;
                String line;
                while ((line = in.readLine()) != null) {
                    if (!first) {
                        buffer.append("\n");
                    }
                    buffer.append(line);
                    first = false;
                }

                notesTextArea.setText(buffer.toString());
                c_notesHashcode = notesTextArea.getText().hashCode();
            } catch (IOException ioe) {
                LOGGER.error("Error reading notes file: " + c_notesFile.getAbsolutePath(), ioe);
                notesTextArea.setText("Error reading notes file.");
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (Exception e) {
                        LOGGER.error("Error closing notes file: " + c_notesFile.getAbsolutePath(), e);
                    }
                }
                setReading(false);
            }
        }
        setModified(false);

    }

    /**
     *
     */
    public void saveNotes() {
        //TODO: if the report is listed in the pdf list, also recreate the pdf file
        BufferedWriter out = null;
        try {
            if(!c_notesFile.canWrite()) 
            {
                JOptionPane.showMessageDialog(this, 
                    "Notes file is not writable.", "Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }
            out = new BufferedWriter(new TFileWriter(c_notesFile));
            out.write(notesTextArea.getText());
            //update the hashcode
            c_notesHashcode = notesTextArea.getText().hashCode();

        } catch (IOException ioe) {
            LOGGER.error("Error saving notes file: " + c_notesFile.getAbsolutePath(), ioe);
            JOptionPane.showMessageDialog(this, "Unable to save notes.", "Error", JOptionPane.ERROR_MESSAGE);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    LOGGER.error("Error closing notes file: " + c_notesFile.getAbsolutePath(), e);
                }
            }

        }
        //Clear the notes table
        c_pack.getConnection().clearWepsData(NotesResultSet.NAME);
        //Tell the viewer to update
        c_pack.startFill();
        ReportManager.getDefault().generateReportPDF(c_pack, new TFile(c_notesFile.getParentFile()));
        setModified(false);
        
        btnSaveActionPerformed(null);
    }

    /**
     *
     * @param enabled
     */
    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        notesScrollPane.setEnabled(enabled);
        notesTextArea.setEnabled(enabled);

    }

    /** 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() {

        tabPane = new javax.swing.JTabbedPane();
        notesPanel = new javax.swing.JPanel();
        notesToolbar = new javax.swing.JToolBar();
        saveButton = new javax.swing.JButton();
        notesScrollPane = new javax.swing.JScrollPane();
        notesTextArea = new javax.swing.JTextArea();
        warningsPanel = new javax.swing.JPanel();
        warningsScrollPane = new javax.swing.JScrollPane();
        warningsTextArea = new javax.swing.JTextArea();

        notesToolbar.setFloatable(false);
        notesToolbar.setRollover(true);

        saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/usda/weru/resources/save.gif"))); // NOI18N
        saveButton.setText("Save Notes");
        saveButton.setFocusable(false);
        saveButton.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        saveButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });
        notesToolbar.add(saveButton);

        notesScrollPane.setEnabled(false);

        notesTextArea.setColumns(20);
        notesTextArea.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        notesTextArea.setRows(10);
        notesTextArea.setBorder(null);
        notesTextArea.setEnabled(false);
        notesScrollPane.setViewportView(notesTextArea);

        javax.swing.GroupLayout notesPanelLayout = new javax.swing.GroupLayout(notesPanel);
        notesPanel.setLayout(notesPanelLayout);
        notesPanelLayout.setHorizontalGroup(
            notesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(notesToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE)
            .addComponent(notesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE)
        );
        notesPanelLayout.setVerticalGroup(
            notesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(notesPanelLayout.createSequentialGroup()
                .addComponent(notesToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(notesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE))
        );

        tabPane.addTab("Notes", new javax.swing.ImageIcon(getClass().getResource("/usda/weru/resources/output.gif")), notesPanel); // NOI18N

        warningsPanel.setVerifyInputWhenFocusTarget(false);

        warningsTextArea.setColumns(20);
        warningsTextArea.setEditable(false);
        warningsTextArea.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        warningsTextArea.setRows(5);
        warningsScrollPane.setViewportView(warningsTextArea);

        javax.swing.GroupLayout warningsPanelLayout = new javax.swing.GroupLayout(warningsPanel);
        warningsPanel.setLayout(warningsPanelLayout);
        warningsPanelLayout.setHorizontalGroup(
            warningsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(warningsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE)
        );
        warningsPanelLayout.setVerticalGroup(
            warningsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(warningsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
        );

        tabPane.addTab("Warnings", warningsPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(tabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 449, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(tabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 202, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
    saveNotes();
}//GEN-LAST:event_saveButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    protected javax.swing.JPanel notesPanel;
    protected javax.swing.JScrollPane notesScrollPane;
    protected javax.swing.JTextArea notesTextArea;
    protected javax.swing.JToolBar notesToolbar;
    protected javax.swing.JButton saveButton;
    protected javax.swing.JTabbedPane tabPane;
    protected javax.swing.JPanel warningsPanel;
    protected javax.swing.JScrollPane warningsScrollPane;
    protected javax.swing.JTextArea warningsTextArea;
    // End of variables declaration//GEN-END:variables
    @Override
    public void reportViewerClosing(ReportViewer viewer) throws VetoException {
        if (isModified()) {
            int response = JOptionPane.showConfirmDialog(getTopLevelAncestor(), "The notes have been modified.\nDo you want to save the notes before closing the report.\nIf you do not save the notes, all modifications since the last save will be lost.", "Close Report", JOptionPane.YES_NO_CANCEL_OPTION);
            switch (response) {
                case JOptionPane.YES_OPTION:
                    saveNotes();
                    return;
                case JOptionPane.NO_OPTION:
                    //exit without closing
                    return;
                case JOptionPane.CLOSED_OPTION:
                case JOptionPane.CANCEL_OPTION:
                    throw new VetoException();
            }
        }
    }

    /**
     *
     * @param viewer
     * @param busy
     */
    @Override
    public void busyStateChanged(ReportViewer viewer, boolean busy) {
        setBusy(busy);
    }

    private void setBusy(boolean busy) {
        setEnabled(!busy);
        if (busy) {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            notesTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        } else {
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            notesTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
    }
    void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {                                        
		// Add your handling code here:
        JRSaveContributor[] saveContributors = viewer.getSaveContributors();
        TFile lastFolder;
        TFile file = new TFile(pdfPath);

        lastFolder = file.getParentFile();

        JRSaveContributor contributor = null;
        int i = 0;
        while(contributor == null && i < saveContributors.length)
        {
            contributor = saveContributors[i++];
            if (!contributor.accept(file))
            {
                contributor = null;
            }
        }

        if (contributor == null)
        {
            contributor = new JRPrintSaveContributor(viewer.getContext().getJasperReportsContext(), getLocale(), viewer.getContext().getResourceBundle());
        }

        try
        {
            contributor.save(viewer.getContext().getJasperPrint(), file);
        }
        catch (JRException e)
        {
        }
    }
}
