bool ComputeShaderChunk::addNodeProceduralVariable(
    const Char8              *name,
          ProcVarNodeFunctor  pFunc,
          UInt32              uiDependency)
{
    if(_sfVariables.getValue() == NULL)
    {
        ShaderProgramVariablesUnrecPtr pParam = 
            ShaderProgramVariables::createDependent(
                this->getFieldFlags()->_bNamespaceMask);

        setVariables(pParam);

        if(_mfComputeShader.size() > 0)
        {
            _mfComputeShader[0]->setVariables(this->getVariables());
        }
    }

    return _sfVariables.getValue()->addNodeProceduralVariable(
        name, 
        pFunc,
        uiDependency,
        editMFProceduralVariableLocations());
}
bool ShaderProgram::addNodeProceduralVariable(
    const Char8              *name,
          ProcVarNodeFunctor  pFunc,
          UInt32              uiDependency)
{
    if(_sfVariables.getValue() == NULL)
    {
        ShaderProgramVariablesUnrecPtr pParam = 
            ShaderProgramVariables::create();

        setVariables(pParam);
    }

#if 0
    return _sfVariables.getValue()->addNodeProceduralVariable(
        name, 
        pFunc,
        uiDependency,
        editMFProceduralVariableLocations());
#else
    return _sfVariables.getValue()->addNodeProceduralVariable(
        name, 
        pFunc,
        uiDependency,
        NULL);
#endif
}
void ComputeShaderChunk::clearUniformVariables(void)
{
    if(_sfVariables.getValue() != NULL)
    {
        _sfVariables.getValue()->clearUniformVariables();
    }

    editMFVariableLocations          ()->clear();
    editMFProceduralVariableLocations()->clear();
}
bool ComputeShaderChunk::subUniformVariable(const Char8 *name)
{
    if(_sfVariables.getValue() != NULL)
    {
        return _sfVariables.getValue()->subUniformVariable(
            name,
            editMFVariableLocations(),
            editMFProceduralVariableLocations());
                                                     
    }

    return false;
}
bool ShaderProgram::subUniformVariable(const Char8 *name)
{
    if(_sfVariables.getValue() != NULL)
    {
#if 0
        return _sfVariables.getValue()->subUniformVariable(
            name,
            editMFVariableLocations(),
            editMFProceduralVariableLocations());
#else
        return _sfVariables.getValue()->subUniformVariable(
            name,
            NULL,
            NULL);
#endif                                                     
    }

    return false;
}
bool ShaderProgram::addOSGVariable(const Char8 *name)
{
    if(_sfVariables.getValue() == NULL)
    {
        ShaderProgramVariablesUnrecPtr pVar = 
            ShaderProgramVariables::create();

        setVariables(pVar);
    }

#if 0
    return _sfVariables.getValue()->addOSGVariable(
        name, 
        editMFProceduralVariableLocations());
#else
    return _sfVariables.getValue()->addOSGVariable(name, 
                                                   NULL);
#endif
}
bool ComputeShaderChunk::addOSGVariable(const Char8 *name)
{
    if(_sfVariables.getValue() == NULL)
    {
        ShaderProgramVariablesUnrecPtr pVar = 
            ShaderProgramVariables::createDependent(
                this->getFieldFlags()->_bNamespaceMask);

        setVariables(pVar);
        
        if(_mfComputeShader.size() > 0)
        {
            _mfComputeShader[0]->setVariables(this->getVariables());
        }
    }

    return _sfVariables.getValue()->addOSGVariable(
        name, 
        editMFProceduralVariableLocations());
}
void ShaderExecutableChunk::changed(ConstFieldMaskArg whichField, 
                                    UInt32            origin,
                                    BitVector         details)
{
    bool bMarkChanged = false;

    if(0x0000 != (whichField & VariablesFieldMask))
    {
        ShaderProgramVariables *pVars = _sfVariables.getValue();

        if(pVars != NULL)
        {
            if(details == 0x0001)
            {
                // be save reset all locations

                if(pVars->getMFVariables()->size() == 0)
                {
                    editMFVariableLocations()->clear();
                }
                else
                {
                    editMFVariableLocations()->resize(
                        pVars->getMFVariables()->size(), 
                        -1);

                    std::fill(editMFVariableLocations()->begin(),
                              editMFVariableLocations()->end  (),
                              -1);
                }

                // be save reset all locations

                if(pVars->getMFProceduralVariables()->size() == 0     )
                {
                    editMFProceduralVariableLocations()->clear();
                }
                else
                {
                    editMFProceduralVariableLocations()->resize(
                        pVars->getMFProceduralVariables()->size(), 
                        -1);

                    std::fill(editMFProceduralVariableLocations()->begin(),
                              editMFProceduralVariableLocations()->end  (),
                              -1);
                }
            }
        }

        Window::refreshGLObject(this->getGLId());
    }

    if(0x0000 != (whichField & (VertexShaderFieldMask   | 
                                GeometryShaderFieldMask |
                                FragmentShaderFieldMask )))
    {
        if(details == ShaderProgram::ProgramFieldMask)
        {
            Window::reinitializeGLObject(this->getGLId());
        }

        else if(details == ShaderProgram::VariablesFieldMask)
        {
            this->remergeVariables();

            Window::refreshGLObject(this->getGLId());
        }
        
        bMarkChanged = true;
    }

    if(0x0000 != (whichField & (GeometryVerticesOutFieldMask | 
                                GeometryInputTypeFieldMask   | 
                                GeometryOutputTypeFieldMask  )))
    {
        // changing parameters requires re-linking the shader
        Window::reinitializeGLObject(this->getGLId());
    }

    if(bMarkChanged == true)
    {
        // be save reset all locations

        std::fill(editMFVariableLocations()->begin(),
                  editMFVariableLocations()->end  (),
                  -1);

        std::fill(editMFProceduralVariableLocations()->begin(),
                  editMFProceduralVariableLocations()->end  (),
                  -1);
    
        if(_sfVariables.getValue() != NULL)
        {
            _sfVariables.getValue()->markAllChanged();
        }
    }

    Inherited::changed(whichField, origin, details);
}
void ComputeShaderChunk::changed(ConstFieldMaskArg whichField, 
                             UInt32            origin,
                             BitVector         details)
{
    bool bMarkChanged = false;

    if(0x0000 != (whichField & ComputeProgramFieldMask) &&
       0      != _sfComputeProgram.getValue().size()     )
    {
        if(_mfComputeShader.size() == 0)
        {
            ShaderProgramUnrecPtr pProg = ShaderProgram::createDependent(
                this->getFieldFlags()->_bNamespaceMask);

            pProg->setShaderType(GL_COMPUTE_SHADER);

            addComputeShader(pProg);

            pProg->setVariables(this->getVariables());
        }
        else if(_mfComputeShader.size() > 1)
        {
            editMFComputeShader()->resize(1);
        }
        
        _mfComputeShader[0]->setProgram(_sfComputeProgram.getValue());

        bMarkChanged = true;

        Window::reinitializeGLObject(this->getGLId());
    }


    if(0x0000 != (whichField & VariablesFieldMask))
    {
        ShaderProgramVariables *pVars = _sfVariables.getValue();

        if(pVars != NULL)
        {
            if(details == 0x0001)
            {
                // be save reset all locations

                if(pVars->getMFVariables()->size() == 0)
                {
                    editMFVariableLocations()->clear();
                }
                else
                {
                    editMFVariableLocations()->resize(
                        pVars->getMFVariables()->size(), 
                        -1);

                    std::fill(editMFVariableLocations()->begin(),
                              editMFVariableLocations()->end  (),
                              -1);
                }

                // be save reset all locations

                if(pVars->getMFProceduralVariables()->size() == 0     )
                {
                    editMFProceduralVariableLocations()->clear();
                }
                else
                {
                    editMFProceduralVariableLocations()->resize(
                        pVars->getMFProceduralVariables()->size(), 
                        -1);

                    std::fill(editMFProceduralVariableLocations()->begin(),
                              editMFProceduralVariableLocations()->end  (),
                              -1);
                }
            }
        }

        Window::refreshGLObject(this->getGLId());
    }

    if(0x0000 != (whichField & ComputeShaderFieldMask))
    {
        bMarkChanged = true;

        Window::reinitializeGLObject(this->getGLId());
    }

    if(bMarkChanged == true)
    {
        // be save reset all locations

        std::fill(editMFVariableLocations()->begin(),
                  editMFVariableLocations()->end  (),
                  -1);

        std::fill(editMFProceduralVariableLocations()->begin(),
                  editMFProceduralVariableLocations()->end  (),
                  -1);
    
        if(_sfVariables.getValue() != NULL)
        {
            _sfVariables.getValue()->markAllChanged();
        }
    }

    Inherited::changed(whichField, origin, details);
}