atom::Message Actuator::getParameter(atom::Message pParam) const
{
    atom::Message message;

    if (pParam.size() < 1)
        return message;
        
    std::string param;
    try
    {
        param = atom::toString(pParam[0]);
    }
    catch (...)
    {
        return message;
    }

    message.push_back(pParam[0]);
    if (param == "name")
        message.push_back(atom::StringValue::create(mClassName.c_str()));
    else if (param == "osc path")
        message.push_back(atom::StringValue::create(mOscPath.c_str()));

    return message;
}
atom::Message Source_2D_Shmdata::getParameter(atom::Message pParam) const
{
    atom::Message msg;

    if (pParam.size() < 1)
        return msg;

    string paramName;
    try
    {
        paramName = atom::toString(pParam[0]);
    }
    catch (atom::BadTypeTagError exception)
    {
        return msg;
    }

    msg.push_back(pParam[0]);
    if (paramName == "width")
        msg.push_back(atom::IntValue::create(mWidth));
    else if (paramName == "height")
        msg.push_back(atom::IntValue::create(mWidth));
    else if (paramName == "framerate")
        msg.push_back(atom::IntValue::create(mFramerate));
    else if (paramName == "subsourcenbr")
        msg.push_back(atom::IntValue::create(mSubsourceNbr));
    else
        msg = getBaseParameter(pParam);

    return msg;
}
atom::Message Source_2D::getBaseParameter(atom::Message pParam) const
{
    atom::Message msg;

    if (pParam.size() < 1)
        return msg;

    std::string paramName;
    try
    {
        paramName = atom::toString(pParam[0]);
    }
    catch (atom::BadTypeTagError exception)
    {
        return msg;
    }

    msg.push_back(pParam[0]);
    if (paramName == "id")
        msg.push_back(atom::FloatValue::create(mId));

    return msg;
}
void Detector_ObjOnAPlane::setParameter(atom::Message pMessage)
{
    std::string cmd;
    try
    {
        cmd = toString(pMessage[0]);
    }
    catch (atom::BadTypeTagError error)
    {
        return;
    }

    // Add a new space to the vector
    if (cmd == "addSpace")
    {
        int size = 0;
        if (mSpaces.size() != 0)
            size = mSpaces[0].size();

        if (pMessage.size() == size + 1 || size == 0)
        {
            std::vector<cv::Vec2f> space;
            for (int i = 1; i < pMessage.size(); i+=2)
            {
                cv::Vec2f point;
                try
                {
                    point[0] = toFloat(pMessage[i]);
                    point[1] = toFloat(pMessage[i+1]);
                }
                catch (atom::BadTypeTagError error)
                {
                    return;
                }
                space.push_back(point);
            }
            mSpaces.push_back(space);
            mMapsUpdated = false;
        }
    }
    // Replace all the current spaces at once
    else if (cmd == "spaces")
    {
        int number;
        if (!readParam(pMessage, number))
            return;

        int size = (pMessage.size()-2) / number;
        // If all spaces specified have not the same size
        // or size is an odd number (we need 2D points)
        // or not enough points are given for each space (3 minimum)
        if (size*number < pMessage.size()-2 || size % 2 != 0  || size < 6)
            return;

        std::vector<std::vector<cv::Vec2f>> tempSpaces;
        for (int i = 0; i < number; ++i)
        {
            std::vector<cv::Vec2f> space;
            for (int j = 0; j < size; j+=2)
            {
                cv::Vec2f point;
                try
                {
                    point[0] = toFloat(pMessage[i*size+2+j]);
                    point[1] = toFloat(pMessage[i*size+2+j+1]);
                }
                catch (atom::BadTypeTagError error)
                {
                    return;
                }

                space.push_back(point);
            }
            tempSpaces.push_back(space);
        }
        
        // Everything went fine, we can replace the old spaces
        mSpaces.clear();
        for (int i = 0; i < tempSpaces.size(); ++i)
            mSpaces.push_back(tempSpaces[i]);

        mMapsUpdated = false;
    }
    else if (cmd == "clearSpaces")
    {
        mSpaces.clear();
        mMapsUpdated = false;
    }
    else if (cmd == "detectionLevel")
    {
        float value;
        if (readParam(pMessage, value))
            mDetectionLevel = std::max(0.f, value);
    }
    else if (cmd == "processNoiseCov")
    {
        float value;
        if (readParam(pMessage, value))
            mProcessNoiseCov = std::max(0.f, value);
    }
    else if (cmd == "measurementNoiseCov")
    {
        float value;
        if (readParam(pMessage, value))
            mMeasurementNoiseCov = std::max(0.f, value);
    }
    else if (cmd == "filterSize")
    {
        float value;
        if (readParam(pMessage, value))
            mFilterSize = std::max(0.f, value);
    }
    else if (cmd == "minBlobArea")
    {
        float value;
        if (readParam(pMessage, value))
            mMinArea = std::max(0.f, value);
    }
    else if (cmd == "maxTrackedBlobs")
    {
        float value;
        if (readParam(pMessage, value))
            mMaxTrackedBlobs = std::max(0.f, value);
    }
    else
        setBaseParameter(pMessage);
}
void Source_2D::setBaseParameter(atom::Message pParam)
{
    std::string paramName;
    try
    {
        paramName = atom::toString(pParam[0]);
    }
    catch (atom::BadTypeTagError error)
    {
        return;
    }

    if (paramName == "mask")
    {
        string filename;
        if (!readParam(pParam, filename))
            return;

        mMask = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
    }
    else if (paramName == "vignetting")
    {
        if (pParam.size() == 4)
        {
            try
            {
                mOpticalDesc.vignetting[0] = atom::toFloat(pParam[1]);
                mOpticalDesc.vignetting[1] = atom::toFloat(pParam[2]);
                mOpticalDesc.vignetting[2] = atom::toFloat(pParam[3]);
            }
            catch (atom::BadTypeTagError error)
            {
                return;
            }

            mCorrectVignetting = true;
            mRecomputeVignettingMat = true;
        }
        else
            return;
    }
    else if (paramName == "noiseFiltering")
    {
        if (pParam.size() == 2)
        {
            int value;
            try
            {
                value = atom::toInt(pParam[1]);
            }
            catch (atom::BadTypeTagError error)
            {
                return;
            }

            if (value)
                mFilterNoise = true;
            else
                mFilterNoise = false;
        }
    }
    else if (paramName == "scale")
    {
        float scale;
        if (readParam(pParam, scale))
            mScale = max(0.1f, scale);
    }
    else if (paramName == "rotation")
    {
        readParam(pParam, mRotation);
    }
    else if (paramName == "distortion")
    {
        // Only one param, we correct only the 4th order
        // coefficient
        if (pParam.size() == 2)
        {
            float value;
            try
            {
                value = atom::toFloat(pParam[1]);
            }
            catch (atom::BadTypeTagError error)
            {
                return;
            }

            mOpticalDesc.distortion[0] = 0.0;
            mOpticalDesc.distortion[1] = value;
            mOpticalDesc.distortion[2] = 0.0;
        }
        // Three params, we correct all params
        else if (pParam.size() == 4)
        {
            try
            {
                mOpticalDesc.distortion[0] = atom::toFloat(pParam[1]);
                mOpticalDesc.distortion[1] = atom::toFloat(pParam[2]);
                mOpticalDesc.distortion[2] = atom::toFloat(pParam[3]);
            }
            catch (atom::BadTypeTagError error)
            {
                return;
            }
        }
        else
            return;

        mCorrectDistortion = true;
        mRecomputeDistortionMat = true;
    }
    else if (paramName == "fisheye")
    {
        if (pParam.size() >= 2)
        {
            try
            {
                mOpticalDesc.fisheye[0] = atom::toFloat(pParam[1]);
                mOpticalDesc.fisheye[1] = atom::toFloat(pParam[2]);
            }
            catch (atom::BadTypeTagError error)
            {
                return;
            }
        }
        else
            return;

        mCorrectFisheye = true;
        mRecomputeFisheyeMat = true;
    }
    else if (paramName == "iccInputProfile")
    {
        std::string filename;
        if (!readParam(pParam, filename))
            return;

        if (mICCTransform != NULL)
            cmsDeleteTransform(mICCTransform);
        mICCTransform = loadICCTransform(filename);
    }
    else if (paramName == "exposureLUT")
    {
        float nbr;
        if (!readParam(pParam, nbr))
        {
            g_log(NULL, G_LOG_LEVEL_WARNING, "%s - Message wrongly formed for exposureLUT: cannot read number of keys", mClassName.c_str());
            return;
        }

        float type;
        if (!readParam(pParam, type, 2))
        {
            g_log(NULL, G_LOG_LEVEL_WARNING, "%s - Message wrongly formed for exposureLUT: cannot read interpolation type", mClassName.c_str());
            return;
        }

        vector< vector<float> > keys;
        for (int i = 0; i < nbr; ++i)
        {
            vector<float> key;
            key.resize(2);
            keys.push_back(key);
            if (!readParam(pParam, keys[i][0], i * 2 + 3))
                return;
            if (!readParam(pParam, keys[i][1], i * 2 + 4))
                return;
        }

        mExposureLUT.set((LookupTable::interpolation)type, keys);
    }
    else if (paramName == "gainLUT")
    {
        int nbr;
        if (!readParam(pParam, nbr))
        {
            g_log(NULL, G_LOG_LEVEL_WARNING, "%s - Message wrongly formed for gainLUT", mClassName.c_str());
            return;
        }

        int type;
        if (!readParam(pParam, type, 2))
        {
            g_log(NULL, G_LOG_LEVEL_WARNING, "%s - Message wrongly formed for gainLUT", mClassName.c_str());
            return;
        }

        vector< vector<float> > keys;
        for (int i = 0; i < nbr / 2; ++i)
        {
            if (!readParam(pParam, keys[i][0], i * 2 + 3))
                return;
            if (!readParam(pParam, keys[i][1], i * 2 + 4))
                return;
        }

        mGainLUT.set((LookupTable::interpolation)type, keys);
    }
    else if (paramName == "autoExposure")
    {
        float v[7];
        for (int i = 0; i < 4; ++i)
            if (!readParam(pParam, v[i], i+1))
            {
                g_log(NULL, G_LOG_LEVEL_WARNING, "%s - Message wrongly formed for autoExposure", mClassName.c_str());
                return;
            }

        mAutoExposureRoi = cv::Rect(v[0], v[1], v[2], v[3]);

        if (readParam(pParam, v[4], 5))
            mAutoExposureTarget = v[4];
        if (readParam(pParam, v[5], 6))
            mAutoExposureThreshold = v[5];
        if (readParam(pParam, v[6], 7))
            mAutoExposureStep = v[6];
    }
    else if (paramName == "hdri")
    {
        if (pParam.size() != 4)
            return;

        try
        {
            mHdriStartExposure = atom::toFloat(pParam[1]);
            mHdriStepSize = atom::toFloat(pParam[2]);
            mHdriSteps = atom::toInt(pParam[3]);
        }
        catch (atom::BadTypeTagError error)
        {
            return;
        }

        mHdriActive = true;
    }
    else if (paramName == "save")
    {
        float active, period;
        string filename;

        if (!readParam(pParam, active, 1))
            return;
        if (!readParam(pParam, period, 2))
            return;
        if (!readParam(pParam, filename, 3))
            return;

        if (active == 1.f)
        {
            mSaveToFile = true;
            mSavePeriod = (int)period;
            mBaseFilename = filename;
        }
        else
        {
            mSaveToFile = false;
        }
    }
}