#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ltr/include/ltr42api.h"

#ifdef _WIN32
#include <locale.h>
#include <conio.h>
#else
#include <signal.h>
#include <unistd.h>
#endif

static int f_out = 0;

#ifndef _WIN32
/* Обработчик сигнала завершения для Linux */
static void f_abort_handler(int sig) {
    f_out = 1;
}
#endif



typedef struct {
    int slot;
    const char *serial;
    DWORD addr;
} t_open_param;

/* Разбор параметров командной строки. Если указано меньше, то используются
 * значения по умолчанию:
 * 1 параметр - номер слота (от 1 до 16)
 * 2 параметр - серийный номер крейта
 * 3 параметр - ip-адрес сервера */
static int f_get_params(int argc, char** argv, t_open_param* par) {
    int err = 0;
    par->slot = LTR_CC_CHNUM_MODULE1;
    par->serial = "";
    par->addr = LTRD_ADDR_DEFAULT;


    if (argc > 1)
        par->slot = atoi(argv[1]);
    if (argc > 2)
        par->serial = argv[2];
    if (argc > 3) {
        int a[4],i;
        if (sscanf(argv[3], "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3])!=4) {
            fprintf(stderr, "Неверный формат IP-адреса!!\n");
            err = -1;
        }

        for (i=0; (i < 4) && !err; i++) {
            if ((a[i]<0) || (a[i] > 255)) {
                fprintf(stderr, "Недействительный IP-адрес!!\n");
                err = -1;
            }
        }

        if (!err) {
            par->addr = (a[0] << 24) | (a[1]<<16) | (a[2]<<8) | a[3];
        }
    }
    return err;
}


/*================================================================================================*/
/*------------------------------------------------------------------------------------------------*/
int main(int argc, char *argv[]) {
    t_open_param par;
    INT err = LTR_OK;
#ifndef _WIN32
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    /* В ОС Linux устанавливаем свой обработчик на сигнал закрытия,
       чтобы завершить сбор корректно */
    sa.sa_handler = f_abort_handler;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGABRT, &sa, NULL);
#endif

#ifdef _WIN32
    /* для вывода русских букв в консоль для ОС Windows*/
    setlocale(LC_ALL, "");
#endif

    err = f_get_params(argc, argv, &par);
    if (err == LTR_OK) {
        TLTR42 hltr42;
        LTR42_Init(&hltr42);

        /* Открываем интерф. канал связи с модулем. Сетевой адрес и номер порта - по умолчанию
         * Серийный номер первого найденного модуля;
         * Номер посадочного места - 1;
         */
        err = LTR42_Open(&hltr42, par.addr, LTRD_PORT_DEFAULT, par.serial, par.slot);
        if (err != LTR_OK) {
            fprintf(stderr, "Не удалось открыть установить соединение с модулем. Ошибка %d (%s).\n",
                    err, LTR42_GetErrorString(err));
        } else {
            WORD out_data=0;
            INT cntr = 0;
            INT close_err;

            if (err==LTR_OK) {
                printf("Тест запущен. Для останова нажмите %s\n",
    #ifdef _WIN32
                       "любую клавишу"
    #else
                       "CTRL+C"
    #endif
                       );
                fflush(stdout);
            }

            if (err == LTR_OK) {
                /* Производим заполнение полей структуры описания модуля требуемыми значениями */
                hltr42.AckEna = TRUE;            /* подтверждения включены */
                hltr42.Marks.SecondMark_Mode = LTR42_MARK_MODE_INTERNAL;
                hltr42.Marks.StartMark_Mode = LTR42_MARK_MODE_INTERNAL;

                err = LTR42_Config(&hltr42);
                if (err != LTR_OK) {
                    fprintf(stderr, "Не удалось сконфигурировать модуль. Ошибка %d (%s).\n",
                            err, LTR42_GetErrorString(err));
                } else {
                    while (!f_out && (err == LTR_OK)) {
                        //LTRAPI_SLEEP_MS(10);
                        err = LTR42_WritePort(&hltr42, out_data);
                        if (err != LTR_OK) {
                            fprintf(stderr, "Не удалось записать слово в порт вывода. Ошибка %d (%s).\n",
                                    err, LTR42_GetErrorString(err));
                        }


                        if (err == LTR_OK) {
                            cntr++;

                            if ((cntr % 0x7) == 0) {
                                printf(".");
                                fflush(stdout);
                            }
            #ifdef _WIN32
                            /* проверка нажатия клавиши для выхода */
                            if (_kbhit())
                               f_out = 1;
            #endif
                        }
                    }

                }
            }

            close_err = LTR42_Close(&hltr42);
            if (close_err!=LTR_OK) {
                fprintf(stderr, "Не удалось закрыть соединение с модулем. Ошибка %d (%s).\n", close_err,
                    LTR42_GetErrorString(close_err));
                if (err == LTR_OK)
                    err = close_err;
            }
        }
    }
    return err;
}
