#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmdio.h"

#define USE_CAM1    (1)
#define USE_CAM2    (0)

int main(int argc, char **argv);
int capture(cmdio_t *p, const int n, const char *filename);

int main(int argc, char **argv)
{
    /*
     * コマンドI/Oを開く。
     */
    cmdio_t *p = cmdio_open("/dev/ttyUSB1");
    if (p == NULL) {
        printf("Failure to open the serial port.\n");
        return 1;
    }

    char send[BUFSIZ];
    char recv[BUFSIZ];

    /*
     * コマンドを発行して応答を得る。
     */
    {
        sprintf(send, "%s", "info sys");
        cmdio_execute(p, send, recv, sizeof(recv));
        printf("send(%s), recv(%s)\n", send, recv);
    }

    {
        sprintf(send, "%s", "info ver");
        cmdio_execute(p, send, recv, sizeof(recv));
        printf("send(%s), recv(%s)\n", send, recv);
    }

    {
        sprintf(send, "%s", "display text hello");
        cmdio_execute(p, send, recv, sizeof(recv));
        printf("send(%s), recv(%s)\n", send, recv);
    }

    {
        sprintf(send, "%s", "display text player");
        cmdio_execute(p, send, recv, sizeof(recv));
        printf("send(%s), recv(%s)\n", send, recv);
    }

    for (int i = 0; i < 1000; i++) {
        char filename[BUFSIZ];
#if USE_CAM1
        sprintf(filename, "cam1-%05d.jpg", i);
        printf("Capture Cam No.1: (%s)\n", filename);
        capture(p, 0, filename);
#endif
#if USE_CAM2
        sprintf(filename, "cam2-%05d.jpg", i);
        printf("Capture Cam No.2: (%s)\n", filename);
        capture(p, 1, filename);
#endif
    }

    /*
     * コマンドI/Oを閉じる。
     */
    cmdio_close(p);

    return 0;
}

/**
 * @brief 与えられた文字がデリミタであるかどうかを判定する。
 * @param c 文字。
 * @param delim デリミタ。
 * @retval 0 デリミタでない。
 * @retval !0 デリミタである。
 */
static int is_delim(const char c, const char *delim)
{
    const int n = strlen(delim);
    char *p = (char *)delim;
    for (int i = 0; i < n; i++) {
        if (c == *p) {
            return 1;
        }
        p++;
    }
    return 0;
}

/**
 * @brief 次のデータへスキップする。
 * @param str 文字列。
 * @param delim デリミタ。
 * @return 次のデータを指し示すポインタ。
 */
static char *skip_to_next(char *str, const char *delim)
{
    const int n = strlen(delim);
    char *p = str;

    /*
     * 現在のポインタは、現在のデータを指し示している。
     * だから、デリミタが見つかるまでスキップする。
     */
    while (*p) {
        if (is_delim(*p, delim)) {
            break;
        }
        p++;
    }

    /*
     * 現在のポインタは、デリミタを指し示している。
     * だから、デリミタでない文字が見つかるまでスキップする。
     */
    while (*p) {
        if (!is_delim(*p, delim)) {
            return p;
        }
        p++;
    }

    return NULL;
}

int capture(cmdio_t *p, const int n, const char *filename)
{
    static const int RECV_BUFSIZ = 32 * 1000 * 1000;
    char send[BUFSIZ];
    char *recv = NULL;
    char tmp[BUFSIZ];

    /*
     * ファイルを開く。
     */
    FILE *fp = fopen(filename, "wb");
    if (fp == NULL) {
        return -1;
    }

    /*
     * 受信バッファを確保する。
     */
    recv = (char *)malloc(sizeof(char) * RECV_BUFSIZ);

    /*
     * コマンドを送信して結果を受け取る。
     */
    sprintf(send, "camera capture %d", n);
    cmdio_execute(p, send, recv, RECV_BUFSIZ);

    /*
     * デバッグ用出力。
     */
    {
        char debfile[BUFSIZ];
        sprintf(debfile, "%s.dat", filename);
        FILE *fp_debug = fopen(debfile, "wb");
        if (fp_debug != NULL) {
            fprintf(fp_debug, "%s", recv);
            fclose(fp_debug);
        }
    }

    /*
     * 結果を保存する。
     */
    char *strp = recv;
    do {
        int hex;
        sscanf(strp, "%x", &hex);
        fputc(hex, fp);
    } while ((strp = skip_to_next(strp, " \r\n")) != NULL);

    /*
     * ファイルを閉じる。
     */
    fclose(fp);

    /*
     * 受信バッファを開放する。
     */
    free(recv);

    return 0;
}

