//***************************************************************************
// Group VDR/GraphTFT
// File graphtft.hpp
// Date 28.10.06 - Jörg Wendel
// This code is distributed under the terms and conditions of the
// GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
//--------------------------------------------------------------------------
// Class GraphTft
// Class ComThread
// Class TcpChannel
//***************************************************************************

#ifndef __GRAPHTFT_HPP__
#define __GRAPHTFT_HPP__

#include <X11/Xlib.h>
#include <Imlib2.h>
#include <string.h>

#define __FRONTEND
#include <../common.h>

#include <common.hpp>
#include <../service.h>

#include <thread.h>

class GraphTft;

//***************************************************************************
// TcpChannel
//***************************************************************************

class TcpChannel
{
   public:

      // declarations

      enum Errors
      {
         errChannel = -100,
         
         errUnknownHostname,
         errBindAddressFailed,
         errAcceptFailed,
         errListenFailed,
         errConnectFailed,
         errIOError,
         errConnectionClosed,
         errInvalidEndpoint,
         errOpenEndpointFailed,

         // Warnungen

         wrnNoEventPending,
         errUnexpectedEvent,
         wrnChannelBlocked,
         wrnNoConnectIndication,
         wrnNoResponseFromServer,
         wrnNoDataAvaileble,
         wrnSysInterrupt,
         wrnTimeout
      };

      struct Header
      {
         int command;
         int size;
      };

      // object

      TcpChannel();
      ~TcpChannel();
      
      // api function

      int open(const char* aHost, int aPort);
      int close();
      int look(int aTimeout);
      int read(char* buf, int bufLen);
      int write(int command, const char* buf = 0, int bufLen = 0);
      int isConnected()    { return handle != 0; }

   private:

      int checkErrno();

      int handle;
      unsigned short port;
      char localHost[100];
      char remoteHost[100];
      long localAddr;
      long remoteAddr;
      long timeout;
      int lookAheadChar;
      int lookAhead;
      int nTtlReceived;
      int nTtlSent;
};

//***************************************************************************
// Communication Thread
//***************************************************************************

class ComThread : public cThread, public cGraphTftComService
{
   public:
      
      enum Misc
      {
         maxBuffer = 1024*1024
      };

      ComThread();
      virtual ~ComThread();

      void stop();

      int mouseEvent(int x, int y, int button, int flag, int data = 0);
      int keyEvent(int key, int flag);

      const char* getBuffer()            { return buffer; }
      int getSize()                      { return header->size; }

      void setHost(const char* aHost)    { strcpy(host, aHost); }
      void setPort(unsigned short aPort) { port = aPort; }
      void setClient(GraphTft* aClient)  { client = aClient; }

   protected:
      
      void Action();
      int read();

      TcpChannel* line;

      char* buffer;
      int bufferSize;
      GraphTft* client;

      long timeout;
      int running;
      TcpChannel::Header* header;
      unsigned short port;
      char host[100];
};

//***************************************************************************
// Graph TFT
//***************************************************************************

class GraphTft
{
   public:
      
      GraphTft();
      virtual ~GraphTft();

      int init();
      int exit();
      int start();
      int run();
      int paint();

      void setArgs(int argc, char *argv[]);
      int sendEvent();
      void updateImage(const unsigned char* buffer, int size);
      void dumpImage(Imlib_Image image);
      void showUsage();
      int resizeBuffer(int size);
      int onButtonPress(XEvent event, int press);
      int onKeyPress(XEvent event);

      static void setEloquence(int aElo) { eloquence = aElo; }
      static int getEloquence()          { return eloquence; }

   protected:
      
      // data

      Window win;
      Display* disp;
      Imlib_Image image;
      ComThread* thread;
      int hideCursor;
      int resize;
      int managed;
      int width;
      int height;
      int border;
      char dump[200];
      int showHelp;
      cMutex bufferLock;
      char* pixelBuffer;
      int pixelBufferSize;
      int vdrWidth;
      int vdrHeight;

      static int eloquence;
};

//***************************************************************************
#endif  // __GRAPHTFT_HPP__
