/**********************************************************************
 *
 *   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 "dialog.h"
#include "gtk_gui.h"

#include "../../misc/language.h"

namespace GTK_DOKO {
#include <gtk/gtkdialog.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtklabel.h>
#include <gtk/gtksignal.h>

  /**
   **
   ** Destructor
   **
   ** @param	gui	pointer to the gui
   ** @param	title	title of the window
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  Dialog::Dialog(GTK_GUI* const gui, string const& title) :
    gui_(gui),
  title(title),
  window_(gtk_dialog_new()),
  button_close(gtk_button_new_with_label("close"))
  {
    DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_INIT,
		  "Dialog::Dialog()");

    gtk_widget_realize(this->window());

    // Kill of the window
    gtk_signal_connect(GTK_OBJECT(this->window()), "delete_event",
		       GTK_SIGNAL_FUNC(Dialog::delete_event),
		       gpointer(this));
    gtk_signal_connect(GTK_OBJECT(this->window()), "hide",
		       GTK_SIGNAL_FUNC(Dialog::hide_event),
		       gpointer(this));
    // show the window
    gtk_signal_connect(GTK_OBJECT(this->window()), "show",
		       GTK_SIGNAL_FUNC(Dialog::show_event),
		       gpointer(this));
    // button press
    gtk_signal_connect(GTK_OBJECT(this->button_close), "clicked",
		       GTK_SIGNAL_FUNC(Dialog::hide_event),
		       gpointer(this));
    // key press
    gtk_signal_connect(GTK_OBJECT(this->window()), "key_press_event",
		       GTK_SIGNAL_FUNC(Dialog::key_event),
		       gpointer(this));

    // show all widgets
    gtk_widget_show_all(GTK_DIALOG(this->window())->vbox);
    gtk_widget_show_all(GTK_DIALOG(this->window())->action_area);

    this->language_update();

    DEBUG_RETURNING(VOID,
		    INFO_GTK_DIALOG && INFO_GTK_INIT,
		    "Dialog::Dialog()");
  } // Dialog::Dialog(class GTK_GUI* gui_a, string const& title_a)

  /**
   **
   ** Destructor
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  Dialog::~Dialog()
  {
    DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_INIT,
		  "Dialog::~Dialog()");

    gtk_widget_destroy(this->window());

    DEBUG_RETURNING(VOID,
		    INFO_GTK_DIALOG && INFO_GTK_INIT,
		    "Dialog::~Dialog()");
  } // Dialog::~Dialog()

  /**
   **
   ** inits the dialog
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   ** @todo	remove this function
   **
   **/
  void
    Dialog::init()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_INIT,
		    "Dialog::init()");

      // show all widgets
      gtk_widget_show_all(GTK_DIALOG(this->window())->vbox);
      gtk_widget_show_all(GTK_DIALOG(this->window())->action_area);

      this->language_update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_INIT,
		      "Dialog::init()");
    } // void Dialog::init()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the gui
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  GTK_GUI&
    Dialog::gui()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_VALUE,
		    "Dialog::gui()");

      DEBUG_ASSERTION((this->gui_ != NULL),
		      "GTK_GUI& Dialog::gui():\n"
		      "  'gui_' == NULL");

      DEBUG_RETURNING(*(this->gui_),
		      INFO_GTK_DIALOG && INFO_GTK_VALUE,
		      "Dialog::gui()");
    } // GTK_GUI& Dialog::gui()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the window
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  GtkWidget*
    Dialog::window()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_VALUE,
		    "Dialog::window()");

      DEBUG_ASSERTION((this->window_ != NULL),
		      "Dialog::window()\n"
		      "  `window_` == NULL");

      DEBUG_RETURNING(this->window_,
		      INFO_GTK_DIALOG && INFO_GTK_VALUE,
		      "Dialog::window()");
    } // GtkWidget* Dialog::window()

  /**
   **
   ** set the title of the window
   **
   ** @param	title	the new title of the window
   **
   ** @return	the title
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  string&
    Dialog::title_set(string const& title)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_VALUE,
		    "Dialog::title_set()");

      this->title = title;

      this->Dialog::language_update();

      DEBUG_RETURNING(this->title,
		      INFO_GTK_DIALOG && INFO_GTK_VALUE,
		      "Dialog::title_set()");
    } // virtual string& Dialog::title_set(string const& title)

  /**
   **
   ** update the language
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::language_update()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_UPDATE,
		    "Dialog::language_update()");

      // set the title of the window
      if (this->title != "")
	gtk_window_set_title(GTK_WINDOW(this->window()),
			     ::language(this->title).c_str());

      // the button
      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->button_close)->child),
			 ::language("Close").c_str());

      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_UPDATE,
		      "Dialog::language_update()");
    } // void Dialog::language_update()

  /**
   **
   ** event: show the dialog
   **
   ** @param	dialog	the dialog of the event
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::show_event(GtkWidget*, gpointer dialog)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::show_event()");

      static_cast<Dialog*>(dialog)->show();
      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::show_event()");
    } // static void Dialog::show_event(GtkWidget*, gpointer dialog)

  /**
   **
   ** event: hide the dialog
   **
   ** @param	dialog	the dialog of the event
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::hide_event(GtkWidget*, gpointer dialog)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::hide_event()");

      static_cast<Dialog*>(dialog)->close();
      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::hide_event()");
    } // static void Dialog::hide_event(GtkWidget*, gpointer dialog)

  /**
   **
   ** event: hide the dialog
   **
   ** @param	dialog	the dialog of the event
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  gboolean
    Dialog::delete_event(GtkWidget*, GdkEvent*, gpointer dialog)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::delete_event()");

      static_cast<Dialog*>(dialog)->close();
      DEBUG_RETURNING(TRUE,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::delete_event()");
    } // static void Dialog::delete_event(GtkWidget*, GdkEvent*, gpointer dialog)

  /**
   **
   ** event: toggle the appearance of the dialog
   **
   ** @param	dialog	the dialog of the event
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::toggle_event(GtkWidget*, gpointer dialog)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::toggle_event()");

      static_cast<Dialog*>(dialog)->toggle();
      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::toggle_event()");
    } // static void Dialog::toggle_event(GtkWidget*, gpointer dialog)

  /**
   **
   ** show the dialog
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::show()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::show()");

      if (!GTK_WIDGET_VISIBLE(this->window())) {
	this->language_update();
	gtk_widget_show(this->window());
	// *** put the window in the foreground
      } // if (!GTK_WIDGET_VISIBLE(window()))
      gdk_window_raise(this->window()->window);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::show()");
    } // void Dialog::show()

  /**
   **
   ** hide the dialog
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::close()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::close()");

      // hide the window
      if (GTK_WIDGET_VISIBLE(this->window()))
	gtk_widget_hide(this->window());

      this->gui().main_quit();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::close()");
    } // void Dialog::close()

  /**
   **
   ** toggle the appearance of the dialog
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::toggle()
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_EVENT,
		    "Dialog::toggle()");

      // hide the window
      if (GTK_WIDGET_VISIBLE(this->window()))
	this->close();
      else
	this->show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_EVENT,
		      "Dialog::toggle()");
    } // void Dialog::toggle()

  /**
   **
   ** event: key press
   **
   ** @param	key	pressed key
   ** @param	dialog	dialog of the key press
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  gboolean
    Dialog::key_event(GtkWidget*, GdkEventKey* key, gpointer dialog)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_KEY && INFO_GTK_EVENT,
		    "Dialog::key_event()");

      DEBUG_ASSERTION((dialog != NULL),
		      "Dialog::key_event():\n"
		      "  'dialog' == NULL");

      static_cast<Dialog*>(dialog)->key(key);

      DEBUG_RETURNING(FALSE,
		      INFO_GTK_DIALOG && INFO_GTK_KEY && INFO_GTK_EVENT,
		      "Dialog::key_event()");
    } // static gboolean Dialog::key_event(GtkWidget*, GdkEventKey*, gpointer)

  /**
   **
   ** key press
   **
   ** @param	key	pressed key
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    Dialog::key(GdkEventKey* key)
    {
      DEBUG_CALLING(INFO_GTK_DIALOG && INFO_GTK_KEY,
		    "Dialog::key()");

#include <gdk/gdkkeysyms.h>

      switch (key->keyval) {
      case GDK_Return:
#ifdef RELEASE
      case GDK_Escape:
#endif
	// close this window
	this->close();
	break;

      default: // pass the key to the gui
	this->gui().key(key);
	break;
      } // switch (key->keyval)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_DIALOG && INFO_GTK_KEY,
		      "Dialog::key()");
    } // void Dialog::key(GdkKeyEvent);

} // namespace GTK_DOKO 

#endif // #ifdef USE_UI_GTK
