/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2004  by Diether Knof and Borg Enders
 *
 *   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 can find this license in the file 'gpl.txt'.
 *
 *   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., 59 Temple Place, Suite 330, Boston, 
 *   MA  02111-1307  USA
 *
 *  Contact:
 *    Diether Knof dknof@gmx.de
 *    Borg Enders  borg@borgsoft.de
 *
 *********************************************************************/

#include "constants.h"

#ifdef USE_UI_GTK

#include "bug_report.h"
#include "gtk_gui.h"
#include "main_window.h"
#include "playfield.h"
#include "party_settings.h"

#include "../../os/bug_report_replay.h"
#include "../../misc/bug_report.h"
#include "../../misc/setting.h"
#include "../../misc/language.h"
#include "../ui.h"
#include "../ui.wrap.h"

namespace GTK_DOKO {
#include <gtk/gtktext.h>
#include <gtk/gtkeditable.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtksignal.h>
#ifdef GTK_2_0
#include <gtk/gtktextview.h>
#endif

  /*****************************************************************************
   *
   * BugReport::BugReport(GTK_GUI* gui_a)
   *
   * Parameters:	gui_a - pointer to the gui
   *
   * Result:	none
   * 
   * Version:	0.3.7
   *
   * Description:	Constructor
   *
   ****************************************************************************/
  BugReport::BugReport(GTK_GUI* gui_a) :
    Dialog(gui_a, "Bug report"), // the base class
#ifdef GTK_2_0
  information(gtk_text_view_new()), // the information text
#else
  information(gtk_text_new(NULL, NULL)), // the information text
#endif
  file(gtk_label_new("")), // the file, the bug report is to append
  save_on_desktop(gtk_check_button_new_with_label("")),
  selector(gtk_file_selection_new("")), // the file select box
#ifdef GTK_2_0
  text(gtk_text_view_new()), // the text
#else
  text(gtk_text_new(NULL, NULL)), // the text of the user
#endif
  save(gtk_button_new_with_label("")), // save the bug report
  cancel(gtk_button_new_with_label("")) // cancel the bug report
  {
    DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_INIT,
		  "BugReport::BugReport()");

    // place the widgets in the windowaction_area
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window())->vbox),
		       this->information, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window())->vbox),
		       this->file, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window())->vbox),
		       this->save_on_desktop, FALSE, FALSE, 0);
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(this->window())->vbox),
		      this->text);

    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(this->window())->action_area),
		      this->cancel);
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(this->window())->action_area),
		      this->save);

#ifndef RELEASE
#ifdef WINDOWS
    gtk_file_selection_set_filename(GTK_FILE_SELECTION(this->selector),
				    "..\\Bugreports\\");
#else
    gtk_file_selection_set_filename(GTK_FILE_SELECTION(this->selector),
				    "../Bugreports/");
#endif
#endif

    // show the window
    gtk_signal_connect(GTK_OBJECT(window()), "show",
		       GTK_SIGNAL_FUNC(reset_event),
		       gpointer(this));

    DEBUG_RETURNING(VOID,
		    INFO_GTK_BUG_REPORT && INFO_GTK_INIT,
		    "BugReport::BugReport()");
  } // BugReport::BugReport(class GTK_GUI* gui_a)

  /*****************************************************************************
   *
   * void BugReport::init()
   *
   * Parameters:	none
   *
   * Result:	none
   * 
   * Version:	0.3.6
   *
   * Description:	inits the 'about' help window
   *
   ****************************************************************************/
  void
    BugReport::init()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_INIT,
		    "BugReport::init()");

      this->Dialog::init();

#ifndef WINDOWS
#ifndef LINUX
      gtk_widget_hide(this->save_on_desktop);
#endif
#endif

      // the information text
#ifdef GTK_2_0
      gtk_text_view_set_editable(GTK_TEXT_VIEW(information), FALSE);
      gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(information), GTK_WRAP_WORD);
#else
      gtk_text_set_editable(GTK_TEXT(information), FALSE);
      gtk_text_set_word_wrap(GTK_TEXT(information), TRUE);
#endif

      { // change the background
	GtkStyle* information_style =
	  gtk_style_copy(gtk_widget_get_style(information));
	information_style->base[GTK_STATE_NORMAL] =
	  information_style->bg[GTK_STATE_INSENSITIVE];
	gtk_widget_set_style(information, information_style);
      }


      {
	// size of the windows
	int x, y, width, height;

	gdk_window_get_geometry(this->gui().main_window().window()->window,
				&x, &y, &width, &height, NULL);

#ifdef BUG_REPORT
	gtk_window_set_default_size(GTK_WINDOW(this->window()),
				    width / 2, height / 2);
	gtk_window_set_position(GTK_WINDOW(this->window()),
				GTK_WIN_POS_MOUSE);
#endif
      }

      // the text of the bug report
#ifdef GTK_2_0
      gtk_text_view_set_editable(GTK_TEXT_VIEW(text), TRUE);
      gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
#else
      gtk_text_set_editable(GTK_TEXT(text), TRUE);
      gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
#endif

      // toggle 'save on desktop'
      gtk_signal_connect(GTK_OBJECT(this->save_on_desktop),
			 "toggled",
			 GTK_SIGNAL_FUNC(BugReport::save_on_desktop_toggled_event),
			 this);

      // save the bug report
      gtk_signal_connect(GTK_OBJECT(save),
			 "clicked",
			 GTK_SIGNAL_FUNC(send_event),
			 this);
      // cancel the bug report
      gtk_signal_connect(GTK_OBJECT(cancel),
			 "clicked",
			 GTK_SIGNAL_FUNC(BugReport::hide_event),
			 gpointer(this));

      // select a bug report
      gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(this->selector)->ok_button),
			 "clicked", GTK_SIGNAL_FUNC(BugReport::load_event),
			 gpointer(this));
      gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(this->selector)->ok_button),
			 "clicked", GTK_SIGNAL_FUNC(GTK_GUI::window_hide),
			 gpointer(this->selector));

      gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(this->selector)->cancel_button),
			 "clicked", GTK_SIGNAL_FUNC(GTK_GUI::window_hide),
			 gpointer(this->selector));

      this->save_on_desktop_update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_INIT,
		      "BugReport::init()");
    } // void BugReport::init()

  /**
   **
   ** update the game seed
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.4.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    BugReport::game_open()
    {
      DEBUG_CALLING(INFO_UI && INFO_GTK_UI,
		    "BugReport::game_open()");

      this->language_update();

      DEBUG_RETURNING(VOID,
		      INFO_UI && INFO_GTK_UI,
		      "BugReport::game_open()");
    } // void BugReport::game_open()

  /**
   **
   ** update the game seed
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.4.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    BugReport::game_close()
    {
      DEBUG_CALLING(INFO_UI && INFO_GTK_UI,
		    "BugReport::game_close()");

      this->language_update();

      DEBUG_RETURNING(VOID,
		      INFO_UI && INFO_GTK_UI,
		      "BugReport::game_close()");
    } // void BugReport::game_close()

  /**
   **
   ** reset the bug report
   **
   ** @param	bug_report	bug report of the event
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    BugReport::reset_event(GtkWidget*, gpointer bug_report)
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::reset_event()");

      static_cast<BugReport*>(bug_report)->reset();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::reset_event()");
    } // static void BugReport::reset_event(GtkWidget*, gpointer bug_report)

  /**
   **
   ** send the bug report
   **
   ** @param	bug_report	bug report of the event
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    BugReport::send_event(GtkWidget*, gpointer bug_report)
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::send_event()");

      static_cast<BugReport*>(bug_report)->send();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::send_event()");
    } // static void BugReport::send_event(GtkWidget*, gpointer bug_report)

  /**
   **
   ** a bug report shall be selected
   **
   ** @param	bug_report	bug report of the event
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    BugReport::open_selector_event(GtkWidget*, gpointer bug_report)
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::open_selector_event()");

      static_cast<BugReport*>(bug_report)->open_selector();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::open_selector_event()");
    } // static void BugReport::open_selector_event(GtkWidget*, gpointer bug_report)

  /**
   **
   ** a bug report shall be loaded
   **
   ** @param	bug_report	bug report of the event
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    BugReport::load_event(GtkWidget*, gpointer bug_report)
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::load_event()");

      static_cast<BugReport*>(bug_report)->load();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::load_event()");
    } // static void BugReport::load_event(GtkWidget*, gpointer bug_report)

  /**
   **
   ** the button 'save on desktop' has been toggled
   **
   ** @param	bug_report	bug report of the event
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    BugReport::save_on_desktop_toggled_event(GtkWidget*, gpointer bug_report)
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::save_on_desktop_toggled_event()");

      static_cast<BugReport*>(bug_report)->save_on_desktop_toggled();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::save_on_desktop_toggled_event()");
    } // static void BugReport::save_on_desktop_toggled_event(GtkWidget*, gpointer bug_report)

  /**
   **
   ** reset the bug report
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    BugReport::reset()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::reset()");

#ifdef GTK_2_0
      gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(this->text)),
			       "", 0);
#else
      gtk_editable_delete_text(GTK_EDITABLE(this->text), 0, -1);
#endif
      this->language_update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::reset()");
    } // void BugReport::reset()

  /**
   **
   ** send the bug report
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    BugReport::send()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::send()");

      ::bug_report.report(gtk_editable_get_chars(GTK_EDITABLE(this->text), 0, -1));
      this->close();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::send()");
    } // void BugReport::send()

  /**
   **
   ** open the file selector box
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    BugReport::open_selector()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::open_selector()");

      gtk_window_set_transient_for(GTK_WINDOW(this->selector),
				   GTK_WINDOW(this->gui().playfield().party_settings().window()));
      gtk_widget_show_all(this->selector);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::open_selector()");
    } // void BugReport::open_selector()

  /**
   **
   ** load the bug report selected in the selection dialog
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    BugReport::load()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::load()");

      string filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->selector));

#ifndef RELEASE
      cout << "loading bugreport '" << filename << "'" << endl;
#endif
      OS* bug_report_replay = new OS_NS::BugReportReplay(filename);
      if (OS_NS::BugReportReplay::bug_report_replay != NULL) {
	static_cast<UI_Wrap*>(::ui)->append(bug_report_replay);
	bug_report_replay->party_open();
	bug_report_replay->party_get_settings();
	this->gui().playfield().party_settings().update();
      } // if (OS_NS::BugReportReplay::bug_report_replay != NULL)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::load()");
    } // void BugReport::load()

  /**
   **
   ** the 'save on desktop' button has been toggled
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    BugReport::save_on_desktop_toggled()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		    "BugReport::save_on_desktop_toggled()");

      ::setting.set(Setting::SAVE_BUG_REPORTS_ON_DESKTOP,
		    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->save_on_desktop)));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_EVENT,
		      "BugReport::save_on_desktop_toggled()");
    } // void BugReport::save_on_desktop_toggled()

  /**
   **
   ** the setting 'save bug reports on desktop' has changed
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  void
    BugReport::save_on_desktop_update()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_UPDATE,
		    "BugReport::save_on_desktop_update()");

      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->save_on_desktop),
				   ::setting(Setting::SAVE_BUG_REPORTS_ON_DESKTOP));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_UPDATE,
		      "BugReport::save_on_desktop_update()");
    } // void BugReport::save_on_desktop_update()

  /*****************************************************************************
   *
   * void BugReport::language_update()
   *
   * Parameters:	none
   *
   * Result:	none
   * 
   * Version:	0.3.6
   *
   * Description:	updates the language in the bug report window
   *
   ****************************************************************************/
  void
    BugReport::language_update()
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_UPDATE,
		    "BugReport::language_update()");

      this->Dialog::language_update();

      gtk_window_set_title(GTK_WINDOW(this->selector),
			   ::language("bug report").c_str());

#ifdef GTK_2_0
      gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(information)),
			       (language("_bug report_") + "\n").c_str(), // text
			       -1); // length
#else
      gtk_text_freeze(GTK_TEXT(information));
      // delete the old text
      gtk_text_set_point(GTK_TEXT(information), 0);
      gtk_text_forward_delete(GTK_TEXT(information),
			      gtk_text_get_length(GTK_TEXT(information)));
      // insert the new text
      gtk_text_insert(GTK_TEXT(information),
		      NULL, // font
		      NULL, // foreground
		      NULL, // background
		      (language("_bug report_") + "\n").c_str(), // text
		      -1); // length
      gtk_text_thaw(GTK_TEXT(information));
#endif
      gtk_label_set_text(GTK_LABEL(file),
			 (language("File") + ": "
			  + ::bug_report.filename()
			 ).c_str()
			);
      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->save_on_desktop)->child),
			 ::language("save on desktop").c_str());
      gtk_label_set_text(GTK_LABEL(GTK_BIN(save)->child),
			 language("Save").c_str());
      gtk_label_set_text(GTK_LABEL(GTK_BIN(cancel)->child),
			 language("Cancel").c_str());

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_UPDATE,
		      "BugReport::language_update()");
    } // void BugReport::language_update()

  /*****************************************************************************
   *
   * void BugReport::key(GdkEventKey* key)
   *
   * Parameters:	key - the pressed key
   *
   * Result:	none
   * 
   * Version:	0.3.7
   *
   * Description:	manages the pressed keys for the BugReport window
   *
   ****************************************************************************/
  void
    BugReport::key(GdkEventKey* key)
    {
      DEBUG_CALLING(INFO_GTK_BUG_REPORT && INFO_GTK_KEY,
		    "BugReport::key()");

#include <gdk/gdkkeysyms.h>

      switch (key->keyval) {
      case GDK_Escape:
	// close this window
	this->close();
	break;
      } // switch (key->keyval)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_BUG_REPORT && INFO_GTK_KEY,
		      "BugReport::key()");
    } // void BugReport::key(GdkKeyEvent);

} // namespace GTK_DOKO
#endif // #ifdef USE_UI_GTK
