/***************************************************************************
 *   Copyright (C) 2004-2010 by Giovanni Venturi                           *
 *   giovanni@ksniffer.org                                                 *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 ***************************************************************************/

#include <QtGui/QComboBox>
#include <QtGui/QGroupBox>
#include <QtGui/QCheckBox>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
#include <QtGui/QToolTip>
#include <QtGui/QWhatsThis>

#include <KIcon>
#include <KLocale>
#include <KPushButton>
#include <KMessageBox>
#include <KSystemTrayIcon>

#include "CaptureDialog.h"
#include "options/OptionDialog.h"

CaptureDialog::CaptureDialog(KSystemTrayIcon *tray, QWidget *parent)
 : KDialog( parent ), m_tray(tray)
{
  setCaption( i18n("New Capture") );
  setButtons( Default | Ok | Cancel );
  setModal( true );
  showButtonSeparator( false );
  setButtonGuiItem( Ok, KGuiItem( i18n("&Start") ) );

  QWidget *page = new QWidget( this );
  setMainWidget( page );

  QVBoxLayout* mainLay = new QVBoxLayout( page );
  mainLay->activate();

  // the groupbox to select the interface to sniff
  QGroupBox* groupBox = new QGroupBox( i18n("Select Interface"), page );
  mainLay->addWidget( groupBox );
  mainLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );

  // redefine the "Default" button
  KGuiItem defaultButton( i18n("&Advanced..."), KIcon("configure"), i18n("Show advanced options"),
    i18n( "<qt><p>Opens the Configure Dialog where you can "
          "choose the settings about the capture.</p>"
          "<p>In case you don't request all the options, the "
          "capture will start using the default "
          "settings.</p></qt>" ) );
  setButtonGuiItem( Default, defaultButton );

  QVBoxLayout* groupLay = new QVBoxLayout( groupBox );
  groupLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );

  QHBoxLayout* ifaceSelectLay = new QHBoxLayout;
  groupLay->addLayout( ifaceSelectLay );

  QLabel* textLabel = new QLabel( i18n("I&nterface:"), groupBox );

  m_interface = new QComboBox( groupBox );
  textLabel->setBuddy( m_interface );
  m_interface->setWhatsThis( i18n( "<p>Contains the list of network interfaces "
    "detected on your system.<br><br>"
    "The special interface <b>any</b> captures network "
    "packets from all network interfaces of your "
    "system.</p>" ) );

  KPushButton* m_redetect = new KPushButton( 
    KGuiItem( i18n( "Re&detect Interfaces" ), KIcon( "view-refresh" ), i18n( "Re&detect Interfaces" ),
    i18n( "Updates the Interface combobox scanning your system again about its network interfaces." ) ),
    groupBox );

  ifaceSelectLay->addWidget( textLabel );
  ifaceSelectLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
  ifaceSelectLay->addWidget( m_interface );
  ifaceSelectLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
  ifaceSelectLay->addWidget( m_redetect );

  QVBoxLayout* vertSpace = new QVBoxLayout();
  groupLay->addLayout( vertSpace );
  vertSpace->addItem( new QSpacerItem( 10, 10, QSizePolicy::Fixed, QSizePolicy::Fixed ) );

  QGridLayout* detailLay = new QGridLayout;
  groupLay->addLayout( detailLay );

//   QLabel* label = new QLabel( groupBox );
//   QPixmap icon( DesktopIcon( "hwinfo" ) );
//   label->setPixmap( icon );
//   detailLay->addWidget( label, 1, 0, Qt::AlignHCenter );

  QLabel* label = new QLabel( i18n("IP address:"), groupBox );
  detailLay->addWidget( label, 0, 0 );

  m_ipaddress = new QLabel( groupBox );
  m_ipaddress->setToolTip( i18n("Shows the IP address of the selected interface, if it's available.") );
  detailLay->addWidget( m_ipaddress, 0, 1 );

  label = new QLabel( i18n("Netmask:"), groupBox );
  detailLay->addWidget( label, 1, 0 );

  m_netmask = new QLabel( groupBox );
  m_netmask->setToolTip( i18n("Shows the netmask of the selected interface, if it's available.") );
  detailLay->addWidget( m_netmask, 1, 1 );

  label = new QLabel( i18n("MAC address:"), groupBox );
  detailLay->addWidget( label, 2, 0 );

  m_macAddress = new QLabel( groupBox );
  m_macAddress->setToolTip( i18n( "Shows the MAC address of the selected interface, if it's available." ) );
  detailLay->addWidget( m_macAddress, 2, 1 );

  groupLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding ) );

  setButtonWhatsThis( Ok, i18n( "Start a new network packet-capture session." ) );

  // fill the Interface ComboBox
  m_interface->addItems( m_netDevices.interfaceList() );

  // read the previous selected network interface from the configuration file
  KConfigGroup config = KGlobal::config()->group("Sniffer");
  QString strUsedInterface = config.readEntry( "Selected interface", "" ); // no selection at startup

  // set the related data for the selected network interface
  if (strUsedInterface != "")
  {
    int index = m_netDevices.interfaceList().indexOf(strUsedInterface);
    if ( index != -1)
    {
      // if the network interface exists select it
      m_interface->setCurrentIndex( index );
      setCurrentInterface( strUsedInterface );
    }
    else
      // ... else take the first available
      setCurrentInterface( m_interface->currentText() );
  }
  else
    setCurrentInterface( m_interface->currentText() );

  resize( QSize( 350, 160 ) );

  connect( m_redetect, SIGNAL( clicked() ), this, SLOT( slotRedetect() ) );
  connect( m_interface, SIGNAL( activated(const QString&) ), this, SLOT( setCurrentInterface(const QString&) ) );
  connect( this, SIGNAL( defaultClicked()), this, SLOT(slotDefault()) );
  connect( this, SIGNAL( okClicked()), this, SLOT(slotOk()) );
}


CaptureDialog::~CaptureDialog()
{
  m_interface->clear();
}


void CaptureDialog::slotOk()
{
  QString strUsedInterface = m_interface->currentText();  // set the selected interface just when click Start button

  // write the selected network interface to the configuration file
  KConfigGroup config = KGlobal::config()->group("Sniffer");
  config.writeEntry( "Selected interface", strUsedInterface );

  // accept the dialog
  accept();
}


void CaptureDialog::slotDefault()
{
  OptionDialog dialogSetting(m_tray, this);

  // get the user option to start capture
  dialogSetting.exec();
}


void CaptureDialog::slotRedetect()
{
  m_netDevices.detect();
  m_interface->clear();
  m_interface->addItems(m_netDevices.interfaceList());
  setCurrentInterface( m_interface->currentText() );
}


void CaptureDialog::setCurrentInterface( const QString & strInterface )
{
  NetworkDevice data = m_netDevices.device(strInterface);

  // updating IP address
  QString str = data.ipAddress();
  if ( str.isEmpty() )
    str = i18n("not available");
  m_ipaddress->setText( str );

  // updating netmask
  str = data.netmask();
  if ( str.isEmpty() )
    str = i18n("not available");
  m_netmask->setText( str );

  // updating MAC address
  str = data.hwAddress();
  if ( str.isEmpty() || (strInterface == "lo"))
    str = i18n("not available");
  m_macAddress->setText( str );
}

#include "CaptureDialog.moc"
