 
/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/

#include "VTKNidROI.h"

#include <map>

namespace sofa
{

namespace component
{

namespace engine
{

template <class DataTypes>
VTKNidROI<DataTypes>::VTKNidROI()
    : d_position(initData(&d_position, "position", "input positions"))
    , d_nid(initData(&d_nid, "nid", "input positions node id"))
    , d_nidROI(initData(&d_nidROI, "nidROI", "input positions node id"))
    , d_indices( initData(&d_indices, "indices", "indices of the point in the ROI") )
    , d_pointsInROI(initData(&d_pointsInROI, "pointsInROI", "points in the ROI"))
{ }

template <class DataTypes>
VTKNidROI<DataTypes>::~VTKNidROI()
{ }

template <class DataTypes>
void VTKNidROI<DataTypes>::init()
{
    addInput(&d_position);
    addInput(&d_nid);
    addInput(&d_nidROI);

    addOutput(&d_indices);
    addOutput(&d_pointsInROI);

    setDirtyValue();
}

template <class DataTypes>
void VTKNidROI<DataTypes>::reinit()
{
    update();
}

template <class DataTypes>
void VTKNidROI<DataTypes>::update()
{
    cleanDirty();

    helper::ReadAccessor<Data<VecCoord> > position(d_position);
    helper::ReadAccessor<Data<VecId> > nid(d_nid);
    helper::ReadAccessor<Data<VecId> > nidROI(d_nidROI);

    helper::WriteAccessor< Data<VecId> > indices(d_indices);
    helper::WriteAccessor<Data<VecCoord> > pointsInROI(d_pointsInROI);

    // first build a map with nid
    std::map<Id, unsigned int> mapId;
    for (unsigned int i=0;i<nid.size();++i) {
        std::pair<std::map<Id, unsigned int>::iterator,bool> res = mapId.insert(std::make_pair(nid[i],i));
        if (!res.second)
            serr << "node with id " << nid[i] << " already exists" << sendl;
    }

    indices.resize(nidROI.size());
    pointsInROI.resize(nidROI.size());
    for (unsigned int i=0;i<nidROI.size();++i) {
        std::map<Id, unsigned int>::iterator it=mapId.find(nidROI[i]);
        if (it==mapId.end())
            serr << "node id " << nidROI[i] << " does not exist in input data" << sendl;
        else {
            indices[i]=it->second;
            pointsInROI[i]=position[it->second];
        }
    }

}

template <class DataTypes>
std::string VTKNidROI<DataTypes>::getTemplateName() const
{
    return templateName(this);
}

template <class DataTypes>
std::string VTKNidROI<DataTypes>::templateName(const VTKNidROI<DataTypes>*)
{
    return DataTypes::Name();
}


} // namespace engine

} // namespace component

} // namespace sofa
