#include "library.h"
#include "ui_library.h"
#include <iostream>
#include <QMessageBox>
#include <QSettings>
#include <QFileDialog>
#include <QDebug>
#include "cdac.h"
#include <QtMath>
#include <cmath>

library::library(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::library)
{
    ui->setupUi(this);
    unsaved=false;
    speakerUnsaved=false;
    dacUnsaved=false;
}

library::~library()
{
    delete ui;
}

void library::setAmpPointer(cAmp *pAmp, unsigned int ampCount){
    m_pCamp=pAmp;
    m_cAmpCount=ampCount;
}

unsigned int library::getAmpCount()
{
    return m_cAmpCount;
}

cAmp *library::getAmps()
{
    return m_pCamp;
}

void library::setSpeakerPointer(cSpeaker *pSpeaker, unsigned int speakerCount)
{
    m_pSpeaker=pSpeaker;
    m_SpeakerCount=speakerCount;
}

unsigned int library::getSpeakerCount()
{
    return m_SpeakerCount;
}

cSpeaker *library::getSpeaker()
{
    return m_pSpeaker;
}

void library::setDacPoint(cdac *dac, unsigned int dacCount)
{
    m_pDac=dac;
    m_dacCount=dacCount;
}

unsigned int library::getDacCount()
{
    return m_dacCount;
}

cdac *library::getDacs()
{
    return m_pDac;
}

void library::open()
{

    ui->listWidget_ampView->setCurrentRow(0);
    QSettings settings("DKM-Tech","Pa-Calculator");
    if (settings.value("library/path","")==""){
        settings.setValue("library/path",QFileDialog::getSaveFileName(this,"Select Library Storage File","","Pa Calculator Library File (*.palib)"));
    }
    //qDebug() << settings.value("library/path","none").toString();
    refreshAmpView();
    refreshSpeakerView();
    refreshDacView();
    this->exec();
}



void library::on_pushButton_addAmp_clicked()
{
    confirmAmpChanges();
    m_cAmpCount+=1;
    cAmp* tempAmps=new cAmp[m_cAmpCount];
    for (unsigned int i=0;i<m_cAmpCount-1;i++){
        tempAmps[i].setName(m_pCamp[i].getName());
        tempAmps[i].setSensivity(m_pCamp[i].getSensitivity());
        tempAmps[i].setSensUnit(m_pCamp[i].getSensivityUnit());
        for (unsigned int j=0;j<m_pCamp[i].getAmpModesCount();j++){
            tempAmps[i].addAmpMode(m_pCamp[i].getAmpMode(j));
        }
    }
    delete [] m_pCamp;
    m_pCamp=tempAmps;
    m_pCamp[m_cAmpCount-1]=cAmp("Unnamed Amp",1,volt);
    refreshAmpView();
    ui->listWidget_ampView->setCurrentRow(m_cAmpCount-1);
    ui->lineEdit_ampName->setFocus();
    ui->lineEdit_ampName->selectAll();
}

void library::refreshAmpView()
{
    ui->listWidget_ampView->clear();
    for (unsigned int i=0;i<m_cAmpCount;i++){
        ui->listWidget_ampView->addItem(QString::fromStdString(m_pCamp[i].getName()));
    }
    //std::cerr<<"refreshAmpView started"<<std::endl;
    //printAllAmps();
}

void library::refreshModeOverview()
{
    ui->listWidget_modeSelector->clear();
    if (m_cAmpCount>0){
        if (m_pCamp[getCurrentAmpIndex()].getAmpModesCount()>0){
            for (unsigned int i=0;i<m_pCamp[getCurrentAmpIndex()].getAmpModesCount();i++){
                ui->listWidget_modeSelector->addItem(QString::fromStdString(m_pCamp[getCurrentAmpIndex()].getAmpMode(i).getName()));
                //std::cout <<"mode "<<i+1<<" : " <<m_pCamp[getCurrentAmpIndex()].getAmpMode(i).getName()<<std::endl;
            }
        }
    }
    //std::cerr<<"refreshModeOverview started"<<std::endl;
    //printAllAmps();


}

void library::refreshSpeakerView()
{
    ui->listWidget_speakerView->clear();
    for (unsigned int i=0;i<m_SpeakerCount;i++){
        ui->listWidget_speakerView->addItem(QString::fromStdString(m_pSpeaker[i].getName()));
    }
}

void library::refreshDacView()
{
    ui->listWidget_dacView->clear();
    for (unsigned int i=0;i<m_dacCount;i++){
        ui->listWidget_dacView->addItem(QString::fromStdString(m_pDac[i].name()));
    }
}

int library::getCurrentAmpIndex()
{
    return ui->listWidget_ampView->currentRow();
}

int library::getCurrentAmpModeIndex()
{
    return ui->listWidget_modeSelector->currentRow();
}

int library::getCurrentSpeakerIndex()
{
    return ui->listWidget_speakerView->currentRow();
}

int library::getCurrentDacIndex()
{
    return ui->listWidget_dacView->currentRow();
}

void library::ampEdited()
{
    if(unsaved==false){
        ui->listWidget_ampView->currentItem()->setText(ui->listWidget_ampView->currentItem()->text()+QString::fromStdString("*"));
        unsaved =true;
    }
}

void library::speakerEdited()
{
    if (speakerUnsaved==false){
        ui->listWidget_speakerView->currentItem()->setText(ui->listWidget_speakerView->currentItem()->text()+QString::fromStdString("*"));
        speakerUnsaved =true;
    }
}

void library::dacEdited()
{
    if (dacUnsaved==false){
        ui->listWidget_dacView->currentItem()->setText(ui->listWidget_dacView->currentItem()->text()+QString::fromStdString("*"));
        dacUnsaved =true;
    }
}

void library::confirmAmpChanges()
{
    if (unsaved){
        int selectedRow=getCurrentAmpIndex();
        ui->tabWidget->setCurrentIndex(0);
        QMessageBox::StandardButton reply;
        reply = QMessageBox::question(this, "Unsaved Changes", "Save unsaved Changes?",
                                      QMessageBox::Yes|QMessageBox::No);
        if (reply == QMessageBox::Yes) {
          on_pushButton_applyChanges_clicked();
        }
        refreshAmpView();
        ui->listWidget_ampView->setCurrentRow(selectedRow);
    }
}

void library::confirmSpeakerChanges()
{
    if (speakerUnsaved){
        int selectedRow=getCurrentSpeakerIndex();
        ui->tabWidget->setCurrentIndex(1);
        QMessageBox::StandardButton reply;
        reply = QMessageBox::question(this, "Unsaved Changes", "Save unsaved Changes?",
                                      QMessageBox::Yes|QMessageBox::No);
        if (reply == QMessageBox::Yes) {
          on_pushButton_applySpeaker_clicked();
        }
        refreshSpeakerView();
        ui->listWidget_speakerView->setCurrentRow(selectedRow);
    }
}

void library::confirmDacChanges()
{
    if (dacUnsaved){
        int selectedRow=getCurrentDacIndex();
        ui->tabWidget->setCurrentIndex(2);
        QMessageBox::StandardButton reply;
        reply = QMessageBox::question(this, "Unsaved Changes", "Save unsaved Changes?",
                                      QMessageBox::Yes|QMessageBox::No);
        if (reply == QMessageBox::Yes) {
          on_pushButton_Apply_clicked();
        }
        refreshDacView();
        ui->listWidget_dacView->setCurrentRow(selectedRow);
    }
}

void library::printAllAmps()
{
    std::cout << "Number of Amps: "<<m_cAmpCount<<std::endl<<std::endl;
    for (unsigned int i=0;i<m_cAmpCount;i++){
        m_pCamp[i].print();
        std::cout <<std::endl;
    }
}


void library::on_listWidget_ampView_currentRowChanged(int currentRow)
{
    if (currentRow>=0){
        ui->lineEdit_ampName->setText(QString::fromStdString(m_pCamp[currentRow].getName()));
        ui->comboBox_sensUnit->setCurrentIndex(m_pCamp[currentRow].getSensivityUnit());
        ui->doubleSpinBox_inputSensitivity->setValue(m_pCamp[currentRow].getSensitivity());
        refreshModeOverview();
        ui->listWidget_modeSelector->setCurrentRow(0);
        ui->lineEdit_ampName->setEnabled(true);
        ui->doubleSpinBox_inputSensitivity->setEnabled(true);
    }else
    {
        ui->lineEdit_ampName->setEnabled(false);
        ui->doubleSpinBox_inputSensitivity->setEnabled(false);
    }
}



void library::on_pushButton_applyChanges_clicked()
{
    if (getCurrentAmpIndex()>=0){
        unsaved =false;
        m_pCamp[getCurrentAmpIndex()].setName(ui->lineEdit_ampName->text().toStdString());
        m_pCamp[getCurrentAmpIndex()].setSensivity(ui->doubleSpinBox_inputSensitivity->value());
        sensitivityUnit currentSens;
        if (ui->comboBox_sensUnit->currentIndex()==0){
            currentSens=volt;
        }else{
            currentSens=dBu;
        }
        m_pCamp[getCurrentAmpIndex()].setSensUnit(currentSens);
        int selectedRow=getCurrentAmpIndex();
        refreshAmpView();
        ui->listWidget_ampView->setCurrentRow(selectedRow);
    }

}


void library::on_comboBox_sensUnit_currentIndexChanged(int index)
{
    ampEdited();
    double oldValue=ui->doubleSpinBox_inputSensitivity->value();
    if (index==0){
       ui->doubleSpinBox_inputSensitivity->setSuffix(QString(" V"));
       ui->doubleSpinBox_inputSensitivity->setDecimals(2);
       ui->doubleSpinBox_inputSensitivity->setValue(0.7746*qPow(10,oldValue/20));
    }else{
       ui->doubleSpinBox_inputSensitivity->setSuffix(QString(" dBu"));
       ui->doubleSpinBox_inputSensitivity->setDecimals(1);
       ui->doubleSpinBox_inputSensitivity->setValue(20*std::log10(oldValue/0.7746));
    }

}


void library::on_pushButton_deleteAmp_clicked()
{
    if (getCurrentAmpIndex()>=0){
        m_cAmpCount-=1;
        cAmp* tempAmps=new cAmp[m_cAmpCount];
        unsigned int selectedRow=getCurrentAmpIndex();
        for (unsigned int i=0;i<selectedRow;i++){
            tempAmps[i]=m_pCamp[i];
        }
        for (unsigned int i=selectedRow+1;i<m_cAmpCount+1;i++){
            tempAmps[i-1]=m_pCamp[i];
        }
        delete [] m_pCamp;
        m_pCamp=tempAmps;

        refreshAmpView();
        if ((selectedRow<1) and (m_cAmpCount>0)){
            ui->listWidget_ampView->setCurrentRow(0);
        }else
        {
            ui->listWidget_ampView->setCurrentRow(selectedRow-1);
        }
    }


}

void library::on_pushButton_addMode_clicked()
{
    if (getCurrentAmpIndex()>=0)
    {
        if (ui->lineEdit_modeName->text()==""){
            QMessageBox msgBox(QMessageBox::Warning,"No mode name","Mode name can't be empty. Please enter a name.");
            msgBox.exec();
        }else{
            cAmpMode mode(ui->lineEdit_modeName->text().toStdString(),ui->spinBox_ratedImp->value(),ui->spinBox_ratedPower->value());
            m_pCamp[getCurrentAmpIndex()].addAmpMode(mode);
        }
    }
    refreshModeOverview();
}


void library::on_listWidget_modeSelector_currentRowChanged(int currentRow)
{
    if (getCurrentAmpIndex()>=0){
        if (currentRow >=0){
            ui->lineEdit_modeName->setText(QString::fromStdString(m_pCamp[getCurrentAmpIndex()].getAmpMode(getCurrentAmpModeIndex()).getName()));
            ui->spinBox_ratedImp->setValue(m_pCamp[getCurrentAmpIndex()].getAmpMode(getCurrentAmpModeIndex()).getRatedImp());
            ui->spinBox_ratedPower->setValue(m_pCamp[getCurrentAmpIndex()].getAmpMode(getCurrentAmpModeIndex()).getRatedPower());
        }
    }

}


void library::on_pushButton_deleteMode_clicked()
{
    int selectedRow=getCurrentAmpModeIndex();
    m_pCamp[getCurrentAmpIndex()].deleteAmpMode(getCurrentAmpModeIndex());
    refreshModeOverview();
    if ((selectedRow<1) && (m_pCamp[getCurrentAmpIndex()].getAmpModesCount())>0){
        ui->listWidget_modeSelector->setCurrentRow(0);
    }else
    {
        ui->listWidget_modeSelector->setCurrentRow(selectedRow-1);
    }
}


void library::on_pushButton_applyMode_clicked()
{
    unsaved =false;
    if (ui->lineEdit_modeName->text()==""){
                QMessageBox msgBox(QMessageBox::Warning,"No mode name","Mode name can't be empty. Please enter a name.");
                msgBox.exec();
    }else{
        cAmpMode mode(ui->lineEdit_modeName->text().toStdString(),ui->spinBox_ratedImp->value(),ui->spinBox_ratedPower->value());
        m_pCamp[getCurrentAmpIndex()].setAmpMode(getCurrentAmpModeIndex(),mode);
    }
    int selectedMode=getCurrentAmpModeIndex();
    refreshModeOverview();
    ui->listWidget_modeSelector->setCurrentRow(selectedMode);
}


void library::on_lineEdit_ampName_textEdited(const QString &arg1)
{
    ampEdited();
}


void library::on_pushButton_addSpeaker_clicked()
{
    confirmSpeakerChanges();
    m_SpeakerCount+=1;
    cSpeaker* tempSpeaker=new cSpeaker[m_SpeakerCount];
    for (unsigned int i=0;i<m_SpeakerCount-1;i++){
        tempSpeaker[i].setName(m_pSpeaker[i].getName());
        tempSpeaker[i].setImpedance(m_pSpeaker[i].getImpedance());
        tempSpeaker[i].setRMSPower(m_pSpeaker[i].getRMSPower());
        tempSpeaker[i].setPeakPower(m_pSpeaker[i].getPeakPower());
        tempSpeaker[i].setHPF(m_pSpeaker[i].getHPF());
    }
    delete [] m_pSpeaker;
    m_pSpeaker=tempSpeaker;
    m_pSpeaker[m_SpeakerCount-1]=cSpeaker("Unnamed Speaker",8,100,400,100);
    refreshSpeakerView();
    ui->listWidget_speakerView->setCurrentRow(m_SpeakerCount-1);
    ui->lineEdit_speakerName->setFocus();
    ui->lineEdit_speakerName->selectAll();
}


void library::on_listWidget_speakerView_currentRowChanged(int currentRow)
{
    if (currentRow>=0){
        ui->lineEdit_speakerName->setText(QString::fromStdString(m_pSpeaker[currentRow].getName()));
        ui->spinBox_speakerImp->setValue(m_pSpeaker[currentRow].getImpedance());
        ui->spinBox_speakerRMSPower->setValue(m_pSpeaker[currentRow].getRMSPower());
        ui->spinBox_speakerPeakPower->setValue(m_pSpeaker[currentRow].getPeakPower());
        ui->spinBox_speakerHPF->setValue(m_pSpeaker[currentRow].getHPF());

        ui->lineEdit_speakerName->setEnabled(true);
        //ui->spinBox_speakerImp->setEnabled(true);
        //ui->spinBox_speakerRMSPower->setEnabled(true);
        //ui->spinBox_speakerPeakPower->setEnabled(true);
        //ui->spinBox_speakerHPF->setEnabled(true);

    }else {
        ui->lineEdit_speakerName->setEnabled(false);
        //ui->spinBox_speakerImp->setEnabled(false);
        //ui->spinBox_speakerRMSPower->setEnabled(false);
        //ui->spinBox_speakerPeakPower->setEnabled(false);
        //ui->spinBox_speakerHPF->setEnabled(false);
    }

}


void library::on_pushButton_deleteSpeaker_clicked()
{
    if (getCurrentSpeakerIndex()>=0){
        m_SpeakerCount-=1;
        cSpeaker* tempSpeaker=new cSpeaker[m_SpeakerCount];
        unsigned int selectedRow=getCurrentSpeakerIndex();
        for (unsigned int i=0;i<selectedRow;i++){
            tempSpeaker[i]=m_pSpeaker[i];
        }
        for (unsigned int i=selectedRow+1;i<m_SpeakerCount+1;i++){
            tempSpeaker[i-1]=m_pSpeaker[i];
        }
        delete [] m_pSpeaker;
        m_pSpeaker=tempSpeaker;

        refreshSpeakerView();
        if ((selectedRow<1) and (m_SpeakerCount>0)){
            ui->listWidget_speakerView->setCurrentRow(0);
        }else
        {
            ui->listWidget_speakerView->setCurrentRow(selectedRow-1);
        }
    }
}


void library::on_pushButton_applySpeaker_clicked()
{
    if (getCurrentSpeakerIndex()>=0){
        speakerUnsaved =false;
        m_pSpeaker[getCurrentSpeakerIndex()].setName(ui->lineEdit_speakerName->text().toStdString());
        m_pSpeaker[getCurrentSpeakerIndex()].setImpedance(ui->spinBox_speakerImp->value());
        m_pSpeaker[getCurrentSpeakerIndex()].setRMSPower(ui->spinBox_speakerRMSPower->value());
        m_pSpeaker[getCurrentSpeakerIndex()].setPeakPower(ui->spinBox_speakerPeakPower->value());
        m_pSpeaker[getCurrentSpeakerIndex()].setHPF(ui->spinBox_speakerHPF->value());


        int selectedRow=getCurrentSpeakerIndex();
        refreshSpeakerView();
        ui->listWidget_speakerView->setCurrentRow(selectedRow);
    }

}


void library::on_lineEdit_speakerName_textEdited(const QString &arg1)
{
    speakerEdited();

}


void library::on_pushButton_dacAdd_clicked()
{
    confirmDacChanges();
    m_dacCount+=1;
    cdac* tempDac=new cdac[m_dacCount];
    for (unsigned int i=0;i<m_dacCount-1;i++){
        tempDac[i].setName(m_pDac[i].name());
        tempDac[i].setOutputLevel(m_pDac[i].outputLevel());
    }
    delete [] m_pDac;
    m_pDac=tempDac;
    m_pDac[m_dacCount-1].setName("Unnamed DAC");
    m_pDac[m_dacCount-1].setOutputLevel(0);
    refreshDacView();
    ui->listWidget_dacView->setCurrentRow(m_dacCount-1);
    ui->lineEdit_dacName->setFocus();
    ui->lineEdit_dacName->selectAll();
}


void library::on_pushButton_deleteDac_clicked()
{
    if (getCurrentDacIndex()>=0){
        m_dacCount-=1;
        cdac* tempdac=new cdac[m_dacCount];
        unsigned int selectedRow=getCurrentDacIndex();
        for (unsigned int i=0;i<selectedRow;i++){
            tempdac[i]=m_pDac[i];
        }
        for (unsigned int i=selectedRow+1;i<m_dacCount+1;i++){
            tempdac[i-1]=m_pDac[i];
        }
        delete [] m_pDac;
        m_pDac=tempdac;

        refreshDacView();
        if ((selectedRow<1) and (m_dacCount>0)){
            ui->listWidget_dacView->setCurrentRow(0);
        }else
        {
            ui->listWidget_dacView->setCurrentRow(selectedRow-1);
        }
    }
}


void library::on_pushButton_Apply_clicked()
{
    if (getCurrentDacIndex()>=0){
        dacUnsaved =false;
        m_pDac[getCurrentDacIndex()].setName(ui->lineEdit_dacName->text().toStdString());
        m_pDac[getCurrentDacIndex()].setOutputLevel(ui->spinBox_dacOutputLevel->value());


        int selectedRow=getCurrentDacIndex();
        refreshDacView();
        ui->listWidget_dacView->setCurrentRow(selectedRow);
    }
}


void library::on_listWidget_dacView_currentRowChanged(int currentRow)
{
    if (currentRow>=0){
        ui->lineEdit_dacName->setText(QString::fromStdString(m_pDac[currentRow].name()));
        ui->spinBox_dacOutputLevel->setValue(m_pDac[currentRow].outputLevel());
        ui->lineEdit_dacName->setEnabled(true);
    }else{
        ui->lineEdit_dacName->setEnabled(false);
    }
}


void library::on_lineEdit_dacName_textEdited(const QString &arg1)
{
    //dacEdited();
}



void library::on_spinBox_dacOutputLevel_editingFinished()
{
    //dacEdited();
}


void library::on_spinBox_speakerImp_editingFinished()
{
    //speakerEdited();
}


void library::on_spinBox_speakerRMSPower_editingFinished()
{
    //speakerEdited();
}


void library::on_spinBox_speakerPeakPower_editingFinished()
{
    //speakerEdited();
}


void library::on_spinBox_speakerHPF_editingFinished()
{
    //speakerEdited();
}


void library::on_doubleSpinBox_inputSensitivity_editingFinished()
{
    //ampEdited();
}

