#ifndef FILTERCONNECTION_H
#define FILTERCONNECTION_H
#include <vector>
#include "Connection.h"
#define BUFFSIZE 128 //WE SHOULD HAVE A BUFFER MAKER

/* 
 * 5.1.1.2 FilterConnection Interface
 * Inherits from Connection.

    * connectFrom(conn:Connection) Accepts a connection FROM conn connection. 
    * The current filterConnection accepts the connection as an input to the connection.
    * process() A step taken which will read in data and output data, fills and dumps 
    * one buffer. Must be called to move audio.
    * disconnectFrom(conn:Connection) Disconnects an incoming patch between the current 
    * connection and "conn" connection.
    * disconnectTo(conn:Connection)Disconnects an outgoing patch between current
    * connection and "conn" connection. 
    *
*/
template<class SAMPLE> class FilterConnection : private Connection<SAMPLE> {
	//public:	
	//	void connectFrom(Connection<SAMPLE> &conn); // Accepts a connection FROM conn connection. 
	//	virtual void process(); // A step taken which will read in data and output data, 
	//			// fills and dumps one buffer. Must be called to move audio.
         //
    	//	void disconnectFrom(Connection<SAMPLE> &conn); //Disconnects an incoming patch between the current 
    	//				 //connection and "conn" connection.
	//	void disconnectTo(Connection<SAMPLE> &conn);//Disconnects an outgoing patch between current
	//			      //connection and "conn" connection. 
	//	virtual ~FilterConnection();
	//	virtual string xmlType(); //FILTER/INPUT/OUTPUT
	//	string * getXML();
	//	FilterConnection(BufferedFile fd);
	//	FilterConnection(BufferedFile fd,string name);
	//protected: 
	//	void * buffer;
	//	void * buffer2;
	//	vector<Connection<SAMPLE>*> inConnections;
	//private:
	//	void destruct();
	//	void initBuffer();
		void * buffer;
		void * buffer2;
		vector<Connection<SAMPLE>*> inConnections;
	FilterConnection<SAMPLE>(BufferedFile file): inConnections() {
		init(file,"Unnamed");
		initBuffer();
	}
	FilterConnection<SAMPLE>(BufferedFile file,string name): inConnections() {
		init(file,name);
		initBuffer();
	}
	void initBuffer() {
		this.buffer = (void*)(new SAMPLE[BUFFSIZE]);
		this.buffer = (void*)(new SAMPLE[BUFFSIZE]);
	}
	void connectFrom(Connection<SAMPLE> &conn) { // Accepts a connection FROM conn connection. 
		if (conn.readable()) {
			inConnections.push_back(conn);
		} else {
			throw new string("Not A Input Connection");
		}
	}
	virtual void process() {
		int i =0;
		int c = 0;
		int size = inConnections.size();
		vector<Connection<SAMPLE>*>::iterator iter;
		for (iter = inConnections.begin(); iter < inConnections.end(); iter++) {
			c++;
			*iter.read(this.buffer2,BUFFSIZE);
			for (i = 0; i < BUFFSIZE; i++ ) {
				this.buffer[i]+=this.buffer2[i]/size;
			}
		}
		if (c) {
			this.write(this.buffer,BUFFSIZE);
		}
	}
	virtual ~FilterConnection<SAMPLE>() {
		destruct();
	}
	void destruct() {
		delete  buffer;
		delete buffer2;
	}
	void disconnectFrom(Connection<SAMPLE> & conn) { //Disconnects an incoming patch between the current 
		vector<Connection<SAMPLE>*>::iterator iter;
		for (iter = inConnections.begin(); iter < inConnections.end(); iter++) {
			if (*iter == &conn) {
				inConnections.erase(iter);
				break;
			}
		}
	}
	void disconnectTo(Connection<SAMPLE> & conn) {//Disconnects an outgoing patch between current
		conn.disconnectTo(this);
	}
	string * getXML() { //gets an XML string 
		string * out =new string("<connection><type>"+this->xmlType()+"</type><name>"+this->getName()+"</name><id>"+getFileHandle()+"</id></connection>\n");
		vector<Connection<SAMPLE>*>::iterator iter;
		for (iter = inConnections.begin(); iter < inConnections.end(); iter++) {
			(*out)+="<patch><from>"+(*iter)->getFileHandle()+"</from><to>"+getFileHandle()+"</to></patch>";
		}
		return out;
	}
	virtual string  xmlType() { //gets an XML string 
		return "FILTER";
	}
};
#endif

