/*
 * Copyright (C) 2009-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 <time.h>

using namespace android;
using namespace android::renderscript;

Script::Script(Context *rsc) : ObjectBase(rsc) {
    memset(&mEnviroment, 0, sizeof(mEnviroment));
    memset(&mHal, 0, sizeof(mHal));

    mSlots = nullptr;
    mTypes = nullptr;
    mInitialized = false;
    mHasObjectSlots = false;
    mApiLevel = 0;
}

Script::~Script() {
    if (mSlots) {
        delete [] mSlots;
        mSlots = nullptr;
    }
    if (mTypes) {
        delete [] mTypes;
        mTypes = nullptr;
    }
}

void Script::setSlot(uint32_t slot, Allocation *a) {
    //ALOGE("setSlot %i %p", slot, a);
    if (slot >= mHal.info.exportedVariableCount) {
        ALOGE("Script::setSlot unable to set allocation, invalid slot index");
        return;
    }

    if (mRSC->hadFatalError()) return;

    mSlots[slot].set(a);
    mHasObjectSlots = true;
    mRSC->mHal.funcs.script.setGlobalBind(mRSC, this, slot, a);
}

void Script::setVar(uint32_t slot, const void *val, size_t len) {
    //ALOGE("setVar %i %p %i", slot, val, len);
    if (slot >= mHal.info.exportedVariableCount) {
        ALOGE("Script::setVar unable to set allocation, invalid slot index");
        return;
    }
    if (mRSC->hadFatalError()) return;

    mRSC->mHal.funcs.script.setGlobalVar(mRSC, this, slot, (void *)val, len);
}

void Script::getVar(uint32_t slot, const void *val, size_t len) {
    //ALOGE("getVar %i %p %i", slot, val, len);
    if (slot >= mHal.info.exportedVariableCount) {
        ALOGE("Script::getVar unable to set allocation, invalid slot index: "
              "%u >= %zu", slot, mHal.info.exportedVariableCount);
        return;
    }
    if (mRSC->hadFatalError()) return;

    mRSC->mHal.funcs.script.getGlobalVar(mRSC, this, slot, (void *)val, len);
}

void Script::setVar(uint32_t slot, const void *val, size_t len, Element *e,
                    const uint32_t *dims, size_t dimLen) {
    if (slot >= mHal.info.exportedVariableCount) {
        ALOGE("Script::setVar unable to set allocation, invalid slot index: "
              "%u >= %zu", slot, mHal.info.exportedVariableCount);
        return;
    }
    if (mRSC->hadFatalError()) return;

    mRSC->mHal.funcs.script.setGlobalVarWithElemDims(mRSC, this, slot,
            (void *)val, len, e, dims, dimLen);
}

void Script::setVarObj(uint32_t slot, ObjectBase *val) {
    //ALOGE("setVarObj %i %p", slot, val);
    if (slot >= mHal.info.exportedVariableCount) {
        ALOGE("Script::setVarObj unable to set allocation, invalid slot index: "
              "%u >= %zu", slot, mHal.info.exportedVariableCount);
        return;
    }
    if (mRSC->hadFatalError()) return;

    mHasObjectSlots = true;
    mRSC->mHal.funcs.script.setGlobalObj(mRSC, this, slot, val);
}

void Script::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
    if (rsc->mHal.funcs.script.updateCachedObject != nullptr) {
        rsc->mHal.funcs.script.updateCachedObject(rsc, this, (rs_script *)dstObj);
    } else {
        *((const void **)dstObj) = this;
    }
}

bool Script::freeChildren() {
    incSysRef();
    mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
    return decSysRef();
}

ScriptKernelID::ScriptKernelID(Context *rsc, Script *s, int slot, int sig)
        : IDBase(rsc, s, slot) {
    mHasKernelInput = (sig & 1) != 0;
    mHasKernelOutput = (sig & 2) != 0;
}

RsA3DClassID ScriptKernelID::getClassId() const {
    return RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID;
}

ScriptInvokeID::ScriptInvokeID(Context *rsc, Script *s, int slot)
    : IDBase(rsc, s, slot) {
}

RsA3DClassID ScriptInvokeID::getClassId() const {
    return RS_A3D_CLASS_ID_SCRIPT_INVOKE_ID;
}

ScriptFieldID::ScriptFieldID(Context *rsc, Script *s, int slot) :
    IDBase(rsc, s, slot) {
}

RsA3DClassID ScriptFieldID::getClassId() const {
    return RS_A3D_CLASS_ID_SCRIPT_FIELD_ID;
}


namespace android {
namespace renderscript {

RsScriptKernelID rsi_ScriptKernelIDCreate(Context *rsc, RsScript vs, int slot, int sig) {
    ScriptKernelID *kid = new ScriptKernelID(rsc, (Script *)vs, slot, sig);
    kid->incUserRef();
    return kid;
}

RsScriptInvokeID rsi_ScriptInvokeIDCreate(Context *rsc, RsScript vs, uint32_t slot) {
    ScriptInvokeID *iid = new ScriptInvokeID(rsc, (Script *)vs, slot);
    iid->incUserRef();
    return iid;
}

RsScriptFieldID rsi_ScriptFieldIDCreate(Context *rsc, RsScript vs, int slot) {
    ScriptFieldID *fid = new ScriptFieldID(rsc, (Script *)vs, slot);
    fid->incUserRef();
    return fid;
}

void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint32_t slot) {
    Script *s = static_cast<Script *>(vs);
    Allocation *a = static_cast<Allocation *>(va);
    s->setSlot(slot, a);
}

void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, size_t length) {
    // We unfortunately need to make a new copy of the string, since it is
    // not nullptr-terminated. We then use setenv(), which properly handles
    // freeing/duplicating the actual string for the environment.
    char *tz = (char *) malloc(length + 1);
    if (!tz) {
        ALOGE("Couldn't allocate memory for timezone buffer");
        return;
    }
    strncpy(tz, timeZone, length);
    tz[length] = '\0';
    if (setenv("TZ", tz, 1) == 0) {
        tzset();
    } else {
        ALOGE("Error setting timezone");
    }
    free(tz);
}

void rsi_ScriptForEachMulti(Context *rsc, RsScript vs, uint32_t slot,
                            RsAllocation *vains, size_t inLen,
                            RsAllocation vaout, const void *params,
                            size_t paramLen, const RsScriptCall *sc,
                            size_t scLen) {

    Script      *s    = static_cast<Script *>(vs);
    Allocation **ains = (Allocation**)(vains);

    s->runForEach(rsc, slot,
                  const_cast<const Allocation **>(ains), inLen,
                  static_cast<Allocation *>(vaout), params, paramLen, sc);

}

void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
                       RsAllocation vain, RsAllocation vaout,
                       const void *params, size_t paramLen,
                       const RsScriptCall *sc, size_t scLen) {

    if (vain == nullptr) {
        rsi_ScriptForEachMulti(rsc, vs, slot, nullptr, 0, vaout, params, paramLen,
                               sc, scLen);
    } else {
        RsAllocation ains[1] = {vain};

        rsi_ScriptForEachMulti(rsc, vs, slot, ains,
                               sizeof(ains) / sizeof(RsAllocation), vaout,
                               params, paramLen, sc, scLen);
    }
}

void rsi_ScriptReduce(Context *rsc, RsScript vs, uint32_t slot,
                      RsAllocation vain, RsAllocation vaout,
                      const RsScriptCall *sc, size_t scLen) {
    Script *s = static_cast<Script *>(vs);
    s->runReduce(rsc, slot, static_cast<const Allocation *>(vain),
                            static_cast<Allocation *>(vaout), sc);
}

void rsi_ScriptReduceNew(Context *rsc, RsScript vs, uint32_t slot,
                         RsAllocation *vains, size_t inLen,
                         RsAllocation vaout, const RsScriptCall *sc,
                         size_t scLen) {
  Script *s = static_cast<Script *>(vs);
  Allocation **ains = (Allocation**)(vains);

  s->runReduceNew(rsc, slot,
                  const_cast<const Allocation **>(ains), inLen,
                  static_cast<Allocation *>(vaout), sc);
}

void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot) {
    Script *s = static_cast<Script *>(vs);
    s->Invoke(rsc, slot, nullptr, 0);
}


void rsi_ScriptInvokeData(Context *rsc, RsScript vs, uint32_t slot, void *data) {
    Script *s = static_cast<Script *>(vs);
    s->Invoke(rsc, slot, nullptr, 0);
}

void rsi_ScriptInvokeV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) {
    Script *s = static_cast<Script *>(vs);
    s->Invoke(rsc, slot, data, len);
}

void rsi_ScriptSetVarI(Context *rsc, RsScript vs, uint32_t slot, int value) {
    Script *s = static_cast<Script *>(vs);
    s->setVar(slot, &value, sizeof(value));
}

void rsi_ScriptSetVarObj(Context *rsc, RsScript vs, uint32_t slot, RsObjectBase value) {
    Script *s = static_cast<Script *>(vs);
    ObjectBase *o = static_cast<ObjectBase *>(value);
    s->setVarObj(slot, o);
}

void rsi_ScriptSetVarJ(Context *rsc, RsScript vs, uint32_t slot, int64_t value) {
    Script *s = static_cast<Script *>(vs);
    s->setVar(slot, &value, sizeof(value));
}

void rsi_ScriptSetVarF(Context *rsc, RsScript vs, uint32_t slot, float value) {
    Script *s = static_cast<Script *>(vs);
    s->setVar(slot, &value, sizeof(value));
}

void rsi_ScriptSetVarD(Context *rsc, RsScript vs, uint32_t slot, double value) {
    Script *s = static_cast<Script *>(vs);
    s->setVar(slot, &value, sizeof(value));
}

void rsi_ScriptSetVarV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) {
    Script *s = static_cast<Script *>(vs);
    s->setVar(slot, data, len);
}

void rsi_ScriptGetVarV(Context *rsc, RsScript vs, uint32_t slot, void *data, size_t len) {
    Script *s = static_cast<Script *>(vs);
    s->getVar(slot, data, len);
}

void rsi_ScriptSetVarVE(Context *rsc, RsScript vs, uint32_t slot,
                        const void *data, size_t len, RsElement ve,
                        const uint32_t *dims, size_t dimLen) {
    Script *s = static_cast<Script *>(vs);
    Element *e = static_cast<Element *>(ve);
    s->setVar(slot, data, len, e, dims, dimLen);
}

}
}
