#include <qapplication.h>

#include <qmessagebox.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/wireless.h>
#include <asm/errno.h>
#include <fcntl.h>
#include <sys/stat.h>  /* for mode definitions */
#include <signal.h>   /* for  disable CTRL-C */
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include "raconfigui.h"
#include "countryform.h"
#include "cardselect.h"
#include "configapi.h"
#include "rt_tool.h"

#define LOCK_FILE  "/tmp/.RaConfig25STA.lck"

PRT_PROFILE_SETTING     RTMPProfile=NULL;
PRT_DEVICE_ADAPTER      pDevice_Adpater=NULL;
bool                    G_bUserAdmin = FALSE;
bool                    G_bSupportAMode = FALSE;
extern int              errno;
char                    Configfile_name[255];
UINT                    G_nCountryRegion = REGSTR_COUNTRYREGION_FCC;


int m_open_cards(int socket_id)
{
    int i;
    char name[25];
    char Device_Name[255];
    int  count=0;
    PRT_DEVICE_ADAPTER prtAdapter=NULL;

    for (i=0; i<8; i++)
    {
        sprintf(name, "ra%d", i);
        memset(Device_Name, 0x00, 255);
        if( OidQueryInformation(RT_OID_DEVICE_NAME, socket_id, name, Device_Name, 255) != 0)
            continue;

        if(memcmp(Device_Name, NIC_DEVICE_NAME, sizeof(NIC_DEVICE_NAME)) == 0)
        {
            count++;
            if(!pDevice_Adpater)
            {
                pDevice_Adpater = (PRT_DEVICE_ADAPTER) malloc(sizeof(RT_DEVICE_ADAPTER));
                if(pDevice_Adpater)
                {
                    pDevice_Adpater->Device_Name = (char *)malloc(strlen(name)+1);
                    if(!pDevice_Adpater->Device_Name)
                        return (-1);  // Not enough memory
                    strcpy(pDevice_Adpater->Device_Name, name);
                    pDevice_Adpater->Next = NULL;
                    prtAdapter = pDevice_Adpater;
                }
                else
                    return (-1); // Not enough memory
            }
            else
            {
                prtAdapter->Next = (PRT_DEVICE_ADAPTER) malloc(sizeof(RT_DEVICE_ADAPTER));
                if(prtAdapter->Next)
                {
                    prtAdapter = prtAdapter->Next;
                    prtAdapter->Device_Name = (char *)malloc(strlen(name)+1);
                    if(!prtAdapter->Device_Name)
                        return (-1); // Not enough memory
                    strcpy(prtAdapter->Device_Name, name);
                    prtAdapter->Next = NULL;
                }
                else
                    return (-1); // Not enough memory
            }
        }
    }

    return count;
}

UCHAR Get_CountryRegion()
{
    char tmpCountryRegion[10];
    int  getCountryFlag=FALSE;
    int  country=0;

    if(getkeystring("Default", "CountryRegion",  tmpCountryRegion, 10, RT2500_SYSTEM_PATH, RT2500_SYSTEM_DATA) == TRUE)
    {
        country = atoi(tmpCountryRegion);
        if ((country >= REGSTR_COUNTRYREGION_MINIMUM) && (country <= REGSTR_COUNTRYREGION_MAXIMUM))
            getCountryFlag = TRUE;
    }

    if( !getCountryFlag )
    {
        CountryForm *ctyForm = new CountryForm;
        ctyForm->show();
        if(ctyForm->exec() == QDialog::Accepted)
        {
            country = ctyForm->GetRegionID();
            sprintf(tmpCountryRegion, "%d", country);
            if (G_bUserAdmin)
                writekeystring("Default", "CountryRegion", tmpCountryRegion, RT2500_SYSTEM_PATH, RT2500_SYSTEM_DATA);
        }
        else
        {
            QMessageBox *mb = new QMessageBox();
            mb->setCaption("Information");
            mb->setText("This message dialog will pop up again next time, if no country region is selected.");
            mb->setIcon(QMessageBox::Information);
            mb->setButtonText(0, "&Ok");
            mb->exec();
            delete mb;
        }
    }
    
    return ((UCHAR)country);
}

int main( int argc, char ** argv )
{
    int             fd;
    char            buffer[255];
    int             pid;
    FILE            *fileLCK;
    int             socket_id;
    int             adapter_num;
    int             isRuning=FALSE;
    DIR             *dirptr;
    RaConfigForm    *w;

    signal( SIGINT, SIG_IGN ); /* disable CTRL-C */
    QApplication App( argc, argv );

    if(getuid() != 0)
    { 
        G_bUserAdmin = FALSE;
        QMessageBox *mb = new QMessageBox();
        mb->setCaption("Information");
        mb->setText("You do not have root privilege!");
        mb->setIcon(QMessageBox::Information);
        mb->setButtonText(0, "&Ok");
        mb->exec();
        delete mb;
    }
    else
        G_bUserAdmin = TRUE;

    fd=open(LOCK_FILE, O_RDWR | O_CREAT | O_EXCL);
    if (fd<0 && errno==EEXIST)
    {
        if((fileLCK=fopen(LOCK_FILE, "rb")) != NULL)
        {
            fgets(buffer, 255, fileLCK);
            sscanf(buffer, "%d", &pid);
            fclose(fileLCK);
            sprintf(buffer, "/proc/%d", pid);
            dirptr = opendir(buffer);
            if(!dirptr)
            {
                isRuning = FALSE;
                if((fileLCK=fopen(LOCK_FILE, "wb")) != NULL)
                {
                    fprintf(fileLCK, "%d", getpid());
                    fclose(fileLCK);
                }
            }
            else
            {
                isRuning = TRUE;
            }
        }
    }
    else if(fd > 0)
    {
        isRuning = FALSE;
        system("chmod a+rw " LOCK_FILE);
        system("chmod u-s " LOCK_FILE);  //remove -rwsrw-rw-  *s*
        sprintf(buffer, "%d", getpid());
        write(fd, buffer, strlen(buffer));
    }
    close(fd);

    if(isRuning)
    {
        QMessageBox *mb = new QMessageBox();
        mb->setCaption("Warning");
        sprintf(buffer, "There is an other program running, please close it and try again!\nPID=%d", pid);
        mb->setText(buffer);
        mb->setIcon(QMessageBox::Critical);
        mb->setButtonText(0, "&Ok");
        mb->exec();
        delete mb;
        return -1;
    }

    if((socket_id = Open_Socket()) < 0)
    {
        QMessageBox *mb = new QMessageBox();
        mb->setCaption("Warning");
        mb->setText("Open socket error!");
        mb->setIcon(QMessageBox::Critical);
        mb->setButtonText(0, "&Exit");
        mb->exec();
        delete mb;
        return -1;
    }

    adapter_num = m_open_cards(socket_id);
    if( adapter_num < 0)
    { //Not enough memory
        QMessageBox *mb = new QMessageBox();
        mb->setCaption("Error");
        mb->setText("Memory allocation error");
        mb->setIcon(QMessageBox::Critical);
        mb->setButtonText(0, "&Ok");
        mb->exec();
        delete mb;
        unlink(LOCK_FILE); 
        return -1;
    }
    else if( adapter_num ==0)
    {//not found.
        QMessageBox *mb = new QMessageBox();
        mb->setCaption("Error");
        mb->setText("Device driver not found!");
        mb->setIcon(QMessageBox::Critical);
        mb->setButtonText(0, "&Ok");
        mb->exec();
        delete mb;
        unlink(LOCK_FILE); 
        return -1;
    }
    else if (adapter_num == 1)
    {
        if (G_bUserAdmin)
        {
            G_nCountryRegion = Get_CountryRegion();
            OidSetInformation(RT_OID_802_11_COUNTRY_REGION, socket_id, (char *)pDevice_Adpater->Device_Name, &G_nCountryRegion, sizeof(G_nCountryRegion));
        }

        w = new RaConfigForm(socket_id, pDevice_Adpater->Device_Name);
        w->resize( 600, 480 ); 
        App.setMainWidget(w);
    }
    else
    {
        CardSelect *cardSel = new CardSelect(socket_id, pDevice_Adpater);
        cardSel->show();
        cardSel->exec();

        if (!cardSel->isClickOk())
        {
            unlink(LOCK_FILE); 
            return 0;
        }

        if (G_bUserAdmin)
        {
            G_nCountryRegion = Get_CountryRegion();
            OidSetInformation(RT_OID_802_11_COUNTRY_REGION, socket_id, (char *)cardSel->Get_Device_Name(), &G_nCountryRegion, sizeof(G_nCountryRegion));
        }

        w = new RaConfigForm(socket_id, cardSel->Get_Device_Name());
        w->resize( 600, 480 ); 
        App.setMainWidget(w);
    }

    w->show();
    App.connect( &App, SIGNAL( lastWindowClosed() ), &App, SLOT( quit() ) );
    App.exec();
    unlink(LOCK_FILE);
    return 0;
}

