/*
 * console.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */


#include <getopt.h>

#include <vdr/plugin.h>
#include <vdr/skins.h>
#include <vdr/interface.h>

#include "virtualconsoles.h"
#include "config.h"
#include "menu.h"
#include "i18n.h"


static const char *VERSION        = "0.6.0";
static const char *DESCRIPTION    = "Expands VDR to a Console on TV";
static const char *MAINMENUENTRY  = "Consoles";

cConsConsoles* gl_pConsConsoles = NULL;


class cPluginConsole : public cPlugin {
private:
public:
  cPluginConsole(void);
  virtual ~cPluginConsole();
  virtual const char* Version(void) { return VERSION; }
  virtual const char* Description(void) { return tr(DESCRIPTION); }
  virtual const char* CommandLineHelp(void);
  virtual bool ProcessArgs(int argc, char *argv[]);
  virtual bool Start();
  virtual void Housekeeping();
  virtual const char* MainMenuEntry();
  virtual cOsdObject* MainMenuAction();
  virtual cMenuSetupPage* SetupMenu();
  virtual bool SetupParse(const char* Name, const char* Value);
  virtual bool CanShutdown(bool UserShutdown);
};



cPluginConsole::cPluginConsole()
{}



cPluginConsole::~cPluginConsole() {
  delete gl_pConsConsoles;
  gl_pConsConsoles = NULL;
}



const char *cPluginConsole::CommandLineHelp() {

  // Return a string that describes all known command line options.
  return "  -c prog, --command=prog   specify the programm which is\n"
         "                            called when you start the plugin\n";
}



bool cPluginConsole::ProcessArgs(int argc, char *argv[]) {

  // Implement command line argument processing here if applicable.
   static struct option long_options[] = {
       { "command", required_argument, 	NULL, 'c' },
       {  NULL,   no_argument,		NULL,  0  },
   };
   
   int c;
   while ((c = getopt_long(argc, argv, "c:", long_options, NULL)) != -1) {
      switch (c) {
	 case 'c':
	    fprintf(stderr, "arg: %s\n", optarg);
	    ConsoleCmd = strdup(optarg);
	    break;
	 default:
	    fprintf(stderr, "arg char: %c\n", c);
	    return false;
      }
   }
   return true;
}



bool cPluginConsole::Start() {

  RegisterI18n(Phrases);

  gl_ConsoleCommands.Load(AddDirectory(ConfigDirectory(), "commands.conf"));


  // Register a key macro so we can start our own plugin later
  // ---------------------------------------------------------
  // Special thanks for this trick to Andreas Brachold

  // Search for a free virtual key
  consoleOwnerMacro = kSetup + 101;

  for (cKeyMacro* searchKey = KeyMacros.First(); searchKey; searchKey = KeyMacros.Next(searchKey)) {
    if (*searchKey->Macro() > consoleOwnerMacro) {
      consoleOwnerMacro = *searchKey->Macro() + 1;
      break;
    }
  }

  // Register a key macro so we can start our own plugin later
  cKeyMacro* pMacro = new cKeyMacro();
  char* ch = strdup("User9 @console");// Create phantom macro with plugin name
  pMacro->Parse(ch);
  free(ch);
  eKeys* pKeys = ((eKeys*)pMacro->Macro());
  *(pKeys + 0) = ((eKeys)consoleOwnerMacro);
  *(pKeys + 1) = k_Plugin;

  KeyMacros.Add(pMacro);



  // Start the consoles handler
  // --------------------------
  gl_pConsConsoles = new cConsConsoles();
  if (gl_pConsConsoles) {

    gl_pConsConsoles->Start();
    return true;
  }
  return false;
}



void cPluginConsole::Housekeeping() {
  // Perform any cleanup or other regular tasks.
}



const char* cPluginConsole::MainMenuEntry() {
  return tr(MAINMENUENTRY);
}



cOsdObject* cPluginConsole::MainMenuAction() {

  if (! cKbdRemote::KbdAvailable()) {
    // No keyboad available - end with a error message.
    //esyslog("[console] VDR reports: no keyboard avaiable!");
    Skins.Message(mtError, "No Keyboard available!");
    return NULL;
  }


  // What shall we display?
  if (gl_pConsConsoles && gl_pConsConsoles->OpenConsoleNr() >= 0) {

    // Ah, display a special console!
    // Save the number of console to be displayed...
    int nr = gl_pConsConsoles->OpenConsoleNr();
    // ...and reset the nr for the next MainMenuAction.
    gl_pConsConsoles->SetOpenConsoleNr(-1);

    if (nr < gl_pConsConsoles->getCount())
      return new cMenuConsole(nr);
  }

  // Display the usual console list.
  return new cMenuConsoleList();
}



cMenuSetupPage* cPluginConsole::SetupMenu(void) {
  return new cMenuConsoleSetup();
}



bool cPluginConsole::SetupParse(const char* Name, const char* Value) {

  if      (!strcasecmp(Name, "TextColor"))             config.TextColor = atoi(Value);
  else if (!strcasecmp(Name, "BoldTextColor"))         config.BoldTextColor = atoi(Value);
  else if (!strcasecmp(Name, "TextBackColor"))         config.TextBackColor = atoi(Value);
  else if (!strcasecmp(Name, "Font"))                  config.Font = atoi(Value);
  else if (!strcasecmp(Name, "AutoEnterKeyboardMode")) config.AutoEnterKeyboardMode = atoi(Value);
  else if (!strcasecmp(Name, "BellTimeout"))           config.BellTimeout = atoi(Value);
  else if (!strcasecmp(Name, "InfobarTimeout"))        config.InfobarTimeout = atoi(Value);
  else if (!strcasecmp(Name, "PreventShutdown"))       config.PreventShutdown = atoi(Value);
  else if (!strcasecmp(Name, "BlinkRate"))             config.BlinkRate = atoi(Value);

  // For backward compatibility
  else if (!strcasecmp(Name, "CompressText")) {
    config.Font = atoi(Value) ? 2 : 1;
    // Remove this old Setting
//    SetupStore("CompressText");
  }
  else
     return false;

  return true;
}



bool cPluginConsole::CanShutdown(bool UserShutdown) {

  if (config.PreventShutdown && cConsConsoles::Active()) {

    if (UserShutdown)
      return Interface->Confirm(tr("Console(s) running - shut down anyway?"));

    return false;
  }
  return true;
}



VDRPLUGINCREATOR(cPluginConsole); // Don't touch this!

