/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2020  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.

*/

#include "header.h"
#include "cwdaemon.h"
#include "fifo.h"
#include "inpout.h"
#include "language2.h"
#include "rc.h"

#if defined(Z_MSC_MINGW_CYGWIN)

int parport_init(struct cwdaemon *cwda){
	
	cwda->hInpOut = LoadLibrary("inpout32.dll");
	if (!cwda->hInpOut) {
		log_addf(VTEXT(T_CANT_LOAD_INPOUT), GetLastError());
		return -1;
	}

	cwda->inp32 = (short (_stdcall *)(short port))GetProcAddress(cwda->hInpOut, "Inp32");
	if (!cwda->inp32){
		log_addf("Can't get entry point for Inp32, error %d", GetLastError());
		FreeLibrary(cwda->hInpOut);
		cwda->hInpOut = NULL;
		return -2;
	}

	cwda->out32 = (void (_stdcall *)(short port, short data))GetProcAddress(cwda->hInpOut, "Out32");
	if (!cwda->inp32){
		log_addf("Can't get entry point for Out32, error %d", GetLastError());
		FreeLibrary(cwda->hInpOut);
		cwda->hInpOut = NULL;
		return -3;
	}

	MUTEX_INIT(cwda->hInpOut);
	cwda->baseport = strtol(cfg->cwda_device, NULL, 0);
	cwda->ctrl = cwda->inp32(cwda->baseport+2);
	parport_reset(cwda);
    return 0;
}


int parport_free(struct cwdaemon *cwda){
    
    if (!cwda || !cwda->hInpOut) return 0;
	
	MUTEX_LOCK(cwda->hInpOut);
	cwda->ctrl &= 0xf0;
    cwda->ctrl |= 0x0b; /* /CW=L=1 PTT=L=0 /SSBW=L=1 /ENABLE=H=0 */
	cwda->out32(cwda->baseport+2, cwda->ctrl);
	MUTEX_UNLOCK(cwda->hInpOut);
	
	FreeLibrary(cwda->hInpOut);
	cwda->hInpOut = NULL;
    MUTEX_FREE(cwda->hInpOut);
	return 0;
}

int parport_reset(struct cwdaemon *cwda){

    if (!cwda || !cwda->hInpOut) return 0;

	MUTEX_LOCK(cwda->hInpOut);
	cwda->ctrl &= 0xf0;
	cwda->ctrl &= ~0x04;
    cwda->ctrl |= 0x0b; /* /CW=L=1 PTT=L=0 /SSBW=L=1 /ENABLE=L=1 */
	cwda->out32(cwda->baseport+2, cwda->ctrl);
	MUTEX_UNLOCK(cwda->hInpOut);
	return 0;
}

int parport_cw(struct cwdaemon *cwda, int onoff){
    
    if (!cwda || !cwda->hInpOut) return 1;
    
	MUTEX_LOCK(cwda->hInpOut);
	if (onoff) 
		cwda->ctrl &= ~0x08; /* /CW=H=0 */
	else
		cwda->ctrl |= 0x08;  /* /CW=L=1 */
	
	cwda->out32(cwda->baseport+2, cwda->ctrl);
	MUTEX_UNLOCK(cwda->hInpOut);
    return 0;
}

int parport_ptt(struct cwdaemon *cwda, int onoff){
   
	if (!cwda || !cwda->hInpOut) return 1;
    
	MUTEX_LOCK(cwda->hInpOut);
	if (onoff) 
		cwda->ctrl |= 0x04;  /* PTT=H=1 */
	else
		cwda->ctrl &= ~0x04; /* PTT=L=0 */
	
	cwda->out32(cwda->baseport+2, cwda->ctrl);
	MUTEX_UNLOCK(cwda->hInpOut);
    return 0;
}

int parport_ssbway(struct cwdaemon *cwda, int onoff){

	if (!cwda || !cwda->hInpOut) return 1;
	
	MUTEX_LOCK(cwda->hInpOut);
	if (onoff) 
		cwda->ctrl &= ~0x02; /* /SSBW=H=0 */
	else
		cwda->ctrl |= 0x02;  /* /SSBW=L=1 */
	
	cwda->out32(cwda->baseport+2, cwda->ctrl);
	MUTEX_UNLOCK(cwda->hInpOut);
    return 0;
}

int parport_band(struct cwdaemon *cwda, int bandsw){
	if (!cwda || !cwda->hInpOut) return 1;

    cwda->data &= ~0xe1;
    if (bandsw & 0x01) cwda->data |= 0x01;
    if (bandsw & 0x02) cwda->data |= 0x20;
    if (bandsw & 0x04) cwda->data |= 0x40;
    if (bandsw & 0x08) cwda->data |= 0x80;

	cwda->out32(cwda->baseport, cwda->data);
    return 0;
}


void parport_info(GString *gs){
    HMODULE hInpOut;
    
    g_string_append_printf(gs, "\n  parport_info:\n");
	g_string_append_printf(gs, "Using inpout32.dll");

	hInpOut = LoadLibrary("inpout32.dll");
	if (!hInpOut) {
		g_string_append_printf(gs, ", can't load library\nError %d ", GetLastError());
        z_lasterror(gs);
        g_string_append_printf(gs, "\n");
	}else{
        g_string_append_printf(gs, ", library loaded\n");
	    FreeLibrary(hInpOut);
    } 

    g_string_append_printf(gs, "\n");
}
#endif
