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

#include "i18n.h"
#include <vdr/plugin.h>
#include <vdr/device.h>
#include <vdr/menu.h>
#include <vdr/channels.h>
#include <vdr/tools.h>
#include <vdr/osd.h>
#include <vdr/remote.h>
#include <vdr/skins.h>
#include <vdr/config.h>
#include <stdarg.h>

static const char *VERSION        = "0.0.3b";
static const char *DESCRIPTION    = "Organizes instantly a Timer for the next Event";
static const char *MAINMENUENTRY  = "Instantimer";
bool ShowChanInfo 		  = true;
bool HideMenu			  = false;

class cPluginInstantimer : public cPlugin {
private:
  // Add any member variables or functions you may need here.
public:
  cPluginInstantimer(void);
  virtual ~cPluginInstantimer();
  virtual const char *Version(void) { return VERSION; }
  virtual const char *Description(void) { return DESCRIPTION; }
  virtual bool Initialize(void);
  virtual const char *MainMenuEntry(void) { return HideMenu? NULL : MAINMENUENTRY; }
  virtual cOsdObject *MainMenuAction(void);
  virtual cMenuSetupPage *SetupMenu(void);
  virtual bool SetupParse(const char *Name, const char *Value);
  };


cPluginInstantimer::cPluginInstantimer(void)
{
}

cPluginInstantimer::~cPluginInstantimer()
{
}

bool cPluginInstantimer::Initialize(void)
{
    RegisterI18n(iTimerPhrases);
  return true;
}

cOsdObject *cPluginInstantimer::MainMenuAction(void)
{


    cSkinDisplayChannel *displayChannel = Skins.Current()->DisplayChannel(false);
    cSchedulesLock SchedulesLock;
    const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
    if (Schedules) {
	 const cSchedule *Schedule = Schedules->GetSchedule(Channels.GetByNumber(cDevice::CurrentChannel(),0)->GetChannelID());
         if (Schedule) {
            const cEvent *Following = Schedule->GetFollowingEvent();
	    if (Following != NULL)
	    {
		    Timers.IncBeingEdited();
	    	    cTimer *Timer =  Timers.GetMatch(Following);
	       if (Timer)
	        {
//		  esyslog("Wir haben einen Timer");
		  if (Timer->HasFlags(tfSwitchOnly))
		  {
//		    esyslog("Timer ist SwitchOnly");
		    char day[8], file[256], eventStr[256];
		    int channel, start, stop, priority, lifetime;
		    struct tm recStart, recStop;
		    time_t tmpT;

		    channel = Channels.GetByChannelID(Following->ChannelID(), true)->Number();
		    tmpT = Following->StartTime() - Setup.MarginStart * 60;
		    (void) localtime_r(&tmpT, &recStart);
		    tmpT = Following->StartTime() + Following->Duration() + Setup.MarginStop * 60;
		    (void) localtime_r(&tmpT, &recStop);
		    
		    snprintf(day, 8, "%d", recStart.tm_mday);
		    start = (recStart.tm_hour * 100) + recStart.tm_min;
		    stop = (recStop.tm_hour * 100) + recStop.tm_min;
		    priority = Setup.DefaultPriority;
		    lifetime = Setup.DefaultLifetime;
		    *file = '\0';
		    
		    if(!isempty(Following->Title()))  {strncpy(file, Following->Title(), sizeof(file));}
		    
		    snprintf(eventStr, 256, "%d:%d:%s:%04d:%04d:%d:%d:%s:",
			    tfActive, channel, day, start, stop,
			    priority, lifetime, file);

		    Timer->InvFlags(tfSwitchOnly);
		    Timer->SetEvent(Following);
		    Timer->Parse(eventStr);
		    Timers.Save();
		    Timers.SetModified();

                  }
		  else {
//		    esyslog("Wir loeschen den Timer");
		    if(Timer->Recording()) Timer->OnOff();
		    Timers.Del(Timer);
		    Timers.Save();
		    Timers.SetModified();

		  }
		} else
		{
//		    esyslog ("We created a new Timer");
		    cTimer *newTimer;
		    char day[8], file[256], eventStr[256];
		    int channel, start, stop, priority, lifetime;
		    struct tm recStart, recStop;
		    time_t tmpT;
		    newTimer = new cTimer;
		    
		    channel = Channels.GetByChannelID(Following->ChannelID(), true)->Number();
		    tmpT = Following->StartTime();
		    (void) localtime_r(&tmpT, &recStart);
		    tmpT = Following->StartTime() + Following->Duration() + Setup.MarginStop * 60;
		    (void) localtime_r(&tmpT, &recStop);
		    
		    snprintf(day, 8, "%d", recStart.tm_mday);
		    start = (recStart.tm_hour * 100) + recStart.tm_min;
		    stop = (recStop.tm_hour * 100) + recStop.tm_min;
		    priority = Setup.DefaultPriority;
		    lifetime = Setup.DefaultLifetime;
		    *file = '\0';
		    
		    if(!isempty(Following->Title()))  {strncpy(file, Following->Title(), sizeof(file));}
		    
		    snprintf(eventStr, 256, "%d:%d:%s:%04d:%04d:%d:%d:%s:",
			    tfActive, channel, day, start, stop,
			    priority, lifetime, file);

		    newTimer->Parse(eventStr);
		    newTimer->SetEvent(Following);
		    newTimer->SetFlags(tfSwitchOnly);
		    Timers.Add(newTimer);
		    Timers.Save();		
	            Timers.SetModified();
		}
	    Timers.DecBeingEdited();
	    if(ShowChanInfo) {
		displayChannel->Flush();
		return new cDisplayChannel(cDevice::CurrentChannel(), false, false);	
    	    }
		
		
	   }
	}	
      }


  return NULL;
}


class cMenuInstanTimerSetup : public cMenuSetupPage {
private:
	int newShowChanInfo;
	int newHideMenu;
protected:
        virtual void Store(void);
public:
	cMenuInstanTimerSetup(void);
};

cMenuInstanTimerSetup::cMenuInstanTimerSetup(void)
{
	newShowChanInfo = ShowChanInfo;
	newHideMenu	= HideMenu;
	
	Add(new cMenuEditBoolItem (tr("Show Channelinfo after"), &newShowChanInfo));
	Add(new cMenuEditBoolItem (tr("Hide MainMenu Entry"), &newHideMenu));
}

void cMenuInstanTimerSetup::Store(void)
{
    ShowChanInfo  = newShowChanInfo;
    HideMenu      = newHideMenu;
    
    SetupStore("ShowChanInfo",		ShowChanInfo);
    SetupStore("HideMenuEntry",		HideMenu);
}

cMenuSetupPage *cPluginInstantimer::SetupMenu(void)
{
  return new cMenuInstanTimerSetup;
}

bool cPluginInstantimer::SetupParse(const char *Name, const char *Value)
{
    if (!strcasecmp(Name, "ShowChanInfo")) {
	    ShowChanInfo = atoi(Value);
    }
   else if (!strcasecmp(Name, "HideMenuEntry")) {
	    HideMenu = atoi(Value);
   }
   else {
             return false;
   }
   
   return true;

}

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