package com.fitbank.fitpatch;

import java.awt.Color;
import java.util.LinkedList;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import org.apache.commons.lang.StringUtils;
import org.tmatesoft.svn.core.SVNException;

import com.fitbank.fitpatch.MantisQueries.ConnectionException;
import com.fitbank.util.Debug;
import com.fitbank.util.SwingUtils;

/**
 * Herramientas para armar patches
 *
 * @author FitBank CI
 */
public class Main extends javax.swing.JFrame {

    private final PreferencesDialog prefsDialog;

    private final PatchHandler patchHandler = new PatchHandler();

    public Main() {
        initComponents();

        try {
            patchHandler.connect();
        } catch (ConnectionException ex) {
            Debug.error(ex);
        }

        SwingUtils.setupOutput(console, Color.WHITE, Color.RED);

        prefsDialog = new PreferencesDialog(this, true);

        if (StringUtils.isBlank(patchHandler.getControlSources())) {
            prefsDialog.setVisible(true);
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainToolbar = new javax.swing.JToolBar();
        javax.swing.JLabel patchLabel = new javax.swing.JLabel();
        patchNumber = new javax.swing.JTextField();
        javax.swing.JButton mantisSync = new javax.swing.JButton();
        merge = new javax.swing.JButton();
        commit = new javax.swing.JButton();
        javax.swing.JButton cleanup = new javax.swing.JButton();
        javax.swing.JToolBar.Separator separador = new javax.swing.JToolBar.Separator();
        javax.swing.JButton preferencesButton = new javax.swing.JButton();
        progreso = new javax.swing.JProgressBar();
        javax.swing.JScrollPane consoleScrollPane = new javax.swing.JScrollPane();
        console = new javax.swing.JTextPane();
        javax.swing.JLabel revisionsLabel = new javax.swing.JLabel();
        revisions = new javax.swing.JTextField();
        javax.swing.JLabel branchesLabel = new javax.swing.JLabel();
        branches = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("FitPatch");

        mainToolbar.setRollover(true);

        patchLabel.setText("No. Parche:");
        mainToolbar.add(patchLabel);

        patchNumber.setMaximumSize(new java.awt.Dimension(100, 25));
        patchNumber.setMinimumSize(new java.awt.Dimension(100, 25));
        patchNumber.setPreferredSize(new java.awt.Dimension(100, 25));
        patchNumber.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                patchNumberActionPerformed();
            }
        });
        mainToolbar.add(patchNumber);

        mantisSync.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/freedesktop/tango/16x16/actions/view-refresh.png"))); // NOI18N
        mantisSync.setText("Sinc. Mantis");
        mantisSync.setEnabled(false);
        mantisSync.setFocusable(false);
        mantisSync.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        mantisSync.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        mantisSync.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mantisSyncActionPerformed();
            }
        });
        mainToolbar.add(mantisSync);

        merge.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/freedesktop/tango/16x16/actions/edit-copy.png"))); // NOI18N
        merge.setText("Merge");
        merge.setEnabled(false);
        merge.setFocusable(false);
        merge.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        merge.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        merge.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mergeActionPerformed();
            }
        });
        mainToolbar.add(merge);

        commit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/freedesktop/tango/16x16/actions/document-save.png"))); // NOI18N
        commit.setText("Commit");
        commit.setEnabled(false);
        commit.setFocusable(false);
        commit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        commit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        commit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                commitActionPerformed();
            }
        });
        mainToolbar.add(commit);

        cleanup.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/freedesktop/tango/16x16/actions/edit-clear.png"))); // NOI18N
        cleanup.setText("Cleanup");
        cleanup.setFocusable(false);
        cleanup.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        cleanup.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        cleanup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cleanupActionPerformed();
            }
        });
        mainToolbar.add(cleanup);
        mainToolbar.add(separador);

        preferencesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/fitbank/fitpatch/iconos/preferencias.png"))); // NOI18N
        preferencesButton.setText("Preferencias");
        preferencesButton.setFocusable(false);
        preferencesButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        preferencesButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        preferencesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                preferencesButtonActionPerformed();
            }
        });
        mainToolbar.add(preferencesButton);

        console.setBackground(Color.black);
        console.setEditable(false);
        consoleScrollPane.setViewportView(console);

        revisionsLabel.setText("Revisiones:");

        revisions.setEditable(false);

        branchesLabel.setText("Branch:");

        branches.setModel(new DefaultComboBoxModel());
        branches.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                branchesActionPerformed();
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 635, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(progreso, javax.swing.GroupLayout.DEFAULT_SIZE, 611, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(revisionsLabel)
                    .addComponent(branchesLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(branches, 0, 528, Short.MAX_VALUE)
                    .addComponent(revisions, javax.swing.GroupLayout.DEFAULT_SIZE, 528, Short.MAX_VALUE))
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(consoleScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 611, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(mainToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(branchesLabel)
                    .addComponent(branches, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(revisionsLabel)
                    .addComponent(revisions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(consoleScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(progreso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

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

    private void preferencesButtonActionPerformed() {//GEN-FIRST:event_preferencesButtonActionPerformed
        prefsDialog.setVisible(true);
    }//GEN-LAST:event_preferencesButtonActionPerformed

    private void patchNumberActionPerformed() {//GEN-FIRST:event_patchNumberActionPerformed
        mantisSyncActionPerformed();
    }//GEN-LAST:event_patchNumberActionPerformed

    private void mantisSyncActionPerformed() {//GEN-FIRST:event_mantisSyncActionPerformed
        query();
    }//GEN-LAST:event_mantisSyncActionPerformed

    private void branchesActionPerformed() {//GEN-FIRST:event_branchesActionPerformed
        select((String) branches.getSelectedItem());
    }//GEN-LAST:event_branchesActionPerformed

    private void mergeActionPerformed() {//GEN-FIRST:event_mergeActionPerformed
        new Thread() {

            @Override
            public void run() {
                progreso.setIndeterminate(true);
                mainToolbar.setEnabled(false);
                try {
                    patchHandler.merge(patchNumber.getText());
                } catch (SVNException ex) {
                    Debug.error(ex);
                } catch (Exception t) {
                    Debug.error(t.getMessage());
                }
                commit.setEnabled(true);
                merge.setEnabled(false);
                mainToolbar.setEnabled(true);
                progreso.setIndeterminate(false);
            }

        }.start();
    }//GEN-LAST:event_mergeActionPerformed

    private void commitActionPerformed() {//GEN-FIRST:event_commitActionPerformed
        new Thread() {

            @Override
            public void run() {
                progreso.setIndeterminate(true);
                mainToolbar.setEnabled(false);
                try {
                    patchHandler.commit();
                } catch (SVNException ex) {
                    Debug.error(ex);
                } catch (Exception t) {
                    Debug.error(t.getMessage());
                }
                commit.setEnabled(false);
                merge.setEnabled(false);
                mainToolbar.setEnabled(true);
                progreso.setIndeterminate(false);
            }

        }.start();
    }//GEN-LAST:event_commitActionPerformed

    private void cleanupActionPerformed() {//GEN-FIRST:event_cleanupActionPerformed
        new Thread() {

            @Override
            public void run() {
                progreso.setIndeterminate(true);
                mainToolbar.setEnabled(false);
                try {
                    patchHandler.cleanup();
                } catch (SVNException ex) {
                    Debug.error(ex);
                } catch (Exception t) {
                    Debug.error(t.getMessage());
                }
                commit.setEnabled(false);
                merge.setEnabled(false);
                mainToolbar.setEnabled(true);
                progreso.setIndeterminate(false);
                query();
            }

        }.start();
    }//GEN-LAST:event_cleanupActionPerformed

    private void query() {
        final String incidencia = StringUtils.leftPad(patchNumber.getText(), 7,
                '0');
        patchNumber.setText(incidencia);
        console.setText("Sincronizando incidencia #" + incidencia);
        setTitle(String.format("Incidencia #%s", incidencia));

        new Thread() {

            @Override
            public void run() {
                Debug.info("Obteniendo revisiones...");
                merge.setEnabled(false);
                commit.setEnabled(false);
                progreso.setIndeterminate(true);
                patchHandler.query(incidencia);

                if (patchHandler.getRevisionMap().containsKey("trunk")) {
                    progreso.setIndeterminate(false);
                    JOptionPane.showMessageDialog(Main.this,
                            "Esta incidencia ya se pasó a control!");
                    return;
                }

                if (patchHandler.getRevisionMap().isEmpty()) {
                    progreso.setIndeterminate(false);
                    JOptionPane.showMessageDialog(Main.this,
                            "Esta incidencia no tiene cambios para pasar a control!");
                    return;
                }

                List<String> branchesList = new LinkedList<String>();
                if (patchHandler.getRevisionMap().size() > 1) {
                    branchesList.add("");
                }
                branchesList.addAll(patchHandler.getRevisionMap().keySet());

                branches.setModel(new DefaultComboBoxModel(
                        branchesList.toArray()));

                progreso.setIndeterminate(false);

                Debug.info("Listo.");

                if (branchesList.size() == 1) {
                    select(branchesList.get(0));
                }
            }

        }.start();
    }

    private void select(String branch) {
        revisions.setText(StringUtils.join(patchHandler.getRevisionMap().get(
                branch), ","));
        merge.setEnabled(true);
    }

    public static void main(String args[]) throws Exception {
        if (args.length > 0) {
            PatchHandler.main(args);

        } else {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            java.awt.EventQueue.invokeLater(new Runnable() {

                public void run() {
                    new Main().setVisible(true);
                }

            });
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox branches;
    private javax.swing.JButton commit;
    private javax.swing.JTextPane console;
    private javax.swing.JToolBar mainToolbar;
    private javax.swing.JButton merge;
    private javax.swing.JTextField patchNumber;
    private javax.swing.JProgressBar progreso;
    private javax.swing.JTextField revisions;
    // End of variables declaration//GEN-END:variables

}
