#ifndef BRANCHINGIMAGE_IMAGECONTAINER_H
#define BRANCHINGIMAGE_IMAGECONTAINER_H

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

namespace sofa 
{

namespace component
{

namespace container
{

/// Specialization for branching Image
template <class T>
struct ImageContainerSpecialization<defaulttype::BranchingImage<T>>
{

    typedef ImageContainer<defaulttype::BranchingImage<T>> ImageContainerT;

    static void constructor( ImageContainerT* container )
    {
        container->addAlias( &container->image, "inputBranchingImage" );
        container->addAlias( &container->image, "branchingImage" );
    }

    static void parse( ImageContainerT* container, sofa::core::objectmodel::BaseObjectDescription */*arg*/=NULL )
    {
        if( container->image.isSet() ) return; // image is set from data link

        // otherwise try to load it from a file
        if( !container->image.getValue().getDimension()[ImageContainerT::ImageTypes::DIMENSION_T] )
            container->load();
    }

    static void init( ImageContainerT* container )
    {
        assert( container->image.getValue().isEmpty() ); // the image is supposed not to be loaded here

        // if the image is not set from data link
        // and was not loaded from a file during parsing
        // try to load it now (maybe the loading was data-dependant, like the filename)
        if( !container->load() )
            container->serr << "no input image " << container->sendl;
    }

    static bool load( ImageContainerT* container, std::string fname )
    {
        typedef typename ImageContainerT::Real Real;

        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]={1.,1.,1.},translation[3]={0.,0.,0.},affine[9]={1.,0.,0.,0.,1.,0.,0.,0.,1.},offsetT=0.,scaleT=1.;
            int isPerspective=0;

            if( typename ImageContainerT::waImage( container->image )->load( fname.c_str(), scale, translation, affine, &offsetT, &scaleT, &isPerspective ) )
            {
                if (!container->transformIsSet) {
                    typename ImageContainerT::waTransform wtransform( container->transform );

                    for(unsigned int i=0;i<3;i++) wtransform->getScale()[i]=(Real)scale[i];
                    for(unsigned int i=0;i<3;i++) wtransform->getTranslation()[i]=(Real)translation[i];
                    defaulttype::Mat<3,3,Real> R; for(unsigned int i=0;i<3;i++) for(unsigned int j=0;j<3;j++) R[i][j]=(Real)affine[3*i+j];
                    helper::Quater< Real > q; q.fromMatrix(R);
                    wtransform->getRotation()=q.toEulerVector() * (Real)180.0 / (Real)M_PI ;
                    wtransform->getOffsetT()=(Real)offsetT;
                    wtransform->getScaleT()=(Real)scaleT;
                    wtransform->isPerspective()=isPerspective;
                }
                return true;
            }
        }

        return false;
    }

    //    static bool load( ImageContainerT* container, std::FILE* const file, std::string fname)
    //    {
    //    }

    static bool loadCamera( ImageContainerT* )
    {
        return false;
    }

};




}

}

}


#endif /*IMAGE_IMAGECONTAINER_H*/
