/***************************************************************************
                          remote.cpp  -  description
                             -------------------
    begin                : Tue Jun 13 2000
    copyright            : (C) 2000 by Calvin Harrigan
    email                : charrig@viaccess.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <unistd.h>
#include "remote.h"
#include "queue.h"

// Opens the comm port indicated by port, sets the correct attributes
// and checks for errors.
Remote::Remote(const char * port)
{
	fFlag = false;
	
	serPort = new linSerial();
	if(serPort == NULL)
	{
		fFlag = true;
		return;
	}
	
	if(serPort->OpenDevice(port))
	{
		fFlag = true;
		return;
	}
	serPort->Set7N2();
	serPort->SetHardwareFlowControl();
	serPort->SetSpeed(2400);
	serPort->SetDTR();
	serPort->SetupRaw();
	fPort = serPort->GetFileHandle();
	sfd = serPort->GetFileDescriptor();
	q = new Queue(50);     // Creates a queue of 50 messages
}

// Deletes all the objects used within the class
Remote::~Remote()
{
	serPort->Close();
	delete serPort;
	delete q;
}

// Returns the file descriptor of the serial port
int Remote::GetFileDescriptor()const
{
	return sfd;
}

// When data arrives from the remote control it is checked in
// the multiple switch statement below to be deciphered.  After which
// the result is put in the queue. Returns 0 on success, -1 on error.
int Remote::Event()
{
	int result;
	result=read(sfd,buffer,6);
	if(result < 6) return -1;

  if(buffer[0] == 64)
	{
		switch(buffer[3])
		{
			case 0: break;
			case 1: q->enqueue('C'); break;
			case 2: q->enqueue('B'); break;
			case 4: q->enqueue('A'); break;
			case 8: q->enqueue('F'); break;
	 		case 16: q->enqueue('E'); break;
			case 32: q->enqueue('D'); break;
			default: break;
		}
		switch(buffer[4])
		{
			case 0: break;
			case 1: q->enqueue('I');break;
			case 2: q->enqueue('H');break;
			case 4: q->enqueue('G'); break;
			case 8:	q->enqueue('L');break;
			case 16: q->enqueue('K');break;
			case 32: q->enqueue('J');break;
			default: break;
		}
		switch(buffer[5])
		{
			case 0: break;
			case 1: q->enqueue('O'); break;
			case 2: q->enqueue('N'); break;
			case 4:	q->enqueue('M'); break;
			case 8:	q->enqueue('R'); break;
			case 16: q->enqueue('Q'); break;
			case 32: q->enqueue('P'); break;
			default: break;
		}
	}
	else return -1;
	return 0;	
}

// returns the next item in the queue, or zero if the queue is empty
int Remote::GetKey()const
{
	int key;
	if(!q->isempty())
	{
		if(q->dequeue(key))return key;
	}
	return 0;
}




