#include <gtk/gtk.h>

void find (GtkTextView *text_view, const gchar *text, GtkTextIter *iter)
{
  GtkTextIter mstart, mend;
  gboolean found;
  GtkTextBuffer *buffer;
  GtkTextMark *last_pos;

  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
  found = gtk_text_iter_forward_search (iter, text, 0, &mstart, &mend, NULL);

  if (found)
    {
      gtk_text_buffer_select_range (buffer, &mstart, &mend);
      last_pos = gtk_text_buffer_create_mark (buffer, "last_pos", 
                                              &mend, FALSE);
      gtk_text_view_scroll_mark_onscreen (text_view, last_pos);
    }
}

typedef struct _App {
  GtkWidget *text_view;
  GtkWidget *search_entry;
} App;

void win_destroy (void)
{
  gtk_main_quit();
}

void next_button_clicked (GtkWidget *next_button, App *app)
{
  const gchar *text;
  GtkTextBuffer *buffer;
  GtkTextMark *last_pos;
  GtkTextIter iter;

  text = gtk_entry_get_text (GTK_ENTRY (app->search_entry));
  
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (app->text_view));

  last_pos = gtk_text_buffer_get_mark (buffer, "last_pos");
  if (last_pos == NULL)
    return;

  gtk_text_buffer_get_iter_at_mark (buffer, &iter, last_pos);
  find (GTK_TEXT_VIEW (app->text_view), text, &iter);
}

void search_button_clicked (GtkWidget *search_button, App *app)
{
  const gchar *text;
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  text = gtk_entry_get_text (GTK_ENTRY (app->search_entry));

  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (app->text_view));
  gtk_text_buffer_get_start_iter (buffer, &iter);
  
  find (GTK_TEXT_VIEW (app->text_view), text, &iter);
}

int  main (int argc, char *argv[])
{
  GtkWidget *win;
  GtkWidget *vbox;
  GtkWidget *hbox;
  GtkWidget *search_button;
  GtkWidget *next_button;
  GtkWidget *swindow;

  App app;

  gtk_init (&argc, &argv);

  win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (G_OBJECT (win), "destroy", win_destroy, NULL);

  vbox = gtk_vbox_new (FALSE, 2);
  gtk_container_add (GTK_CONTAINER (win), vbox);

  hbox = gtk_hbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  
  app.search_entry = gtk_entry_new ();
  gtk_box_pack_start (GTK_BOX (hbox), app.search_entry, TRUE, TRUE, 0);

  search_button = gtk_button_new_with_label ("Search");  
  gtk_box_pack_start (GTK_BOX (hbox), search_button, FALSE, FALSE, 0);
  g_signal_connect (G_OBJECT (search_button), "clicked", 
                    G_CALLBACK (search_button_clicked), &app);

  next_button = gtk_button_new_with_label ("Next");
  gtk_box_pack_start (GTK_BOX (hbox), next_button, FALSE, FALSE, 0);
  g_signal_connect (G_OBJECT (next_button), "clicked",
                    G_CALLBACK (next_button_clicked), &app);

  swindow = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start (GTK_BOX (vbox), swindow, TRUE, TRUE, 0);

  app.text_view = gtk_text_view_new ();
  gtk_container_add (GTK_CONTAINER (swindow), app.text_view);

  gtk_widget_show_all (win);

  gtk_main();
  
  return 0;
}