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

#include <vdr/plugin.h>
#include <vdr/i18n.h>
#include "menu-roaster.h"
#include "commands.h"
#include "statebag.h"
#include "i18n.h"
#include "menu-setup.h"
#include "commands-plugins.h"

static const char *VERSION        = "0.1.1";
static const char *DESCRIPTION    = "Convert video to mpg, iso, and roast!";
static const char *MAINMENUENTRY  = "Roaster";

class cPluginRoaster : public cPlugin {
private:
  // Add any member variables or functions you may need here.
  cRoasterStatebag* Statebag;
public:
  cPluginRoaster(void);
  virtual ~cPluginRoaster();
  virtual const char *Version(void) { return VERSION; }
  virtual const char *Description(void) { return DESCRIPTION; }
  virtual const char *CommandLineHelp(void);
  virtual bool ProcessArgs(int argc, char *argv[]);
  virtual bool Initialize(void);
  virtual bool Start(void);
  virtual void Housekeeping(void);
  virtual const char *MainMenuEntry(void) { return tr(MAINMENUENTRY); }
  virtual cOsdObject *MainMenuAction(void);
  virtual cMenuSetupPage *SetupMenu(void);
  virtual bool SetupParse(const char *Name, const char *Value);
  };

cPluginRoaster::cPluginRoaster(void)
{
  // Initialize any member variables here.
  // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
  // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
  Statebag=new cRoasterStatebag();
}

cPluginRoaster::~cPluginRoaster()
{
  // Clean up after yourself!
  delete Statebag;
}

const char *cPluginRoaster::CommandLineHelp(void)
{
  // Return a string that describes all known command line options.
  return NULL;
}

bool cPluginRoaster::ProcessArgs(int argc, char *argv[])
{
  // Implement command line argument processing here if applicable.
  return true;
}

bool cPluginRoaster::Initialize(void)
{
  // Initialize any background activities the plugin shall perform.
  return true;
}

bool cPluginRoaster::Start(void)
{
  RegisterI18n(Phrases);

  Statebag->RoasterPlugin=this;

  Statebag->ConfigDirectory=ConfigDirectory(Name());
  
  cConfigReader CommandsReader=cConfigReader(Statebag, "commands.conf");
  char* Line=NULL;
  while((Line=CommandsReader.Read()))
  {
    Statebag->GetCommands()->Add(new cRoasterCommandContainer(cRoasterConfigCommand::Parse(Line, Statebag)));
  }

  Statebag->GetCommands()->Add(new cRoasterCommandContainer(new cRoasterCommandImagePlugin()));
  Statebag->GetCommands()->Add(new cRoasterCommandContainer(new cRoasterCommandMPlayerPlugin()));  Statebag->GetCommands()->Add(new cRoasterCommandContainer(new cRoasterCommandMP3Plugin()));
  Statebag->GetCommands()->Add(new cRoasterCommandContainer(new cRoasterCommandThreadList(Statebag)));

  /*
  Do ordering: Mentioned commands first, then unmentioned
  */

  cConfigReader OrderReader=cConfigReader(Statebag, "order.conf");
  cRoasterCommandContainer* Current=Statebag->GetCommands()->First();
  while((Line=OrderReader.Read()))
  {
    cCommandParser Parser=cCommandParser(Line, false, false);
    cString ParsedLine=Parser.Parse();
    const char* Name=(Line[0]=='-' ? *ParsedLine + 1 : *ParsedLine);
    D(fprintf(stderr, "Searching %s in Commands\n", Name));
    for(cRoasterCommandContainer* Command=Current; Command; Command=Command->Next())
    {
      if(strcmp(Command->GetObject()->GetName(), Name)==0)
      {
        if(Line[0]=='-')
        {
          D(fprintf(stderr, "Deleting %s from commands\n", Name));
          Current=Command->Next();
          Command->Unlink();
          delete Command;
          break;
        }
        if(Command!=Current)
        {
          //TODO: Move behaves strange when you do Move(foo, foo) - is this a bug or by design?
          //Then foo->Next()=foo, foo->Prev()=foo...
          Statebag->GetCommands()->Move(Command, Current);
        }
        Current=Command->Next();
        D(fprintf(stderr, "Found %s in Commands - Command is %s, Current is %s\n", Name, Command->GetObject()->GetName(), Current->GetObject()->GetName()));
      }
    }
  }

  D(fprintf(stderr, "Now Commands are Ordered:\n"));
  for(cRoasterCommandContainer* Command=Statebag->GetCommands()->First(); Command; Command=Command->Next())
  {
    D(fprintf(stderr, "%s\n", Command->GetObject()->GetName()));
  }

  return true;
}

void cPluginRoaster::Housekeeping(void)
{
  cThreadContainer* i=Statebag->GetThreads()->First();
  while(i)
  {
    if(i->GetObject()->IsRemoveRequested())
    {
      cThreadContainer* tmp=i;
      i=Statebag->GetThreads()->Next(i);
      Statebag->GetThreads()->Del(tmp);
      continue;
    }
  }
}

cOsdObject *cPluginRoaster::MainMenuAction(void)
{
  D(fprintf(stderr, "starting menu\n"));
  return new cOsdMenuRoaster(Statebag->BaseDir, Statebag);
}

cMenuSetupPage *cPluginRoaster::SetupMenu(void)
{
  return new cRoasterSetupPage(Statebag);
}

bool cPluginRoaster::SetupParse(const char *Name, const char *Value)
{
  if(strcmp(Name, SETUP_PARAM_BASEDIR)==0)
  {
    strcpy(Statebag->BaseDir, Value);
  }
  if(strcmp(Name, SETUP_PARAM_FILTER)==0)
  {
    Statebag->Filter=cString(Value);
  }
  else if(strcmp(Name, SETUP_PARAM_SHOW_HIDDEN_FILES)==0)
  {
    Statebag->ShowHiddenFiles=atoi(Value);
  }
  else if(strcmp(Name, SETUP_PARAM_SHOW_FULL_PATH)==0)
  {
    Statebag->ShowFullPath=atoi(Value);
  }
  else
  {
    return false;
  }
  return true;
}

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