/* This file is part of cardwords
   (c) 1999 Tobias Peters
   see file COPYING for the copyright terms.
   
   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 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
*/

// cardwords_gtk_startserverdialog.cc

#include "cardwords_gtk_startserverdialog.hh"
#include "cardwords_gettext.hh"
#include "cardwords_readfile.hh"
#include <gtk--/button.h>
#include <gtk--/label.h>
#include <gtk--/spinbutton.h>
#include <gtk--/adjustment.h>
#include <gtk--/fileselection.h>

static const string option_names[11] = {
  "server_program",
  "charset_file",
  "cardset_file",
  "cardtable_file",
  "bonus_file",
  "dictionary_file",
  "personal_dictionary_file",
  "number_of_players",
  "number_of_robots",
  "number_of_watchers",
  "local_port_number",
};

static const string default_string_values[11] = {
  BINDIR_STR "/cardwords_server",
  LIBDIR_STR "/default.charset",
  LIBDIR_STR "/default.cards",
  LIBDIR_STR "/default.cardtable",
  LIBDIR_STR "/default.bonus",
  LIBDIR_STR "/default.dictionary",
  "",
  "NEVER SEEN",
  "NEVER SEEN",
  "NEVER SEEN",
  "NEVER SEEN"
};
static const unsigned default_unsigned_values[11] = {
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  1,
  1,
  0,
  DEFAULT_PORT
};
static const unsigned default_unsigned_lowers[11] = {
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  1,
  0,
  0,
  1024
};
static const unsigned default_unsigned_uppers[11] = {
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  100,
  100,
  100,
  65525
};
static const unsigned default_unsigned_page_incr[11] = {
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  (unsigned)-1,
  3,
  3,
  3,
  20
};

static const string label_text[11] = {
  gettext_noop("Server program:"),
  gettext_noop("Charset file:"),
  gettext_noop("Cardset file:"),
  gettext_noop("Card-table file:"),
  gettext_noop("Bonus file:"),
  gettext_noop("Dictionary file:"),
  gettext_noop("Personal dictionary file:"),
  gettext_noop("Number of players:"),
  gettext_noop("Number of robots:"),
  gettext_noop("Number of watchers:"),
  gettext_noop("Port number:")
};

CardWords_Gtk_StartServerDialog::
CardWords_Gtk_StartServerDialog(CardWords_Options * opt)
  : Gtk::Table(12, 3, false),
    options(opt)
  // [0] - server program
  // [1] - charset file
  // [2] - cardset file
  // [3] - cardtable file
  // [4] - bonus file
  // [5] - dictionary file
  // [6] - personal dictionary file
  // [7] - number of players
  // [8] - number of robots
  // [9] - number of watchers
  // [10]- port number
{
  help_button = new Gtk::Button(gettext("Help"));
  attach(*help_button, 0,3, 11,12);
  help_button->show();
  help_button->clicked.
    connect(SigC::slot(this, &CardWords_Gtk_StartServerDialog::emit_help_signal));
  
  int row;
  for (row = 0; row < 11; ++row) {
    label[row] = new Gtk::Label(gettext(label_text[row].c_str()));
    label[row]->set_alignment(1.0, 0.5);
    attach(*label[row], 0,1, row,row+1, 0,0);
    label[row]->show();

    bool is_filename = row < 7;

    if (is_filename) {

      entry[row] = new Gtk::Entry;
      switch (options->get_type(option_names[row])) {
      case UNKNOWN_TYPE:
        entry[row]->set_text(default_string_values[row]);
        break;
      case STRING_TYPE:
        {
          string text;
          options->get(option_names[row], &text);
          entry[row]->set_text(text);
        }
        break;
      default:
        // There must be a false entry in the options file
        options->false_entry(option_names[row], "string");
        // This exits the program.
      }

      adjustment[row] = 0;

      choose_file_button[row] = new Gtk::Button(gettext("Choose file"));
      attach(*choose_file_button[row], 2,3, row,row+1, 0);
      choose_file_button[row]->show();
      choose_file_button[row]->clicked.
        connect(bind(SigC::slot(this,
                          &CardWords_Gtk_StartServerDialog::
                          show_file_selection),
                     row));
    }
    else { // no filename
      adjustment[row] =
        new Gtk::Adjustment(default_unsigned_values[row],
                           default_unsigned_lowers[row],
                           default_unsigned_uppers[row],
                           1,
                           default_unsigned_page_incr[row],
                           default_unsigned_page_incr[row]);
      
      entry[row] = new Gtk::SpinButton(*adjustment[row], 1, 0);
      switch (options->get_type(option_names[row])) {
      case UNKNOWN_TYPE:
        break;
      case UNSIGNED_TYPE:
        {
          unsigned value;
          options->get(option_names[row], &value);
          assert(dynamic_cast<Gtk::SpinButton *>(entry[row]) != 0);
          dynamic_cast<Gtk::SpinButton *>(entry[row])->set_value(value);
        }
        break;
      default:
        // There must be a false entry in the options file
        options->false_entry(option_names[row], "unsigned");
        // This exits the program.
      }

      choose_file_button[row] = 0;
    }
    attach(*entry[row], 1,2, row,row+1);
    entry[row]->show();

    file_selection[row] = 0;
  }
}
CardWords_Gtk_StartServerDialog::~CardWords_Gtk_StartServerDialog()
{
  help_button->hide();

  remove(*help_button);
  delete help_button;

  size_t index;
  for (index = 0; index < 11; ++index) {
    label[index]->hide();
    remove(*label[index]);
    delete label[index];

    entry[index]->hide();
    remove(*entry[index]);
    delete entry[index];
    
    if (choose_file_button[index] != 0) {
      choose_file_button[index]->hide();
      remove(*choose_file_button[index]);
      delete choose_file_button[index];
    }
    if (file_selection[index] != 0) {
      delete file_selection[index];
    }
    if (adjustment[index] != 0) {
      delete adjustment[index];
    }
  }
}

// Put the entries' contents into the options object.
void
CardWords_Gtk_StartServerDialog::store_options(void)
{
  size_t index;

  for (index = 0; index < 7; ++index) {
    options->set(option_names[index], entry[index]->get_text());
  }
  for (index = 7; index < 11; ++index) {
    assert(dynamic_cast<Gtk::SpinButton *>(entry[index]) != 0);
    options->set(option_names[index],
                 static_cast<unsigned>
                 (dynamic_cast<Gtk::SpinButton *>(entry[index])
                  ->get_value_as_int())
                 );
  }
}
void
CardWords_Gtk_StartServerDialog::show_file_selection(int index)
{
  if (file_selection[index] != 0) {
    // The window is already open but hidden behind some other windows on
    // the screen. This should bring it to the top again.
    gdk_window_show(this->get_window());
    gdk_window_raise(this->get_window());
  }
  else {
    file_selection[index] = new Gtk::FileSelection(label_text[index]);
    file_selection[index]->set_filename(entry[index]->get_text());
  
    file_selection[index]->get_ok_button()->clicked.
      connect(bind(SigC::slot(this,
                        &CardWords_Gtk_StartServerDialog::
                        file_selection_dialog_ok),
                   index));

    file_selection[index]->get_cancel_button()->clicked.
      connect(bind(SigC::slot(this,
                        &CardWords_Gtk_StartServerDialog::
                        file_selection_dialog_cancel),
                   index));

    file_selection[index]->delete_event.
      connect(SigC::slot(this,
                   &CardWords_Gtk_StartServerDialog::
                   file_selection_dialog_delete)/* ,
                                                   index */);

    file_selection[index]->show();
  }
}

void
CardWords_Gtk_StartServerDialog::file_selection_dialog_ok(int index)
{
  assert (file_selection[index] != 0);
  entry[index]->set_text(file_selection[index]->get_filename());
  file_selection[index]->hide();
  delete file_selection[index];
  file_selection[index] = 0;
}
int
CardWords_Gtk_StartServerDialog::
file_selection_dialog_delete(GdkEventAny * /* , int index */)
{
  for (int index = 0; index < 11; ++index) {
    if (file_selection[index])
      file_selection_dialog_cancel(index);
  }
  return true;
}
void
CardWords_Gtk_StartServerDialog::file_selection_dialog_cancel(int index)
{
  assert (file_selection[index] != 0);
  file_selection[index]->hide();
  delete file_selection[index];
  file_selection[index] = 0;
}
void
CardWords_Gtk_StartServerDialog::emit_help_signal(void)
{
  CardWords_ReadFile help_file(gettext("/gtk_startserverdialog.help_text"));
  // Note to *translators*: this is the name of a file containing a help text.
  // The help text is generated from the README.<locale>.sgml.m4 file.
  // The filename above is then to be translated to
  // "/gtk_clientoptionsdialog.<locale>.help_text".
  // But leave this untranslated as long as there is no translated version
  // of the README. If you want to translate the README, please contact me at
  // cardwords@crosswinds.net . Tobias.
  
  if (help_file == false) {
    // Help text file not found
    cerr << gettext("WARNING: Cannot open help text file ")
         << LIBDIR_STR
         << gettext("/gtk_startserverdialog.help_text")
         << endl;
    return;
  }

  help_signal(help_file.str());
}
