/*
  Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
            (C) 2001-2004 by Stefan Winter <mail@stefan-winter.de>

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this library; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
*/

#include <qlayout.h>
#include <qtabwidget.h>

#include <kaboutdata.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kgenericfactory.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kprocio.h>

#include "kcmwifi.h"
#include "ifconfigpage.h"
#include "mainconfig.h"
#include "configcrypto.h"
#include "wificonfig.h"

typedef KGenericFactory < KCMWifi, QWidget > KWiFiFactory;
K_EXPORT_COMPONENT_FACTORY (kcm_wifi, KWiFiFactory("kcmwifi") )

KCMWifi::KCMWifi(QWidget * parent, const char *name, const QStringList &)
    : KCModule (parent, name)
{
  QTabWidget *tabs = new QTabWidget (this, "tabs");

  for ( int i=0; i<4; ++i )
  {
    IfConfigPage *ifConfigPage = new IfConfigPage( i, tabs, "m_configPage" );
    tabs->addTab(ifConfigPage, i18n ("Config &%1").arg( i+1 ));
    connect(ifConfigPage, SIGNAL(changed()), SLOT( slotChanged() ) );

    m_ifConfigPage[ i ] = ifConfigPage;
  }

  m_mainConfig = new MainConfig(this, "m_mainConfig");

  QVBoxLayout *top = new QVBoxLayout (this, 0, KDialog::spacingHint());
  top->addWidget( tabs );
  top->addWidget( m_mainConfig );
  top->addStretch();

  connect(m_mainConfig, SIGNAL(changed()), SLOT( slotChanged() ) );
  connect(m_mainConfig, SIGNAL(activateClicked()), SLOT(slotActivate()));

  if ( geteuid() != 0 )
  {
    tabs->setEnabled( false );
    m_mainConfig->setEnabled( false );
  }
  else
  {
    KProcess iwconfigtest;
    iwconfigtest << "iwconfig";
    if (!iwconfigtest.start(KProcess::DontCare))
    {
      KMessageBox::sorry(0, i18n("Error executing iwconfig. WLAN "
          "configurations can only be altered if the wireless tools are "
          "properly installed."), i18n ("No Wireless Tools"));

      tabs->setEnabled( false );
      m_mainConfig->setEnabled( false );
    }
  }

  load();
}


KCMWifi::~KCMWifi()
{
}

void KCMWifi::load()
{
  for ( int i=0; i<4; ++i )
    m_ifConfigPage[ i ]->load();

  m_mainConfig->load();
}

void KCMWifi::save()
{
  for ( int i=0; i<4; ++i )
    m_ifConfigPage[ i ]->save();

  m_mainConfig->save();

  WifiConfig *config = WifiConfig::instance();
  config->save();
}

void KCMWifi::slotActivate()
{
  save();
  activate();
}

void KCMWifi::defaults()
{
}

void KCMWifi::slotChanged()
{
  emit changed( true );
}

void KCMWifi::activate()
{
  KProcess proc;

  WifiConfig *config = WifiConfig::instance();
  IfConfig ifconfig = config->m_ifConfig[ config->m_presetConfig ];

  proc << "ifconfig"
       << config->m_interface
       << "down";
  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);

  proc.clearArguments();

  proc << "iwconfig"
       << config->m_interface;
  proc << "essid"
       << ifconfig.m_networkName;

  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);
  proc.clearArguments();

  proc << "iwconfig"
       << config->m_interface;
  proc << "mode"
       << ifconfig.wifimodeAsString();

  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);
  proc.clearArguments();

  proc << "iwconfig"
       << config->m_interface;
  proc << "rate"
       << ifconfig.speedAsString();

  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);
  proc.clearArguments();

  proc << "iwconfig"
       << config->m_interface;

  if (!ifconfig.m_useCrypto )
  {
    proc << "key"
         << "off";
  }
  else
  {
    for ( int i=0; i<4; ++i )
    {
      if ( ifconfig.m_keys[ i ].isValid() )
      {
        proc << "key"
             << QString( "[%1]").arg( i+1 )
	     << QString( "%1").arg( ifconfig.m_keys[ i ].rawKey() );
      }
    }

    if ( ifconfig.activeKey().isValid() )
    {
      proc << "key"
           << ifconfig.cryptomodeAsString();
      proc << "key"
           << QString( "[%1]" ).arg( ifconfig.activeKeyId() );
      proc << "key"
           << "on";
    }
  }
  
  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);
  proc.clearArguments();

  proc << "iwconfig"
       << config->m_interface;

  if ( !ifconfig.m_pmEnabled )
  {
    proc << "power"
         << "off";
  }
  else
  {
    proc << "power"
	 << "period"
         << QString( "%1" ).arg( ifconfig.m_wakeupPeriod );
    proc << "power"
	 << "timeout"
         << QString( "%1" ).arg( ifconfig.m_sleepTimeout );
    proc << ifconfig.powermodeAsString();
  }

  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);

  proc.clearArguments();
  proc << "ifconfig"
       << config->m_interface
       << "up";
  
  kdDebug() << "Command: " << proc.args() << endl;
  proc.start (KProcess::Block);

  if ( ifconfig.m_runScript )
  {
    proc.clearArguments();
    proc << QStringList::split( " ", ifconfig.m_connectScript );

    proc.start(KProcess::DontCare);
  }
}

extern "C"
{
  void init_wifi()
  {
    KCMWifi::activate();
  }
}


#include "kcmwifi.moc"
