/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "rsContext.h"
#include "rsAnimation.h"


using namespace android;
using namespace android::renderscript;

void Animation::serialize(Context *rsc, OStream *stream) const {
}

Animation *Animation::createFromStream(Context *rsc, IStream *stream) {
    return nullptr;
}

/*
Animation::Animation(Context *rsc) : ObjectBase(rsc)
{
    mAllocFile = __FILE__;
    mAllocLine = __LINE__;

    mValuesInput = nullptr;
    mValuesOutput = nullptr;
    mValueCount = 0;
    mInterpolation = RS_ANIMATION_INTERPOLATION_STEP;
    mEdgePre = RS_ANIMATION_EDGE_UNDEFINED;
    mEdgePost = RS_ANIMATION_EDGE_UNDEFINED;
    mInputMin = 0;
    mInputMax = 0;
}

Animation * Animation::create(Context *rsc,
                              const float *inValues, const float *outValues,
                              uint32_t valueCount, RsAnimationInterpolation interp,
                              RsAnimationEdge pre, RsAnimationEdge post)
{
    if (valueCount < 2) {
        rsc->setError(RS_ERROR_BAD_VALUE, "Animations require more than 2 values.");
        return nullptr;
    }
    Animation *a = new Animation(rsc);
    if (!a) {
        rsc->setError(RS_ERROR_OUT_OF_MEMORY);
        return nullptr;
    }

    float *vin = (float *)malloc(valueCount * sizeof(float));
    float *vout = (float *)malloc(valueCount * sizeof(float));
    a->mValuesInput = vin;
    a->mValuesOutput = vout;
    if (a->mValuesInput == nullptr || a->mValuesOutput == nullptr) {
        delete a;
        rsc->setError(RS_ERROR_OUT_OF_MEMORY);
        return nullptr;
    }

    a->mEdgePre = pre;
    a->mEdgePost = post;
    a->mInterpolation = interp;
    a->mValueCount = valueCount;

    memcpy(vin, inValues, valueCount * sizeof(float));
    memcpy(vout, outValues, valueCount * sizeof(float));
    a->mInputMin = inValues[0];
    a->mInputMax = inValues[0];

    bool needSort = false;
    for (uint32_t ct=1; ct < valueCount; ct++) {
        if (a->mInputMin > vin[ct]) {
            needSort = true;
            a->mInputMin = vin[ct];
        }
        if (a->mInputMax < vin[ct]) {
            a->mInputMax = vin[ct];
        } else {
            needSort = true;
        }
    }

    while (1) {
        bool changed = false;
        for (uint32_t ct=1; ct < valueCount; ct++) {
            if (vin[ct-1] > vin[ct]) {
                float t = vin[ct-1];
                vin[ct-1] = vin[ct];
                vin[ct] = t;
                t = vout[ct-1];
                vout[ct-1] = vout[ct];
                vout[ct] = t;
                changed = true;
            }
        }
        if (!changed) break;
    }

    return a;
}
*/


/////////////////////////////////////////
//

namespace android {
namespace renderscript {

RsAnimation rsi_AnimationCreate(Context *rsc,
                                const float *inValues,
                                const float *outValues,
                                uint32_t valueCount,
                                RsAnimationInterpolation interp,
                                RsAnimationEdge pre,
                                RsAnimationEdge post) {
    //ALOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
    Animation *a = nullptr;//Animation::create(rsc, inValues, outValues, valueCount, interp, pre, post);
    if (a != nullptr) {
        a->incUserRef();
    }
    return (RsAnimation)a;
}


}
}

