#ifndef SOFA_BRANCHINGIMAGE_IMAGEEXPORTER_H
#define SOFA_BRANCHINGIMAGE_IMAGEEXPORTER_H

#include <BranchingImage/config.h>
#include <image/ImageExporter.h>
#include "BranchingImage.h"


namespace sofa
{

namespace component
{

namespace misc
{


/// Specialization for BranchingImage
template <class T>
struct ImageExporterSpecialization<defaulttype::BranchingImage<T>>
{
    typedef ImageExporter<defaulttype::BranchingImage<T>> ImageExporterT;

    static void init( ImageExporterT& exporter )
    {
        exporter.addAlias( &exporter.image, "outputBranchingImage" );
        exporter.addAlias( &exporter.image, "branchingImage" );
    }

    static bool write( ImageExporterT& exporter )
    {
        typedef typename ImageExporterT::ImageTypes ImageTypes;
        typedef typename ImageExporterT::Real Real;

        if (!exporter.m_filename.isSet()) { exporter.serr << "ImageExporterT: file not set"<<exporter.name<<exporter.sendl; return false; }
        std::string fname(exporter.m_filename.getFullPath());

        typename ImageExporterT::raImage rimage(exporter.image);
        typename ImageExporterT::raTransform rtransform(exporter.transform);
        if (!rimage->getDimension()[ImageTypes::DIMENSION_T]) { exporter.serr << "ImageExporterT: no image "<<exporter.name<<exporter.sendl; return false; }

        // .BIA is for BranchingImageAscii (maybe some day there will be a .BIB, BranchingImageBinary)

        if(fname.find(".mhd")!=std::string::npos || fname.find(".MHD")!=std::string::npos || fname.find(".Mhd")!=std::string::npos
           || fname.find(".bia")!=std::string::npos || fname.find(".BIA")!=std::string::npos || fname.find(".Bia")!=std::string::npos)
        {
            if(fname.find(".bia")!=std::string::npos || fname.find(".BIA")!=std::string::npos || fname.find(".Bia")!=std::string::npos)      fname.replace(fname.find_last_of('.')+1,fname.size(),"mhd");

            double scale[3]; for(unsigned int i=0; i<3; i++) scale[i]=(double)rtransform->getScale()[i];
            double translation[3]; for(unsigned int i=0; i<3; i++) translation[i]=(double)rtransform->getTranslation()[i];
            defaulttype::Vec<3,Real> rotation = rtransform->getRotation() * (Real)M_PI / (Real)180.0;
            helper::Quater< Real > q = helper::Quater< Real >::createQuaterFromEuler(rotation);
            defaulttype::Mat<3,3,Real> R;  q.toMatrix(R);
            double affine[9]; for(unsigned int i=0; i<3; i++) for(unsigned int j=0; j<3; j++) affine[3*i+j]=(double)R[i][j];
            double offsetT=(double)rtransform->getOffsetT();
            double scaleT=(double)rtransform->getScaleT();
            int isPerspective=rtransform->isPerspective();

            exporter.image.getValue().save( fname.c_str(), scale, translation, affine, offsetT, scaleT, isPerspective );

            exporter.sout << "Saved image " << fname << exporter.sendl;

            return true;
        }

        return false;
    }
};




} // namespace misc

} // namespace component

} // namespace sofa

#endif // SOFA_BRANCHINGIMAGE_IMAGEEXPORTER_H
