#ifndef PIPEFACE_PIPEFACE_H
#define PIPEFACE_PIPEFACE_H

#include "pipe/pipe.h"
#include "base/itag.h"
#include "msgcore/message.h"

typedef struct PipeFace {
	Pipe IOPipe;
	int PipeFaceType;
	int RegCount;
	int Flags;
	ITag iTag;

	void (*getmsgFunction)(struct PipeFace *, Message **);
	void (*putmsgFunction)(struct PipeFace *, Message *);

	void (*freeFunction)(struct PipeFace *);
//todo: replace with better identity structures.
	struct PipeFace *opposite;
//todo: get rid of this once the message core is changed
	int retried;
	int active;
} PipeFace;


typedef void (*PipeFaceFuncGetMsg)(struct PipeFace *, Message **);
typedef void (*PipeFaceFuncPutMsg)(struct PipeFace *, Message *);
typedef void (*PipeFaceFuncFree)(struct PipeFace *);


typedef struct PipeFaceArray {
	int size;
	PipeFace **data;
} PipeFaceArray;



#define PFT_UNKNOWN 0
#define PFT_CONNECT 1 //This pipe is going through the hoops to establish a connection.
#define PFT_CORE 2 //a regular node to node connection
#define PFT_VIRC 3 //client irc interface
#define PFT_RAW	100 //primitive raw

#define PFFLAG_DEFAULT		0x0000 
#define PFFLAG_READY		0x0001 //pipeface is ready for messages
#define PFFLAG_BROADCAST	0x0002 //pipeface will do broadcast messages
#define PFFLAG_RELAY		0x0004 //pipeface will do random message relays


#define BLANKPIPEFACE_FUNCS NULL, NULL, NULL
#define BLANKPIPEFACE {BLANKPIPE_FACE, PFT_UNKNOWN, 0, PFFLAG_DEFAULT, 0, BLANKPIPEFACE_FUNCS, NULL, 0, 0}



void pipefaceInit(PipeFace *pf, Pipe *backpipe);
void pipefaceInitFuncs(PipeFace *pf, void (*getf)(struct PipeFace *, Message **), void (*putf)(struct PipeFace *, Message *), void (*freef)(struct PipeFace *));
PipeFace *pipefaceMake(void);
void pipefaceMakeAt(PipeFace *pf);
void pipefaceFree(PipeFace *pf);
void pipefaceSwap(PipeFace *oldpf, PipeFace *newpf);

Message *pipefaceGetMessage(PipeFace *pf);
void pipefacePutMessage(PipeFace *pf, Message *msg);


PipeFaceArray *pfaMake(void);
void pfaAdd(PipeFaceArray *pfa, PipeFace *pf);
void pfaDelete(PipeFaceArray *pfa, PipeFace *pf);
void pipefaceClose(PipeFace *pf);
void pfaSwap(PipeFaceArray *pfa, PipeFace *oldpf, PipeFace *newpf);
int pfaFindByITag(PipeFaceArray *pfa, ITag itag);


#endif //PIPEFACE_PIPEFACE_H
