#ifndef __EXTB_IRSEND__H
#define __EXTB_IRSEND__H

#include <vector>
#define __STL_CONFIG_H
#include <vdr/thread.h>

///////////////////////////////////////////////////////////////////////////////
// Want more debugstuff comment out follow line
//#define MOREDEBUGMSG
///////////////////////////////////////////////////////////////////////////////
#ifdef MOREDEBUGMSG 
 #define moredsyslog(a...) dsyslog(a...)
#else 
 #define moredsyslog(a...) void() 
#endif
///////////////////////////////////////////////////////////////////////////////



struct cLircCmd
{
    char*   m_szCmd;
    struct timeval* m_pTime;
    
    cLircCmd(char* szCmd,unsigned int nDelayMS);
};



struct cLircQueue
 : public std::vector<cLircCmd>
{
  virtual ~cLircQueue()
  {
    iterator i = begin();
    const_iterator e = end();
    for(;e!=i;++i) {
        free(i->m_szCmd);
        if(i->m_pTime)
            free(i->m_pTime);
    }
    clear();
  }

  inline size_t max_size() const 
  {
    return 32;
  }

  inline bool add(char* szCmd,unsigned int nDelayMS)
  {
    if(size()<max_size())
    {
      //fprintf(stderr,"extb: add (%d) - %s", nDelayMS, szCmd);fflush( stderr );
      push_back(cLircCmd(szCmd,nDelayMS));

      return true;
    }  
    return false;
  }

  inline void remove(const char* szCmd)
  {
    //fprintf(stderr,"extb: rem %s", szCmd);fflush( stderr );
    iterator i = begin();
    while(end()!=i) {
        if(0 == strcmp(i->m_szCmd,szCmd)) {
            //fprintf(stderr,"extb: del %s", i->m_szCmd);fflush( stderr );
            free(i->m_szCmd);
            if(i->m_pTime)
                free(i->m_pTime);
            erase(i);
        } else {
            ++i;
        }
    }
  }  
};

class cLirc
  : private cThread
{
  char* m_szDevice;
  int m_fd;
  static volatile bool m_bTimeout;

  volatile bool m_bShutdown;
  mutable cMutex    m_Mutex;
  cCondVar  m_condVar;
  cLircQueue m_queue;
  volatile unsigned int m_nQueued;
protected:  
  static void sigalrm(int sig);
  const char *read_string(void);
  int send_packet(const char *packet);

  virtual void Action(void);

  inline bool reopen(void) { return open(m_szDevice);}
public:
  cLirc();
  virtual ~cLirc();
  
  bool open(const char* szDevice);
  inline bool isopen() const { return -1 != m_fd; }
  void close(void);
  void send(const char *cmd,unsigned int nDelayMS = 0,const char *r = NULL);
  void sendmore(const char *cmd);

  void flush();
};


class cLircPtr
{
protected:
  cLirc* m_pLirc;
public:  
  cLircPtr(cLirc* pLirc)
  :m_pLirc(pLirc) { }
};
#endif
