/*
   
        (c) 2006 by Thomas Michel <tom.michel@arcor.de>

        Kwlan 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.

        Kwlan 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 Street, Fifth Floor,
        Boston, MA 02110-1301, USA.
*/

#ifndef KWLANINTERFACE_H
#define KWLANINTERFACE_H

//#include "kwlan.h"
#include "wpa_ctrl.h"
#include "wpamsg.h"
#include "kuserdatarequestdlg.h"
#include "configuration.h"
#include "kwlansuprocess.h"
#include "kwlanmainwin.h"
#include "kwlnetworklist.h"


#include <kapplication.h>
#include <QSocketNotifier>
#include <QTimer>
#include <wlanlib.h>
#include <arpa/inet.h>

#include <solid/device.h>

#undef __STRICT_ANSI__
#include <linux/netdevice.h>
#define __STRICT_ANSI__

class QString;
class QStringList;
class K3Process;
class KEventHistoryDlg;
class KScanDlg;
class KwlanTrayWin;
class QObject;
class KTemporaryFile;


class KwlanInterface  : public QObject
{
    Q_OBJECT
    public:
        KwlanInterface(KwlanMainWin *mainWin);
        ~KwlanInterface();
        enum InterfaceState
        {
            UNKNOWN_STATE = -1,
            NOT_EXISTING  = 0,
            NOT_AVAILABLE = 1,
            AVAILABLE     = 2,
            RX_TRAFFIC    = 4,
            TX_TRAFFIC    = 8
        };

        enum InterfaceType
        {
            UNKNOWN_TYPE = -1,
            ETHERNET = 0,
            PPP = 1
        };
        
        enum State
        {
            DISABLED     = 0,
            NOTCONNECTED = 1,
            CONNECTED    = 2,
            CONFIGURED   = 3
        };
        void setSolidDevice( Solid::Device *soldev )
        {
            m_solidDevice = soldev;
        }

        Solid::Device* getSoldDevice()
        {
            return m_solidDevice;
        }
        
        void setType( int type )
        {
            m_type = type;
        }

        int getType()
        {
            return m_type;
        }

        void setState( int state )
        {
            m_state = state;
        }

        int getState()
        {
            return m_state;
        }
        interfaceData getInterfaceData()
        {
            if ( m_interfaceData.wirelessDevice && m_wirelessData.radioOff )
            m_interfaceData.connected = FALSE;
            return m_interfaceData;
        }
        wirelessData getWirelessData()
        {
            return m_wirelessData;
        }
        QString getCurrentProfile()
        {
            return m_ssid;
        }
        QString getConfFile()
        {
            return m_confFile;
        }
        Configuration *getConfiguration()
        {
            return m_configuration;
        }
        void setConfiguration(Configuration *config)
        {
            m_configuration = config;
        }
        bool hasControlConnection()
        {
            if (m_controlConnection) return TRUE;
            return FALSE;
        }
        wpa_ctrl *getControlConnection()
        {
            return m_controlConnection;
        }
        bool getWpaStarted()
        {
            return m_wpaStarted;
        }
        bool getConfigureInterface()
        {
            return m_configureInterface;
        }
        KwlanMainWin* getMainWin()
        {
            return m_mainWin;
        }
        bool profileActivateNonWpa(QString ssid);
        bool profileActivateWpa(QString ssid);
        void startScriptAfterConnect();
        void setDnsSettings();
        void checkType();
        
    public slots:
        void init(QString interface,Solid::Device *dev=NULL);
        void slotWpaStatusChanged(bool status);
        int  openControlConnection();
        void checkWpaConnection();
        int  ctrlRequest(const char *command, char *bur, size_t *buflen);
        bool hasProfiles();
        QStringList listProfiles();
        QStringList listWpaProfiles();
        QStringList listNonWpaProfiles(QStringList wpaProfiles);
        int getWpaId(QString ssid);
        bool profileActivate(QString ssid);
        void releaseIpAddress();
        void getIpAddress();
        void processWpaMessage(char *message);
        void receiveMsgs();
        void processCtrlReq( const char * request );
        void startWpa(QString driver);
        void stopWpa();
        QString getInterfaceName();
        void profileAdded();
        //void iwconfigProcessExited( K3Process* process );
        //void iwconfigProcessStdout( K3Process*, char* buffer, int buflen );
        void dhcpProcessExited(KwlanSuProcess *);
        void releaseProcessExited(KwlanSuProcess *);
        //void iwconfigProcessExited( K3Process* process );
        //void iwconfigProcessStdout( K3Process* process, char* buffer, int buflen );
        void updateData();
        void logViewer();
        void enableInterface(bool enable);
        void slotNewProfile();
        void slotEditProfile(QString profile);
        void slotDeleteProfile(QString profile);
        void slotEnableConfigureInterface(QString, bool);
        kwlNetworkList getAvailableProfiles();
        void slotScan();
        void slotScanAvailableNetworks();

    signals:
        void wpaStatusChanged(bool started);
        void connectionStatusChanged (bool connected);
        void networksChanged();
        void ipChanged(QString ip);
        void wpaEvent( WpaMsg msg );
        void wpaEvents( WpaMsgList msgs );
        void interfaceUp(bool up);
        void interfaceGone(KwlanInterface *interface);
        void sigMessage(QString message);
        
    private:
        char *m_controlInterface,*m_controlInterfaceDir;
        wpa_ctrl *m_controlConnection, *m_monitorConnection;
        WpaMsgList m_messages;
        
        Solid::Device *m_solidDevice; 
        QSocketNotifier *m_messageNotifier;
        bool m_networkChange;
        bool m_startDhclient;
        bool m_associated;
        bool m_IpAddress;
        bool m_wpaStarted;
        bool m_useDhclient;
        bool m_useDhcpcd;
        bool m_dhcpEnabled;
        bool m_wpaWarned; // User has been warned in case of failure to connect to wpa_supplicant
        bool m_ipConfigured;
        bool m_configureInterface;
        bool m_isScanning;
        bool m_isConfiguring;
        QString m_ssid;
        QString m_staticIpAddress,  m_staticGateway, m_staticNetmask;
        QString m_staticDns1, m_staticDns2, m_domain;
        bool m_dontOverrideDns, m_dontOverrideGw;
        QStringList m_dnsSearchlist;
        QString m_dhclientPath, m_dhcpcdPath, m_wpaPath; //Path to external applications that are frequently used
        QString m_ifconfigPath, m_iwconfigPath;
        QString m_wpaConf; // path to wpa_supplicant config file for this interface;
        QTimer *m_timer, *m_scanTimer;
        KUserDataRequestDlg *m_userDataRequest;
        KTemporaryFile *resolvconf;
        interfaceData m_interfaceData;
        wirelessData m_wirelessData;
        QString m_ifconfigStdout, m_iwconfigStdout;
        K3Process *m_ifconfigProcess, *m_iwconfigProcess;
        int m_type;
        int m_state;
        QString m_confFile;
        Configuration *m_configuration;
        KEventHistoryDlg *m_eventHistory;
        KScanDlg *m_scanDlg;
        KwlanTrayWin *m_trayWin;
        QString m_sysClassPath;
        int m_fdSock;
        struct ifreq m_devInfo;
        //KwlanSuProcess *m_dhcpProcess;
        KwlanSuProcess *m_dhcpProcess;
        KwlanSuProcess *m_releaseProcess;
        KwlanMainWin *m_mainWin;
        bool m_available;
        kwlNetworkList m_availableNetworks;
        
        void parseIwconfigOutput();
        //void updateInterfaceData( QString& config,  int type );
        void updateWirelessData( QString& config );
        void getIpData();
        unsigned long readInterfaceNumValue(const char *name);
        bool openFdSocket();
        void say(QString message);
        void newInterfaceWizard(QString interface);

};

#endif
