/*
 * ProviewR   Open Source Process Control.
 * Copyright (C) 2005-2025 SSAB EMEA AB.
 *
 * This file is part of ProviewR.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ProviewR. If not, see <http://www.gnu.org/licenses/>
 *
 * Linking ProviewR statically or dynamically with other modules is
 * making a combined work based on ProviewR. Thus, the terms and
 * conditions of the GNU General Public License cover the whole
 * combination.
 *
 * In addition, as a special exception, the copyright holders of
 * ProviewR give you permission to, from the build function in the
 * ProviewR Configurator, combine ProviewR with modules generated by the
 * ProviewR PLC Editor to a PLC program, regardless of the license
 * terms of these modules. You may copy and distribute the resulting
 * combined work under the terms of your choice, provided that every
 * copy of the combined work is accompanied by a complete copy of
 * the source code of ProviewR (the version used to produce the
 * combined work), being distributed under the terms of the GNU
 * General Public License plus this exception.
 */
#define false 0
#define true 1
#define _z_ ,

InitStep


#define initstep_exec(obj, reset, chain)                                       \
  if (reset)                                                                   \
    obj->Status[0] = false;                                                    \
  else if (obj->ResetOld)                                                      \
    obj->Status[0] = true;                                                     \
  obj->ResetOld = reset;                                                       \
  chain obj->Status[1] = obj->Status[0]

Step


#define step_exec(obj, reset, chain)                                           \
  if (reset)                                                                   \
    obj->Status[0] = false;                                                    \
  chain obj->Status[1] = obj->Status[0]

SubStep


#define substep_exec(obj, reset, subseq, chain)                                \
  if (reset)                                                                   \
    obj->Status[0] = false;                                                    \
  chain subseq

SsBegin


#define ssbegin_exec(obj, substep, reset, chain)                               \
  if (substep->Status[0] && !obj->StatusOld)                                   \
    obj->Status[0] = true;                                                     \
  if (reset)                                                                   \
    obj->Status[0] = false;                                                    \
  obj->StatusOld = substep->Status[0];                                         \
  chain obj->Status[1] = obj->Status[0]

SsEnd


#define ssend_exec(obj, substep, reset, chain)                                 \
  if (reset || !substep->Status[0])                                            \
    obj->Status[0] = false;                                                    \
  chain substep->Status[1] = obj->Status[1] = obj->Status[0]

Trans


#define trans_exec(obj, insteplist, outsteplist, cond)                         \
  {                                                                            \
    pwr_tBoolean* inptr[] = insteplist;                                        \
    pwr_tBoolean* outptr[] = outsteplist;                                      \
    pwr_tBoolean test;                                                         \
    int idx;                                                                   \
                                                                               \
    /* Test condition */                                                       \
    cond if (obj->Man) obj->Cond = obj->OpCond;                                \
    if (obj->Cond) {                                                           \
      /* Test if step(s) above are active */                                   \
      test = true;                                                             \
      idx = 0;                                                                 \
      while (test && inptr[idx] != NULL) {                                     \
        if (!*inptr[idx])                                                      \
          test = false;                                                        \
        else if (!*(inptr[idx] + 1))                                           \
          test = false;                                                        \
        idx++;                                                                 \
      }                                                                        \
      /* Transfer active status to step(s) below */                            \
      if (test) {                                                              \
        idx = 0;                                                               \
        while (inptr[idx] != NULL)                                             \
          *inptr[idx++] = false;                                               \
        idx = 0;                                                               \
        while (outptr[idx] != NULL)                                            \
          *outptr[idx++] = true;                                               \
        obj->OpCond = false;                                                   \
      }                                                                        \
    }                                                                          \
  }

Order


#define order_exec(obj, stepobj, chain)                                        \
  {                                                                            \
    pwr_tBoolean order_old;                                                    \
    order_old = obj->Status[0];                                                \
    obj->Status[0] = stepobj->Status[0];                                       \
    if (obj->Status[0] || order_old || stepobj->Status[0]                      \
        || stepobj->Status[1]) {                                               \
      chain                                                                    \
    }                                                                          \
  }

DOrder


#define dorder_exec(obj, stepobj)                                              \
  timer2_scan(tp, obj);                                                        \
  if (stepobj->Status[0]) {                                                    \
    if (!obj->Old) {                                                           \
      timer2_in(tp, obj);                                                      \
    }                                                                          \
    obj->Status[0] = (obj->TimerFlag) ? false : true;                          \
  } else {                                                                     \
    if (obj->Status[0]) {                                                      \
      obj->TimerCount = 0;                                                     \
      obj->Status[0] = false;                                                  \
    }                                                                          \
  }                                                                            \
  obj->Status[1] = stepobj->Status[0] || stepobj->Status[1];                   \
  obj->Old = stepobj->Status[0];

LOrder


#define lorder_exec(obj, stepobj)                                              \
  timer2_scan(tp, obj);                                                        \
  if (stepobj->Status[0]) {                                                    \
    if (!obj->StatusOld) {                                                     \
      timer2_in(tp, obj);                                                      \
      obj->Status[0] = true;                                                   \
    } else                                                                     \
      obj->Status[0] = obj->TimerFlag;                                         \
  } else {                                                                     \
    if (obj->Status[0]) {                                                      \
      obj->TimerCount = 0;                                                     \
      obj->Status[0] = false;                                                  \
    }                                                                          \
  }                                                                            \
  obj->Status[1] = stepobj->Status[0] || stepobj->Status[1];                   \
  obj->StatusOld = stepobj->Status[0]

POrder


#define porder_exec(obj, stepobj)                                              \
  obj->Status[0] = (stepobj->Status[0] && !obj->StatusOld);                    \
  obj->Status[1] = stepobj->Status[0] || stepobj->Status[1];                   \
  obj->StatusOld = stepobj->Status[0]

COrder


#define corder_exec(obj, stepobj, condition)                                   \
  condition obj->Status[0] = stepobj->Status[0] && obj->Cond;                  \
  obj->Status[1] = stepobj->Status[0] || stepobj->Status[1]

SOrder


#define sorder_exec(obj, stepobj, reset)                                       \
  if (obj->Reset || reset)                                                     \
    obj->Status[0] = false;                                                    \
  if (stepobj->Status[0] && !obj->Old)                                         \
    obj->Status[0] = true;                                                     \
  obj->Old = stepobj->Status[0];                                               \
  obj->Status[1] = obj->Status[0] || stepobj->Status[1];                       \
  obj->Reset = false

Reset_SO


#define reset_so_exec(sorderobj, in)                                           \
  if (in)                                                                      \
  sorderobj->Reset = true

SetCond


#define setcond_exec(obj, in) obj->Cond = in

CSub


#define csub_exec(in, chain)                                                   \
  if (in) {                                                                    \
    chain                                                                      \
  }