/* Ofront+ 1.0 -sxpC -48 */
#include "SYSTEM.oh"

typedef
  CHAR *CmdArgs_PtrSTR;


#ifndef CHAR8_ARRAY_DEF
#define CHAR8_ARRAY_DEF
typedef struct CHAR8_ARRAY {
  INTEGER len[1];
  CHAR data[1];
} CHAR8_ARRAY;
#endif 

#ifndef INT32_ARRAY_DEF
#define INT32_ARRAY_DEF
typedef struct INT32_ARRAY {
  INTEGER len[1];
  INTEGER data[1];
} INT32_ARRAY;
#endif 

export INTEGER CmdArgs_Count;
static INTEGER CmdArgs_current;
static CmdArgs_PtrSTR CmdArgs_cmdline;
static struct CHAR8_ARRAY *CmdArgs_env;
static struct INT32_ARRAY *CmdArgs_envPtr;
static INTEGER CmdArgs_envCount;
static CHAR CmdArgs_dummy[1];


export INTEGER CmdArgs_EnvCount (void);
__EXTERN BOOLEAN __STDCALL FreeEnvironmentStringsA (CmdArgs_PtrSTR env);
export void CmdArgs_Get (INTEGER n, CHAR *val, INTEGER val__len);
__EXTERN CmdArgs_PtrSTR __STDCALL GetCommandLineA (void);
export void CmdArgs_GetEnv (CHAR *var, INTEGER var__len, CHAR *val, INTEGER val__len);
export void CmdArgs_GetEnvN (INTEGER n, CHAR *s, INTEGER s__len);
__EXTERN CmdArgs_PtrSTR __STDCALL GetEnvironmentStringsA (void);
__EXTERN INTEGER __STDCALL GetEnvironmentVariableA (CmdArgs_PtrSTR lpName, CmdArgs_PtrSTR lpBuffer, INTEGER nSize);
export void CmdArgs_GetInt (INTEGER n, INTEGER *val);
static void CmdArgs_MaybeLoadEnv (void);
export INTEGER CmdArgs_Pos (CHAR *s, INTEGER s__len);


/*============================================================================*/

void CmdArgs_Get (INTEGER n, CHAR *val, INTEGER val__len)
{
  INTEGER i, j;
  CHAR param[260];
  CmdArgs_current = -1;
  i = 0;
  while ((CmdArgs_cmdline)[i] != 0x00 && (CmdArgs_cmdline)[i] <= ' ') {
    i += 1;
  }
  while ((CmdArgs_cmdline)[i] != 0x00) {
    if ((CmdArgs_cmdline)[i] == '\"') {
      i += 1;
      j = 0;
      while ((CmdArgs_cmdline)[i] != 0x00 && (CmdArgs_cmdline)[i] != '\"') {
        if (j < 259) {
          param[j] = (CmdArgs_cmdline)[i];
          j += 1;
        }
        i += 1;
      }
      if ((CmdArgs_cmdline)[i] == '\"') {
        i += 1;
      }
    } else {
      j = 0;
      while ((CmdArgs_cmdline)[i] > ' ') {
        if (j < 259) {
          param[j] = (CmdArgs_cmdline)[i];
          j += 1;
        }
        i += 1;
      }
    }
    param[j] = 0x00;
    CmdArgs_current += 1;
    if (CmdArgs_current == n) {
      if (val__len > __STRLEN(param, 260, (CHAR*)"CmdArgs", 10552)) {
        __STRCOPYCC(param, val, __MIN(val__len, 260), (CHAR*)"CmdArgs", 10548);
      }
      return;
    }
    while ((CmdArgs_cmdline)[i] != 0x00 && (CmdArgs_cmdline)[i] <= ' ') {
      i += 1;
    }
  }
}

/*----------------------------------------------------------------------------*/
void CmdArgs_GetInt (INTEGER n, INTEGER *val)
{
  CHAR s[64];
  INTEGER k, d, i;
  s[0] = 0x00;
  CmdArgs_Get(n, (void*)s, 64);
  i = 0;
  if (s[0] == '-') {
    i = 1;
  }
  k = 0;
  d = (INTEGER)s[i] - 48;
  while (d >= 0 && d <= 9) {
    k = k * 10 + d;
    i += 1;
    d = (INTEGER)s[i] - 48;
  }
  if (s[0] == '-') {
    k = -k;
    i -= 1;
  }
  if (i > 0) {
    *val = k;
  }
}

/*----------------------------------------------------------------------------*/
INTEGER CmdArgs_Pos (CHAR *s, INTEGER s__len)
{
  INTEGER i;
  CHAR arg[256];
  i = 0;
  CmdArgs_Get(i, (void*)arg, 256);
  while (i <= CmdArgs_Count && __STRCMPCC(s, arg) != 0) {
    i += 1;
    CmdArgs_Get(i, (void*)arg, 256);
  }
  return i;
}

/*----------------------------------------------------------------------------*/
void CmdArgs_GetEnv (CHAR *var, INTEGER var__len, CHAR *val, INTEGER val__len)
{
  CHAR buf[4096];
  INTEGER res;
  res = GetEnvironmentVariableA((void*)var, (void*)buf, 4096);
  if (res > 0 && res < 4096) {
    __STRCOPYCC(buf, val, __MIN(val__len, 4096), (CHAR*)"CmdArgs", 21300);
  } else {
    val[0] = 0x00;
  }
}

/*----------------------------------------------------------------------------*/
static void CmdArgs_MaybeLoadEnv (void)
{
  CmdArgs_PtrSTR p;
  INTEGER i, j, len;
  if (CmdArgs_envCount == -1) {
    CmdArgs_envCount = 0;
    p = GetEnvironmentStringsA();
    if (p != NIL) {
      i = 0;
      while ((p)[i] != 0x00) {
        while ((p)[i] != 0x00) {
          i += 1;
        }
        i += 1;
        CmdArgs_envCount += 1;
      }
      CmdArgs_env = __NEWARR(NIL, 1, 1, 1, 1, (SYSTEM_ARRLEN)(i - 1));
      CmdArgs_envPtr = __NEWARR(NIL, 4, 4, 1, 1, (SYSTEM_ARRLEN)CmdArgs_envCount);
      i = 0;
      j = 0;
      while ((p)[i] != 0x00) {
        (CmdArgs_envPtr->data)[j] = i;
        j += 1;
        while ((p)[i] != 0x00) {
          (CmdArgs_env->data)[i] = (p)[i];
          i += 1;
        }
        (CmdArgs_env->data)[i] = 0x00;
        i += 1;
      }
      if (FreeEnvironmentStringsA(p)) {
      }
    }
  }
}

void CmdArgs_GetEnvN (INTEGER n, CHAR *s, INTEGER s__len)
{
  CmdArgs_PtrSTR p;
  INTEGER i, j;
  CmdArgs_MaybeLoadEnv();
  if (0 <= n && n < CmdArgs_envCount) {
    i = 0;
    j = (CmdArgs_envPtr->data)[n];
    while (i < s__len - 1 && (CmdArgs_env->data)[j] != 0x00) {
      s[i] = (CmdArgs_env->data)[j];
      i += 1;
      j += 1;
    }
    s[i] = 0x00;
  } else {
    s[0] = 0x00;
  }
}

/*----------------------------------------------------------------------------*/
INTEGER CmdArgs_EnvCount (void)
{
  CmdArgs_MaybeLoadEnv();
  return CmdArgs_envCount;
}

/*----------------------------------------------------------------------------*/
static void EnumPtrs(void (*P)(void*))
{
  P(CmdArgs_env);
  P(CmdArgs_envPtr);
}


export void *CmdArgs__init (void)
{
  __DEFMOD;
  __REGMOD("CmdArgs", EnumPtrs);
/* BEGIN */
  CmdArgs_cmdline = GetCommandLineA();
  CmdArgs_Get(-1, (void*)CmdArgs_dummy, 1);
  CmdArgs_Count = CmdArgs_current;
  CmdArgs_envCount = -1;
  __ENDMOD;
}
