/***************************************************************************
 *                         time_mod.c -  description
 *                            -------------------
 *   begin                : Mon 19 Dec 2005 04:20:14 PM EST
 *   copyright            : (C) 2005 by Terry D. Boldt
 *   email                : fastsnip-wm1@yahoo.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
/*
 *
 *   QTAwk plugin function to demonstrate creating and returning arrays
 * Also, creating and returning arrays in call arguments
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

/* Note QTAwk_plugins.h header file depeneds on "string.h" header file.
 * ALWAYS include "string.h" before QTAwk_plugins
 */
#include "QTAwk_plugins.h"
/* define some useful constants
 */
#define TRUE  1
#define FALSE 0

/* define End Of String marker
 */
#define EOS '\x000'

/* define initialization function
 */
unsigned QTAwk_init_load_module(
void)
{
    /* array of pointers to string with argument names for loaded functions
     * Here both functions take a single string function
     */
    unsigned char *arguments[] = {
                    "lcl_time",
                    NULL
                    };

    /* declare error return variable
     */
    unsigned char *reg_err;

    /* call function to initialize for installing dynamic function(s)
     */
    QTAwk_register_function_count(4);

    /* now call function to register each dynamic function to load
     *
     * Note that 'QTAwk_register_function' returns a pointer to a string or NULL
     * if no error in registering function. Here we are ignoring the return value
     * until returning from the call.
     * We "should" examine the return value for every call to 'QTAwk_register_function'
     * and report any errors.
     */
    reg_err = QTAwk_register_function("time_mod_version",NULL,FALSE);
    reg_err = QTAwk_register_function("systime",NULL,FALSE);
    reg_err = QTAwk_register_function("local_time",NULL,FALSE);
    reg_err = QTAwk_register_function("local_time_a",arguments,FALSE);

    QTAwk_set_module_exit_function("time_mod_exit");

    return reg_err ? -1 : 0;
} /* QTAwk_init_load_module */

/* function registered to accomplish actual work.
 *
 * All dynamically loaded functions have the following prototype form:
 *
 *      Variable_ptr loaded_function(unsigned argument_count);
 *
 * Where 'Variable_ptr' is a QTAwk variable defined in the QTAwk plugin
 *  header file "QTAwk_plugins.h"
 *  Do NOT manipulate the fields in the structure directly. Use the function
 *  calls defined in "QTAwk_plugins.h" for that purpose.
 *
 *
 *
 */

/* version string
 */
static unsigned char time_mod_version_string[] = "Time Module version 1.00";

/* function to return module version string
 */
Variable_ptr  time_mod_version(
void)
{
    Variable_ptr   retval;

    retval = QTAwk_get_variable_set((void *)time_mod_version_string,STRING_VAL);

    return retval;
} /* time_mod_version */

/*
 * Return the system time == the number of seconds since the system epoch.
 * On POSIX systems, this is the number of seconds since 1970-01-01
 * 00:00:00 UTC, not counting leap seconds.
 * It may be a different number on other systems.
 *
 */
Variable_ptr systime(
unsigned     arg_cnt)
{
    time_t         timev;
    Variable_ptr   retval;
    qta_long       elem_value;

    time(&timev);

    /* set system time into QTAwk long integer
     */
    elem_value = timev;

    /* get QTAwk variable for setting array elements to time structure values
     */
    retval = QTAwk_get_variable_set((void *)&elem_value,LONG_VAL);

    return retval;
} /* systime */

/* return an array - get the time and return the 'C' time structure
 * in an array
 *
 * this function takes zero arguments.
 */
Variable_ptr local_time(
unsigned     arg_cnt)
{
    struct tm     rtime;
    struct tm    *lcl_time;
    time_t         timev;
    Variable_ptr   retval;
    qta_long       elem_value;
    const unsigned char *zone;

    time(&timev);

    lcl_time = localtime_r(&timev,&rtime);

    /* get QTAwk variable for setting array elements to time structure values
     */
    retval = QTAwk_get_variable_set(NULL,NO_VAL);

    /* now set array elements using string indices for time elements of broken down
     * time structure
     * for each array element call 'QTAwk_get_array_element' to create the aray element
     * then call 'QTAwk_set_value' to set the array element value. All element values
     * are integers except the time zone value.
     */
    elem_value = rtime.tm_sec;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_sec");
    elem_value = rtime.tm_min;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_min");

    elem_value = rtime.tm_hour;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_hour");

    elem_value = rtime.tm_mday;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_mday");
    elem_value = rtime.tm_mon;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_mon");
    elem_value = rtime.tm_year;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_year");
    elem_value = rtime.tm_wday;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_wday");
    elem_value = rtime.tm_yday;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_yday");
    elem_value = rtime.tm_isdst;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_isdst");
    elem_value = rtime.tm_gmtoff;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_gmtoff");

    zone = rtime.tm_zone;
    (void)QTAwk_create_array_element(retval,
                                     (void *)zone,
                                     STRING_VAL,
                                     "s",
                                     "tm_zone");

    return retval;
} /* local_time */


/* return an array - get the time and return the 'C' time structure
 * in an array - the array is returned in the argument to the function
 * also.
 *
 * this function takes one argument.
 */
Variable_ptr local_time_a(
unsigned     arg_cnt)
{
    struct tm     rtime;
    struct tm    *lcl_time;
    time_t         timev;
    Variable_ptr   retval;
    Variable_ptr   arg_array;
    qta_long       elem_value;
    const unsigned char *zone;

    time(&timev);

    lcl_time = localtime_r(&timev,&rtime);

    /* get argument
     */
    arg_array = QTAwk_get_argument(1,NULL);

    /* get QTAwk variable for setting array elements to time structure values
     */
    retval = QTAwk_get_variable_set(NULL,NO_VAL);

    /* now set array elements using string indices for time elements of broken down
     * time structure
     * for each array element call 'QTAwk_get_array_element' to create the aray element
     * then call 'QTAwk_set_value' to set the array element value. All element values
     * are integers except the time zone value.
     *
     * Two calls to create array element for each index, one call for return variable
     * and second call for argument variable to return array in argument variable also.
     */
    elem_value = rtime.tm_sec;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_sec");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_sec");
    elem_value = rtime.tm_min;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_min");

    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_min");
    elem_value = rtime.tm_hour;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_hour");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_hour");
    elem_value = rtime.tm_mday;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_mday");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_mday");
    elem_value = rtime.tm_mon;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_mon");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_mon");
    elem_value = rtime.tm_year;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_year");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_year");
    elem_value = rtime.tm_wday;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_wday");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_wday");
    elem_value = rtime.tm_yday;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_yday");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_yday");
    elem_value = rtime.tm_isdst;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_isdst");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_isdst");
    elem_value = rtime.tm_gmtoff;
    (void)QTAwk_create_array_element(retval,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_gmtoff");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)&(elem_value),
                                     LONG_VAL,
                                     "s",
                                     "tm_gmtoff");
    zone = rtime.tm_zone;
    (void)QTAwk_create_array_element(retval,
                                     (void *)zone,
                                     STRING_VAL,
                                     "s",
                                     "tm_zone");
    (void)QTAwk_create_array_element(arg_array,
                                     (void *)zone,
                                     STRING_VAL,
                                     "s",
                                     "tm_zone");

    return retval;
} /* local_time */

/* exit function - executed before unloading module
 * Using default function name here.
 */
unsigned time_mod_exit(
void)
{
    printf("Unloading time module.\n");
} /* time_mod_exit */