/***************************************************************************
 *   Copyright (C) 2003 by Mattia Merzi                                    *
 *   ottobit@ferrara.linux.it                                              *
 *                                                                         *
 *   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 <sys/socket.h>
#include <qmessagebox.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <kdebug.h>

#include "KBlueLockScanner.h"

using namespace KBluetooth;

#define SCAN_RESULT_DEF

KBlueLockScanner* KBlueLockScanner::_instance = 0;

KBlueLockScanner* KBlueLockScanner::getDefaultScanner()
{
    kdDebug() << "init" << endl;
    if (_instance == 0)
    {
        _instance = new KBlueLockScanner();
    }
    return _instance;
}

KBlueLockScanner::KBlueLockScanner() {
  config = kbluelockrc::getDefaultRC();
  notFoundCounter = 0;
  trustedDeviceFound = false;
}

bool KBlueLockScanner::init() {
  inquiry = new Inquiry(NULL, this);
  if (inquiry) return true;
  else return false;
}

void KBlueLockScanner::run() {
  exit_condition = false;
  inquiry_finished = true;
  connect(inquiry,
    SIGNAL(neighbourFound(const KBluetooth::DeviceAddress&, int)),
    this, SLOT(slotInquiryDeviceFound(const KBluetooth::DeviceAddress&)));
  connect(inquiry, SIGNAL(finnished()),
    this, SLOT(slotInquiryFinnished()));
  kdDebug() << "scanner->run()" << endl;
  while(!exit_condition) {
    if (inquiry_finished) {
      inquiry_finished = false;
      inquiry->inquiry();
      kdDebug() << "Inquiry called ..." << endl;
    }
    ::sleep(1);
  }
  process->terminate();
  kdDebug() << "scanner->finished ! :)" << endl;
}

void KBlueLockScanner::slotInquiryDeviceFound(const KBluetooth::DeviceAddress& addr) {
  if (checkTrustedDevice(QString(addr))) {
    // Only set exit_condition to true if the device
    // wasn't found two times in a row before
    if (notFoundCounter >= 2) {
        exit_condition = true;
    }
    notFoundCounter = 0;
    trustedDeviceFound = true;
  }
}

void KBlueLockScanner::slotInquiryFinnished() {
  ::sleep(config->getScanInterval());
  if (!trustedDeviceFound) {
    ++notFoundCounter;
  }
  trustedDeviceFound = false;
  inquiry_finished = true;
}

bool KBlueLockScanner::checkTrustedDevice(QString _bdaddr) {
  kdDebug() << "checking trusted devices ..." << endl;
  return ((config->getValidateBDADDR()?validate_bdaddr(_bdaddr):true) &&
          (config->getValidateName()?validate_name(_bdaddr):true) &&
          (config->getValidateDeviceType()?validate_devtype(999):true));
}

bool KBlueLockScanner::validate_bdaddr(QString _bdaddr) {
  QStringList addr = *(config->getDeviceAddresses());
  QStringList::Iterator it = addr.begin();
  for (;it != addr.end();++it) {
    kdDebug() << "cycling trusted addresses: " << *it << endl;
    if (*it == _bdaddr) {
      kdDebug() << "trusted device found !" << endl;
      return true;
    }
  }
  return false;
}

bool KBlueLockScanner::validate_name(QString /*_bdaddr*/) {
  return true;
}

bool KBlueLockScanner::validate_devtype(int /*count*/) {
  return true;
}

KBlueLockScanner::~KBlueLockScanner()
{
}

#include "KBlueLockScanner.moc"
