/*
    Tucnak - VHF contest log
    Copyright (C) 2011-2021 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#ifndef __CWDAEMON_H
#define __CWDAEMON_H

#include "header.h"
#include "cwdaemon.h"
#include "session.h"

struct cq;

enum cwtype { CWD_NONE, CWD_PARPORT, CWD_TTYS, CWD_DAVAC4, CWD_CWD, CWD_WINKEY, CWD_WINKEY4x, CWD_WINKEYTCP, CWD_TTYS_SINGLE, CWD_HAMLIB, CWD_DAVAC5
};

struct cwdaemon {
	int (*init)    (struct cwdaemon *);
	int (*free)    (struct cwdaemon *);
	int (*reset)   (struct cwdaemon *);
    int (*text)    (struct cwdaemon *, char *);
	int (*sspeed)  (struct cwdaemon *, int);
	int (*sweight) (struct cwdaemon *, int);
	int (*cw)      (struct cwdaemon *, int);
	int (*ptt)     (struct cwdaemon *, int);
	int (*ssbway)  (struct cwdaemon *, int);
	int (*monitor) (struct cwdaemon *, int);
	int (*echo)    (struct cwdaemon *);
    int (*dtune)   (struct cwdaemon *, int);
    int (*back)    (struct cwdaemon *);
    int (*band)    (struct cwdaemon *, int bandsw);

	int fd;
	char *desc;
    gint speed, weight;
    GThread *thread;
    int thread_break, abort;
    int pipe_read, pipe_write;
    GString *code;
    GString *played;
    MUTEX_DEFINE(code);
/*    GMutex *code_mutex;
#ifdef LEAK_DEBUG_LIST
    char *code_file;
    int code_line;
#endif*/
    struct cwdev *dev;
#if defined(Z_MSC_MINGW_CYGWIN)
	HINSTANCE hInpOut;
    MUTEX_DEFINE(hInpOut);
/*    GMutex *hInpOut_mutex;
#ifdef LEAK_DEBUG_LIST
    char *hInpOut_file;
    int hInpOut_line;
#endif  */
	int xx;
	short (_stdcall *inp32)(short port);
	void (_stdcall *out32)(short port, short data);
	short baseport;
	unsigned char ctrl;
#endif
    unsigned char data;
#ifdef Z_HAVE_LIBFTDI
    struct ftdi_context *ftdi;
    unsigned char ftdi_state;
    MUTEX_DEFINE(ftdi);
#endif
#ifdef HAVE_HIDAPI
    hid_device* hid;
    unsigned char hid_state;
    MUTEX_DEFINE(hid);
#endif
    int tune;
    int sock;
    unsigned char winkey_version, winkey_oldstatus;
    int ttys_locked; // for CWD_TTYS and CWD_WINKEY
    int hold_ptt;
    int freeing;
	struct zserial *zser;
    int zser_fd;
};

extern struct cwdaemon *cwda;

struct cwdaemon *init_cwdaemon(void);
void free_cwdaemon(struct cwdaemon *cwda);

void cwdaemon_read_handler(struct cwdaemon *cwda, char *s, char *played);
void cq_cw_wait(struct cq *cq);
void cq_timer_cw2(void *cq);
void cwdaemon_set_defaults(struct cwdaemon *cwda, int speed);
gpointer cwdaemon_thread_func(gpointer data);
void cwdaemon_echo(struct cwdaemon *cwda);

int cwdaemon_text(struct cwdaemon *cwda, char *text);
void cwdaemon_abort(struct cwdaemon *cwda);
void cwdaemon_safe_abort(struct cwdaemon *cwda);
void cwdaemon_ptt(struct cwdaemon *cwda, int ptt, int hold_ptt);
void cwdaemon_ssbway(struct cwdaemon *cwda, int ssbway); /* 0=microphone, 1=soundcard */
int cwdaemon_speed(struct cwdaemon *cwda, int wpm);
void cwdaemon_qrq(struct cwdaemon *cwda, int qrq);
void cwdaemon_qrs(struct cwdaemon *cwda, int qrs);
int cwdaemon_weight(struct cwdaemon *cwda, int weight);
void cwdaemon_tune(struct cwdaemon *cwda, int tune);
int cwdaemon_back(struct cwdaemon *cwda);
int cwdaemon_band(struct cwdaemon *, int bandsw);



int cwd_init   (struct cwdaemon *);
int cwd_free   (struct cwdaemon *);
int cwd_reset  (struct cwdaemon *);
int cwd_text   (struct cwdaemon *, char *text);
int cwd_speed  (struct cwdaemon *, int onoff);
int cwd_weight (struct cwdaemon *, int onoff);
int cwd_cw     (struct cwdaemon *, int onoff);
int cwd_ptt    (struct cwdaemon *, int onoff);
int cwd_ssbway (struct cwdaemon *, int onoff);
int cwd_echo   (struct cwdaemon *);
void cwd_read_handler(void *arg);
void cwd_tone  (struct cwdaemon *cwda, int tone);
int cwd_tune   (struct cwdaemon *cwda, int tune);
int cwd_band   (struct cwdaemon *, int bandsw);


struct cq{
    int nr;
    enum modes mode; 

    gchar *cw_str;
    int    cw_speed;  /* 0 = unused */
	int    cw_repeat; /* 0 or 1 */
	int    cw_breakable; /* 0 or 1 */
    int    cw_ts;     /* tenth of second */
    int    cw_allowifundef;
    
    gchar *ssb_file;
	int    ssb_repeat;/* 0 or 1 */
	int    ssb_breakable;/* 0 or 1 */
    int    ssb_ts;    /* tenth of second */

    int stripcall;
};       

struct cq *init_cq(void);
struct cq *get_cq_by_number(GPtrArray *cqs, int nr);
void free_cq (struct cq *cq);

int cq_run_cw(struct cq *cq);
int cq_run_ssb(struct cq *cq);
int cq_run_by_number(int no);
int cq_abort(int abort_rec);
//void cq_timer_cw(void *cq);
void cq_timer_ssb1(void *cq);
void cq_ssb_wait(struct cq *cq);
void cq_timer_ssb2(void *cq);

gchar *convert_cq(struct cq *cq);
gchar *convert_esc(gchar *format, int *undef, int flags, time_t now); 
        
void menu_runmode(void *arg);
void menu_spmode(void *arg);
void runmode(int run);
void menu_extcq(void *arg);
int cq_remains_run(void);
int cq_remains_brk(void);
void cq_timer_brk(void *arg);
void ac_cq(void);

int cwd_hamlib_text(struct cwdaemon *cwda, char *text);
int cwd_hamlib_reset(struct cwdaemon *cwda);



#endif
