#include <QtGui>

#include "ipQalc.h"
#include <QMessageBox>



ipQalc::ipQalc(QWidget *parent) : QWidget(parent){
    ui.setupUi(this);


    this->setFixedHeight(350);
    this->setWindowTitle("IP Qalc, v"+QString(VERSION));

    connect(ui.cmdClose, SIGNAL(clicked()), qApp, SLOT(quit()));
    connect(ui.Command1, SIGNAL(clicked()), this, SLOT(calc()));
    



    // Заполнение таблицы масок
    ui.comboBox->addItem("0 - 0.0.0.0","0.0.0.0");
    ui.comboBox->addItem("1 - 128.0.0.0","128.0.0.0");
    ui.comboBox->addItem("2 - 192.0.0.0","192.0.0.0");
    ui.comboBox->addItem("3 - 224.0.0.0","224.0.0.0");
    ui.comboBox->addItem("4 - 240.0.0.0","240.0.0.0");
    ui.comboBox->addItem("5 - 248.0.0.0","248.0.0.0");
    ui.comboBox->addItem("6 - 252.0.0.0","252.0.0.0");
    ui.comboBox->addItem("7 - 254.0.0.0","254.0.0.0");
    ui.comboBox->addItem("8 - 255.0.0.0","255.0.0.0");
    ui.comboBox->addItem("9 - 255.128.0.0","255.128.0.0");
    ui.comboBox->addItem("10 - 255.192.0.0","255.192.0.0");
    ui.comboBox->addItem("11 - 255.224.0.0","255.224.0.0");
    ui.comboBox->addItem("12 - 255.240.0.0","255.240.0.0");
    ui.comboBox->addItem("13 - 255.248.0.0","255.248.0.0");
    ui.comboBox->addItem("14 - 255.252.0.0","255.252.0.0");
    ui.comboBox->addItem("15 - 255.254.0.0","255.254.0.0");
    ui.comboBox->addItem("16 - 255.255.0.0","255.255.0.0");
    ui.comboBox->addItem("17 - 255.255.128.0","255.255.128.0");
    ui.comboBox->addItem("18 - 255.255.192.0","255.255.192.0");
    ui.comboBox->addItem("19 - 255.255.224.0","255.255.224.0");
    ui.comboBox->addItem("20 - 255.255.240.0","255.255.240.0");
    ui.comboBox->addItem("21 - 255.255.248.0","255.255.248.0");
    ui.comboBox->addItem("22 - 255.255.252.0","255.255.252.0");
    ui.comboBox->addItem("23 - 255.255.254.0","255.255.254.0");
    ui.comboBox->addItem("24 - 255.255.255.0","255.255.255.0");
    ui.comboBox->addItem("25 - 255.255.255.128","255.255.255.128");
    ui.comboBox->addItem("26 - 255.255.255.192","255.255.255.192");
    ui.comboBox->addItem("27 - 255.255.255.224","255.255.255.224");
    ui.comboBox->addItem("28 - 255.255.255.240","255.255.255.240");
    ui.comboBox->addItem("29 - 255.255.255.248","255.255.255.248");
    ui.comboBox->addItem("30 - 255.255.255.252","255.255.255.252");
    ui.comboBox->addItem("31 - 255.255.255.254","255.255.255.254");
    ui.comboBox->addItem("32 - 255.255.255.255","255.255.255.255");


    ui.comboBox->setCurrentIndex(24);


    ui.Ip->setText("192.168.0.1");
    //ui.NetMask->setText("255.255.255.0");
    
    ui.Ip->installEventFilter(this);
    ui.comboBox->installEventFilter(this);

    calc();

}



bool ipQalc::eventFilter(QObject *o, QEvent *e){

    if (e->type() == QEvent::KeyPress){
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
        if (o==ui.Ip or o==ui.comboBox){
            if(keyEvent->key() ==  Qt::Key_Escape){
                QApplication::quit();
            }
            if(keyEvent->key() ==  Qt::Key_Enter or keyEvent->key() ==  Qt::Key_Return){
                calc();
                return 1;
            }
        }
    }

    return QWidget::eventFilter(o, e);
}



void ipQalc::calc() {


    if (isValidIP(ui.Ip->text())==false ){        
        //"Неправильно набран IP адрес"
        QMessageBox::warning(this,"Error",tr("Invalid Input IP address"));
        return;
    }

//    if (isValidMask(ui.NetMask->text())==false ){
//        // "Неправильно набрана маска сети"
//        QMessageBox::warning(this,"Error",tr("Invalid Input Netmask."));
//        return;
//    }


    SubNet = new IpAdress(ui.Ip->text(),ui.comboBox->itemData(ui.comboBox->currentIndex()).toString());


    ui.label_4->setText(SubNet->GetIpAdress(10));
    ui.label_5->setText(SubNet->GetIpAdress(2));
    ui.label_6->setText(SubNet->GetIpAdress(16));

    ui.label_8->setText(SubNet->GetNetMask(10));
    ui.label_9->setText(SubNet->GetNetMask(2));
    ui.label_10->setText(SubNet->GetNetMask(16));
    
    ui.label_12->setText(SubNet->GetInversMask(10));
    ui.label_13->setText(SubNet->GetInversMask(2));
    ui.label_14->setText(SubNet->GetInversMask(16));

    ui.label_16->setText(SubNet->GetMaskPrefix());

    ui.label_18->setText(SubNet->GetNetAdress(10));
    ui.label_19->setText(SubNet->GetNetAdress(2));
    ui.label_20->setText(SubNet->GetNetAdress(16));

    ui.label_22->setText(SubNet->GetBroadCast(10));
    ui.label_23->setText(SubNet->GetBroadCast(2));
    ui.label_24->setText(SubNet->GetBroadCast(16));

    ui.label_26->setText(SubNet->GetMinIP(10));
    ui.label_27->setText(SubNet->GetMinIP(2));
    ui.label_28->setText(SubNet->GetMinIP(16));

    ui.label_30->setText(SubNet->GetMaxIP(10));
    ui.label_31->setText(SubNet->GetMaxIP(2));
    ui.label_32->setText(SubNet->GetMaxIP(16));
    
    ui.label_34->setText(SubNet->GetHosts());
    
    
}


bool ipQalc::isValidIP(QString ipAdress){
    QRegExp rx( "\\b(([01]?\\d?\\d|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d?\\d|2[0-4]\\d|25[0-5])\\b" );
    if (!rx.exactMatch(ipAdress)){
	return false;
    }

    return true;
}

bool ipQalc::isValidMask(QString ipAdress){

    if (ipAdress.mid(0,1) == "/" or ipAdress.size()<=2){
        QString newmask;
        QString tempIP;
        bool ok;

        ipAdress.replace("/","");
        int prefix = ipAdress.toInt(&ok,10);

        if (prefix<=0 or prefix>32) return false;

        for (int i=0;i<prefix;i++) tempIP.append("1");
        for (int i=0;i<(32-prefix);i++) tempIP.append("0");

        for (int x=0;x<4;x++){
            for (int i=(x*8);i<(x*8)+8;i++) newmask.append(tempIP[i]);
            newmask.append(".");
        }
        ipAdress = IpAdress::Conv(newmask,2,10);
    }



    if (isValidIP(ipAdress)==false) return false;

    QString str = "";
    QStringList strList;
    QByteArray text;
    bool ok;

    QStringList adr = ipAdress.split(".");
    for (int i=0;i<4;i++){
        text.setNum(adr[i].toInt(&ok,10),2);
        strList.append(text);

	int len=strList[i].length();
        for (int x=0;x<(8-len);x++){
            strList[i].insert(0,"0");
        }

    }

    str = strList.join("");

    for (int i=0;i<32;i++){
	if (str.mid(i,1) == "0" and str.mid(i+1,1) == "1"){
	    return false;
	}
    }

    return true;
}
