//infer uniform type from structure of ofParameterGroup g
//and set in shader from values in g.
//assumes shader->begin() has been called already
void ofxBaseShaderNode::setShaderParam(ofParameterGroup &g){
    size_t dim = g.size();

    //need to infer the uniform type from size of, and types in, this group
    //unfortunately g.getType(0) is weird and compiler dependent, so this.
    //weep for me, weep for c++
    string type = "";
    if(g.contains("0i"))
        type = "int";
    else if(g.contains("0f"))
        type = "float";

    string param_name = g.getName();

    // cout<<"node "<<name<<" setting "<<type<<" "<<dim<<" uniform "<<param_name<<endl;

    if(type=="float"){
        // cout<<g.getFloat("0f")<<endl;
        switch(dim){
            case 1:
                shader->setUniform1f(param_name, g.getFloat("0f"));
                break;
            case 2:
                shader->setUniform2f(param_name, g.getFloat("0f"), g.getFloat("1f"));
                break;
            case 3:
                shader->setUniform3f(param_name, g.getFloat("0f"), g.getFloat("1f"), g.getFloat("2f"));
                break;
            case 4:
                shader->setUniform4f(param_name, g.getFloat("0f"), g.getFloat("1f"), g.getFloat("2f"), g.getFloat("3f"));
        }
    }
    else if(type=="int"){
        switch(dim){
            case 1:
                shader->setUniform1i(param_name, g.getInt("0i"));
                break;
            case 2:
                shader->setUniform2i(param_name, g.getInt("0i"), g.getInt("1i"));
                break;
            case 3:
                shader->setUniform3i(param_name, g.getInt("0i"), g.getInt("1i"), g.getInt("2i"));
                break;
            case 4:
                shader->setUniform4i(param_name, g.getInt("0i"), g.getInt("1i"), g.getInt("2i"), g.getInt("3i"));
        }
    }
}
//--------------------------------------------------------------
void ofShader::setUniforms(const ofParameterGroup & parameters) const{
	for(int i=0;i<parameters.size();i++){
		if(parameters[i].type()==typeid(ofParameter<int>).name()){
			setUniform1i(parameters[i].getEscapedName(),parameters[i].cast<int>());
		}else if(parameters[i].type()==typeid(ofParameter<float>).name()){
			setUniform1f(parameters[i].getEscapedName(),parameters[i].cast<float>());
		}else if(parameters[i].type()==typeid(ofParameter<ofVec2f>).name()){
			setUniform2f(parameters[i].getEscapedName(),parameters[i].cast<ofVec2f>());
		}else if(parameters[i].type()==typeid(ofParameter<ofVec3f>).name()){
			setUniform3f(parameters[i].getEscapedName(),parameters[i].cast<ofVec3f>());
		}else if(parameters[i].type()==typeid(ofParameter<ofVec4f>).name()){
			setUniform4f(parameters[i].getEscapedName(),parameters[i].cast<ofVec4f>());
		}else if(parameters[i].type()==typeid(ofParameterGroup).name()){
			setUniforms((ofParameterGroup&)parameters[i]);
		}
	}
}
//--------------------------------------------------------------
void testApp::update()
{
	
	// get value directly
	
	string s;
	if (keyValue.get("/string_value", s))
	{
		cout << "/string_value: " << s << endl;
	}
	
	
	// get value as osc message
	
	ofxOscMessage m;
	if (keyValue.get("/test", m))
	{
		cout << "/test: " << m.getArgAsFloat(0) << endl;
	}
	
	
	// use Key-Value-Store style address

	keyValue.get("/myObject1.pos", myObject1.pos);
	keyValue.get("/myObject1.color", myObject1.color);


  for (int i = 0; i < params.size(); i++)
  {
    string name = "/"+params.getName(i);
    if ( keyValue.get( name, params.get(i) ) )
      cout << "update param " << name << " = " << params.get(i) << endl;
  }

	
	// FIFO queue access
	
	int value;
	while (keyValue.get("/uzi", value))
	{
		printf("%i\n", value);
	}

}