#include "util.h"
#include "CameraHelper.h"
#include "NodeIteratorVisitorHelper.h"
#include <maya/MFnCamera.h>
#include <maya/MFnAttribute.h>
#include <maya/MFnNumericData.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MGlobal.h>
#include <maya/MTime.h>
#include <maya/MVector.h>
#include <maya/MDagModifier.h>
void read(double iFrame, Alembic::AbcGeom::ICamera & iCamera,
    std::vector<double> & oArray)
{
    oArray.resize(18);
    
    oArray[13] = 1.0;
    oArray[16] = 1.0;
    oArray[17] = 1.0;
    Alembic::AbcGeom::ICameraSchema schema = iCamera.getSchema();
    Alembic::AbcCoreAbstract::index_t index, ceilIndex;
    double alpha = getWeightAndIndex(iFrame,
        schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex);
    if (alpha != 0.0)
    {
        Alembic::AbcGeom::CameraSample samp, ceilSamp;
        schema.get(samp, index);
        schema.get(ceilSamp, ceilIndex);
        oArray[0] = simpleLerp<double>(alpha, samp.getFocalLength(),
            ceilSamp.getFocalLength());
        oArray[1] = simpleLerp<double>(alpha, samp.getLensSqueezeRatio(),
            ceilSamp.getLensSqueezeRatio());
        oArray[2] = simpleLerp<double>(alpha, samp.getHorizontalAperture(),
            ceilSamp.getHorizontalAperture()) / 2.54;
        oArray[3] = simpleLerp<double>(alpha, samp.getVerticalAperture(),
            ceilSamp.getVerticalAperture()) / 2.54;
        oArray[4] = simpleLerp<double>(alpha,
            samp.getHorizontalFilmOffset(),
            ceilSamp.getHorizontalFilmOffset()) / 2.54;
        oArray[5] = simpleLerp<double>(alpha,
            samp.getVerticalFilmOffset(),
            ceilSamp.getVerticalFilmOffset()) / 2.54;
        if (samp.getOverScanLeft() == samp.getOverScanRight() &&
            samp.getOverScanTop() == samp.getOverScanBottom() &&
            samp.getOverScanLeft() == samp.getOverScanTop() &&
            ceilSamp.getOverScanLeft() == ceilSamp.getOverScanRight() &&
            ceilSamp.getOverScanTop() == ceilSamp.getOverScanBottom() &&
            ceilSamp.getOverScanLeft() == ceilSamp.getOverScanTop())
        {
            oArray[6] = simpleLerp<double>(alpha,
                samp.getOverScanLeft() + 1.0,
                ceilSamp.getOverScanLeft() + 1.0);
        }
        else
        {
            oArray[6] = 1.0;
        }
        oArray[7] = simpleLerp<double>(alpha, samp.getNearClippingPlane(),
            ceilSamp.getNearClippingPlane());
        oArray[8] = simpleLerp<double>(alpha, samp.getFarClippingPlane(),
            ceilSamp.getFarClippingPlane());
        oArray[9] = simpleLerp<double>(alpha, samp.getFStop(),
            ceilSamp.getFStop());
        oArray[10] = simpleLerp<double>(alpha, samp.getFocusDistance(),
            ceilSamp.getFocusDistance());
        double shutterClose = simpleLerp<double>(alpha, samp.getShutterClose(),
            ceilSamp.getShutterClose());
        double shutterOpen = simpleLerp<double>(alpha, samp.getShutterOpen(),
            ceilSamp.getShutterOpen());
        oArray[11] =
        std::size_t numOps = samp.getNumOps();
        for (std::size_t i = 0; i < numOps; ++i)
        {
            Alembic::AbcGeom::FilmBackXformOp & op = samp[i];
            Alembic::AbcGeom::FilmBackXformOp & ceilOp = ceilSamp[i];
            if (op.getHint() == "filmFitOffs")
            {
                double val = op.getChannelValue(0) *
                    samp.getHorizontalAperture();
                double ceilVal = ceilOp.getChannelValue(0) *
                    ceilSamp.getHorizontalAperture();
                if (val != 0.0)
                {
                    
                    oArray[12] = simpleLerp<double>(alpha, val, ceilVal) / 5.08;
                }
                else
                {
                    val = op.getChannelValue(1) * samp.getHorizontalAperture();
                    ceilVal = ceilOp.getChannelValue(1) *
                        ceilSamp.getHorizontalAperture();
                    
                    oArray[12] = simpleLerp<double>(alpha, val, ceilVal) / 5.08;
                }
            }
            else if (op.getHint() == "preScale")
            {
                oArray[13] = 1.0 / simpleLerp<double>(alpha,
                    op.getChannelValue(0), ceilOp.getChannelValue(0));
            }
            else if (op.getHint() == "filmTranslate")
            {
                oArray[14] = simpleLerp<double>(alpha,
                    op.getChannelValue(0), ceilOp.getChannelValue(0));
                oArray[15] = simpleLerp<double>(alpha,
                    op.getChannelValue(1), ceilOp.getChannelValue(1));
            }
            else if (op.getHint() == "postScale")
            {
                oArray[16] = 1.0 / simpleLerp<double>(alpha,
                    op.getChannelValue(0), ceilOp.getChannelValue(0));
            }
            else if (op.getHint() == "cameraScale")
            {
                oArray[17] = simpleLerp<double>(alpha,
                    op.getChannelValue(0), ceilOp.getChannelValue(0));
            }
        }
    }
    else
    {
        Alembic::AbcGeom::CameraSample samp;
        schema.get(samp, index);
        oArray[0] = samp.getFocalLength();
        oArray[1] = samp.getLensSqueezeRatio();
        oArray[2] = samp.getHorizontalAperture()/2.54;
        oArray[3] = samp.getVerticalAperture()/2.54;
        oArray[4] = samp.getHorizontalFilmOffset()/2.54;
        oArray[5] = samp.getVerticalFilmOffset()/2.54;
        if (samp.getOverScanLeft() == samp.getOverScanRight() &&
            samp.getOverScanTop() == samp.getOverScanBottom() &&
            samp.getOverScanLeft() == samp.getOverScanTop())
        {
            oArray[6] = samp.getOverScanLeft() + 1.0;
        }
        else
        {
            oArray[6] = 1.0;
        }
        oArray[7] = samp.getNearClippingPlane();
        oArray[8] = samp.getFarClippingPlane();
        oArray[9] = samp.getFStop();
        oArray[10] = samp.getFocusDistance();
        oArray[11] = 360.0 * (samp.getShutterClose()-samp.getShutterOpen()) *
        
        
        std::size_t numOps = samp.getNumOps();
        for (std::size_t i = 0; i < numOps; ++i)
        {
            Alembic::AbcGeom::FilmBackXformOp & op = samp[i];
            if (op.getHint() == "filmFitOffs")
            {
                if (op.getChannelValue(0) != 0.0)
                {
                    oArray[12] = op.getChannelValue(0) *
                        samp.getHorizontalAperture() / 5.08;
                }
                else
                {
                    oArray[12] = op.getChannelValue(1) *
                        samp.getHorizontalAperture() / 5.08;
                }
            }
            else if (op.getHint() == "preScale")
            {
                oArray[13] = 1.0 / op.getChannelValue(0);
            }
            else if (op.getHint() == "filmTranslate")
            {
                oArray[14] = op.getChannelValue(0);
                oArray[15] = op.getChannelValue(1);
            }
            else if (op.getHint() == "postScale")
            {
                oArray[16] = 1.0 / op.getChannelValue(0);
            }
            else if (op.getHint() == "cameraScale")
            {
                oArray[17] = op.getChannelValue(0);
            }
        }
    }
}
{
    Alembic::AbcGeom::ICameraSchema schema = iNode.getSchema();
    MString name(iNode.getName().c_str());
 
    MObject obj = fnCamera.create(iParent);
 
    fnCamera.setName(name);
    
    Alembic::AbcGeom::CameraSample samp;
    iNode.getSchema().get(samp);
    std::size_t numOps = samp.getNumOps();
    if (numOps > 0)
    {
        std::string hint = samp[0].getHint();
        if (hint == "filmFitFill")
        {
        }
        else if (hint == "filmFitHorz")
        {
        }
        else if (hint == "filmFitVert")
        {
        }
        else if (hint == "filmFitOver")
        {
        }
    }
    if (schema.isConstant())
    {
        
        fnCamera.setFocalLength(samp.getFocalLength());
        fnCamera.setLensSqueezeRatio(samp.getLensSqueezeRatio());
        
        
        fnCamera.setHorizontalFilmAperture(samp.getHorizontalAperture()/2.54);
        fnCamera.setVerticalFilmAperture(samp.getVerticalAperture()/2.54);
        fnCamera.setHorizontalFilmOffset(samp.getHorizontalFilmOffset()/2.54);
        fnCamera.setVerticalFilmOffset(samp.getVerticalFilmOffset()/2.54);
        
        if (samp.getOverScanLeft() == samp.getOverScanRight() &&
            samp.getOverScanTop() == samp.getOverScanBottom() &&
            samp.getOverScanLeft() == samp.getOverScanTop())
        {
            fnCamera.setOverscan(samp.getOverScanLeft() + 1.0);
        }
        else
        {
            MString warn = iNode.getName().c_str();
 
            warn += " has unsupported overscan values.";
        }
        fnCamera.setNearClippingPlane(samp.getNearClippingPlane());
        fnCamera.setFarClippingPlane(samp.getFarClippingPlane());
        
        
        fnCamera.setFStop(samp.getFStop());
        fnCamera.setFocusDistance(samp.getFocusDistance());
        fnCamera.setShutterAngle(Alembic::AbcGeom::DegreesToRadians(
            360.0 * (samp.getShutterClose()-samp.getShutterOpen()) *
        for (std::size_t i = 0; i < numOps; ++i)
        {
            Alembic::AbcGeom::FilmBackXformOp & op = samp[i];
            if (op.getHint() == "filmFitOffs")
            {
                double val = op.getChannelValue(0) *
                    samp.getHorizontalAperture() / 5.08;
                if (val != 0.0)
                {
                    fnCamera.setFilmFitOffset(val);
                }
                else
                {
                    fnCamera.setFilmFitOffset(op.getChannelValue(1) *
                        samp.getHorizontalAperture() / 5.08);
                }
            }
            else if (op.getHint() == "preScale")
            {
                fnCamera.setPreScale(1.0/op.getChannelValue(0));
            }
            else if (op.getHint() == "filmTranslate")
            {
                fnCamera.setFilmTranslateH(op.getChannelValue(0));
                fnCamera.setFilmTranslateV(op.getChannelValue(1));
            }
            else if (op.getHint() == "postScale")
            {
                fnCamera.setPostScale(1.0/op.getChannelValue(0));
            }
            else if (op.getHint() == "cameraScale")
            {
                fnCamera.setCameraScale(op.getChannelValue(0));
            }
        }
    }
    
    
    return camObj;
}