void DeferredLight::draw() const{
	if(renderer->getMode() != DeferredContainer::Light) return;
	Camera* cam = (Camera*)getGame()->getObjectByName("playerCam");
	vec3f posWorldSpace = vec3f(fullTransform*vec4f(0,0,0,1));
	vec3f posViewSpace = vec3f(cam->getView()*vec4f(posWorldSpace,1.0));

	mat4f t(1.0);
	if(glm::length(posViewSpace) > radius) {
		vec3f front = cam->getWorldPos()-posWorldSpace;
		front = glm::normalize(front);
		vec3f dummyUp(0, 1, 0);
		vec3f right = glm::cross(dummyUp, front);
		right = glm::normalize(right);
		vec3f up = glm::cross(front, right);
		up = glm::normalize(up);
		mat4f rot(right.x, right.y, right.z, 0,
				  up.x   , up.y   , up.z   , 0,
				  front.x, front.y, front.z, 0,
				  0      , 0      , 0      , 1);
		t = glm::scale(rot, vec3f(radius));
		t = glm::translate(t, vec3f(0, 0, 1));
		Programs.get("deferredLight").uniform("MVP")->set(cam->projection*cam->getView()*fullTransform*t);
	}
	else
		Programs.get("deferredLight").uniform("MVP")->set(t);

	Programs.get("deferredLight").uniform("invResolution")->set(vec2f(1.0f/Window::getInstance()->getSize().x, 1.0f/Window::getInstance()->getSize().y));
	Programs.get("deferredLight").uniform("color0")->set(renderer->getColor0());
	Programs.get("deferredLight").uniform("color1")->set(renderer->getColor1());
	Programs.get("deferredLight").uniform("depth")->set(renderer->getDepth());
	Programs.get("deferredLight").uniform("lightPos")->set(posViewSpace);
	Programs.get("deferredLight").uniform("invProj")->set(glm::inverse(cam->projection));
	Programs.get("deferredLight").uniform("lightColor")->set(color);
	Programs.get("deferredLight").uniform("lightRadius")->set(radius);
	quad->draw(Programs.get("deferredLight"));
}
DTFrame* ServerClientProxy::getFrameBinaryProtocol(){
    char buff[BUFFLEN];
	int receivedBytes = UDP.Receive(buff,BUFFLEN);
    //copio la lectura en el buffer principal
    if (receivedBytes>0){
        if((this->intBinaryBuffIndex + receivedBytes)<BUFFLEN){
            memcpy(&(this->binaryBuffer)+this->intBinaryBuffIndex,&buff,receivedBytes);
            //aumento el index del buffer
            this->intBinaryBuffIndex += receivedBytes;
        }
    }
    //Cuando hay OVERFLOW, se pierden paquetes--> se da el mismo tratamiento que frente a un error--> se resincroniza mandando mensaje de error
    
    // intento parsear el primer paquete que figura en el buffer principal
    if (this->intBinaryBuffIndex>18){
        //tengo informacion en el buffer
        //el cabezal del paquete tiene 18 bytes
        //obtengo el largo del contenido de data
        
        u_int8_t hi = this->binaryBuffer[15];
        u_int8_t lo = this->binaryBuffer[16];
        
        int size = (hi << 8) + lo;
        bool error=false;
        if(this->intBinaryBuffIndex >= (18+size)){
            //tengo todo el paquete
            
            
            u_int8_t seqIdHi = this->binaryBuffer[9];
            u_int8_t seqIdLo = this->binaryBuffer[10];
            unsigned short sequence= (seqIdHi << 8) + seqIdLo;
            
            u_int8_t minIdHi = this->binaryBuffer[11];
            u_int8_t minIdLo = this->binaryBuffer[12];
            unsigned short minId = (minIdHi << 8) + minIdLo;
            
            u_int8_t maxIdHi = this->binaryBuffer[13];
            u_int8_t maxIdLo = this->binaryBuffer[14];

            unsigned short maxId= (maxIdHi << 8) + maxIdLo;

            unsigned short finished = this->binaryBuffer[17];
            
            int nextPacketSequence = this->sequence + 1;
            if (nextPacketSequence>65535){
                nextPacketSequence=0;
            }
            
            if (nextPacketSequence==sequence){
                if (this->parcialFrame!=0){
                    //continuo construyendo el frame
                    int cont = 0;
                    for (int q=0; q<size; q+=3){
                        u_int8_t cR= this->binaryBuffer[18 + q];
                        u_int8_t cG= this->binaryBuffer[18 + q + 1];
                        u_int8_t cB= this->binaryBuffer[18 + q + 2];
                        float R = (float) cR;
                        float G = (float) cG;
                        float B = (float) cB;
                        ofVec3f dummyFront(0,0,0);
                        ofVec3f dummyUp(0,0,0);
                        //we pass 0 as ledTypeId since is dummy information
                        DTPixel* newPixel = new DTPixel(minId+cont, R, G, B, 255, 0, 0, 0, dummyFront, dummyUp, "dummy",0);
                        this->parcialFrame->addPixel(newPixel);
                        cont++;
                    }

                }
                else{ 
                    vector<DTPixel*>* newPixels = new vector<DTPixel*>;
                    cl_float* pixelArray = new cl_float[this->pixelQuantity * 4];
                    int cont = 0;
                    for (int q=0; q<size; q+=3){
                        u_int8_t cR= this->binaryBuffer[18 + q];
                        u_int8_t cG= this->binaryBuffer[18 + q + 1];
                        u_int8_t cB= this->binaryBuffer[18 + q + 2];
                        float R = (float) cR;
                        float G = (float) cG;
                        float B = (float) cB;
                        ofVec3f dummyFront(0,0,0);
                        ofVec3f dummyUp(0,0,0);
                        //we pass 0 as ledTypeId since is dummy information
                        DTPixel* newPixel = new DTPixel(minId+cont, R, G, B, 255, 0, 0, 0, dummyFront, dummyUp, "dummy",0);
                        newPixels->push_back(newPixel);
                        
                        pixelArray[((minId+cont)*4)]=(cl_float)R;
                        pixelArray[((minId+cont)*4)+1]=(cl_float)G;
                        pixelArray[((minId+cont)*4)+2]=(cl_float)B;
                        pixelArray[((minId+cont)*4)+3]=255.0f;

                        
                        cont++;
                    }
                    this->parcialFrame= new DTFrame(0, newPixels, pixelArray, this->pixelQuantity, sequence);
                }
                this->sequence=nextPacketSequence;
            
            }
            else{
                //error purgo el frame
                error=true;
                this->errorQty+=1;
                if (this->parcialFrame!=0){
                    delete this->parcialFrame;
                }
                this->parcialFrame=0;
                //continuo en el proximo frame a leer desde el nuevo sequence. pueden generarse frames no completos y mezclados
                //debo purgar todo lo recibido, y enviar mensage de esera y retransmision
                this->sendErrorMessage(this->fps,true,this->sequence);
                while (receivedBytes>0){ //limpio el buffer de UDP
                    receivedBytes = UDP.Receive(buff,BUFFLEN);
                }
                //limpio el buffer recibido
                for(int i=0; i<BUFFLEN;i++){
                    this->binaryBuffer[i]=0;
                    this->intBinaryBuffIndex=0;
                }
            }
            if(!error){
                //elimino la informacion procesada del buffer
                
                clearBinaryBuffer(size);
                
                //verifico si el paquete tiene marca de fin de frame
                if(this->parcialFrame!=0){
                    if (finished!=0){
                        //paquete terminado, retorno el dataFrame
                        DTFrame* returningFrame = this->parcialFrame;
                        this->parcialFrame=0;
                        this->updatePixelsFromDTFrame(returningFrame);
                        this->errorWindow-=1;
                        if(this->errorWindow<0){
                            this->errorQty=0;
                            this->errorWindow=10000;
                        }
                        return returningFrame;
                    }
                }
            }
        }
    }
    return 0;
}
DTFrame::DTFrame(string sourceXML)
{
	vector <DTPixel*> * newVector= new vector<DTPixel*>;
	this->pixels=newVector;

	ofxXmlSettings XML;
	XML.loadFromBuffer(sourceXML);
	int protocolVersion = 1;
	//if( XML.bDocLoaded ){
		TiXmlElement* myFrame=XML.doc.RootElement();
        int numPixelTags = XML.getNumTags("Pixel");
		if (myFrame){
			string timestampName = "timestamp";
			if (myFrame->Attribute(timestampName.c_str())){
				this->timestamp=ofToInt(myFrame->Attribute("timestamp"));
			}
			else{
				this->timestamp = 0;
			}
			string clientIDName = "clientID";
			if (myFrame->Attribute(clientIDName.c_str())){
				this->clientID=ofToInt(myFrame->Attribute("clientID"));
			}
			else{
				clientID = 0;
			}
			string clientNameName = "clientName";
			if (myFrame->Attribute(clientNameName.c_str())){
				this->clientName=myFrame->Attribute("clientName");
			}
			else{
				this->clientName="Unknown";
			}
			string protocolVersionName = "protocolVersion";
			if (myFrame->Attribute(protocolVersionName.c_str())){
				protocolVersion=ofToInt(myFrame->Attribute("protocolVersion"));
			}
			else{
				protocolVersion = 1;
			}
            if (protocolVersion==1){
                TiXmlElement* myPixel= myFrame->FirstChildElement();
                if (myPixel){
					int error = 0;
					int cont = 0;
					for( myPixel; myPixel; myPixel=myPixel->NextSiblingElement())
					{
						cont ++;
						string idName = "id";
						int id=0;
						if (ofToInt(myPixel->Attribute(idName.c_str()))){
							id = ofToInt(myPixel->Attribute("id"));
						}
						
						float r=0;
						string rName = "r";
						if (ofToInt(myPixel->Attribute(rName.c_str()))){
							r = ofToFloat(myPixel->Attribute("r"));
						}
						else{
							r=0;
						}

						float g=0;
						string gName = "g";
						if (ofToInt(myPixel->Attribute(gName.c_str()))){
							g = ofToFloat(myPixel->Attribute("g"));
						}
						else{
							g=0;
						}

						float b=0;
						string bName = "b";
						if (ofToInt(myPixel->Attribute(bName.c_str()))){
							b = ofToFloat(myPixel->Attribute("b"));
						}
						else{
							b=0;
						}

						float a=0;
						string aName = "a";
						if (ofToInt(myPixel->Attribute(aName.c_str()))){
							a = ofToFloat(myPixel->Attribute("a"));
						}
						else{
							a=255;
						}
                        
                        TiXmlElement* render=myPixel->FirstChildElement();
                        if (!render){
                            error=1;
                        }
                        
                        string meshName= "mesh";
                        string linkedMesh="";
                        if(render->Attribute(meshName.c_str())){
                            linkedMesh=render->Attribute("mesh");
                        }
                        else{
                            error=1;
                        }
                        
                        ofVec3f front;
                        ofVec3f up;
                        ofVec3f positionPixel;
                        
                        TiXmlElement* frontElement=render->FirstChildElement();
                        if (!frontElement){
                            error=1;
                        }
                        
                        TiXmlElement* upElement=frontElement->NextSiblingElement();
                        if (!upElement){
                            error=1;
                        }
                        
                        TiXmlElement* positionElement=upElement->NextSiblingElement();
                        if (!positionElement){
                            error=1;
                        }
                        
                        string xName = "x";
                        string yName = "y";
                        string zName = "z";
                        
                        float xFront=0.0f;
                        if (frontElement->Attribute(xName.c_str())){
                            string test = frontElement->Attribute("x");
                            xFront=ofToFloat(frontElement->Attribute("x"));
                            //cout << xFront << endl;
                        }
                        else{
                            xFront=0.0f;
                        }
                        
                        float yFront=0.0f;
                        if (frontElement->Attribute(yName.c_str())){
                            yFront=ofToFloat(frontElement->Attribute("y"));
                        }
                        else{
                            yFront=0.0f;
                        }
                        
                        float zFront=0.0f;
                        if (frontElement->Attribute(zName.c_str())){
                            zFront=ofToFloat(frontElement->Attribute("z"));
                        }
                        else{
                            zFront=0.0f;
                        }
                        
                        float xUp=0.0f;
                        if (upElement->Attribute(xName.c_str())){
                            xUp=ofToFloat(upElement->Attribute("x"));
                        }
                        else{
                            xUp=0.0f;
                        }
                        
                        float yUp=0.0f;
                        if (upElement->Attribute(yName.c_str())){
                            yUp=ofToFloat(upElement->Attribute("y"));
                        }
                        else{
                            yUp=0.0f;
                        }
                        
                        float zUp=0.0f;
                        if (upElement->Attribute(zName.c_str())){
                            zUp=ofToFloat(upElement->Attribute("z"));
                        }
                        else{
                            zUp=0.0f;
                        }
                        
                        float xPos=0.0f;
                        if (positionElement->Attribute(xName.c_str())){
                            string test = positionElement->Attribute("x");
                            xPos=ofToFloat(test);
                            //cout << xPos << endl;
                        }
                        else{
                            xPos=0.0f;
                        }
                        
                        float yPos=0.0f;
                        if (positionElement->Attribute(yName.c_str())){
                            yPos=ofToFloat(positionElement->Attribute("y"));
                        }
                        else{
                            yPos=0.0f;
                        }
                        
                        float zPos=0.0f;
                        if (positionElement->Attribute(zName.c_str())){
                            zPos=ofToFloat(positionElement->Attribute("z"));
                        }
                        else{
                            zPos=0.0f;
                        }
                        
                        positionPixel.x = xPos;
                        positionPixel.y = yPos;
                        positionPixel.z = zPos;
                        
                        front.x = xFront;
                        front.y = yFront;
                        front.z= zFront;
                        
                        up.x = xUp;
                        up.y = yUp;
                        up.z = zUp;

						//DTPixel* newPixel = new DTPixel(id,r,g,b,a,x,y,z);
						DTPixel* newPixel = new DTPixel(id,r,g,b,a,positionPixel.x,positionPixel.y,positionPixel.z,front,up,linkedMesh);

						newVector->push_back(newPixel);
                        
 					}
					if (error==1){
						//error
						this->clientID = -1;
					}
                }
				else{
                    
                    //error
                    this->clientID = -1;
					                    
                    
                    
				}
            }
			
			else{
				//el hijo es un nodo CData
                //busqué en internet... y hay algunos problemas al guardar binario en cdata..,
                //hay problemas con: /0, y algún binario que forme ]]> sin querer.
                
                string dataToParse = myFrame->GetText();
                vector<string> parserPixels=ofSplitString(dataToParse, "|");
                for (int i=0; i<parserPixels.size(); i++){
                    string pixelData=parserPixels[i];
                    vector<string> splittedData= ofSplitString(pixelData,";");
                    int parsedId =  ofToFloat(ofSplitString(splittedData[0],":")[1]);
                    float parsedR = ofToFloat(ofSplitString(splittedData[1],":")[1]);
                    float parsedG = ofToFloat(ofSplitString(splittedData[2],":")[1]);
                    float parsedB = ofToFloat(ofSplitString(splittedData[3],":")[1]);
                    float parsedA = ofToFloat(ofSplitString(splittedData[4],":")[1]);
                    ofVec3f dummyFront(0,0,0);
                    ofVec3f dummyUp(0,0,0);
                    
                    DTPixel* newPixel = new DTPixel(parsedId,parsedR,parsedG,parsedB,parsedA,0,0,0,dummyFront,dummyUp,"dummy");
                    
                    newVector->push_back(newPixel);
                    
                }

			}
		}


	//}else{
		//error
	//	this->clientID = -1;
	//}
}