/*
 * MATLAB Compiler: 3.0
 * Date: Mon Sep 20 09:40:14 2004
 * Arguments: "-B" "macro_default" "-O" "all" "-O" "fold_scalar_mxarrays:on"
 * "-O" "fold_non_scalar_mxarrays:on" "-O" "optimize_integer_for_loops:on" "-O"
 * "array_indexing:on" "-O" "optimize_conditionals:on" "-B" "sgl" "-m" "-W"
 * "main" "-L" "C" "-t" "-T" "link:exe" "-h" "libmmfile.mlib" "-W" "mainhg"
 * "libmwsglm.mlib" "recarga_multiple" 
 */
#include "storageout.h"
#include "mwservices.h"
#include "libmatlbm.h"
static mxArray * _mxarray0_;
static mxArray * _mxarray1_;
static mxArray * _mxarray2_;

void InitializeModule_storageout(void) {
    _mxarray0_ = mclInitializeDouble(1.0);
    _mxarray1_ = mclInitializeDoubleVector(0, 0, (double *)NULL);
    _mxarray2_ = mclInitializeDouble(0.0);
}

void TerminateModule_storageout(void) {
    mxDestroyArray(_mxarray2_);
    mxDestroyArray(_mxarray1_);
    mxDestroyArray(_mxarray0_);
}

static mxArray * Mstorageout(int nargout_,
                             mxArray * timerain,
                             mxArray * Sd,
                             mxArray * evaprate,
                             mxArray * data4);

_mexLocalFunctionTable _local_function_table_storageout
  = { 0, (mexFunctionTableEntry *)NULL };

/*
 * The function "mlfStorageout" contains the normal interface for the
 * "storageout" M-function from file "u:\final_recarga6\recarga\storageout.m"
 * (lines 1-39). This function processes any input arguments and passes them to
 * the implementation version of the function, appearing above.
 */
mxArray * mlfStorageout(mxArray * timerain,
                        mxArray * Sd,
                        mxArray * evaprate,
                        mxArray * data4) {
    int nargout = 1;
    mxArray * y = NULL;
    mlfEnterNewContext(0, 4, timerain, Sd, evaprate, data4);
    y = Mstorageout(nargout, timerain, Sd, evaprate, data4);
    mlfRestorePreviousContext(0, 4, timerain, Sd, evaprate, data4);
    return mlfReturnValue(y);
}

/*
 * The function "mlxStorageout" contains the feval interface for the
 * "storageout" M-function from file "u:\final_recarga6\recarga\storageout.m"
 * (lines 1-39). The feval function calls the implementation version of
 * storageout through this function. This function processes any input
 * arguments and passes them to the implementation version of the function,
 * appearing above.
 */
void mlxStorageout(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]) {
    mxArray * mprhs[4];
    mxArray * mplhs[1];
    int i;
    if (nlhs > 1) {
        mlfError(
          mxCreateString(
            "Run-time Error: File: storageout Line: 1 Column:"
            " 1 The function \"storageout\" was called with m"
            "ore than the declared number of outputs (1)."),
          NULL);
    }
    if (nrhs > 4) {
        mlfError(
          mxCreateString(
            "Run-time Error: File: storageout Line: 1 Column"
            ": 1 The function \"storageout\" was called with"
            " more than the declared number of inputs (4)."),
          NULL);
    }
    for (i = 0; i < 1; ++i) {
        mplhs[i] = NULL;
    }
    for (i = 0; i < 4 && i < nrhs; ++i) {
        mprhs[i] = prhs[i];
    }
    for (; i < 4; ++i) {
        mprhs[i] = NULL;
    }
    mlfEnterNewContext(0, 4, mprhs[0], mprhs[1], mprhs[2], mprhs[3]);
    mplhs[0] = Mstorageout(nlhs, mprhs[0], mprhs[1], mprhs[2], mprhs[3]);
    mlfRestorePreviousContext(0, 4, mprhs[0], mprhs[1], mprhs[2], mprhs[3]);
    plhs[0] = mplhs[0];
}

/*
 * The function "Mstorageout" is the implementation version of the "storageout"
 * M-function from file "u:\final_recarga6\recarga\storageout.m" (lines 1-39).
 * It contains the actual compiled code for that M-function. It is a static
 * function and must only be called from one of the interface functions,
 * appearing below.
 */
/*
 * function y = storageout (timerain, Sd, evaprate, data4)
 */
static mxArray * Mstorageout(int nargout_,
                             mxArray * timerain,
                             mxArray * Sd,
                             mxArray * evaprate,
                             mxArray * data4) {
    mexLocalFunctionTable save_local_function_table_
      = mclSetCurrentLocalFunctionTable(&_local_function_table_storageout);
    mxArray * y = NULL;
    mxArray * Pcompl = NULL;
    mxArray * newtimerain = NULL;
    mxArray * i = NULL;
    mxArray * datapts = NULL;
    mxArray * avail = NULL;
    mclCopyArray(&timerain);
    mclCopyArray(&Sd);
    mclCopyArray(&evaprate);
    mclCopyArray(&data4);
    /*
     * %
     * % Accepts a 2-column array, timerain, with columns for time and ppt
     * % Sd, the storage depth, and evaprate, the rate of evaporation.
     * % It goes through the precipitation table and takes off the storage
     * % depth for the entire array.
     * % The evaporation rate must be in compatible units with Sd and timerain
     * % (e.g., if Sd is in inches and the time step in the timerain table is 
     * % hours, then evaprate must be in inches per hour).
     * %
     * avail = Sd; % initializes the available storage depth
     */
    mlfAssign(&avail, mclVa(Sd, "Sd"));
    /*
     * datapts = size(timerain,1); % Determines the number of data points
     */
    mlfAssign(
      &datapts,
      mlfSize(mclValueVarargout(), mclVa(timerain, "timerain"), _mxarray0_));
    /*
     * for i = 1:datapts
     */
    {
        int v_ = mclForIntStart(1);
        int e_ = mclForIntEnd(mclVv(datapts, "datapts"));
        if (v_ > e_) {
            mlfAssign(&i, _mxarray1_);
        } else {
            /*
             * newtimerain(i,1) = timerain(i,1); % time
             * if avail <= 0
             * newtimerain(i,2) = timerain(i,2);   % no effect in effective rain if no avail storage
             * elseif avail >= timerain(i,2) % storage bigger than rain
             * newtimerain(i,2) = 0;   % zero effective rain (all stored)
             * avail = avail - timerain(i,2);  % correct for rain using avail storage
             * if avail < 0
             * avail = 0;
             * end
             * elseif avail < timerain(i,2)  % storage less than rain
             * newtimerain(i,2) = timerain(i,2) - avail;
             * if newtimerain(i,2)<0
             * newtimerain = 0;
             * end
             * avail = 0;
             * end
             * if data4(i,3)==0 
             * avail = avail + evaprate; % evap increases avail storage only in dry periods
             * end  
             * if avail > Sd
             * avail = Sd;
             * end
             * Pcompl=100*i/datapts; % {DBA}
             * %set(handles.Progress,'String',num2str(Pcompl)); %{DBA}
             * end
             */
            for (; ; ) {
                mclIntArrayAssign2(
                  &newtimerain,
                  mclIntArrayRef2(mclVa(timerain, "timerain"), v_, 1),
                  v_,
                  1);
                if (mclLeBool(mclVv(avail, "avail"), _mxarray2_)) {
                    mclIntArrayAssign2(
                      &newtimerain,
                      mclIntArrayRef2(mclVa(timerain, "timerain"), v_, 2),
                      v_,
                      2);
                } else if (mclGeBool(
                             mclVv(avail, "avail"),
                             mclIntArrayRef2(
                               mclVa(timerain, "timerain"), v_, 2))) {
                    mclIntArrayAssign2(&newtimerain, _mxarray2_, v_, 2);
                    mlfAssign(
                      &avail,
                      mclMinus(
                        mclVv(avail, "avail"),
                        mclIntArrayRef2(mclVa(timerain, "timerain"), v_, 2)));
                    if (mclLtBool(mclVv(avail, "avail"), _mxarray2_)) {
                        mlfAssign(&avail, _mxarray2_);
                    }
                } else if (mclLtBool(
                             mclVv(avail, "avail"),
                             mclIntArrayRef2(
                               mclVa(timerain, "timerain"), v_, 2))) {
                    mclIntArrayAssign2(
                      &newtimerain,
                      mclMinus(
                        mclIntArrayRef2(mclVa(timerain, "timerain"), v_, 2),
                        mclVv(avail, "avail")),
                      v_,
                      2);
                    if (mclLtBool(
                          mclIntArrayRef2(
                            mclVv(newtimerain, "newtimerain"), v_, 2),
                          _mxarray2_)) {
                        mlfAssign(&newtimerain, _mxarray2_);
                    }
                    mlfAssign(&avail, _mxarray2_);
                }
                if (mclEqBool(
                      mclIntArrayRef2(mclVa(data4, "data4"), v_, 3),
                      _mxarray2_)) {
                    mlfAssign(
                      &avail,
                      mclPlus(
                        mclVv(avail, "avail"), mclVa(evaprate, "evaprate")));
                }
                if (mclGtBool(mclVv(avail, "avail"), mclVa(Sd, "Sd"))) {
                    mlfAssign(&avail, mclVa(Sd, "Sd"));
                }
                mlfAssign(
                  &Pcompl,
                  mclMrdivide(
                    mlfScalar(svDoubleScalarTimes(100.0, (double) v_)),
                    mclVv(datapts, "datapts")));
                if (v_ == e_) {
                    break;
                }
                ++v_;
            }
            mlfAssign(&i, mlfScalar(v_));
        }
    }
    /*
     * y = newtimerain;
     */
    mlfAssign(&y, mclVv(newtimerain, "newtimerain"));
    mclValidateOutput(y, 1, nargout_, "y", "storageout");
    mxDestroyArray(avail);
    mxDestroyArray(datapts);
    mxDestroyArray(i);
    mxDestroyArray(newtimerain);
    mxDestroyArray(Pcompl);
    mxDestroyArray(data4);
    mxDestroyArray(evaprate);
    mxDestroyArray(Sd);
    mxDestroyArray(timerain);
    mclSetCurrentLocalFunctionTable(save_local_function_table_);
    return y;
}
