/*
 * Copyright (C) 2012 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 "rsScriptIntrinsic.h"
#include <time.h>

using namespace android;
using namespace android::renderscript;

ScriptIntrinsic::ScriptIntrinsic(Context *rsc) : Script(rsc) {
    mIntrinsicID = 0;
}

ScriptIntrinsic::~ScriptIntrinsic() {
    if (mIntrinsicID != 0) {
        mRSC->mHal.funcs.script.destroy(mRSC, this);
    }
}

bool ScriptIntrinsic::init(Context *rsc, RsScriptIntrinsicID iid, Element *e) {
    mIntrinsicID = iid;
    mElement.set(e);
    mSlots = new ObjectBaseRef<Allocation>[2];
    mTypes = new ObjectBaseRef<const Type>[2];

    rsc->mHal.funcs.script.initIntrinsic(rsc, this, iid, e);


    return true;
}

bool ScriptIntrinsic::freeChildren() {
    return false;
}

void ScriptIntrinsic::setupScript(Context *rsc) {
}

uint32_t ScriptIntrinsic::run(Context *rsc) {
    rsAssert(!"ScriptIntrinsic::run - should not happen");
    return 0;
}


void ScriptIntrinsic::runForEach(Context *rsc,
                         uint32_t slot,
                         const Allocation * ain,
                         Allocation * aout,
                         const void * usr,
                         size_t usrBytes,
                         const RsScriptCall *sc) {

    rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc);
}

void ScriptIntrinsic::runForEach(Context* rsc,
                         uint32_t slot,
                         const Allocation** ains,
                         size_t inLen,
                         Allocation* aout,
                         const void* usr,
                         size_t usrBytes,
                         const RsScriptCall* sc) {

    rsc->mHal.funcs.script.invokeForEachMulti(rsc, this, slot, ains, inLen, aout, usr, usrBytes, sc);
}

void ScriptIntrinsic::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) {
}

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

RsA3DClassID ScriptIntrinsic::getClassId() const {
    return (RsA3DClassID)0;
}



namespace android {
namespace renderscript {


RsScript rsi_ScriptIntrinsicCreate(Context *rsc, uint32_t id, RsElement ve) {
    ScriptIntrinsic *si = new ScriptIntrinsic(rsc);
    if (!si->init(rsc, (RsScriptIntrinsicID)id, (Element *)ve)) {
        delete si;
        return NULL;
    }
    si->incUserRef();
    return si;
}

}
}


