/* 
 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * 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; version 2 of the
 * License.
 * 
 * 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 St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "stdafx.h"

#ifdef __APPLE__
  #include "search_replace.h"
#else
  #include "dialogs/search_replace.h"
#endif
#include "base/string_utilities.h"

#include <string.h>
#include "base/string_utilities.h"

using namespace mforms;

//----------------- SearchReplace ----------------------------------------------------------------------

SearchReplace::SearchReplace()
: Form(NULL, FormSingleFrame), _top_box(false), _find_label(""), _replace_label(""), _button_box(true), 
  _find_selector(SelectorCombobox),
  _replace_selector(SelectorCombobox)
{
  set_size(500, 185);
  _top_box.set_padding(12);
  _top_box.set_spacing(12);

  _top_table.set_row_count(3);
  _top_table.set_row_spacing(12);
  _top_table.set_column_count(2);
  _top_table.set_column_spacing(8);
  
  _table.set_row_count(3);
  _table.set_row_spacing(10);
  _table.set_column_count(1);
  _table.set_column_spacing(5);
  
  _find_label.set_text(_("Find:"));
  _find_label.set_text_align(MiddleRight);
  _top_table.add(&_find_label, 0, 1, 0, 1, HFillFlag);
  _top_table.add(&_find_selector, 1, 2, 0, 1, HFillFlag|HExpandFlag);

  _replace_label.set_text(_("Replace with:"));
  _replace_label.set_text_align(MiddleRight);
  _top_table.add(&_replace_label, 0, 1, 1, 2, HFillFlag);
  _top_table.add(&_replace_selector, 1, 2, 1, 2, HFillFlag|HExpandFlag);
  _top_box.add(&_top_table, false, true);

  _ignore_case_checkbox.set_text(_("Ignore case"));
  _table.add(&_ignore_case_checkbox, 0, 1, 0, 1, HFillFlag);
  _use_regex_checkbox.set_text(_("Enable RegEx Support"));
  _table.add(&_use_regex_checkbox, 0, 1, 1, 2, HFillFlag);
#ifndef _WIN32
  // not supported in mac and linux
  _use_regex_checkbox.show(false);
#endif  
  _match_whole_word_checkbox.set_text(_("Match whole word"));
  //_table.add(&_match_whole_word_checkbox, 0, 1, 2, 3, HFillFlag);
  _top_table.add(&_table, 1, 2, 2, 3, HFillFlag|HExpandFlag|VFillFlag|VExpandFlag);

  _replace_all_button.set_text(_("Replace All"));
  _replace_all_button.enable_internal_padding(true);
  scoped_connect(_replace_all_button.signal_clicked(),boost::bind(&SearchReplace::button_pressed, this, &_replace_all_button));

  _replace_button.set_text(_("Replace"));
  _replace_button.enable_internal_padding(true);
  scoped_connect(_replace_button.signal_clicked(),boost::bind(&SearchReplace::button_pressed, this, &_replace_button));
  
  _find_previous_button.set_text(_("Find Previous"));
  _find_previous_button.enable_internal_padding(true);
  scoped_connect(_find_previous_button.signal_clicked(),boost::bind(&SearchReplace::button_pressed, this, &_find_previous_button));

  _find_next_button.set_text(_("Find Next"));
  _find_next_button.enable_internal_padding(true);
  scoped_connect(_find_next_button.signal_clicked(),boost::bind(&SearchReplace::button_pressed, this, &_find_next_button));

  _button_box.set_spacing(12);
  _button_box.add(&_replace_all_button, false, true);
  _button_box.add(&_replace_button, false, true);
  _button_box.add_end(&_find_next_button, false, true);
  _button_box.add_end(&_find_previous_button, false, true);

  set_title(_("Search and Replace"));
  
  _top_box.add_end(&_button_box, false, true);

  set_content(&_top_box);

  // The cancel button is not visible. It just serves as communicator to allow ESC to close the dialog.
  scoped_connect(_cancel_button.signal_clicked(),boost::bind(&SearchReplace::cancel_pressed, this));
}

//--------------------------------------------------------------------------------------------------

void SearchReplace::show(bool modal, SearchFlags flags, bool replace)
{
  if (replace)
    set_title(_("Search and Replace"));
  else
    set_title(_("Search Text"));
  _replace_label.show(replace);
  _replace_selector.show(replace);
  _replace_button.show(replace);
  _replace_all_button.show(replace);

  _ignore_case_checkbox.set_active((flags & SearchMatchCase) == 0);
  _use_regex_checkbox.set_active((flags & SearchUseRegularExpression) != 0);

  if (modal)
    run_modal(NULL, &_cancel_button);
  else
    show_modal(NULL, &_cancel_button);
}

//--------------------------------------------------------------------------------------------------

void SearchReplace::cancel_pressed()
{
  close();
}

//--------------------------------------------------------------------------------------------------

void SearchReplace::set_callback(SearchCallback new_callback)
{
  _on_action= new_callback;
}

//--------------------------------------------------------------------------------------------------

/**
 * Trigger when any of the search or replace buttons are pressed. Triggers the callback if set
 * so the owner can actually perform the search/replace action.
 */
void SearchReplace::button_pressed(Button* button)
{
  SearchFlags flags= SearchNone;
  if (!_ignore_case_checkbox.get_active())
    flags = SearchFlags(flags | SearchMatchCase);
  if (_use_regex_checkbox.get_active())
    flags = SearchFlags(flags | SearchUseRegularExpression);

  if (button == &_replace_button || button == &_replace_all_button)
  {
    flags= SearchFlags(flags | SearchDoReplace);
    if (button == &_replace_all_button)
      flags= SearchFlags(flags | SearchAll);
  }
  else
    if (button == &_find_previous_button)
      flags= SearchFlags(flags | SearchPrevious);
  if (_on_action(_find_selector.get_string_value(), _replace_selector.get_string_value(), flags))
    close();
}

//--------------------------------------------------------------------------------------------------

