/***************************************************************************
                          networkscanning.cpp  -  description
                             -------------------
    begin                : Sam Apr 24 11:44:20 CEST 2005
    copyright            : (C) 2005 by Stefan Winter
    email                : swinter@kde.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>

#include <tqstring.h>
#include <tqwidget.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqtable.h>

#include <kdebug.h>
#include <tdelocale.h>
#include <tdeprocess.h>
#include <tdemessagebox.h>
#include <tdetempfile.h>

#include "networkscanning.h"
#include "interface_wireless.h"

NetworkScanning::NetworkScanning (Interface_wireless * dev, TQWidget * parent, const char * name ) : TQWidget ( parent, name ) {
  device = dev;
  networkScan();
}

void
NetworkScanning::networkScan ()
{
  networks = device->get_available_networks ();

  if ( networks->numRows() > 0 ) {

      networks->setColumnReadOnly( 0, true);
      networks->setColumnReadOnly( 1, true);
      networks->setColumnReadOnly( 2, true);
      networks->setColumnReadOnly( 3, false);
      for ( int i = 0; i < networks->numRows(); i++) {
	if ( networks->text( i, 3 ) == i18n( "off" )) networks->setRowReadOnly( i, true );
      }

      networks->setSelectionMode(TQTable::SingleRow);
      connect(networks,TQ_SIGNAL(selectionChanged()),this,TQ_SLOT(checkWEP()));

      this->setCaption( i18n( "Scan Results" ) );

      TQGridLayout* networkSelectionLayout = new TQGridLayout ( this, 2, 3, 0, 5);
      switchNet = new TQPushButton( i18n( "Switch to Network..." ), this );
      switchNet->setEnabled(false);
      TQPushButton* close = new TQPushButton( i18n( "Close" ), this );

      networks->reparent( this, TQPoint( 0, 0 ) );
      networks->setLeftMargin( 0 );
      networks->verticalHeader()->hide();

      connect ( close, TQ_SIGNAL( clicked() ), this, TQ_SLOT( hide() ) );
      connect ( switchNet, TQ_SIGNAL( clicked() ), this, TQ_SLOT( switchToNetwork() ) );
      connect ( networks, TQ_SIGNAL( currentChanged(int,int)), this, TQ_SLOT( checkSettings(int,int)));
      connect ( networks, TQ_SIGNAL( valueChanged(int,int)), this, TQ_SLOT( checkSettings(int,int)));

      networkSelectionLayout->addMultiCellWidget( networks, 0, 0, 0, 2 );
      networkSelectionLayout->addWidget( switchNet, 1, 0 );
      networkSelectionLayout->addWidget( close, 1, 2 );

      this->show();

    } else
    {
      KMessageBox::sorry(0,i18n("The scan is complete, but no networks have been found."),i18n("No Network Available"));
    }
}

void NetworkScanning::checkSettings(int row, int)
{
	if ((networks->text(row,0)!=i18n("(hidden cell)")) && (checkWEP()!=INVALID)) switchNet->setEnabled(true);
	else switchNet->setEnabled(false);
}

WEP_KEY
NetworkScanning::checkWEP()
{
  kdDebug() << "In checkWEP()\n";
  if (  (networks->text( networks->currentRow() , 3 ) == i18n( "off" )) ||
	(networks->text( networks->currentRow() , 3 ) == "" ) ) return NONE;
  if (  (networks->text( networks->currentRow() , 3 ).length()== 5 ) || 
	(networks->text( networks->currentRow() , 3 ).length()== 13 ) ) return VALID_STRING;
  if (  (networks->text( networks->currentRow() , 3 ).length()== 10 ) ||
        (networks->text( networks->currentRow() , 3 ).length()== 26 ) ) return VALID_HEX;
  return INVALID;
}

void
NetworkScanning::switchToNetwork()
{

  WEP_KEY encryption = checkWEP();

  if (encryption == INVALID) {
    KMessageBox::sorry(0,i18n( "Aborting network switching due to invalid WEP key specification." ), i18n( "Invalid WEP Key" ));
    return;
  }

  TQString cmdline;

  KTempFile* tempfile = new KTempFile( TQString(), TQString(), 0700 );
  TQString tempfilename = tempfile->name();

  cmdline = (TQString)"ifconfig %1 down\n";
  cmdline = cmdline.arg( device->get_interface_name() );
  write( tempfile->handle(), cmdline.ascii(), strlen( cmdline.ascii() ) );

  cmdline = (TQString)"iwconfig %1 essid %2 mode %3 enc %4\n";
  cmdline = cmdline.arg( device->get_interface_name() );
  cmdline = cmdline.arg( TDEProcess::quote( networks->text( networks->currentRow(), 0 ) ) );

  TQString modetemp;
  if (networks->text( networks->currentRow(), 1 ) == i18n("Managed") ) modetemp = "Managed"; else modetemp = "Ad-Hoc"; 
  cmdline = cmdline.arg( modetemp );

  if ( encryption != NONE ) {
    cmdline = cmdline.arg( (encryption == VALID_STRING ? "s:" : "" ) + TDEProcess::quote( networks->text( networks->currentRow(), 3 ) ) );
  } else {
    cmdline = cmdline.arg("off");
  }
  write( tempfile->handle(), cmdline.ascii(), strlen( cmdline.ascii() ) );

  cmdline = (TQString)"ifconfig %1 up\n";
  cmdline = cmdline.arg( device->get_interface_name() );
  write( tempfile->handle(), cmdline.ascii(), strlen( cmdline.ascii() ) );

  delete tempfile; // autoDeletion off, so the file remains on disk

  TDEProcess switchProc;
  switchProc << "tdesu" << tempfilename;
  switchProc.start( TDEProcess::Block );

  remove(tempfilename.ascii());

}


#include "networkscanning.moc"
