//c - c++
#include "iostream"
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/kd.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <getopt.h>
#include <unistd.h>
//this
#include "SerLEDDeviceConsole.H"

using namespace std;

#ifndef CLOCK_TICK_RATE
#define CLOCK_TICK_RATE 1193180
#endif


//////////////////////////////////
// Initialize(const char dev)	//
//////////////////////////////////

void SerLEDDeviceConsole :: Initialize(const std::vector<std::string> &items)
	{
	string filename("/dev/console");
	if(items.size()>2)
		{
		filename=items[2];
		}
	_file_d = open(filename.c_str() , O_WRONLY);
		if(_file_d==-1)
			{
			cerr<<"Cannot open'"<<items[2]<<"'!"<<endl;
			exit(1);
			}
//	Off(RTS);
//	Off(DTR);
	}


//////////////////////////////////////////////////////////////////
// GetLEDnumber(const std::vector<std::string> & items) const	//
//////////////////////////////////////////////////////////////////

int SerLEDDeviceConsole :: GetLEDNumber(const std::vector<std::string> & items)
	{
	int led_nr(-1);
	if(items[0]=="NUM_LOCK") led_nr=NUM_LOCK;
	if(items[0]=="CAPS_LOCK") led_nr=CAPS_LOCK;
	if(items[0]=="SCROLL_LOCK") led_nr=SCROLL_LOCK;
	if(items[0]=="BEEP") led_nr=BEEP;
	if(led_nr==-1) 
		{
		cerr<<"Led '"<<items[0]<<"' is unknown to device console!"<<endl;
		return -1;
		}
	Off(led_nr);
	return led_nr;
	}



//////////////////////////
// On(unsigned int led)	//
//////////////////////////

void SerLEDDeviceConsole :: On(int led)
	{
//beep led is special
	if(led==BEEP)
		{
		if(ioctl(_file_d, KIOCSOUND, static_cast<int>(CLOCK_TICK_RATE/1000.0)) < 0)
			{
			cerr<<"SerLEDDeviceConsole :: On: Cannot beep!"<<endl;
			}
		return;
		}
//keyboard leds
	unsigned char led_mask;
	switch(led)
		{
		case NUM_LOCK:
			led_mask=LED_NUM;
			break;
		case CAPS_LOCK:
			led_mask=LED_CAP;
			break;
		case SCROLL_LOCK:
			led_mask=LED_SCR;
			break;
		default:
			cerr<<"SerLEDDeviceConsole :: On: Program error - contact author of plugin serled!"<<endl;
			exit(1);
		}
//turn ol led
	unsigned char state;
	ioctl(_file_d, KDGETLED, &state);
	ioctl(_file_d, KDSETLED, state | led_mask);
	}

//////////////////////////////////
// Off(unsigned int led)	//
//////////////////////////////////

void SerLEDDeviceConsole :: Off(int led)
	{
//beep led is special
	if(led==BEEP)
		{
		if(ioctl(_file_d, KIOCSOUND, 0) < 0)
			{
			cerr<<"SerLEDDeviceConsole :: Off: Cannot beep!"<<endl;
			}
		return;
		}
//keyboard leds
	unsigned char led_mask;
	switch(led)
		{
		case NUM_LOCK:
			led_mask=LED_NUM;
			break;
		case CAPS_LOCK:
			led_mask=LED_CAP;
			break;
		case SCROLL_LOCK:
			led_mask=LED_SCR;
			break;
		default:
			cerr<<"SerLEDDeviceConsole :: On: Program error - contact author of plugin serled!"<<endl;
			exit(1);
		}
//turn ol led
	unsigned char state;
	ioctl(_file_d, KDGETLED, &state);
	ioctl(_file_d, KDSETLED, state & ~led_mask);
	}

