#ifndef __EPGSEARCH_TOOLS_INC__
#define __EPGSEARCH_TOOLS_INC__

#include <vdr/config.h> // For VDRVERSNUM only
#include <vdr/font.h>
#include "epgsearchext.h"
#include "recdone.h"

#if VDRVERSNUM >= 10336
#define MAXPARSEBUFFER KILOBYTE(10)
#endif

#undef CHANNELNAME
#if VDRVERSNUM && VDRVERSNUM >= 10315
#define CHANNELNAME(x) (x ? x->ShortName(true) : "")
#else
#define CHANNELNAME(x) (x ? x->Name() : "")
#endif

#undef TIMESTRING
#if VDRVERSNUM && VDRVERSNUM >= 10325
#define TIMESTRING(x) *(TimeString(x)) 
#else
#define TIMESTRING(x) TimeString(x)
#endif

#undef DATESTRING
#if VDRVERSNUM && VDRVERSNUM >= 10325
#define DATESTRING(x) *(DateString(x)) 
#else
#define DATESTRING(x) DateString(x)
#endif

#undef GETDATESTRING
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define GETDATESTRING(x) *(x->GetDateString()) 
#else
#define GETDATESTRING(x) x->GetDateString()
#endif

#undef GETTIMESTRING
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define GETTIMESTRING(x) *(x->GetTimeString()) 
#else
#define GETTIMESTRING(x) x->GetTimeString()
#endif

#undef PRINTDAY
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define PRINTDAY *cTimer::PrintDay
#else
#define PRINTDAY cTimer::PrintDay
#endif

#undef DAYDATETIME
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define DAYDATETIME(x) *DayDateTime(x) 
#else
#define DAYDATETIME(x) DayDateTime(x)
#endif

#undef CHANNELSTRING
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define CHANNELSTRING(x) (*x->GetChannelID().ToString()) 
#else
#define CHANNELSTRING(x) (x->GetChannelID().ToString()) 
#endif

#undef WEEKDAYNAME
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define WEEKDAYNAME(x) (*WeekDayName(x)) 
#else
#define WEEKDAYNAME(x) (WeekDayName(x)) 
#endif

#undef ADDDIR
#if VDRVERSNUM && VDRVERSNUM >= 10318
#define ADDDIR *AddDirectory 
#else
#define ADDDIR AddDirectory
#endif


#undef CONFIGDIR
#define CONFIGDIR (!ConfigDir?cPlugin::ConfigDirectory():ConfigDir)

#define CHNUMWIDTH  (numdigits(Channels.MaxNumber()) + 2)

#define SHORTTEXT(EVENT) \
  (EVENT && EPGSearchConfig.showShortText && !isempty((EVENT)->ShortText()))?" ~ ":"", \
  (EVENT && EPGSearchConfig.showShortText && !isempty((EVENT)->ShortText()))?(EVENT)->ShortText():""

#define ISRADIO(x) ((x)->Vpid()==0||(x)->Vpid()==1||(x)->Vpid()==0x1fff)

extern const char AllowedChars[];

extern char* ConfigDir;

// Helper functions
class cSearchExt;
class cSearchExtCat;
class cEvent;

char* IndentMenuItem(const char*);
void PatchFont(eDvbFont);
bool MatchesSearchMode(char* test, char* values, int searchmode, const char* delim, int tolerance);
char* GetExtEPGValue(const cEvent* e, cSearchExtCat* SearchExtCat);
char* GetExtEPGValue(const char* description, const char* catname);
#if VDRVERSNUM > 10343 
char* GetAuxValue(const char* aux, const char* name);
char* GetAuxValue(cRecording *recording, const char* name);
char* GetAuxValue(cTimer* timer, const char* name);
#endif
void ToLower(char* szText);
char *strreplacei(char *s, const char *s1, const char *s2);
char *strreplaceall(char* source, char ch, char* replacement);
void sleepMSec(long ms);
void sleepSec(long s);
bool SendViaSVDRP(const char* SVDRPcmd);
void SendMsg(const char* Message);
bool InEditMode(const char* ItemText, const char* ItemName, const char* ItemValue);
cSearchExt* TriggeredFromSearchTimer(cTimer* timer);
bool CopyFile(char* file_path_from,  char* file_path_to);
double FuzzyMatch(const char* s1, const char* s2, int maxLength);
bool DescriptionMatches(const char* eDescr, const char* rDescr);
const cEvent* GetEvent(cTimer* timer);
char* GetRawDescription(const char* descr);
void PrepareTimerFile(const cEvent* event, cTimer* timer);
int CompareEventTime(const void *p1, const void *p2);
int CompareEventChannel(const void *p1, const void *p2);
bool EventsMatch(const cEvent* event1, const cEvent* event2, bool compareTitle, bool compareSubtitle, bool compareSummary, unsigned long catvaluesAvoidRepeat);
int ChannelNrFromEvent(const cEvent* pEvent);
int ChannelNrFromRecDone(cRecDone* pEvent);
void DelTimer(int index);
char* FixSeparators(char* buffer, char sep);

#if VDRVERSNUM <= 10310    
time_t LastModifiedTime(const char *FileName);
#endif

#if VDRVERSNUM <= 10324    
const char* TimeString(time_t t);
#endif

#if VDRVERSNUM <= 10318    
class cReadLine {
private:
  size_t size;
  char *buffer;
public:
  cReadLine(void);
  ~cReadLine();
  char *Read(FILE *f);
  };
#endif

// --- cTimerObj --------------------------------------------------------
class cTimerObj : public cListObject {
public:
    cTimer* timer;
    cTimerObj(cTimer* Timer) : timer(Timer) {}
    ~cTimerObj() { timer = NULL;  } // do not delete anything!
};

// --- cTimerObjList --------------------------------------------------------
class cTimerObjList : public cList<cTimerObj> {
public:
    void DelTimer(cTimer* t)
	{
	    for (cTimerObj* pTObj = First(); pTObj; pTObj = Next(pTObj))
		if (pTObj->timer == t)
		{
		    Del(pTObj);
		    return;
		}
	}
};

#endif
