/* 
 * This software is licensed under terms of the GNU GENERAL PUBLIC LICENSE
 *
 * This software 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 3 of the License, or
 * (at your option) any later version.
 *
 * This software  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 this software.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Source code is available at http://ppcenter.free.fr
 */


#ifndef _INCLUDE_LOG_H_
#define _INCLUDE_LOG_H_

#ifdef  __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdarg.h>


/**
 * About the log module.
 *
 * This module provides logging functions for communication DLLs, DLL wrapper and host programs (slnk, satlink).
 * It provides flexible logging from various sources to various outputs, like printf, file, etc.
**/





/**
 * Enumerate the available log types.
**/
/* Log message that comes from communication DLL.     */
#define SCLT_DLLPG  0
/* Log message that comes from DLL wrapper.           */
#define SCLT_DLLWRP 1
/* Log message that comes from host program.          */
#define SCLT_HOSTPG 2
/* Log message that comes from Saturn, console type.  */
#define SCLT_SATMSG 3
/* Log message that comes from Saturn, grid type.     */
#define SCLT_SATGRD 4

/* Types count (max possible = 8). */
#define SCLT_COUNT 5

/*--- Define bit masks for types. ---*/
/* bits 0~3: type value. */
#define SCLT_TYPE_MSK   0x0F
/* bit4 : set to 1 when prompt answer is requested. */
#define SCLT_PROMPT_MSK 0x10




/**
 * Enumerate the available log outputs.
**/
/* Print log to standard output.                      */
#define SCLO_PRINTF  0
/* Send log to DebugView.                             */
#define SCLO_DBGVIEW 1
/* Send log to file though buffer.                    */
#define SCLO_FILE    2
/* Transmit log to host program through callback #1   */
#define SCLO_CBCK1   3
/* Transmit log to host program through callback #2   */
#define SCLO_CBCK2   4
/* Transmit log to host program through callback #3   */
#define SCLO_CBCK3   5

/* Outputs count (max possible = 6). */
#define SCLO_COUNT   6
#define SCLO_CALLBACKS_COUNT 3



/**
 * The log callback prototype.
 * parameter1 : unsigned char log type    (SCLT_* value)
 * parameter2 : unsigned char loglevel    0->critical~9:not important
 * parameter3 : unsigned char prompt      different from zero: a prompt answer is expected
 * parameter4 : unsigned char log_ofs     Offset to the log message itself in the string (*)
 * parameter5 : char* logmessage
 *
 * (*) About log_ofs: Some characters are appended at the begining of the debug string.
 *     Appended characters tell some informations about the log type and level.
 *     Example: log message = "test" will  be displayed as something like "40>test".
 *     In order to avoid this display use "logmessage+log_ofs" instead of "logmessage".
**/
/* Callback used receiving log data from DLL.       */
typedef char (*Fct_scl_callback)(unsigned char, unsigned char, unsigned char, unsigned char, char*);




/**
 * Describes the log settings structure.
**/
typedef struct _scl_settings_t
{
    /* Stuff used for buffering log to file. */
    char* bufflog_ptr;
    long  bufflog_sz;
    long  bufflog_maxsz, bufflog_filesz;
    long  bufflog_end;
    FILE* bufflog_stream;

    /* Pointer to callback functions. */
    Fct_scl_callback callbacks[SCLO_CALLBACKS_COUNT];

    /* Threshold level for each type and where to output. */
    unsigned char levels[SCLT_COUNT][SCLO_COUNT];


    /** Stuff for debug mode. **/
    /* Indicates if debug mode is on or off. */
    unsigned char silent_on;
    /* Indicates which output to turn to off when debug. */
    unsigned char dbg_outmask;
    /* Log levels backup. */
    unsigned char levels_backup[SCLT_COUNT][SCLO_COUNT];
} scl_settings_t;





/**
 * Log engine initialisation.
 * Need to be called by the host program on startup.
 * Don't need to be called by DLL or wrapper.
 * parameter1 : pointer to a log setting structure.
 * parameter2 : set to 1 when init for SatLink.
**/
void scl_init(scl_settings_t* settings, unsigned char satlink_init);
/**
 * Log engine ending.
 * Flush log data to disk, and close log file.
 * Need to be called by the host program on before ending.
 * Don't need to be called by DLL or wrapper.
**/
void scl_end(void);


/**
 * Read log settings from INI file.
 * Typically called by the host program on startup, or when user requested to re-read ini file.
 * In order to separate settings between slnk and satlink, specify a different section_name in each case.
 * Hence, it is possible to handle settings for various applications in a single file.
**/
void scl_read_ini(char* filename, char* section_name);

/**
 * Set log enable/disable.
**/
void scl_set_logsw(int sw);

/**
 * Set user callback for logging.
**/
void scl_set_callback(int id, Fct_scl_callback c);



/**
 * The log function.
 * Can be called by host program, DLL and wrapper.
 * parameter1  : unsigned char log type   (SCLT_* value)
 * parameter2  : unsigned char loglevel   0->critical~9:not important
 * parameter3~ : char* string, ...
**/
void scl_log(unsigned char type_prompt, unsigned char level, const char *string, ...);
/**
 * Log flush function.
 * Call this function when you want to flush log data from memory to hard disk.
 * (useful in the case your program may crash soon ...)
**/
void scl_logflush(void);



/**
 * Turn on/off silent mode.
 * This is used when user don't wan excessive log amount so that transfer speed can be higher.
 *
 * This is also used when polling Saturn debug data in order not to log polling related messages.
 * Hence, user can focus on Saturn debug messages at this time.
 * When "silent mode" is turned off, the user can focus on transfer-related logs.
**/
void scl_silentmode(unsigned char silent_on, unsigned char silent_level);


/**
 * Adjust log level and output to a given log type.
**/
void scl_adjust(unsigned char type, unsigned char output, unsigned char level);


#ifdef  __cplusplus
}
#endif


#endif // _INCLUDE_LOG_H_
