/****************************************************************************
 * DESCRIPTION:
 *            
 *
 * $Id: autotimer.cpp,v 1.7 2005/05/21 11:58:10 ralf Exp $
 *
 * Contact:    ranga@teddycats.de
 *
 * Copyright (C) 2005 by Ralf Dotzert
 ****************************************************************************/

#include "setup.h"
#include <stdlib.h>
#include "vdr/channels.h"
#include "autotimer.h"
#include "i18n.h"


#ifdef HAVE_ICONPATCH
  #include <vdr/iconpatch.h>
#else
  #define ICON_UHR '*'
#endif

#define FIELD_TITLE       "title"
#define FIELD_SUBTITLE    "subtitle"
#define FIELD_DESCRIPTION "description"

#define WEEK_MON   "Mon"
#define WEEK_TUE   "Tue"
#define WEEK_WED   "Wed"
#define WEEK_THU   "Thu"
#define WEEK_FRI   "Fri"
#define WEEK_SAT   "Sat"
#define WEEK_SUN   "Sun"

#define STRADD(str, args...)   snprintf(str +strlen(str), sizeof(str)-strlen(str), ##args )



cXxvAutoTimer::cXxvAutoTimer()
{
   Reset();
}

void cXxvAutoTimer::Reset( )
{
   _active    = true;
   _done      = true;
   _search[0] = '\0';
   _searchFields[0] = '\0';
   _searchTitle = true;
   _searchSubTitle = true;
   _searchDescription = false;

   _useChannel = false;
   _channels.clear();
   _channelStr.clear();
   _channelNames.clear();
   _nrChannelsToUse = 1;
   _useStart   = false;
   _start     = 0;
   _stop      = 0;
   _useStop    = false;
   _minlength = 0;
   _priority  = autotimerSetup.defaultLifetime;
   _lifetime  = autotimerSetup.defaultPriority;
   _dir[0]    = '\0';

   _vps          = false;
   _prevMinutes  = 0;
   _afterMinutes = 0;

   _useWeekDays  = false;
   _weekMon      = false;
   _weekTue      = false;
   _weekWed      = false;
   _weekThu      = false;
   _weekFri      = false;
   _weekSat      = false;
   _weekSun      = false;
   _weekDays[0]  = '\0';;
   
}


cXxvAutoTimer::~cXxvAutoTimer()
{

}

void cXxvAutoTimer::cXxvAutoTimer::operator =( cXxvAutoTimer &param )
{
  if( &param != this)
  {
       _id = param._id;
       _active = param._active;
       _done   = param._done;
       strcpy(_search, param._search);
       strcpy(_searchFields, param._searchFields);
       _searchTitle       = param._searchTitle;
       _searchSubTitle    = param._searchSubTitle;
       _searchDescription = param._searchDescription;
       _channelNames      = param._channelNames;
       _channelStr        = param._channelStr;
       _nrChannelsToUse   = param._nrChannelsToUse;
       _channels  = param._channels;
       _start     = param._start;
       _stop      = param._stop;
       _minlength = param._minlength;
       _priority  = param._priority;
       _lifetime  = param._lifetime;
       strcpy(_dir, param._dir);
       _useChannel = param._useChannel;
       _useStart   = param._useStart;
       _useStop    = param._useStop;
       strcpy(_sql, param._sql);

       _vps          = param._vps;
       _prevMinutes  = param._prevMinutes;
       _afterMinutes = param._afterMinutes;

       _useWeekDays  = param._useWeekDays;
       _weekMon      = param._weekMon;
       _weekTue      = param._weekTue;
       _weekWed      = param._weekWed;
       _weekThu      = param._weekThu;
       _weekFri      = param._weekFri;
       _weekSat      = param._weekSat;
       _weekSun      = param._weekSun;
       strcpy(_weekDays, param._weekDays);
  }
}



void cXxvAutoTimer::SetInfields( const char * theValue )
{
  strstr(theValue, FIELD_TITLE)       != NULL ? _searchTitle = true : _searchTitle = false;
  strstr(theValue, FIELD_SUBTITLE)    != NULL ? _searchSubTitle = true : _searchSubTitle = false;
  strstr(theValue, FIELD_DESCRIPTION) != NULL ? _searchDescription = true : _searchDescription = false;
}


void cXxvAutoTimer::SetChannels(const char* theValue)
{
  _useChannel = false;
  char *channel = NULL;
  
  if( strlen(theValue)>0)
  {
    channel = strtok((char*)theValue, ",");
    do
    {
      tChannelID cid = tChannelID::FromString(channel);
      if( cid.Valid())
      {
        cChannel *chan = Channels.GetByChannelID(cid);
        if( chan != NULL)
        {
            _channels.push_back(chan->Number());
        }
      }
    }while( (channel=strtok(NULL, ",")));
    _useChannel = true;
    _nrChannelsToUse = _channels.size();
  }
}


void cXxvAutoTimer::SetStart(const int& theValue)
{
  _start = theValue;
   if( theValue != 0)
     _useStart = true;
   else
    _useStart = false;
}


void cXxvAutoTimer::SetStop(const int& theValue)
{
  _stop = theValue;

   if( theValue != 0)
     _useStop = true;
   else
    _useStop = false;
}

const char * cXxvAutoTimer::ToString( )
{
  char *buffer = NULL;
  char *tmp[]  = { NULL, NULL, NULL, NULL };
  int pos = 0;
  asprintf(&tmp[pos++], "\t%s%s%s",
                          _searchTitle ? tr("Display1$T") : "-",
                          _searchSubTitle ? tr("Display2$S") : "-",
                          _searchDescription ? tr("Display3$D") : "-");

    if (_useChannel)
    {
      asprintf(&tmp[pos++], "\t%.7s", GetChannelNames());
    }
    else
      asprintf(&tmp[pos++], "\t--");


    if (_useStart)
      asprintf(&tmp[pos++], "\t%02d:%02d", _start / 100, _start % 100);
    else
      asprintf(&tmp[pos++], "\t--:--");



    if (_useStop)
      asprintf(&tmp[pos++], "\t%02d:%02d", _stop / 100, _stop % 100);
    else
      asprintf(&tmp[pos++], "\t--:--");


  asprintf(&buffer, "%c%s%s%s%s\t%s", _active ? ICON_UHR : ' ', tmp[0], tmp[1], tmp[2], tmp[3], _search);

  //release alloctaed buffers
  free(tmp[0]);
  free(tmp[1]);
  free(tmp[2]);
  free(tmp[3]);

  return(buffer);

}


const char * cXxvAutoTimer::GetChannelNames( )
{
  _channelNames.clear();

  for(unsigned int i=0; i<_channels.size(); i++)
  {
    cChannel *chan = Channels.GetByNumber( _channels[i] );
    if( chan != NULL)
    {
      if(i >0) _channelNames += ", ";
      _channelNames += chan->Name();
    }
  }
  return(_channelNames.c_str());
}


const char * cXxvAutoTimer::GetChannelStr( )
{
  _channelStr.clear();

  if( _useChannel == 1 )
  {
    for(unsigned int i=0; i<_channels.size(); i++)
    {
      cChannel *chan = Channels.GetByNumber(_channels[i]);
      if(chan != NULL)
      {
        char *tmp=NULL;
        asprintf(&tmp, "%s-%d-%d-%d", (const char*)cSource::ToString(chan->Source()),
                                            chan->Nid(), chan->Tid(), chan->Sid());
        if( i>0) _channelStr += ",";
        _channelStr += tmp;
        free(tmp);
      }
    }
  }
  return(_channelStr.c_str());
}


const char * cXxvAutoTimer::fieldsToString( )
{
  bool fieldSet=false;
  _searchFields[0] = '\0';
  if( _searchTitle == 1 || _searchSubTitle == 1 || _searchDescription == 1)
  {
     if( _searchTitle == 1)
     { snprintf(_searchFields +strlen(_searchFields), sizeof(_searchFields), FIELDTITLE);
       fieldSet=true;
     }
     if(_searchSubTitle  == 1)
     { if(fieldSet) snprintf(_searchFields +strlen(_searchFields), sizeof(_searchFields), ",");
       snprintf(_searchFields +strlen(_searchFields), sizeof(_searchFields), FIELDSUBTITLE);
       fieldSet=true;
     }
     if( _searchDescription == 1)
     { if(fieldSet) snprintf(_searchFields +strlen(_searchFields), sizeof(_searchFields), ",");
       snprintf(_searchFields +strlen(_searchFields), sizeof(_searchFields), FIELDDESCRIPTION);
       fieldSet=true;
     }
  }
  return(_searchFields);
}




const char * cXxvAutoTimer::CreateUpdateSqlString(Database *db )
{
  char escSearch[2*sizeof(_search)]= "";
  char escDir[2*sizeof(_dir)]      = "";
  Database::OPENDB  *oDb = db->grabdb();

  mysql_real_escape_string(&(oDb->mysql), escSearch, _search, strlen(_search));
  mysql_real_escape_string(&(oDb->mysql), escDir,    _dir, strlen(_dir));

  _sql[0] = '\0';
  STRADD(_sql,  "UPDATE AUTOTIMER SET Id=%d, Activ='%s', Done='%s', Search='%s', Infields='%s', Channels='%s', Minlength=%d, Priority=%d, Lifetime=%d, Dir='%s'", _id, boolToString(_active), boolToString(_done), escSearch, fieldsToString(), GetChannelStr(), GetMinlength(), GetPriority(), GetLifetime(), escDir);


  _useStart ? STRADD(_sql, ", Start='%04d'", GetStart()) :
              STRADD(_sql, ", Start=NULL");


  _useStop ? STRADD(_sql,  ", Stop='%04d'", GetStop()) :
      STRADD(_sql,  ", Stop=NULL");

  if(!autotimerSetup.xxv020)
    STRADD(_sql,", VPS='%s', prevminutes=%d, afterminutes=%d, weekdays='%s'",  boolToString(_vps), GetPrevMinutes(), GetAfterMinutes(), GetWeekDays());

  STRADD(_sql,  " WHERE Id=%d", _id);

  return(_sql);
}

const char * cXxvAutoTimer::CreateInsertSqlString( Database * db )
{
  char escSearch[2*sizeof(_search)]= "";
  char escDir[2*sizeof(_dir)]      = "";
  Database::OPENDB  *oDb = db->grabdb();

  mysql_real_escape_string(&(oDb->mysql), escSearch, _search, strlen(_search));
  mysql_real_escape_string(&(oDb->mysql), escDir,    _dir, strlen(_dir));

  _sql[0] = '\0';
  STRADD(_sql, "INSERT AUTOTIMER  (Activ, Done,Search,Infields,Channels,  Minlength, Priority, Lifetime, Dir, Start, Stop");

  if(!autotimerSetup.xxv020)
    STRADD(_sql, ",VPS, prevminutes, afterminutes, Weekdays");

  STRADD(_sql,") VALUES('%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s'",
           boolToString(_active), boolToString(_done), escSearch, fieldsToString(),
           GetChannelStr(), GetMinlength(), GetPriority(), GetLifetime(), escDir);

  _useStart ? STRADD(_sql,  ",'%04d'", GetStart()) :
              STRADD(_sql,  ", NULL");


  _useStop ? STRADD(_sql,  ",'%04d'", GetStop()) :
             STRADD(_sql,  ", NULL");

  if(!autotimerSetup.xxv020)
    STRADD(_sql,", '%s', %d, %d, '%s'",  boolToString(_vps), GetPrevMinutes(), GetAfterMinutes(),GetWeekDays());

  STRADD(_sql,  ")");
  
  return(_sql);
}

const char * cXxvAutoTimer::CreateDeleteSqlString( Database * db )
{
  _sql[0] = '\0';
  STRADD(_sql,  "DELETE FROM AUTOTIMER  Where Id=%d", _id);

  return(_sql);
}




void cXxvAutoTimer::SetWeekDays( const char* theValue )
{
  if( theValue != NULL && strlen(theValue)>0)
  {
  _useWeekDays = true;

  strstr(theValue, WEEK_MON)     != NULL ? _weekMon = true : _weekMon = false;
  strstr(theValue, WEEK_TUE)     != NULL ? _weekTue = true : _weekTue = false;
  strstr(theValue, WEEK_WED)     != NULL ? _weekWed = true : _weekWed = false;
  strstr(theValue, WEEK_THU)     != NULL ? _weekThu = true : _weekThu = false;
  strstr(theValue, WEEK_FRI)     != NULL ? _weekFri = true : _weekFri = false;
  strstr(theValue, WEEK_SAT)     != NULL ? _weekSat = true : _weekSat = false;
  strstr(theValue, WEEK_SUN)     != NULL ? _weekSun = true : _weekSun = false;
  }
  else
    _useWeekDays = false;
}




const char * cXxvAutoTimer::GetWeekDays( )
{
  bool fieldSet=false;
  _weekDays[0] = '\0';

  if( _useWeekDays)
  {
    if( _weekMon == 1)
    { snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_MON);
      fieldSet=true;
    }

    if( _weekTue  == 1)
    { if(fieldSet) snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), ",");
      snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_TUE);
      fieldSet=true;
    }

    if( _weekWed  == 1)
    { if(fieldSet) snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), ",");
    snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_WED);
    fieldSet=true;
    }

    if( _weekThu  == 1)
    { if(fieldSet) snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), ",");
    snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_THU);
    fieldSet=true;
    }

    if( _weekFri  == 1)
    { if(fieldSet) snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), ",");
    snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_FRI);
    fieldSet=true;
    }

    if( _weekSat  == 1)
    { if(fieldSet) snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), ",");
    snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_SAT);
    fieldSet=true;
    }

    if( _weekSun  == 1)
    { if(fieldSet) snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), ",");
    snprintf(_weekDays +strlen(_weekDays), sizeof(_weekDays), WEEK_SUN);
    fieldSet=true;
    }
  }

  return(_weekDays);
}

