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

#include "menu_commands.h"
#include <vdr/interface.h>
#include <vdr/menu.h>
#include <vdr/plugin.h>
#include "menu_searchresults.h"
#include "menu_myedittimer.h"
#include "epgsearchext.h"
#include "epgsearchcfg.h"
#include "tools.h"

// --- cMenuSearchCommands ---------------------------------------------------------

cMenuSearchCommands::cMenuSearchCommands(const char *Title, const cEvent* Event, bool DirectCall)
:cOsdMenu(Title)
{
    directCall = DirectCall;
    SetHasHotkeys();
    LoadCommands();

    event = Event;
    Add(new cOsdItem(hk(tr("Repeats"))));
    Add(new cOsdItem(hk(tr("Record"))));
    Add(new cOsdItem(hk(tr("Switch"))));
    Add(new cOsdItem(hk(tr("Create search"))));
    Add(new cOsdItem(hk(tr("Search in recordings"))));
    for (cCommand *command = commands.First(); command; command = commands.Next(command))
	Add(new cOsdItem(hk(command->Title())));
    if (event)
    {
	char* szTitle = NULL;
	asprintf(&szTitle, "%s: %s", tr("EPG Commands"), event->Title());
	SetTitle(szTitle);
	free(szTitle);
    }
}

cMenuSearchCommands::~cMenuSearchCommands()
{
}

void cMenuSearchCommands::LoadCommands()
{
    const char* szLanguageCode = I18nLanguageCode(Setup.OSDLanguage);
    char *pstrSearchToken, *pptr;
    char *pstrSearch=strdup(szLanguageCode);
    pstrSearchToken=strtok_r(pstrSearch, ",", &pptr);
    bool bLoaded = false;
    while(pstrSearchToken) // may contain multiple code, e.g. 'ger,deu'
    {
	char* cmdFile = NULL;
	asprintf(&cmdFile, "%s-%s.conf", ADDDIR(CONFIGDIR, "epgsearchcmds"), pstrSearchToken);
	if (access(cmdFile, F_OK) == 0) 	
	{
	    commands.Load(cmdFile, true);
	    free(cmdFile);
	    bLoaded = true;
	    break;
	}
	free(cmdFile);
	pstrSearchToken=strtok_r(NULL, ",", &pptr);
    }
    if (!bLoaded)
	commands.Load(AddDirectory(CONFIGDIR, "epgsearchcmds.conf"), true);
    free(pstrSearch);
}

eOSState cMenuSearchCommands::Switch(void)
{
    cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true);
    if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
        return osEnd;
     else
     {
	 Skins.Message(mtInfo, tr("Can't switch channel!")); 
	 return osContinue;
     }
}

eOSState cMenuSearchCommands::ExtendedSearch(void)
{
    return AddSubMenu(new cMenuEPGSearchExt());
}

eOSState cMenuSearchCommands::Record(void)
{
     if (!event) return osContinue;
     cTimer *timer = new cTimer(event);
     cTimer *t = Timers.GetTimer(timer);
     if (t) {
        delete timer;
        timer = t;
        }
     return AddSubMenu(new cMenuMyEditTimer(timer, !t, event));
}

eOSState cMenuSearchCommands::CreateSearchTimer(void)
{
     if (!event) return osContinue;

     cSearchExt* pNew = new cSearchExt;
     strcpy(pNew->search, event->Title());
     return AddSubMenu(new cMenuEditSearchExt(pNew, true));
}

eOSState cMenuSearchCommands::Execute(void)
{
  int current = Current();
  if (current <= 4)
  {
     if (current == 0)
     	return AddSubMenu(new cMenuSearchResults(event->Title()));
     if (current == 1)
	return Record(); 
     if (current == 2)
	 return Switch();
     if (current == 3)
     	return CreateSearchTimer(); 
     if (current == 4)
     	return AddSubMenu(new cMenuSearchResults(event->Title(), true));
  }

  cCommand *command = commands.Get(current-5);
  if (command) {
     char *buffer = NULL;
     bool confirmed = true;
     if (command->Confirm()) {
        asprintf(&buffer, "%s?", command->Title());
        confirmed = Interface->Confirm(buffer);
        free(buffer);
        }
     if (confirmed) {
        asprintf(&buffer, "%s...", command->Title());
        Skins.Message(mtStatus, buffer);
        free(buffer);

        asprintf(&buffer, "\"%s\" %ld %ld %d \"%s\" \"%s\"", event->Title(), event->StartTime(), event->EndTime(), Channels.GetByChannelID(event->ChannelID())->Number(), Channels.GetByChannelID(event->ChannelID())->Name(), event->ShortText()?event->ShortText():"");
        const char *Result = command->Execute(buffer);
        free(buffer);
        Skins.Message(mtStatus, NULL);
        if (Result)
           return AddSubMenu(new cMenuText(command->Title(), Result, fontFix));
        return osBack;
        }
     }
  return osContinue;
}

eOSState cMenuSearchCommands::ProcessKey(eKeys Key)
{
    bool hadSubmenu = HasSubMenu();
    eOSState state = cOsdMenu::ProcessKey(Key);

    // jump back to calling menu, if a command was called directly with key '1' .. '9'
    if (directCall && hadSubmenu && !HasSubMenu())
	return osBack;

    if (state == osUnknown) {
	switch (Key) {
	    case kGreen:
	    case kYellow:
	    case kBlue:
		return osContinue;
	    case kOk:  
		return Execute();
	    default:   break;
	}
    }
    return state;
}
