/*
 * event und message handler
 */

#include <time.h>
#include <unistd.h>
#include <vdr/plugin.h>
#include <vdr/timers.h>
#include "helpers.h"

string cHelpers::GetRunningRecordings()
{
  return SafeCall(GetRunningRecordingsIntern);
}

string cHelpers::GetNextRecordings(time_t& starttime)
{
  return SafeCall(GetNextRecordingsIntern, starttime);
}

string cHelpers::GetRunningRecordingsIntern()
{
  int count = 0;

  // send clear command
  string lines = "CREC\n";
  
  // iterate through all timers
  for(cTimer * timer = Timers.First(); timer; timer = Timers.Next(timer))
  {
    if (timer->Recording())
    {
      lines += string("AREC ") +  (const char *)(timer->ToText());
      count++;
    }
  }

  char text[20];
  sprintf(text, "RECS %d\n", count);

  return lines + text;
}

string cHelpers::GetNextRecordingsIntern(time_t& starttime)
{
  time_t now = time(0);

  cTimer *timer = NULL;
  for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti))
  {
    // skip inactive timers
    if (!ti->HasFlags(tfActive))
      continue;

    // skip old (possibly running) timers
    if (ti->StartTime() < now)
      continue;

    // select the nearest
    if (timer == 0 || ti->Compare(*timer) < 0)
      timer = ti;
  }

  if (timer == NULL)
  {
    starttime = 0;
    return "NNXT\n";
  }

  // assemble text
  string recs = "CNXT\n";
  char text[20];
  starttime = timer->StartTime();
  sprintf(text, "%08x ", (int)starttime);

  // it may be multiple recordings
  for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti))
  {
    // skip inactive or wrong timers
    if (!ti->HasFlags(tfActive) || ti->StartTime() != timer->StartTime())
      continue;

    // cTimer::ToText() already contains a newline
    recs += string("NEXT ") + text + (const char *)(ti->ToText());
  }

  return recs;
}

string cHelpers::ToUpper(string text)
{
  for(unsigned i = 0; i < text.length(); i++)
  {
    if (islower(text[i]))
      text[i] = toupper(text[i]);
  }

  return text;
}

string cHelpers::SafeCall(string (*f)())
{
  // loop, if vdr modified list and we crash
  for (int i = 0; i < 3; i++)
  {
    try
    {
      return f();
    }
    catch (...)
    {
      usleep(100);
    }
  }

  return "";
}

string cHelpers::SafeCall(string (*f)(time_t& starttime), time_t& starttime)
{
  // loop, if vdr modified list and we crash
  for (int i = 0; i < 3; i++)
  {
    try
    {
      return f(starttime);
    }
    catch (...)
    {
      usleep(100);
    }
  }

  return "";
}

