package jrex.ui;

import jrex.ui.model.MutableTableModel;
import com.google.common.collect.Table;
import java.util.Arrays;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JTextArea;

/**
 * @author Mark George
 */
public class ReplacePanel extends javax.swing.JPanel {

	private final MutableTableModel model = new MutableTableModel(Arrays.asList("Search", "Replace"));
	private JTextArea txtInput;
	private JTextArea txtOutput;

	public ReplacePanel() {
		initComponents();
		tblExpressions.setModel(model);
		model.addRow(new String[]{"", ""});
		model.fireTableStructureChanged();
		tblExpressions.setShowHorizontalLines(true);
		tblExpressions.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
	}

	public void setComponents(JTextArea input, JTextArea output) {
		this.txtInput = input;
		this.txtOutput = output;
	}

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

      scrlTable = new javax.swing.JScrollPane();
      tblExpressions = new javax.swing.JTable();
      btnAddRow = new javax.swing.JButton();
      btnReplace = new javax.swing.JButton();
      btnUp = new javax.swing.JButton();
      btnDown = new javax.swing.JButton();
      btnDelete = new javax.swing.JButton();
      jLabel1 = new javax.swing.JLabel();

      setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Search/Replace", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 0, 12))); // NOI18N
      setMinimumSize(new java.awt.Dimension(250, 0));
      setName(""); // NOI18N
      setPreferredSize(new java.awt.Dimension(300, 229));

      scrlTable.setAlignmentY(0.0F);
      scrlTable.setName("scrlTable"); // NOI18N

      tblExpressions.setFillsViewportHeight(true);
      tblExpressions.setName("tblExpressions"); // NOI18N
      tblExpressions.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
      scrlTable.setViewportView(tblExpressions);

      btnAddRow.setMnemonic('a');
      btnAddRow.setText("Add Row");
      btnAddRow.setName("btnAddRow"); // NOI18N
      btnAddRow.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnAddRowActionPerformed(evt);
         }
      });

      btnReplace.setMnemonic('r');
      btnReplace.setText("Replace");
      btnReplace.setName("btnReplace"); // NOI18N
      btnReplace.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnReplaceActionPerformed(evt);
         }
      });

      btnUp.setMnemonic('u');
      btnUp.setText("Move Up");
      btnUp.setName("btnUp"); // NOI18N
      btnUp.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnUpActionPerformed(evt);
         }
      });

      btnDown.setMnemonic('d');
      btnDown.setText("Move Down");
      btnDown.setName("btnDown"); // NOI18N
      btnDown.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnDownActionPerformed(evt);
         }
      });

      btnDelete.setMnemonic('d');
      btnDelete.setText("Delete Row");
      btnDelete.setName("btnDelete"); // NOI18N
      btnDelete.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnDeleteActionPerformed(evt);
         }
      });

      jLabel1.setText("<html>Accepts regular expressions.  Use '$' as the prefix for capture references.  Literal '$' characters (and any other meta-characters) will need to be escaped with a backslash.</html>");
      jLabel1.setName("jLabel1"); // NOI18N

      javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
      this.setLayout(layout);
      layout.setHorizontalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addComponent(btnReplace, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
         .addComponent(scrlTable, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
         .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
               .addComponent(btnAddRow, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE)
               .addComponent(btnUp, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
               .addComponent(btnDown, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)
               .addComponent(btnDelete, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
         .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
      );
      layout.setVerticalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(layout.createSequentialGroup()
            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(7, 7, 7)
            .addComponent(scrlTable, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
               .addComponent(btnAddRow)
               .addComponent(btnDelete))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
               .addComponent(btnUp)
               .addComponent(btnDown))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(btnReplace))
      );
   }// </editor-fold>//GEN-END:initComponents

   private void btnAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddRowActionPerformed
		model.addRow(new String[]{"", ""});
   }//GEN-LAST:event_btnAddRowActionPerformed

   private void btnReplaceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnReplaceActionPerformed
		String data = txtInput.getText();

		Table<Integer, Integer, String> table = model.getTable();

		for (Map<Integer, String> row : table.rowMap().values()) {
			if (!row.get(0).isEmpty()) {
				String search = row.get(0);
				String replace = row.get(1);
				data = performReplace(data, search, replace);
			}
		}

		txtOutput.setText(data);
   }//GEN-LAST:event_btnReplaceActionPerformed

   private void btnUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnUpActionPerformed
		int row = tblExpressions.getSelectedRow();
		if (row > 0) {
			model.moveUp(row);
			tblExpressions.setRowSelectionInterval(row - 1, row - 1);
		}

   }//GEN-LAST:event_btnUpActionPerformed

   private void btnDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownActionPerformed
		int row = tblExpressions.getSelectedRow();
		if (row < model.getRowCount() - 1) {
			model.moveDown(row);
			tblExpressions.setRowSelectionInterval(row + 1, row + 1);
		}
   }//GEN-LAST:event_btnDownActionPerformed

   private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeleteActionPerformed
		int row = tblExpressions.getSelectedRow();
		if (row >= 0) {
			model.deleteRow(row);
			if (model.getRowCount() > 0) {
				if (row < model.getRowCount() - 1) {
					tblExpressions.setRowSelectionInterval(row, row);
				} else {
					tblExpressions.setRowSelectionInterval(model.getRowCount() - 1, model.getRowCount() - 1);
				}
			}
		}
   }//GEN-LAST:event_btnDeleteActionPerformed

	public String performReplace(String input, String search, String replace) {
		try {
			Pattern pattern = Pattern.compile(search, Pattern.MULTILINE);
			Matcher matcher = pattern.matcher(input);
			return matcher.replaceAll(replace);
		} catch (Exception ex) {
			return ex.getMessage();
		}
	}

	public MutableTableModel getModel() {
		return model;
	}

   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JButton btnAddRow;
   private javax.swing.JButton btnDelete;
   private javax.swing.JButton btnDown;
   private javax.swing.JButton btnReplace;
   private javax.swing.JButton btnUp;
   private javax.swing.JLabel jLabel1;
   private javax.swing.JScrollPane scrlTable;
   private javax.swing.JTable tblExpressions;
   // End of variables declaration//GEN-END:variables
}
