
#ifndef _JOB_H
#define _JOB_H

#include "config.h"
#include "header.h"
#include "acbuf.h"
#include <sys/types.h>

class fileitem_base;
typedef SHARED_PTR<fileitem_base> tFileItemPtr;

class con;

class job {


   public:

	   typedef enum
	{
		R_DONE = 0, R_AGAIN = 1, R_DISCON = 2, R_NOTFORUS = 3
	} eJobResult;

	   typedef enum {
	   	STATE_SEND_MAIN_HEAD,
	   	STATE_HEADER_SENT,
	   	STATE_SEND_PLAIN_DATA,
	   	STATE_SEND_CHUNK_HEADER,
	   	STATE_SEND_CHUNK_DATA,
	   	STATE_TODISCON,
	   	STATE_ALLDONE,
	   	STATE_SEND_BUFFER,
	   	STATE_ERRORCONT,
	   	STATE_FINISHJOB
	   } eJobState;

      job(header *h, con *pParent);
      ~job();
      //  __attribute__((externally_visible))  
      
      void PrepareDownload();

      /*
       * Start or continue returning the file.
       */
      eJobResult SendData(int confd, int nAllJobCount);
  
   private:
      
	  int m_filefd;
	  con *m_pParentCon;
      
      bool m_bChunkMode;
      bool m_bClientWants2Close;
      bool m_bIsHttp11;
      bool m_bNoDownloadStarted;
      
      eJobState m_state, m_backstate;
      
      //mstring m_sErrorMsgBuffer;
      tSS m_sendbuf;
      mstring m_sFileLoc; // local_relative_path_to_file
      mstring m_sMaintCmd;
      mstring m_sOrigUrl; // local SAFE copy of the originating source
      
      header *m_pReqHead; // copy of users requests header

      tFileItemPtr m_pItem;
      off_t m_nSendPos, m_nCurrentRangeLast;
      off_t m_nAllDataCount;
      
      unsigned long m_nChunkRemainingBytes;
      USHORT m_type; // file type, bit mask
      
      job(const job&);
      job & operator=(const job&);

      const char * BuildAndEnqueHeader(const FiStatus &fistate, const off_t &nGooddataSize, header& respHead);
      FiStatus _SwitchToPtItem(const mstring &fileLoc);
      void SetErrorResponse(const char * errorLine);
      void HandleLocalDownload(const mstring &visPath,
    			const mstring &fsBase, const mstring &fsSubpath);

      bool ParseRange();

      off_t m_nReqRangeFrom, m_nReqRangeTo;

      int m_nRedirRemaining;
      bool CreateRedirect(header &respHead);
};

#endif
