/*
 * Copyright (C) 2002 Zsolt Rizsanyi <rizsanyi@myrealbox.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "lirc.h"
#include "lirc.moc"
#include <qsocketnotifier.h>
#include <kdebug.h>
#include <fcntl.h>
#include <stdlib.h>

Lirc::Lirc( QObject *parent, const QString& appname ) 
     :QObject( parent, "lirc" )
{
    _appname = appname;
#ifdef HAVE_LIRC
    _config = 0;
    if ((_lircfd = lirc_init((char*)_appname.latin1(), 1)) < 0) {
	kdDebug() << "lirc: Failed to initialize" << endl;
	_lircfd = -1;
	return;
    }
    fcntl(_lircfd,F_SETFL,O_NONBLOCK);
    fcntl(_lircfd,F_SETFD,FD_CLOEXEC);

    if (lirc_readconfig(NULL, &_config, NULL) != 0) {
	kdDebug() << "lirc: Couldn't read config file" << endl;
	_config = 0;
    }
    kdDebug() << "lirc: Succesfully initialized" << endl;

    QSocketNotifier* sn = new QSocketNotifier( _lircfd, QSocketNotifier::Read, parent );
    QObject::connect( sn, SIGNAL(activated(int)), this, SLOT(dataReceived()) );
#else
    kdDebug() << "lirc: No lirc support available" << endl;
#endif
}

Lirc::~Lirc()
{
#ifdef HAVE_LIRC
    if (_config)
        lirc_freeconfig(_config);
    lirc_deinit();
#endif
}

void Lirc::dataReceived()
{
#ifdef HAVE_LIRC
    if (_lircfd < 0)
	return;

    char *code, event[24], *cmd;
    unsigned dummy, repeat;

    strcpy(event,"");
    while (lirc_nextcode(&code)==0  &&  code!=NULL) {
	if (3 != sscanf(code,"%x %x %20s",&dummy,&repeat,event)) {
	    kdDebug() << "lirc: oops, parse error: " << code << endl;
	    free(code);
	    continue;
	}
	kdDebug() << "lirc: key '" << event << "' repeat " << repeat << endl;
	if (_config) {
	    // use config (~/.lircrc)
	    while (lirc_code2char(_config,code,&cmd)==0 && cmd != NULL) {
		kdDebug() << "lirc: cmd '" << cmd << "'" << endl;
		if (0 == strcasecmp(cmd, "default")) {
		    QMap<QString, QString>::iterator val = _keymap.find(event);
		    if ( val != _keymap.end())
			emit command(*val, repeat);
		    else
			emit Lirc::event(event, repeat);
		} else {
		    emit command(cmd, repeat);
		}
	    }
	} else {
	    /* standalone mode */
	    QMap<QString, QString>::iterator val = _keymap.find(event);
	    if ( val != _keymap.end())
		emit command(*val, repeat);
	    else
		emit Lirc::event(event, repeat);
	}
	free(code);
    }
#endif
}
