/****************************************************************************
**
** Copyright (C) 2019 Minnesota Department of Transportation
** Office of Materials & Road Research
** 1400 Gervais Avenue
** Saint Paul, Minnesota 55109-2044
** USA
** http://www.dot.state.mn.us/materials/pvmtdesign/software.html
**
**
** $QT_BEGIN_LICENSE:GPL$
**
** 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 3 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 General Public License for more details.
**
** If you did not receive a copy of the GNU General Public License
** see http://www.gnu.org/licenses
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "trafficdlg.h"
#include "ui_trafficdlg.h"
#include "calc.h"
#include "globals.h"
#include "mnpave.h"

TrafficDlg::TrafficDlg(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TrafficDlg)
{
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    ui->setupUi(this);

    loadW(); // load widget pointers & geometries
}

TrafficDlg::~TrafficDlg()
{
    delete ui;
}

void TrafficDlg::resizeEvent(QResizeEvent *e)
{// proportional widget resizing
    int ew = e->size().width(); // MainWindow
    int eh = e->size().height();
    int i, nw, nh;
    double ht;
    if(ew >= eh)
    { // Landscape
        nw = LANDW;
        nh = LANDH;
    }
    else
    { // Portrait
        nw = PORTW;
        nh = PORTH;
    }
    for(i = 0; i < 91; ++i) // resize widgets
        pW[i]->setGeometry(wRect[i].x()*ew/nw, wRect[i].y()*eh/nh, wRect[i].width()*ew/nw, wRect[i].height()*eh/nh);

    // test height/width ratio
    if((double) eh / (double) ew < 0.75) ht = (double) ew * 0.75 / (double) nw * 8.; // new font size
    else ht = (double) eh / (double) nh * 8.; // new font size
    eh = nint(ht);

    QFont newFont = ui->truckClassLabel->font();
    if(eh != newFont.pointSize())
    {
        newFont.setPointSize(eh);
        QDialog::setFont(newFont);
    }
}

void TrafficDlg::loadW()
{
    // Truck edit boxes
    pEdit[0] = ui->truckEdit02;
    pEdit[1] = ui->truckEdit03;
    pEdit[2] = ui->truckEdit04;
    pEdit[3] = ui->truckEdit05;
    pEdit[4] = ui->truckEdit06;
    pEdit[5] = ui->truckEdit07;
    pEdit[6] = ui->truckEdit08;
    pEdit[7] = ui->truckEdit09;
    pEdit[8] = ui->truckEdit10;
    pEdit[9] = ui->truckEdit11;
    // pointers to all widgets for resizing
    pW[0] = ui->axleLabel;
    pW[1] = ui->axleCombo;
    pW[2] = ui->esalGroup;
    pW[3] = ui->esalRadio1;
    pW[4] = ui->esalLabel1;
    pW[5] = ui->esalEdit1;
    pW[6] = ui->esalLabel1u;
    pW[7] = ui->esalRadio2;
    pW[8] = ui->esalLabel2;
    pW[9] = ui->esalEdit2;
    pW[10] = ui->esalLabel2u;
    pW[11] = ui->esalLabel3;
    pW[12] = ui->esalEdit3;
    pW[13] = ui->esalLabel3u;
    pW[14] = ui->esalLabel4;
    pW[15] = ui->esalEdit4;
    pW[16] = ui->esalLabel4u;
    pW[17] = ui->esalLabel5;
    pW[18] = ui->esalEdit5;
    pW[19] = ui->esalLabel5u;
    pW[20] = ui->esalLabel6;
    pW[21] = ui->esalEdit6;
    pW[22] = ui->esalLabel6u;
    pW[23] = ui->esalButton;
    pW[24] = ui->esalLabel7;
    pW[25] = ui->esalEdit7;
    pW[26] = ui->esalLabel7u;
    pW[27] = ui->stressGroup;
    pW[28] = ui->stressLabelH1;
    pW[29] = ui->stressLabel1;
    pW[30] = ui->stressEdit1;
    pW[31] = ui->stressLabel1u;
    pW[32] = ui->stressLabel2;
    pW[33] = ui->stressEdit2;
    pW[34] = ui->stressLabel2u;
    pW[35] = ui->stressLabelH2;
    pW[36] = ui->stressLabel3;
    pW[37] = ui->stressEdit3;
    pW[38] = ui->stressLabel3u;
    pW[39] = ui->stressLabel4;
    pW[40] = ui->stressEdit4;
    pW[41] = ui->stressLabel4u;
    pW[42] = ui->stressLabel5;
    pW[43] = ui->stressEdit5;
    pW[44] = ui->stressLabel5u;
    pW[45] = ui->stressButton;
    pW[46] = ui->buttonBox;
    pW[47] = ui->truckGroup;
    pW[48] = ui->truckCombo;
    pW[49] = ui->truckClassLabel;
    pW[50] = ui->truckDescLabel;
    pW[51] = ui->truckPctLabel;
    pW[52] = ui->classLabel01;
    pW[53] = ui->truckLabel01;
    pW[54] = ui->truckEdit01;
    pW[55] = ui->classLabel02;
    pW[56] = ui->truckLabel02;
    pW[57] = ui->truckEdit02;
    pW[58] = ui->classLabel03;
    pW[59] = ui->truckLabel03;
    pW[60] = ui->truckEdit03;
    pW[61] = ui->classLabel04;
    pW[62] = ui->truckLabel04;
    pW[63] = ui->truckEdit04;
    pW[64] = ui->classLabel05;
    pW[65] = ui->truckLabel05;
    pW[66] = ui->truckEdit05;
    pW[67] = ui->classLabel06;
    pW[68] = ui->truckLabel06;
    pW[69] = ui->truckEdit06;
    pW[70] = ui->classLabel07;
    pW[71] = ui->truckLabel07;
    pW[72] = ui->truckEdit07;
    pW[73] = ui->classLabel08;
    pW[74] = ui->truckLabel08;
    pW[75] = ui->truckEdit08;
    pW[76] = ui->classLabel09;
    pW[77] = ui->truckLabel09;
    pW[78] = ui->truckEdit09;
    pW[79] = ui->classLabel10;
    pW[80] = ui->truckLabel10;
    pW[81] = ui->truckEdit10;
    pW[82] = ui->classLabel11;
    pW[83] = ui->truckLabel11;
    pW[84] = ui->truckEdit11;
    pW[85] = ui->truckLabel12;
    pW[86] = ui->truckEdit12;
    pW[87] = ui->truckLabel13;
    pW[88] = ui->truckLabel14;
    pW[89] = ui->growthLabel;
    pW[90] = ui->growthCombo;

    // geometries
    wRect[0] = QRect(10,10,80,22);
    wRect[1] = QRect(100,10,90,22); // axleCombo
    wRect[2] = QRect(4,36,208,202);
    wRect[3] = QRect(16,16,70,20); // esalRadio1
    wRect[4] = QRect(4,16,80,20); // esalLabel1
    wRect[5] = QRect(90,16,54,20); // esalEdit1
    wRect[6] = QRect(150,16,48,20); // esalLabel1u
    wRect[7] = QRect(16,40,70,20); // esalRadio2
    wRect[8] = QRect(4,40,80,20); // esalLabel2
    wRect[9] = QRect(90,40,54,20); // esalEdit2
    wRect[10] = QRect(150,40,48,20); // esalLabel2u
    wRect[11] = QRect(4,72,80,20); // esalLabel3
    wRect[12] = QRect(90,72,54,20); // esalEdit3
    wRect[13] = QRect(150,72,40,20); // esalLabel3u
    wRect[14] = QRect(4,96,80,20); // esalLabel4
    wRect[15] = QRect(90,96,54,20); // esalEdit4
    wRect[16] = QRect(150,96,40,20); // esalLabel4u
    wRect[17] = QRect(4,120,80,20); // esalLabel5
    wRect[18] = QRect(90,120,54,20); // esalEdit5
    wRect[19] = QRect(150,120,40,20); // esalLabel5u
    wRect[20] = QRect(4,144,80,20); // esalLabel6
    wRect[21] = QRect(90,144,54,20); // esalEdit6
    wRect[22] = QRect(150,144,40,20); // esalLabel6u
    wRect[23] = QRect(44,170,120,24); // esalButton
    wRect[24] = QRect(4,168,80,20); // esalLabel7
    wRect[25] = QRect(90,168,54,20); // esalEdit7
    wRect[26] = QRect(150,168,40,20); // esalLabel7u
    wRect[27] = QRect(4,244,208,226); // stressGroup
    wRect[28] = QRect(10,22,180,16); // stressLabelH1
    wRect[29] = QRect(4,42,80,20); // stressLabel1
    wRect[30] = QRect(90,42,54,20); // stressEdit1
    wRect[31] = QRect(150,42,40,20); // stressLabel1u
    wRect[32] = QRect(4,66,80,20); // stressLabel2
    wRect[33] = QRect(90,66,54,20); // stressEdit2
    wRect[34] = QRect(150,66,40,20); // stressLabel2u
    wRect[35] = QRect(10,100,180,16); // stressLabelH2
    wRect[36] = QRect(4,120,80,20); // stressLabel3
    wRect[37] = QRect(90,120,54,20); // stressEdit3
    wRect[38] = QRect(150,120,40,20); // stressLabel3u
    wRect[39] = QRect(4,144,80,20); // stressLabel4
    wRect[40] = QRect(90,144,54,20); // stressEdit4
    wRect[41] = QRect(150,144,40,20); // stressLabel4u
    wRect[42] = QRect(4,168,80,20); // stressLabel5
    wRect[43] = QRect(90,168,54,20); // stressEdit5
    wRect[44] = QRect(150,168,40,20); // stressLabel5u
    wRect[45] = QRect(44,194,120,24); // stressButton
    wRect[46] = QRect(216,6,208,32); // buttonBox
    wRect[47] = QRect(216,36,208,400); // truckGroup
    wRect[48] = QRect(10,20,72,22); // truckCombo
    wRect[49] = QRect(4,48,40,16); // truckClassLabel
    wRect[50] = QRect(50,48,100,16); // truckDescLabel
    wRect[51] = QRect(152,48,50,16); // truckPctLabel
    wRect[52] = QRect(12,66,22,20); // classLabel01
    wRect[53] = QRect(42,66,110,20); // truckLabel01
    wRect[54] = QRect(160,66,36,20); // truckEdit01
    wRect[55] = QRect(12,90,22,20); // classLabel02
    wRect[56] = QRect(42,90,110,20); // truckLabel02
    wRect[57] = QRect(160,90,36,20); // truckEdit02
    wRect[58] = QRect(12,114,22,20); // classLabel03
    wRect[59] = QRect(42,114,110,20); // truckLabel03
    wRect[60] = QRect(160,114,36,20); // truckEdit03
    wRect[61] = QRect(12,138,22,20); // classLabel04
    wRect[62] = QRect(42,138,110,20); // truckLabel04
    wRect[63] = QRect(160,138,36,20); // truckEdit04
    wRect[64] = QRect(12,162,22,20); // classLabel05
    wRect[65] = QRect(42,162,110,20); // truckLabel05
    wRect[66] = QRect(160,162,36,20); // truckEdit05
    wRect[67] = QRect(12,186,22,20); // classLabel06
    wRect[68] = QRect(42,186,110,20); // truckLabel06
    wRect[69] = QRect(160,186,36,20); // truckEdit06
    wRect[70] = QRect(12,210,22,20); // classLabel07
    wRect[71] = QRect(42,210,110,20); // truckLabel07
    wRect[72] = QRect(160,210,36,20); // truckEdit07
    wRect[73] = QRect(12,234,22,20); // classLabel08
    wRect[74] = QRect(42,234,110,20); // truckLabel08
    wRect[75] = QRect(160,234,36,20); // truckEdit08
    wRect[76] = QRect(12,258,22,20); // classLabel09
    wRect[77] = QRect(42,258,110,20); // truckLabel09
    wRect[78] = QRect(160,258,36,20); // truckEdit09
    wRect[79] = QRect(12,282,22,20); // classLabel10
    wRect[80] = QRect(42,282,110,20); // truckLabel10
    wRect[81] = QRect(160,282,36,20); // truckEdit10
    wRect[82] = QRect(12,306,22,20); // classLabel11
    wRect[83] = QRect(42,306,110,20); // truckLabel11
    wRect[84] = QRect(160,306,36,20); // truckEdit11
    wRect[85] = QRect(16,336,136,20); // truckLabel12
    wRect[86] = QRect(160,336,36,20); // truckEdit12
    wRect[87] = QRect(10,360,180,16); // truckLabel13
    wRect[88] = QRect(10,378,180,16); // truckLabel14
    wRect[89] = QRect(222,440,80,22); // growthLabel
    wRect[90] = QRect(312,440,90,22); // growthCombo
}

void TrafficDlg::setWidgets()
{
    ui->growthCombo->setEnabled(bResearch);
    switch(nMode)
    {
        case 0: //return spectrum only
        {
            ui->axleLabel->setVisible(false);
            ui->axleCombo->setVisible(false);
            ui->growthLabel->setVisible(false);
            ui->growthCombo->setVisible(false);
            ui->esalGroup->setVisible(false);
            ui->esalRadio1->setVisible(false);
            ui->esalLabel1->setVisible(false);
            ui->esalEdit1->setVisible(false);
            ui->esalLabel1u->setVisible(false);
            ui->esalRadio2->setVisible(false);
            ui->esalLabel2->setVisible(false);
            ui->esalEdit2->setVisible(false);
            ui->esalLabel2u->setVisible(false);
            ui->esalLabel3->setVisible(false);
            ui->esalEdit3->setVisible(false);
            ui->esalLabel3u->setVisible(false);
            ui->esalLabel4->setVisible(false);
            ui->esalEdit4->setVisible(false);
            ui->esalLabel4u->setVisible(false);
            ui->esalLabel5->setVisible(false);
            ui->esalEdit5->setVisible(false);
            ui->esalLabel5u->setVisible(false);
            ui->esalLabel6->setVisible(false);
            ui->esalEdit6->setVisible(false);
            ui->esalLabel6u->setVisible(false);
            ui->esalButton->setVisible(false);
            ui->esalLabel7->setVisible(false);
            ui->esalEdit7->setVisible(false);
            ui->esalLabel7u->setVisible(false);
            ui->stressGroup->setVisible(false);
            ui->stressLabelH1->setVisible(false);
            ui->stressLabel1->setVisible(false);
            ui->stressEdit1->setVisible(false);
            ui->stressLabel1u->setVisible(false);
            ui->stressLabel2->setVisible(false);
            ui->stressEdit2->setVisible(false);
            ui->stressLabel2u->setVisible(false);
            ui->stressLabelH2->setVisible(false);
            ui->stressLabel3->setVisible(false);
            ui->stressEdit3->setVisible(false);
            ui->stressLabel3u->setVisible(false);
            ui->stressLabel4->setVisible(false);
            ui->stressEdit4->setVisible(false);
            ui->stressLabel4u->setVisible(false);
            ui->stressLabel5->setVisible(false);
            ui->stressEdit5->setVisible(false);
            ui->stressLabel5u->setVisible(false);
            ui->stressButton->setVisible(false);
            ui->truckGroup->setVisible(true);
            ui->truckCombo->setVisible(false);
            ui->truckClassLabel->setVisible(true);
            ui->truckDescLabel->setVisible(true);
            ui->truckPctLabel->setVisible(true);
            ui->classLabel01->setVisible(true);
            ui->truckLabel01->setVisible(true);
            ui->truckEdit01->setVisible(true);
            ui->classLabel02->setVisible(true);
            ui->truckLabel02->setVisible(true);
            ui->truckEdit02->setVisible(true);
            ui->classLabel03->setVisible(true);
            ui->truckLabel03->setVisible(true);
            ui->truckEdit03->setVisible(true);
            ui->classLabel04->setVisible(true);
            ui->truckLabel04->setVisible(true);
            ui->truckEdit04->setVisible(true);
            ui->classLabel05->setVisible(true);
            ui->truckLabel05->setVisible(true);
            ui->truckEdit05->setVisible(true);
            ui->classLabel06->setVisible(true);
            ui->truckLabel06->setVisible(true);
            ui->truckEdit06->setVisible(true);
            ui->classLabel07->setVisible(true);
            ui->truckLabel07->setVisible(true);
            ui->truckEdit07->setVisible(true);
            ui->classLabel08->setVisible(true);
            ui->truckLabel08->setVisible(true);
            ui->truckEdit08->setVisible(true);
            ui->classLabel09->setVisible(true);
            ui->truckLabel09->setVisible(true);
            ui->truckEdit09->setVisible(true);
            ui->classLabel10->setVisible(true);
            ui->truckLabel10->setVisible(true);
            ui->truckEdit10->setVisible(true);
            ui->classLabel11->setVisible(false);
            ui->truckLabel11->setVisible(false);
            ui->truckEdit11->setVisible(false);
            ui->truckLabel12->setVisible(true);
            ui->truckEdit12->setVisible(true);
            ui->truckLabel13->setVisible(true);
            ui->truckLabel14->setVisible(true);
            // enable
            ui->truckEdit01->setEnabled(false);
            ui->truckEdit12->setEnabled(false);
            // labels
            ui->classLabel08->setText(bFHWA ? "10" : "");
            ui->classLabel09->setText(bFHWA ? "11" : "10");
            ui->classLabel10->setText(bFHWA ? "12" : "11");
            ui->truckLabel02->setText(bFHWA ? tr("Buses") : tr("2 Axle 6 Tire"));
            ui->truckLabel03->setText(bFHWA ? tr("2 Axle 6 Tire") : tr("3+ Axle Single"));
            ui->truckLabel04->setText(bFHWA ? tr("3 Axle Single") : tr("3 Axle Semi"));
            ui->truckLabel05->setText(bFHWA ? tr("4+ Axle Single") : tr("4 Axle Semi"));
            ui->truckLabel06->setText(bFHWA ? tr("3 & 4 Axle Semi") : tr("5+ Axle Semi"));
            ui->truckLabel07->setText(bFHWA ? tr("5 Axle Semi") : tr("(5+ Axle Max)"));
            ui->truckLabel08->setText(bFHWA ? tr("6+ Axle Semi") : tr("(5+ Axle Other)"));
            ui->truckLabel09->setText(bFHWA ? tr("5 Axle Multi-Trailer") : tr("Trailers & Buses"));
            ui->truckLabel10->setText(bFHWA ? tr("6 Axle Multi-Trailer") : tr("Twin Trailer"));
        }
        break;
        case 1: //launch rigid
        {
        }
        break;
        case 2: //launch ESALs
        {
            ui->axleLabel->setVisible(bResearch);
            ui->axleCombo->setVisible(bResearch);
            ui->growthLabel->setVisible(bResearch);
            ui->growthCombo->setVisible(bResearch);
            ui->esalGroup->setVisible(true);
            ui->esalRadio1->setVisible(true);
            ui->esalLabel1->setVisible(true);
            ui->esalEdit1->setVisible(true);
            ui->esalLabel1u->setVisible(true);
            ui->esalRadio2->setVisible(true);
            ui->esalLabel2->setVisible(true);
            ui->esalEdit2->setVisible(true);
            ui->esalLabel2u->setVisible(true);
            ui->esalLabel3->setVisible(true);
            ui->esalEdit3->setVisible(true);
            ui->esalLabel3u->setVisible(true);
            ui->esalLabel4->setVisible(true);
            ui->esalEdit4->setVisible(true);
            ui->esalLabel4u->setVisible(true);
            ui->esalLabel5->setVisible(true);
            ui->esalEdit5->setVisible(true);
            ui->esalLabel5u->setVisible(true);
            ui->esalLabel6->setVisible(true);
            ui->esalEdit6->setVisible(true);
            ui->esalLabel6u->setVisible(true);
            ui->stressGroup->setVisible(true);
            ui->stressLabelH1->setVisible(true);
            ui->stressLabel1->setVisible(true);
            ui->stressEdit1->setVisible(true);
            ui->stressLabel1u->setVisible(true);
            ui->stressLabel2->setVisible(true);
            ui->stressEdit2->setVisible(true);
            ui->stressLabel2u->setVisible(true);
            ui->stressLabelH2->setVisible(true);
            ui->stressLabel3->setVisible(true);
            ui->stressEdit3->setVisible(true);
            ui->stressLabel3u->setVisible(true);
            ui->stressLabel4->setVisible(true);
            ui->stressEdit4->setVisible(true);
            ui->stressLabel4u->setVisible(true);
            ui->stressLabel5->setVisible(true);
            ui->stressEdit5->setVisible(true);
            ui->stressLabel5u->setVisible(true);
            ui->stressButton->setVisible(bResearch);
            ui->truckGroup->setVisible(false);
            ui->truckCombo->setVisible(false);
            ui->truckClassLabel->setVisible(false);
            ui->truckDescLabel->setVisible(false);
            ui->truckPctLabel->setVisible(false);
            ui->classLabel01->setVisible(false);
            ui->truckLabel01->setVisible(false);
            ui->truckEdit01->setVisible(false);
            ui->classLabel02->setVisible(false);
            ui->truckLabel02->setVisible(false);
            ui->truckEdit02->setVisible(false);
            ui->classLabel03->setVisible(false);
            ui->truckLabel03->setVisible(false);
            ui->truckEdit03->setVisible(false);
            ui->classLabel04->setVisible(false);
            ui->truckLabel04->setVisible(false);
            ui->truckEdit04->setVisible(false);
            ui->classLabel05->setVisible(false);
            ui->truckLabel05->setVisible(false);
            ui->truckEdit05->setVisible(false);
            ui->classLabel06->setVisible(false);
            ui->truckLabel06->setVisible(false);
            ui->truckEdit06->setVisible(false);
            ui->classLabel07->setVisible(false);
            ui->truckLabel07->setVisible(false);
            ui->truckEdit07->setVisible(false);
            ui->classLabel08->setVisible(false);
            ui->truckLabel08->setVisible(false);
            ui->truckEdit08->setVisible(false);
            ui->classLabel09->setVisible(false);
            ui->truckLabel09->setVisible(false);
            ui->truckEdit09->setVisible(false);
            ui->classLabel10->setVisible(false);
            ui->truckLabel10->setVisible(false);
            ui->truckEdit10->setVisible(false);
            ui->classLabel11->setVisible(false);
            ui->truckLabel11->setVisible(false);
            ui->truckEdit11->setVisible(false);
            ui->truckLabel12->setVisible(false);
            ui->truckEdit12->setVisible(false);
            ui->truckLabel13->setVisible(false);
            ui->truckLabel14->setVisible(false);
        }
        break;
        case 3: //launch flex spec
        {
        }
        break;
    }
    //setValues();
}

void TrafficDlg::setValues(bool bconv)
{
    int i;
    double dadj;
    QString ttmp = "";
    ui->growthCombo->setCurrentIndex(bCompound ? 1 : 0);
    ui->truckCombo->setCurrentIndex(bFHWA ? 1 : 0);
    switch(nMode)
    {
        case 0: // rigid
        {
            setWindowTitle(tr("Select Axle Load Spectrum"));
            if(bFHWA)
            {
                for(i = 0; i < 10; ++i) pEdit[i]->setText(txtdbl(fhwa[i],DEC_PCT));
            }
            else
            {
                if(bconv)
                {// convert FHWA to MnDOT per MnDOT_Forecast_Manual_2012.pdf
                    mndot[0] = fhwa[1]; // 2 Axle 6 Tire
                    mndot[1] = fhwa[2] + fhwa[3]; // 3+ Axle Single
                    mndot[2] = rnd2dec(fhwa[4] * MN3AXLE,DEC_PCT); // 3 Axle Semi
                    mndot[3] = fhwa[4] - mndot[2]; // 4 Axle Semi
                    mndot[4] = fhwa[5] + fhwa[6]; // 5+ Axle Semi
                    mndot[5] = mndot[6] = 0.; // 5+ Axle Max & Other
                    mndot[7] = fhwa[0]; // Trailers & Buses
                    mndot[8] = fhwa[7] + fhwa[8] + fhwa[9]; // Twin Trailer
                }
                for(i = 0; i < 9; ++i) pEdit[i]->setText(txtdbl(mndot[i],DEC_PCT));
            }
            nRigidSpec = calcTraffic(-1);
            // determine load spectrum here
        }
        break;
        case 2: // esal
        {
            ui->axleCombo->setCurrentIndex(nCustAxle == 0 ? 0 : 1);
            setWindowTitle(nCustAxle == 0 ? tr("ESAL Details") : tr("Custom Axle Details"));
            ui->esalGroup->setTitle(nCustAxle == 0 ? tr("ESALs") : tr("Custom Axle"));
            if(bFirstYearESAL) ui->esalRadio2->setChecked(true);
            else ui->esalRadio1->setChecked(true);
            ui->esalEdit1->setText(nCustAxle == 0 ? txtdbl(esal, 3) : QString::number(nCustWheel));
            ui->esalEdit2->setText(nCustAxle == 0 ? txtdbl(esal1, 4) : QString::number(nCustAxle));
            ui->esalEdit1->setEnabled(!bFirstYearESAL || nCustAxle > 0);
            ui->esalEdit2->setEnabled(bFirstYearESAL || nCustAxle > 0);
            ui->esalRadio1->setVisible(nCustAxle == 0);
            ui->esalRadio2->setVisible(nCustAxle == 0);
            ui->esalLabel1->setVisible(nCustAxle > 0);
            ui->esalLabel2->setVisible(nCustAxle > 0);
            ui->esalEdit3->setEnabled(bResearch);
            ui->esalEdit4->setEnabled(nCustAxle > 0);
            ui->esalEdit5->setEnabled(false);
            ui->esalEdit6->setEnabled(nCustAxle > 0);
            ui->stressEdit1->setEnabled(bResearch);
            ui->stressEdit2->setEnabled(bResearch);
            ui->stressEdit3->setEnabled(bResearch);
            ui->stressEdit4->setEnabled(bResearch);
            ui->stressEdit5->setEnabled(bResearch);
            ui->esalButton->setVisible(nCustAxle == 0);
            ui->esalLabel7->setVisible(nCustAxle > 1);
            ui->esalEdit7->setVisible(nCustAxle > 1);
            ui->esalLabel7u->setVisible(nCustAxle > 1);
            ui->esalLabel1u->setText(nCustAxle == 0 ? tr("million") : tr("(½ axle)"));
            ui->esalLabel2u->setText(nCustAxle == 0 ? tr("million") : "");
            ui->esalEdit3->setText(txtdbl(convp(false,nCustAxle == 0 ? esalP : custP,bsi),DEC_P));
            ui->esalEdit4->setText(txtdbl(convf(false,nCustAxle == 0 ? ESAL_KIP : custWt,bsi),2));
            ui->esalEdit5->setText(txtdbl(convf(false,nCustAxle == 0 ? ESAL_KIP*0.25 : custWt/(nCustWheel*2*nCustAxle),bsi),2));
            ui->esalEdit6->setText(txtdbl(convl(false,nCustAxle == 0 ? esalX : custX,bsi),decl(bsi,false)));
            ui->esalEdit7->setText(txtdbl(convl(false,custY,bsi),decl(bsi,false)));
            ui->stressEdit1->setText(txtdbl(convp(false,mohrP[0],bsi),DEC_P));
            ui->stressEdit2->setText(txtdbl(convf(false,mohrWt[0],bsi),FIG_WT,true));
            ui->stressEdit3->setText(txtdbl(convp(false,mohrP[1],bsi),DEC_P));
            ui->stressEdit4->setText(txtdbl(convf(false,mohrWt[1],bsi),FIG_WT,true));
            ui->stressEdit5->setText(txtdbl(convl(false,mohrX[1],bsi),decl(bsi,false)));
            ui->esalLabel3u->setText(txtp(bsi));
            ui->esalLabel4u->setText(txtff(bsi));
            ui->esalLabel5u->setText(txtff(bsi));
            ui->esalLabel6u->setText(txtl(bsi));
            ui->stressLabel1u->setText(txtp(bsi));
            ui->stressLabel2u->setText(txtff(bsi));
            ui->stressLabel3u->setText(txtp(bsi));
            ui->stressLabel4u->setText(txtff(bsi));
            ui->stressLabel5u->setText(txtl(bsi));
        }
        break;
        case 3: // flexible spectrum
        {
            setWindowTitle(tr("Set Flexible Load Spectrum"));
            if(bFHWA)
            {
                for(i = 0; i < 10; ++i) pEdit[i]->setText(txtdbl(fhwa[i],DEC_PCT));
            }
            else
            {
                if(bconv)
                {// convert FHWA to MnDOT per MnDOT_Forecast_Manual_2012.pdf
                    mndot[0] = fhwa[1]; // 2 Axle 6 Tire
                    mndot[1] = fhwa[2] + fhwa[3]; // 3+ Axle Single
                    mndot[2] = rnd2dec(fhwa[4] * MN3AXLE,DEC_PCT); // 3 Axle Semi
                    mndot[3] = fhwa[4] - mndot[2]; // 4 Axle Semi
                    mndot[4] = fhwa[5] + fhwa[6]; // 5+ Axle Semi
                    mndot[5] = mndot[6] = 0.; // 5+ Axle Max & Other
                    mndot[7] = fhwa[0]; // Trailers & Buses
                    mndot[8] = fhwa[7] + fhwa[8] + fhwa[9]; // Twin Trailer
                }
                for(i = 0; i < 9; ++i) pEdit[i]->setText(txtdbl(mndot[i],DEC_PCT));
            }
            nRigidSpec = calcTraffic(-1);
            ui->truckLabel14->setText(SPECTXT[nRigidSpec]);
            // determine load spectrum here
        }
        break;
    }
}

void TrafficDlg::checkWheels()
{
    if(nCustWheel < 1) nCustWheel = 1;
    if(nCustAxle < 1) nCustAxle = 1;
    // check for maximum WESLEA load points
    if(nCustWheel * nCustAxle > 20)
    {
        QMessageBox msg;
        msg.setText(tr("Total load points (wheels * axles) are limited to 20."));
        msg.exec();
        nCustAxle = 20 / nCustWheel;
    }
}
int TrafficDlg::calcTraffic(int ntruck)
{
    int i;
    int nSp = 0;
    double heavy = 0.;
    double total = 0.;
    double dadj = 1.0;
    QString ttmp = "";
    QMessageBox msg;
    if(bFHWA)
    {
        if(ntruck >= 0) fhwa[ntruck] = rnd2dec(dtmp, DEC_PCT);
        for(i = 0; i < 10; ++i) total += fhwa[i];
        if(total > 0.) heavy = (fhwa[7] + fhwa[8] + fhwa[9]) / total;
        if(ntruck >= 0)
        {
            if(total > 100.)
            {
                msg.setText(tr("Vehicle total exceeds 100%."));
                msg.exec();
                fhwa[ntruck] -= (total - 100.);
            }
            pEdit[ntruck]->setText(txtdbl(fhwa[ntruck],DEC_PCT));
        }
    }
    else
    {
        if(ntruck >= 0) mndot[ntruck] = rnd2dec(dtmp, DEC_PCT);
        for(i = 0; i < 9; ++i) total += mndot[i];
        if(total > 0.) heavy = (mndot[5] + mndot[6] + mndot[8]) / total;
        if(ntruck >= 0)
        {
            if(total > 100.)
            {
                msg.setText(tr("Vehicle total exceeds 100%."));
                msg.exec();
                mndot[ntruck] -= (total - 100.);
            }
            pEdit[ntruck]->setText(txtdbl(mndot[ntruck],DEC_PCT));
        }
    }
    ui->truckEdit01->setText(txtdbl(100.-total,DEC_PCT));
    ui->truckEdit12->setText(txtdbl(total,DEC_PCT));
    // calculate adjustment if necessary
    dadj = adjHCADT(mndot, HCADT);
    ttmp = dadj > 1.0 ? tr(", HCADT * %1").arg(txtdbl(dadj, 3)) : "";
    // determine Spectrum
    if(heavy < 0.1) nSp = 0;
    else if(heavy > 0.25) nSp = 2;
    else nSp = 1;
    ui->truckLabel14->setText(SPECTXT[nSp] + ttmp);
    return nSp;
}

double TrafficDlg::calcESAL(bool calcLifeESAL, double inESAL)
{
    // Calculate lifetime traffic factor
    int i;
    double YearFactor = 1.;
    double LifeFactor = 0.;
    double retESAL;
    for(i = 1; i <= nFlexLife; i++)	// Years
    {
        LifeFactor += YearFactor;
        if(bCompound) YearFactor *= (1. + ipct / 100.0); // Compound Growth
        else YearFactor += (ipct / 100.0);	// Simple Growth
    }
    if(calcLifeESAL) retESAL = inESAL * LifeFactor;
    else retESAL = inESAL / LifeFactor;
    return retESAL;
}

double TrafficDlg::adjHCADT(double *mdtraf, double HCADT)
{ // adjustment factor for heavy trucks exceeding MEPDG spectrum
    // 2019 Created by Steve Henrichs, MnDOT Assistant Pavement Design Engineer
    if(mdtraf[5] <= 3.0) return 1.0; // no adjustment
    int i;
    double dsum1 = 0.0;
    double dsum2 = 0.0;
    double fESAL[9]; // ESAL factors
    double MEPDG[9]; // MEPDG truck percentages
    fESAL[0] = 0.25;
    fESAL[1] = 0.58;
    fESAL[2] = 0.39;
    fESAL[3] = 0.51;
    fESAL[4] = 1.13;
    fESAL[5] = 2.4;
    fESAL[6] = 0.87;
    fESAL[7] = 0.57;
    fESAL[8] = 2.4;
    MEPDG[0] = 0.246;
    MEPDG[1] = 0.081;
    MEPDG[2] = 0.025;
    MEPDG[3] = 0.025;
    MEPDG[4] = 0.411;
    MEPDG[5] = 0;
    MEPDG[6] = 0;
    MEPDG[7] = 0.018;
    MEPDG[8] = 0.194;

    dsum1 = 0.0;
    for(i = 0; i < 9; ++i) dsum1 += mdtraf[i];
    dsum2 = 0.0;
    for(i = 0; i < 9; ++i) dsum2 += rnd2dec(mdtraf[i]/dsum1*HCADT,0) * fESAL[i];
    dsum1 = 0.0;
    for(i = 0; i < 9; ++i) dsum1 += rnd2dec(MEPDG[i]*HCADT,0) * fESAL[i];
    return dsum2/dsum1;
}
void TrafficDlg::on_axleCombo_activated(int index)
{
    nCustAxle = index;
    setValues();
}

void TrafficDlg::on_growthCombo_activated(int index)
{
    bCompound = index == 1;
    if(bFirstYearESAL) esal = calcESAL(true, esal1);
    else esal1 = calcESAL(false, esal);
    setValues();
}

void TrafficDlg::on_esalRadio1_clicked()
{
    bFirstYearESAL = false;
    esal = calcESAL(true, esal1);
    ui->esalEdit1->setEnabled(true);
    ui->esalEdit2->setEnabled(false);
    setValues();
}

void TrafficDlg::on_esalRadio2_clicked()
{
    bFirstYearESAL = true;
    esal1 = calcESAL(false, esal);
    ui->esalEdit1->setEnabled(false);
    ui->esalEdit2->setEnabled(true);
    setValues();
}

void TrafficDlg::on_esalEdit1_editingFinished()
{
    if(nCustAxle == 0)
    {
        esal = ui->esalEdit1->text().toDouble();
        esal1 = calcESAL(false, esal);
    }
    else
    {
        nCustWheel = ui->esalEdit1->text().toInt();
        checkWheels();
    }
    setValues();
}

void TrafficDlg::on_esalEdit2_editingFinished()
{
    if(nCustAxle == 0)
    {
        esal1 = ui->esalEdit2->text().toDouble();
        esal = calcESAL(true, esal1);
    }
    else
    {
        nCustAxle = ui->esalEdit2->text().toInt();
        checkWheels();
    }
    setValues();
}

void TrafficDlg::on_esalEdit3_editingFinished()
{
    if(nCustAxle == 0) esalP = convp(bsi,ui->esalEdit3->text().toDouble());
    else custP = convp(bsi,ui->esalEdit3->text().toDouble());
    setValues();
}

void TrafficDlg::on_esalEdit4_editingFinished()
{
    custWt = convf(bsi,ui->esalEdit4->text().toDouble());
    setValues();
}

void TrafficDlg::on_esalEdit6_editingFinished()
{
    custX = convl(bsi,ui->esalEdit6->text().toDouble());
    setValues();
}

void TrafficDlg::on_esalEdit7_editingFinished()
{
    custY = convl(bsi,ui->esalEdit7->text().toDouble());
    setValues();
}

void TrafficDlg::on_esalButton_clicked()
{
    esalP = 80.;
    setValues();
}

void TrafficDlg::on_stressEdit1_editingFinished()
{
    mohrP[0] = convp(bsi,ui->stressEdit1->text().toDouble());
    setValues();
}

void TrafficDlg::on_stressEdit2_editingFinished()
{
    mohrWt[0] = convf(bsi,ui->stressEdit2->text().toDouble());
    setValues();
}

void TrafficDlg::on_stressEdit3_editingFinished()
{
    mohrP[1] = convp(bsi,ui->stressEdit3->text().toDouble());
    setValues();
}

void TrafficDlg::on_stressEdit4_editingFinished()
{
    mohrWt[1] = convf(bsi,ui->stressEdit4->text().toDouble());
    setValues();
}

void TrafficDlg::on_stressEdit5_editingFinished()
{
    mohrX[1] = convl(bsi,ui->stressEdit5->text().toDouble());
    setValues();
}

void TrafficDlg::on_stressButton_clicked()
{
    mohrP[0] = MOHR_P1_PSI;
    mohrP[1] = MOHR_P2_PSI;
    mohrWt[0] = MOHR_WT1_KIP;
    mohrWt[1] = MOHR_WT2_KIP;
    mohrX[1] = MOHR_X2_IN;
    setValues();
}

void TrafficDlg::on_truckCombo_activated(int index)
{
    bool bconv = false;
    if(bFHWA && index == 0)
    {
        double total = 0.;
        for(int i = 0; i < 10; ++i) total += fhwa[i];
        if(total > 0.)
        {
            QMessageBox msg;
            msg.setText(tr("Do you want to convert these FHWA vehicle classes to MnDOT classes?"));
            msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
            int ret = msg.exec();
            if(ret == QMessageBox::Yes) bconv = true;
            else if(ret == QMessageBox::Cancel) index = 1; // don't change
        }
    }
    bFHWA = index == 1;
    setWidgets();
    setValues(bconv);
}

void TrafficDlg::on_truckEdit02_editingFinished()
{
    dtmp = QString(ui->truckEdit02->text()).toDouble();
    nRigidSpec = calcTraffic(0);
}

void TrafficDlg::on_truckEdit03_editingFinished()
{
    dtmp = QString(ui->truckEdit03->text()).toDouble();
    nRigidSpec = calcTraffic(1);
}

void TrafficDlg::on_truckEdit04_editingFinished()
{
    dtmp = QString(ui->truckEdit04->text()).toDouble();
    nRigidSpec = calcTraffic(2);
}

void TrafficDlg::on_truckEdit05_editingFinished()
{
    dtmp = QString(ui->truckEdit05->text()).toDouble();
    nRigidSpec = calcTraffic(3);
}

void TrafficDlg::on_truckEdit06_editingFinished()
{
    dtmp = QString(ui->truckEdit06->text()).toDouble();
    nRigidSpec = calcTraffic(4);
}

void TrafficDlg::on_truckEdit07_editingFinished()
{
    dtmp = QString(ui->truckEdit07->text()).toDouble();
    nRigidSpec = calcTraffic(5);
}

void TrafficDlg::on_truckEdit08_editingFinished()
{
    dtmp = QString(ui->truckEdit08->text()).toDouble();
    nRigidSpec = calcTraffic(6);
}

void TrafficDlg::on_truckEdit09_editingFinished()
{
    dtmp = QString(ui->truckEdit09->text()).toDouble();
    nRigidSpec = calcTraffic(7);
}

void TrafficDlg::on_truckEdit10_editingFinished()
{
    dtmp = QString(ui->truckEdit10->text()).toDouble();
    nRigidSpec = calcTraffic(8);
}

void TrafficDlg::on_truckEdit11_editingFinished()
{
    dtmp = QString(ui->truckEdit11->text()).toDouble();
    nRigidSpec = calcTraffic(9);
}
