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

//***************************************************************************
// Includes
//***************************************************************************

#include <vdr/interface.h>

#include "menu.h"
#include "pin.h"

//***************************************************************************
// Pin Menu
//***************************************************************************
//***************************************************************************
// Object
//***************************************************************************

cPinMenu::cPinMenu(const char* title, cLockItems* theChannels, 
                   cLockedBroadcasts* theBroadcasts, cLockItems* thePlugins)
   : cOsdMenu(title)
{
   lockedChannels = theChannels;
   lockedBroadcasts = theBroadcasts;
   lockedPlugins = thePlugins;

   cOsdMenu::Add(new cPinMenuItem(tr("1 Edit channel locks"), miEditChannelList));
   cOsdMenu::Add(new cPinMenuItem(tr("2 Edit broadcast locks"), miEditBroadcastList));
   cOsdMenu::Add(new cPinMenuItem(tr("3 Edit plugin locks"), miEditPluginList));
   cOsdMenu::Add(new cPinMenuItem(tr("4 Add current channel to protection list"), miAddCurrentChannel));
   cOsdMenu::Add(new cPinMenuItem(tr("5 Add current broadcast to protection list"), miAddCurrentBroadcast));
   cOsdMenu::Add(new cPinMenuItem(tr("6 Activate lock"), miLock));

	Display();
}

cPinMenu::~cPinMenu()
{
   // Aenderungen speichern

   lockedChannels->Save();
   lockedBroadcasts->Save();
   lockedPlugins->Save();
}

//***************************************************************************
// Process Key
//***************************************************************************

eOSState cPinMenu::ProcessKey(eKeys key)
{
   eOSState state = cOsdMenu::ProcessKey(key);
   int action;

   if (state == osUnknown)
   {
       switch (key)
       {
          case k1:  action = miEditChannelList;     break;
          case k2:  action = miEditBroadcastList;   break;
          case k3:  action = miEditPluginList;      break;
          case k4:  action = miAddCurrentChannel;   break;
          case k5:  action = miAddCurrentBroadcast; break;
          case k6:  action = miLock;                break;
             
          case kOk: action = currentAction();       break;
          default: return state;
       }

       switch (action)
       {
          case miLock:
          {
             cOsd::pinValid = false;
             Skins.Message(mtInfo, tr("Activated pin protection"));
             return osEnd;
          }
          
          case miAddCurrentChannel:   addCurrentChannel();   break;
          case miAddCurrentBroadcast: addCurrentBroadcast(); break;
          case miEditChannelList:     state = AddSubMenu(new cChannelMenu(tr("Protected channels"), lockedChannels));       break;
          case miEditBroadcastList:   state = AddSubMenu(new cBroadcastMenu(tr("Protected broadcasts"), lockedBroadcasts)); break;
          case miEditPluginList:      state = AddSubMenu(new cPluginMenu(tr("Plugin protections"), lockedPlugins));         break;
       }
    }

    return state;
}

//***************************************************************************
// Add Current Channel
//***************************************************************************

int cPinMenu::addCurrentChannel()
{
   char* buf;
   cChannel* channel = Channels.GetByNumber(cDevice::CurrentChannel());

   if (!channel || channel->GroupSep())
      return ignore;

   if (lockedChannels->FindByName(channel->Name()))
   {
      asprintf(&buf, "%s - %s", channel->Name(), tr("already in list"));
      Skins.Message(mtInfo, buf);
      free(buf);

      return ignore;
   }

   asprintf(&buf, "%s - %s", channel->Name(), tr("added to protection list"));
   Skins.Message(mtInfo, buf);
   free(buf);

   // append channel to lock list

   lockedChannels->Add(new cLockItem(channel->Name()));

   return success;
}

//***************************************************************************
// Add Current Broadcast 
//***************************************************************************

int cPinMenu::addCurrentBroadcast()
{
   cSchedulesLock schedLock;
   const cSchedules* scheds;
   const cSchedule *sched;
   const cEvent* event;
   char* buf;

   cChannel* channel = Channels.GetByNumber(cDevice::CurrentChannel());

   if (channel && !channel->GroupSep())
   {
      if (!(scheds = cSchedules::Schedules(schedLock)))
         return done;

      if (!(sched = scheds->GetSchedule(channel->GetChannelID())))
         return done;

      if (!(event = sched->GetPresentEvent()))
         return done;

      // Info

      asprintf(&buf, "%s - %s", event->Title(), tr("added to protection list"));
      Skins.Message(mtInfo, buf);
      free(buf);

      // append event to lock list
      
      lockedBroadcasts->Add(new cLockedBroadcast(event->Title()));
   }

   return success;
}

//***************************************************************************
// Pin Menu Item
//***************************************************************************
//***************************************************************************
// Process Key
//***************************************************************************

cPinMenuItem::cPinMenuItem(const char* title, int aAction) 
   : cOsdItem()
{
   action = aAction;
   SetText(title, /*copy*/ true);
}

//***************************************************************************
// Channel Menu
//***************************************************************************
//***************************************************************************
// Object
//***************************************************************************

cChannelMenu::cChannelMenu(const char* title, cLockItems* theChannels)
   : cOsdMenu(title)
{
   cLockItem* channel;

   lockedChannels = theChannels;

   for (channel = lockedChannels->First(); channel; channel = lockedChannels->Next(channel))
      cOsdMenu::Add(new cChannelMenuItem(channel));

   SetHelp(tr("Edit"), tr("Add"), tr("Delete"), "");
	Display();
}

cChannelMenu::~cChannelMenu()
{
}

//***************************************************************************
// Process Key
//***************************************************************************

eOSState cChannelMenu::ProcessKey(eKeys key)
{
   eOSState state = cOsdMenu::ProcessKey(key);

   if (state == osUnknown)
   {
      switch (key)
      { 
         case kOk:
         case k1:
         case kRed:
         {
            state = AddSubMenu(new cChannelEditMenu(((cChannelMenuItem*)Get(Current()))->GetChannel()));
            break;
         }

         case k2:
         case kGreen:  
         {
            cLockItem* channel;

            lockedChannels->Add(channel = new cLockItem("- new -"));
            cOsdMenu::Add(new cChannelMenuItem(channel));

            Display();
            break;
         }

         case k3:
         case kYellow: 
         {
            if (Interface->Confirm(tr("Remove channel?")))
            {
               // remove from list
                
               lockedChannels->Del(((cChannelMenuItem*)Get(Current()))->GetChannel());
               cOsdMenu::Del(Current());
            }

            Display();             
            break;
         }

         default:  break;
      }
   }

   return state;
}

//***************************************************************************
// Channel Menu Item
//***************************************************************************
//***************************************************************************
// Object
//***************************************************************************

cChannelMenuItem::cChannelMenuItem(cLockItem* aChannel) 
   : cOsdItem()
{
   channel = aChannel;
   SetText(channel->GetName(), /*copy*/ true);
}

cChannelMenuItem::~cChannelMenuItem()
{
}

//***************************************************************************
// Channel Edit Menu
//***************************************************************************
//***************************************************************************
// Object
//***************************************************************************

cChannelEditMenu::cChannelEditMenu(cLockItem* aChannel)
{
   long l;

   channel = aChannel;
   strncpy(name, channel->GetName(), sizeChannelNameMax);
   name[sizeChannelNameMax] = 0;
   active = channel->GetActive();
   l = channel->GetStart();
   start = (l/60/60) * 100 + l/60%60;
   l = channel->GetEnd();
   end = (l/60/60) * 100 + l/60%60;

   SetTitle(channel->GetName());

   Add(new cMenuEditStrItem(tr("Channel"), name, sizeChannelNameMax, 
                            "+-/()[]{}ßöäüÖÄÜ.,;#<>@abcdefghijklmnopqrstuvw0123456789ABCDEFGHIJKLMNOPQRSTUVW"));
   Add(new cMenuEditBoolItem(tr("Lock active"), &active));
   Add(new cMenuEditTimeItem(tr("Start"), &start));
   Add(new cMenuEditTimeItem(tr("Stop"), &end));
}

cChannelEditMenu::~cChannelEditMenu()
{
   // nothing yet
}

//***************************************************************************
// Store
//***************************************************************************

void cChannelEditMenu::Store(void)
{
   channel->SetName(name);
   channel->SetActive(active);

   channel->SetStart((start/100)*60*60 + (start%100)*60);
   channel->SetEnd((end/100)*60*60 + (end%100)*60);
}
