// src/parseopts.cc - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This 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.
//
// SGPEMv2 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 SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#include "config.h"
#include "gettext.h"

#include <sgpemv2/global_preferences.hh>
#include <sgpemv2/plugin_manager.hh>
#include <sgpemv2/cpu_policy_manager.hh>
#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/module.hh>

#include "text_simulation.hh"
#include "gui_builder.hh"
#include "parse_opts.hh"


#include <glibmm/optioncontext.h>
#include <gtkmm/main.h>

#include <string>
#include <iostream>

using namespace sgpem;
using namespace std;

void
parse_options(int argc, char** argv)
{
  using Glib::OptionEntry;
  using Glib::OptionContext;
  using Glib::OptionGroup;

  print_license();

  // Prepare the option entries

  OptionEntry no_gui;
  OptionEntry policies_dir;
  OptionEntry modules_dir;
  OptionEntry filename;

  no_gui.set_short_name('N');
  policies_dir.set_short_name('P');
  modules_dir.set_short_name('M');

  no_gui.set_long_name("no-gui");
  policies_dir.set_long_name("policies-dir");
  modules_dir.set_long_name("modules_dir");
  filename.set_long_name(G_OPTION_REMAINING);

  no_gui.set_description(_("starts the program in command line mode"));
  policies_dir.set_description(_("adds this directory to the default modules search path"));
  modules_dir.set_description(_("adds this directory to default plugin search path"));
  filename.set_description(_("a list of savefiles; only the first will be opened"));

  // Places where araguments will be saved
  bool no_gui_enabled = false;
  OptionGroup::vecustrings policies_dir_val;
  OptionGroup::vecustrings modules_dir_val;
  OptionGroup::vecstrings  fnames;

  no_gui.set_flags(OptionEntry::FLAG_NO_ARG);
  filename.set_flags(OptionEntry::FLAG_FILENAME | OptionEntry::FLAG_OPTIONAL_ARG);

  // Create the only group
  OptionGroup group("options", "options");

  group.add_entry(no_gui, no_gui_enabled);
  group.add_entry(policies_dir, policies_dir_val);
  group.add_entry(modules_dir, modules_dir_val);
  group.add_entry_filename(filename, fnames);

  // Create context
  OptionContext context(_("SGPEMv2, a graphical simulator for process "
                          "scheduling in a multitasking computer"));

  context.set_main_group(group);
  context.set_help_enabled(true);
  context.set_ignore_unknown_options(false);

  try
  {
    // Parse options, initialising the Gtk::Main at the same time
    Gtk::Main main_loop(argc, argv, context);

    GlobalPreferences& prefs = GlobalPreferences::get_instance();
    try
    {
      prefs.load_configrc();

    }
    catch (std::exception e)
    {
      std::cout << std::endl 
                << _("Error while loading preferences") << std::endl;
    }

    for (Glib::OptionGroup::vecustrings::const_iterator it = policies_dir_val.begin();
         it != policies_dir_val.end(); ++it)
      prefs.add_policies_dir(*it);

    for (Glib::OptionGroup::vecustrings::const_iterator it = modules_dir_val.begin();
         it != modules_dir_val.end(); ++it)
      prefs.add_modules_dir(*it);


    // Now that GlobalPreferences has been initialized properly,
    // initialize plugins, too
    vector<Module*> modules = PluginManager::get_instance().get_module_list();

    for (vector<Module*>::iterator it = modules.begin(); it != modules.end(); ++it)
      (*it)->set_enabled(true);

    vector<CPUPolicyManager*> managers = CPUPoliciesGatekeeper::get_instance().get_registered();

    if (no_gui_enabled)
    {
      // We don't return to main, instead we
      // initialize the command line version
      // of sgpemv2
      TextSimulation sim;
      std::string str;

      std::cout << std::endl 
                << _(" [II] To see a list of commands available,\n"
                     " [II] please type \"help\" and hit the ENTER key.") 
                << std::endl;

      std::cout << std::endl << "% ";
      while (getline(std::cin, str))
      {
        // Enter main loop
        TextSimulation::parse_command(sim, str);
        std::cout << std::endl << "% ";
      }
    }
    else
    {
      GuiBuilder* gui = new GuiBuilder();
      if (fnames.begin() != fnames.end())
        gui->open_file(*fnames.begin());
      main_loop.run(gui->get_initial_window());
      delete gui;
    }

  } // ~ try
  catch (Glib::OptionError e)
  {
    std::cout << _("Bad invocation: ") << e.what() << std::endl;
    std::cout << _("Use the `-?' or `--help' option to see the help") << std::endl;
  }
}


void
print_license()
{
  // Do _NOT_ translate this text.
  std::cerr <<
  "SGPEMv2, Copyright (C) 2005, 2006  University of Padova,\n"
  "                  dept. of Pure and Applied Mathematics.\n"
  "SGPEMv2 comes with ABSOLUTELY NO WARRANTY. This is free \n"
  "software, and you are welcome to redistribute it under  \n"
  "the terms of the GNU General Public License; for details\n"
  "see file COPYING contained in the source package.       \n"
  << std::endl;
}
