/*
 * jNPad v0.3 - jNPad's an Simple Text Editor written in Java
 *
 * Copyright (C) 2014-2017  rgs
 *
 * Require JDK 1.6 (or later)
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 *
 * Info, Questions, Suggestions & Bugs Report to rgsevero@gmail.com
 */

package jnpad.search;

import java.util.logging.Level;
import java.util.logging.Logger;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import jnpad.JNPadFrame;
import jnpad.ui.EscapableDialog;
import jnpad.ui.JNPadLabel;
import jnpad.ui.ReporterUtilities;
import jnpad.util.Utilities;

/**
 * The Class SearchManagerDialog.
 *
 * @version 0.3
 * @since   jNPad v0.1
 */
public class SearchManagerDialog extends EscapableDialog {
  JPanel                      contentPane;
  JLabel                      lbText           = new JNPadLabel();
  JPanel                      pnButtons        = new JPanel();
  JButton                     btPrevious       = new JButton();
  JButton                     btReplace        = new JButton();
  JButton                     btNext           = new JButton();
  JButton                     btOptions        = new JButton();
  JButton                     btCancel         = new JButton();
  JButton                     btAll            = new JButton();

  static final int            FIND             = 10;
  static final int            REPLACE          = 11;

  private int                 mode             = FIND;
  private Point               location         = null;
  private SearchDialog        searchDialog;
  private String              searchFor        = Utilities.EMPTY_STRING;
  private JNPadFrame          jNPad;

  /** Logger */
  private static final Logger LOGGER           = Logger.getLogger(SearchManagerDialog.class.getName());

  /** UID */
  private static final long   serialVersionUID = 8300833753032334654L;

  /**
   * Instantiates a new search manager dialog.
   *
   * @param jNPad JNPadFrame
   * @param searchDialog SearchDialog
   */
  public SearchManagerDialog(JNPadFrame jNPad, SearchDialog searchDialog) {
    super(jNPad, true);
    this.jNPad = jNPad;
    this.searchDialog = searchDialog;
    try {
      jbInit();
      pack();
      if (location == null) {
        setLocationRelativeTo(jNPad);
        location = getLocation();
      }
    }
    catch (Exception ex) {
      LOGGER.log(Level.WARNING, ex.getMessage(), ex);
    }
  }

  /**
   * Component initialization.
   *
   * @throws Exception the exception
   */
  private void jbInit() throws Exception {
    contentPane = (JPanel)this.getContentPane();
    contentPane.setLayout(new BorderLayout());
    contentPane.add(lbText, BorderLayout.CENTER);
    contentPane.add(pnButtons, BorderLayout.SOUTH);

    lbText.setHorizontalAlignment(SwingConstants.CENTER);
    lbText.setText(Utilities.SPACE_STRING);

    btReplace.setText(SearchBundle.getString("SearchManagerDialog.replace"));   //$NON-NLS-1$
    btNext.setText(SearchBundle.getString("SearchManagerDialog.next"));         //$NON-NLS-1$
    btPrevious.setText(SearchBundle.getString("SearchManagerDialog.previous")); //$NON-NLS-1$
    btOptions.setText(SearchBundle.getString("SearchManagerDialog.options"));   //$NON-NLS-1$
    btCancel.setText(SearchBundle.getString("SearchManagerDialog.cancel"));     //$NON-NLS-1$
    btAll.setText(SearchBundle.getString("SearchManagerDialog.all"));           //$NON-NLS-1$

    ActionHandler actionHandler = new ActionHandler();

    btOptions.addActionListener(actionHandler);
    btReplace.addActionListener(actionHandler);
    btNext.addActionListener(actionHandler);
    btPrevious.addActionListener(actionHandler);
    btCancel.addActionListener(actionHandler);
    btAll.addActionListener(actionHandler);

    setResizable(false);
  }

  /**
   * Sets the mode.
   *
   * @param mode int
   * @param searchFor String
   * @param replaceWith String
   */
  public void setMode(int mode, String searchFor, String replaceWith) {
    this.mode = mode;
    this.searchFor = searchFor;
    pnButtons.removeAll();
    if (mode == FIND) {
      lbText.setText(SearchBundle.getString("SearchManagerDialog.textFind", searchFor)); //$NON-NLS-1$
      btNext.requestFocus();
      pnButtons.add(btPrevious, null);
    }
    else if (mode == REPLACE) {
      lbText.setText(SearchBundle.getString("SearchManagerDialog.textReplace", searchFor, replaceWith)); //$NON-NLS-1$
      pnButtons.add(btReplace, null);
    }
    pnButtons.add(btNext, null);
    pnButtons.add(btAll, null);
    pnButtons.add(btOptions, null);
    pnButtons.add(btCancel, null);
    pack();
    setLocationRelativeTo(jNPad);
  }

  /**
   * Escape pressed.
   *
   * @see jnpad.ui.EscapableDialog#escapePressed()
   */
  @Override
  protected void escapePressed() {
    saveState();
  }

  /**
   * Process window event.
   *
   * @param e the WindowEvent
   * @see javax.swing.JDialog#processWindowEvent(java.awt.event.WindowEvent)
   */
  @Override
  protected void processWindowEvent(WindowEvent e) {
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      saveState();
    }
    super.processWindowEvent(e);
  }

  /**
   * Save state.
   */
  public void saveState() {
    location = getLocation();
    setVisible(false);
  }

  /**
   * Load state.
   */
  public void loadState() {
    setLocation(location);
    setVisible(true);
  }

  /**
   * Normal replace.
   */
  private void normalReplace() {
    if (!searchDialog.replace(false)) {
      saveState();
      reportWordNotFound(true);
    }
  }

  /**
   * Report word not found.
   *
   * @param next the next
   */
  private void reportWordNotFound(boolean next) {
    if(next) {
      ReporterUtilities.reportInfo(jNPad, SearchBundle.getString("SearchManagerDialog.notFound.next", searchFor)); //$NON-NLS-1$
    }
    else {
      ReporterUtilities.reportInfo(jNPad, SearchBundle.getString("SearchManagerDialog.notFound.previous", searchFor)); //$NON-NLS-1$
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  private class ActionHandler implements ActionListener {
    /**
     * Action performed.
     *
     * @param e the ActionEvent
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed(ActionEvent e) {
      Object obj = e.getSource();
      if (obj == btCancel)
        saveState();
      else if (obj == btOptions) {
        saveState();
        searchDialog.setVisible(true);
      }
      else if (obj == btReplace) {
        normalReplace();
      }
      else if (obj == btPrevious) {
        if (!searchDialog.searchPrevious()) {
          saveState();
          reportWordNotFound(false);
        }
      }
      else if (obj == btNext) {
        if (mode == FIND) {
          if (!searchDialog.searchNext()) {
            saveState();
            reportWordNotFound(true);
          }
        }
        else if (mode == REPLACE) {
          searchDialog.resetReplace();
          normalReplace();
        }
      }
      else if (obj == btAll) {
        saveState();
        searchDialog.resetFind();
        if (mode == FIND) {
          searchDialog.find(true);
        }
        else if (mode == REPLACE) {
          searchDialog.resetReplace();
          searchDialog.replace(true);
        }
      }
    }
  }
  //////////////////////////////////////////////////////////////////////////////

}
