/* -------------------------------------------------------------

   dict.h (part of The TDE Dictionary Client)

   Copyright (C) 2000-2001 Christian Gebauer <gebauer@kde.org>
   (C) by Matthias Hölzer 1998

   This file is distributed under the Artistic License.
   See LICENSE for details.

   -------------------------------------------------------------

   JobData          used for data transfer between Client and Interface
   DictAsyncClient  all network related stuff happens here in an asynchrous thread
   DictInterface    interface for DictAsyncClient, job management

   -------------------------------------------------------------*/

#ifndef _DICT_H_
#define _DICT_H_

#include <tqthread.h>
#include <tqptrlist.h>
#include <tqsocketnotifier.h>

class TQSocketNotifier;
struct in_addr;


//********* JobData ******************************************


class JobData
{

public:
  
  enum QueryType {            //type of transaction
    TDefine=0,
    TGetDefinitions,
    TMatch,
    TShowDatabases,
    TShowDbInfo,
    TShowStrategies,
    TShowInfo,
    TUpdate
  };

  enum ErrType {             // error codes
    ErrNoErr=0,
    ErrCommunication,        // display result!
    ErrTimeout,
    ErrBadHost,
    ErrConnect,              // display result!
    ErrRefused,
    ErrNotAvailable,
    ErrSyntax,
    ErrCommandNotImplemented,
    ErrAccessDenied,
    ErrAuthFailed,
    ErrInvalidDbStrat,
    ErrNoDatabases,
    ErrNoStrategies,
    ErrServerError,          // display result!
    ErrMsgTooLong
  };
  
  JobData(QueryType Ntype,bool NnewServer,TQString const& Nserver,int Nport,
          int NidleHold, int Ntimeout, int NpipeSize, TQString const& Nencoding, bool NAuthEnabled,
          TQString const& Nuser, TQString const& Nsecret, unsigned int NheadLayout);

  QueryType type;
  ErrType error;
  
  bool canceled;
  int numFetched;
  TQString result;
  TQStringList matches;

  TQString query;
  TQStringList defines;

  bool newServer;
  TQString server;
  int port, timeout, pipeSize, idleHold;
  TQString encoding;
  bool authEnabled;
  TQString user, secret;
  TQStringList databases,strategies;
  TQString strategy;
  unsigned int headLayout;
};


//********* DictAsyncClient ******************************************


class DictAsyncClient : public TQThread
{
public:

  DictAsyncClient(int NfdPipeIn, int NfdPipeOut);
  ~DictAsyncClient();

  void run();       // main loop
  void request_termination() { m_request_termination = true; }
  
  void insertJob(JobData *newJob);
  void removeJob(); 

private:

  void define();
  bool getDefinitions();
  bool match();
  void showDatabases();
  void showDbInfo();
  void showStrategies();
  void showInfo();
  void update();

  void openConnection();       // connect, handshake and authorization
  void closeSocket();
  void doQuit();               // send "quit" without timeout, without checks, close connection
  bool waitForRead();          // used by getNextIntoBuffer()
  bool waitForWrite();         // used by sendBuffer() & connect()
  void clearPipe();            // remove start/stop signal

  bool sendBuffer();           // send cmdBuffer to the server
  bool getNextLine();          // set thisLine to next complete line of input
  bool nextResponseOk(int code); // reads next line and checks the response code
  bool getNextResponse(int &code); // reads next line and returns the response code
  void handleErrors();

  void resultAppend(const char* str);
  void resultAppend(TQString str);

  JobData *job;
  char *input;
  TQCString  cmdBuffer;
  const unsigned int inputSize;
  char *thisLine, *nextLine, *inputEnd;
  int fdPipeIn,fdPipeOut;      //IPC-Pipes to/from async thread
  int tcpSocket,timeout,idleHold;
  TQTextCodec *codec;
  bool m_request_termination;
};


//********* DictInterface *************************************************

class DictInterface : public TQObject
{
  TQ_OBJECT
  
 
public:
  
  DictInterface();
  ~DictInterface();

public slots:

  void serverChanged();     // inform the client when server settings get changed
  void stop();              // cancel all pending jobs
   
  void define(const TQString &query);
  void getDefinitions(TQStringList query);
  void match(const TQString &query);
  void showDbInfo(const TQString &db); // fetch detailed db info
  void showDatabases();        // fetch misc. info...
  void showStrategies();
  void showInfo();
  void updateServer();         // get info about databases & strategies the server knows
    
signals:

  void infoReady();                   // updateServer done
  void resultReady(const TQString &result, const TQString &query);     // define done
  void matchReady(const TQStringList &result);  // match done
  void started(const TQString &message);      // Client is active now, activate indicator
  void stopped(const TQString &message);      // Client is now halted, deactivate indicator

private slots:

  void clientDone();

private:

  JobData* generateQuery(JobData::QueryType type, TQString query);
  void insertJob(JobData* job);  // insert in job list, if nesscary cancel/remove previous jobs
  void startClient();            // send start signal
  void cleanPipes();             // empty the pipes, so that notifier stops firing

  TQSocketNotifier *notifier;
  int fdPipeIn[2],fdPipeOut[2];    //IPC-Pipes to/from async thread
  DictAsyncClient *client;
  TQPtrList<JobData> jobList;
  bool newServer,clientDoneInProgress;
};

extern DictInterface *interface;

#endif
