#ifndef DBTEST_HTTP_H_INCLUDED
#define DBTEST_HTTP_H_INCLUDED 1

#include <in_sock.h>
#include <es_sock.h>
#include <wapcli.h>
#include <AgentClient.h>
#include <capcodec.h>
#include "app_context.h"
#include <intconninit.h>

class MTimeOut {
public:
	virtual void expired() = 0;
};

class CTimeOut : public CTimer {
public:
	void Wait(int seconds);
	void Reset();
	static CTimeOut* NewL(MTimeOut& i_cb);
	virtual ~CTimeOut();
private:
	MTimeOut& cb;

	CTimeOut(MTimeOut& i_cb);
	void ConstructL();
	void RunL();
};

class MSocketObserver {
public:
	virtual void success(CBase* source) = 0;
	virtual void error(CBase* source, TInt code, const TDesC& reason) = 0;
	virtual void info(CBase* source, const TDesC& msg) = 0;
};

class CConnectionOpener : public MContextBase, public CActive, public MTimeOut {
	// separate class since the CIntConnectionInitiator gives multiple
	// events from single invokation :-(
public:
	static CConnectionOpener* NewL(MApp_context& Context, MSocketObserver& Observer);
	void MakeConnectionL(TUint32 Iap); // async
	void CloseConnection(); // sync
	~CConnectionOpener();
private:
	CConnectionOpener(MApp_context& Context, MSocketObserver& Observer);
	void ConstructL();
	enum state { IDLE, CLOSING, RETRYING_CLOSE, CONNECTING, RETRYING_CONNECT, CONNECTED };
	state current_state;
	
	void RunL();
	void DoCancel();
	TInt RunError(TInt aError);

	MSocketObserver& iObserver;
	CIntConnectionInitiator *iInitiator;
	TUint32		iIapId;
	CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref iConnPref;

	TInt	iRetryCount;
	static const TInt MAX_RETRIES;
	CTimeOut	*iWait;
	void expired();

};

class CWap : public CActive, public MContextBase, public MTimeOut, public MSocketObserver {
public:
	static CWap* NewL(MApp_context& Context, MSocketObserver& obs);
	~CWap();
	void Connect(TUint32 IapID, const TDesC& UrlBase);
	void Store(const TDesC& filename);
	void Close();
	void Cwd(const TDesC& dir);
private:
	CWap(MApp_context& Context, MSocketObserver& obs) : MContextBase(Context),
		CActive(EPriorityNormal), observer(obs) { }
	void ConstructL();
	MSocketObserver& observer;
	void MakeContentLength(TUint size, TDes8& header);
	void GetGwAddress(TDes8& addr);
	void ReleaseTx();
	void ReleaseConn();
	void HandleFile();

	// MSocketObserver
	virtual void success(CBase* source);
	virtual void error(CBase* source, TInt code, const TDesC& reason);
	virtual void info(CBase* source, const TDesC& msg);

	void RunL();
	void DoCancel();
	TInt RunError(TInt aError);

	void expired();

	enum state { IDLE, CONNECTING, TX, CONNECTED, RESULT_OK_WAIT };
	state current_state;
	bool		iAgentOpen;
	RWAPServ	server;
	RWSPCOConn	connection;
	bool		iConnOpen;
	RWSPCOTrans	transaction;
	bool		iTxOpen;
	RWSPCOTrans	event_tx;
	RWSPCOConn::TEvent event;
	RGenericAgent agent;

	TUint32		iIapId;
	CCapCodec* iCap;
	CConnectionOpener *iInitiator;

	RFile		file;
	RFile		input;
	TBuf<256>	iPath;
	TBuf<128>	iHost;
	TBuf<40>	iState;
	TFileName	iFilename;
	HBufC8*		iContents;
	HBufC*		iURL;
	TBuf8<100> head;
	TInt		iFileSize;
	TInt		iOffset;
	TInt		iRetryCount;
	static const TInt	MAX_RETRIES;
	static const TInt	MAXSIZE;
	CTimeOut	*iWait;
};

#endif
