/* Copyright (C) 1998-2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glibmm/vectorutils.h>
#include <gdkmm/paintable.h>
#include <gtkmm/textbuffer.h>
#include <gtkmm/textmark.h>
#include <gtkmm/textchildanchor.h>

/**** Gtk::TextIterBase *******************************************************/

namespace
{
extern "C"
{
static gboolean TextIterBase_find_char_callback(gunichar ch, void* user_data)
{
  try
  {
    auto slot = static_cast<Gtk::TextIterBase::SlotFindChar*>(user_data);
    return (*slot)(ch);
  }
  catch (...)
  {
    Glib::exception_handlers_invoke();
    return false;
  }
}
} // extern "C"
} // anonymous namespace

namespace Gtk
{
bool TextIterBase::forward_find_char(const SlotFindChar& slot, const TextIterBase& limit)
{
  // Use the original slot (not a copy).
  auto slot_copy = const_cast<SlotFindChar*>(&slot);

  return gtk_text_iter_forward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, limit.gobj());
}

bool TextIterBase::forward_find_char(const SlotFindChar& slot)
{
  // Use the original slot (not a copy).
  auto slot_copy = const_cast<SlotFindChar*>(&slot);

  return gtk_text_iter_forward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, nullptr);
}

bool TextIterBase::backward_find_char(const SlotFindChar& slot, const TextIterBase& limit)
{
  // Use the original slot (not a copy).
  auto slot_copy = const_cast<SlotFindChar*>(&slot);

  return gtk_text_iter_backward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, limit.gobj());
}

bool TextIterBase::backward_find_char(const SlotFindChar& slot)
{
  // Use the original slot (not a copy).
  auto slot_copy = const_cast<SlotFindChar*>(&slot);

  return gtk_text_iter_backward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, nullptr);
}

} // namespace Gtk

/**** Gtk::TextIter and Gtk::TextConstIter ************************************/

namespace Glib
{
// Can't have overloaded functions that differ only in return type.
// These can't be called Glib::wrap().

Gtk::TextIter& wrap_iter(GtkTextIter* object)
{
  return *reinterpret_cast<Gtk::TextIter*>(object);
}

const Gtk::TextIter& wrap_iter(const GtkTextIter* object)
{
  return *reinterpret_cast<const Gtk::TextIter*>(object);
}

Gtk::TextConstIter& wrap_const_iter(GtkTextIter* object)
{
  return *reinterpret_cast<Gtk::TextConstIter*>(object);
}

const Gtk::TextConstIter& wrap_const_iter(const GtkTextIter* object)
{
  return *reinterpret_cast<const Gtk::TextConstIter*>(object);
}

} // namespace Glib
