/*
 * 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., 51 Franklin Steet, Fifth Floor,
 * Boston, MA 02110-1301, 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_KDETV
    _config = 0;
    if ((_lircfd = lirc_init((char*)_appname.latin1(), 1)) < 0) {
        kdWarning() << "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) {
        kdWarning() << "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
    kdWarning() << "lirc: No lirc support available" << endl;
#endif
}

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

void Lirc::dataReceived()
{
#ifdef HAVE_LIRC_KDETV
    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)) {
            kdWarning() << "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>::const_iterator val = _keymap.find(event);
                    if ( val != _keymap.constEnd())
                        emit command(*val, repeat);
                    else
                        emit Lirc::event(event, repeat);
                } else {
                    emit command(cmd, repeat);
                }
            }
        } else {
            /* standalone mode */
            QMap<QString, QString>::const_iterator val = _keymap.find(event);
            if ( val != _keymap.constEnd())
                emit command(*val, repeat);
            else
                emit Lirc::event(event, repeat);
        }
        free(code);
    }
#endif
}
