/*
 * 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.
 */

#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
#else
#include "rsContextHostStub.h"
#endif //ANDROID_RS_BUILD_FOR_HOST

#include "rsAnimation.h"


using namespace android;
using namespace android::renderscript;

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

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

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

    mValuesInput = NULL;
    mValuesOutput = NULL;
    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 NULL;
    }
    Animation *a = new Animation(rsc);
    if (!a) {
        rsc->setError(RS_ERROR_OUT_OF_MEMORY);
        return NULL;
    }

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

    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) {
    //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
    Animation *a = NULL;//Animation::create(rsc, inValues, outValues, valueCount, interp, pre, post);
    if (a != NULL) {
        a->incUserRef();
    }
    return (RsAnimation)a;
}


}
}

