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

#include "nordlichtsepg.h"
#include "mymenuevent.h"
#include "patchfont.h"

int hidemainmenu=false;
int bookmark=2015;
int Step=30;
int keeposd=0;

static const char *VERSION        = "0.3";
static const char *DESCRIPTION    = "Electronic Program Guide";
static const char *MAINMENUENTRY  = "Nordlicht's EPG";

// --- myMenuSetup ------------------------------------------------------------
class myMenuSetup:public cMenuSetupPage
{
 protected:
  virtual void Store()
  {
   SetupStore("hidemainmenu",hidemainmenu);
   SetupStore("bookmark",bookmark);
   SetupStore("step",Step);
   SetupStore("keeposd",keeposd);
  }
 public:
  myMenuSetup()
  {
   Add(new cMenuEditBoolItem(tr("Hide main menu entry"),&hidemainmenu));
   Add(new cMenuEditIntItem(tr("Step width (min)"),&Step));
   Add(new cMenuEditTimeItem(tr("Jump to"),&bookmark));
   Add(new cMenuEditBoolItem(tr("Keep display after switching"),&keeposd));
  }
};

// --- myMenuWhatsOn ----------------------------------------------------------
class myMenuWhatsOn:public cOsdMenu
{
 private:
  char jumptime[16];
  bool next;
  time_t t,t_backup;
  int currentChannel;
  cSchedulesLock schedulesLock;
  const cSchedules *schedules;
  
  int Tab(){if(Setup.UseSmallFont==2)return 5;else return 6;}
  void LoadSchedules(int shift);
  void GoToDay(int day);
  eOSState Switch();
 public:
  myMenuWhatsOn();
  ~myMenuWhatsOn();
  virtual eOSState ProcessKey(eKeys Key);
};

myMenuWhatsOn::myMenuWhatsOn():cOsdMenu("",10,Tab(),2)
{
 if(Setup.UseSmallFont==2)PatchFont(fontSml);
 else PatchFont(fontOsd);

 t=time(NULL);t_backup=0;
 next=false;

 currentChannel=cDevice::CurrentChannel();

 LoadSchedules(0);
}

myMenuWhatsOn::~myMenuWhatsOn()
{
 if(Setup.UseSmallFont==2)cFont::SetFont(fontSml);
 else cFont::SetFont(fontOsd);
}

void myMenuWhatsOn::LoadSchedules(int shift)
{
 t+=shift*Step*60;

 myWhatsOnItem *mi=(myWhatsOnItem *)Get(Current());
 if(mi)currentChannel = mi->channel->Number();

 Clear();
 
 schedules=cSchedules::Schedules(schedulesLock);
 for(cChannel *Channel=Channels.First();Channel;Channel=Channels.Next(Channel))
 {
  if(!Channel->GroupSep())
  {
   const cSchedule *Schedule=schedules->GetSchedule(Channel->GetChannelID());
   if(Schedule)
   {
    const cEvent *Event=next?Schedule->GetEventAround(t):Schedule->GetPresentEvent();
    if(Event)Add(new myWhatsOnItem(Event,Channel,next),Channel->Number()==currentChannel);
   }
  }
 }

 sprintf(jumptime,"%d:%d",bookmark/100,bookmark%100);

 SetTitle(next?*DayDateTime(t):tr("What's on now?"));
 SetHelp(bookmark?jumptime:NULL,"<<",">>",next?tr("Now"):tr("Switch"));
 Display();
}

void myMenuWhatsOn::GoToDay(int day)
{
 
 if(!t_backup)t_backup=t;else t=t_backup;

// int wday;
// time_t tnow=time(NULL);
// struct tm *tmnow=localtime(&tnow);
// if(tmnow->tm_wday==0)wday=6;else wday=tmnow->tm_wday-1;
// if(day<=wday)t+=(7-(wday-day))*86400;
// else t+=(day-wday)*86400;

 t+=day*86400;
 
 next=1;
 LoadSchedules(0);
}

eOSState myMenuWhatsOn::Switch(void)
{
 myWhatsOnItem *item = (myWhatsOnItem *)Get(Current());
 if(item)
 {
  cChannel *channel = Channels.GetByChannelID(item->event->ChannelID(), true);
  if(channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))return keeposd?osContinue:osEnd;
 }
 Skins.Message(mtError, tr("Can't switch channel!"));
 return osContinue;
}

eOSState myMenuWhatsOn::ProcessKey(eKeys Key)
{
 eOSState state = cOsdMenu::ProcessKey(Key);

 if(state == osUnknown)
 {
  switch (Key)
  {
   case k1...k7:GoToDay(Key-k0);break;
   case kRed:	if(bookmark)
		{
		 time_t tnow=time(NULL);
		 struct tm *tmnow=localtime(&tnow);

		 tmnow->tm_hour=bookmark/100;
		 tmnow->tm_min=bookmark%100;
		 t=mktime(tmnow);

		 next=true;
		 LoadSchedules(0);
		}
		break;
   case kGreen:	next=true;
		LoadSchedules(-1);
		break;
   case kYellow:next=true;
		LoadSchedules(1);
		break;
   case kBlue:	if(next)
		{
		 next=false;t_backup=0;
		 t=time(NULL);
		 LoadSchedules(0);
		}
		else return Switch();
		break;
   case kOk:	if(Count())return AddSubMenu(new myMenuEvent((myWhatsOnItem*)Get(Current())));
		break;
   default:	break;
  }
 }
 return state;
}

// --- cPluginNordlichtsepg ---------------------------------------------------
class cPluginNordlichtsepg : public cPlugin {
private:
public:
  cPluginNordlichtsepg(void);
  virtual ~cPluginNordlichtsepg();
  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 Stop(void);
  virtual void Housekeeping(void);
  virtual const char *MainMenuEntry(void) {return hidemainmenu?NULL:MAINMENUENTRY;}
  virtual cOsdObject *MainMenuAction(void);
  virtual cMenuSetupPage *SetupMenu(void);
  virtual bool SetupParse(const char *Name, const char *Value);
  virtual bool Service(const char *Id, void *Data = NULL){return false;};
  virtual const char **SVDRPHelpPages(void){return NULL;};
  virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode){return NULL;};
  };

cPluginNordlichtsepg::cPluginNordlichtsepg(void)
{
}

cPluginNordlichtsepg::~cPluginNordlichtsepg()
{
}

const char *cPluginNordlichtsepg::CommandLineHelp(void)
{
  return NULL;
}

bool cPluginNordlichtsepg::ProcessArgs(int argc, char *argv[])
{
  return true;
}

bool cPluginNordlichtsepg::Initialize(void)
{
 RegisterI18n(Phrases);
 return true;
}

bool cPluginNordlichtsepg::Start(void)
{
 return true;
}

void cPluginNordlichtsepg::Stop(void)
{
}

void cPluginNordlichtsepg::Housekeeping(void)
{
}

cOsdObject *cPluginNordlichtsepg::MainMenuAction(void)
{
  return new myMenuWhatsOn;
}

cMenuSetupPage *cPluginNordlichtsepg::SetupMenu(void)
{
  return new myMenuSetup;
}

bool cPluginNordlichtsepg::SetupParse(const char *Name, const char *Value)
{
 if(!strcmp("hidemainmenu",Name))hidemainmenu=atoi(Value);
 if(!strcmp("bookmark",Name))bookmark=atoi(Value);
 if(!strcmp("step",Name))Step=atoi(Value);
 if(!strcmp("keeposd",Name))keeposd=atoi(Value);
 return false;
}

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