/****************************************************************************
    Kalkulon - A programmable calculator for programmers

    This file is part of the Kalkulon GUI.

    If you find this source code useful, your are encouraged to use it in your own projects.
    Please give me credit!

    COPYRIGHT by Juergen Holetzeck 2003 - 2007
    e-mail:		contact@kalkulon.de
    homepage:	www.kalkulon.de
****************************************************************************/

#include <QtGui>

#include "OptionsDlg.h"

// static helper structure to fill combo box with color group names
static const struct Colorgroups
{
    const char * name;
    enum COLORGROUP {OP=0,
                     FUNC,
                     STRING,
                     LABEL,
                     NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7 // these must be in a row
                     }
                     group;
} colorgroups[] =
{
    {"Functions", Colorgroups::FUNC},
    {"Operators", Colorgroups::OP},
    {"Labels", Colorgroups::LABEL},
    {"Strings", Colorgroups::STRING},
    {"Numbers 1. segment", Colorgroups::NUM0},
    {"Numbers 2. segment", Colorgroups::NUM1},
    {"Numbers 3. segment", Colorgroups::NUM2},
    {"Numbers 4. segment", Colorgroups::NUM3},
    {"Numbers 5. segment", Colorgroups::NUM4},
    {"Numbers 6. segment", Colorgroups::NUM5},
    {"Numbers 7. segment", Colorgroups::NUM6},
    {"Numbers 8. segment", Colorgroups::NUM7},
};
static const size_t NUMCOLORGROUPS = sizeof(colorgroups)/sizeof(colorgroups[0]);


OptionsDlg::OptionsDlg(QWidget *parent) : QDialog(parent)
{
    setupUi(this);
    shl_ = new SyntaxHighlighter(outputWin->document());

    connect(spinBoxDec, SIGNAL(valueChanged(int)),
            shl_, SLOT(on_sameDigitsDec_changed(int)));
    connect(spinBoxHex, SIGNAL(valueChanged(int)),
            shl_, SLOT(on_sameDigitsHex_changed(int)));
    connect(spinBoxBin, SIGNAL(valueChanged(int)),
            shl_, SLOT(on_sameDigitsBin_changed(int)));
    connect(spinBoxOct, SIGNAL(valueChanged(int)),
            shl_, SLOT(on_sameDigitsOct_changed(int)));
    connect(spinBoxRed, SIGNAL(valueChanged(int)),
            this, SLOT(colorChanged()));
    connect(spinBoxGreen, SIGNAL(valueChanged(int)),
            this, SLOT(colorChanged()));
    connect(spinBoxBlue, SIGNAL(valueChanged(int)),
            this, SLOT(colorChanged()));


    QStringList colorgroupnames;
    for(size_t i=0; i<NUMCOLORGROUPS; ++i)
        colorgroupnames << colorgroups[i].name;
    comboBoxColors->addItems(colorgroupnames);

    updateValues();
}

void OptionsDlg::updateValues()
{
    spinBoxDec->setValue(shl_->settings().sameDigitsDec_);
    spinBoxHex->setValue(shl_->settings().sameDigitsHex_);
    spinBoxBin->setValue(shl_->settings().sameDigitsBin_);
    spinBoxOct->setValue(shl_->settings().sameDigitsOct_);
    outputWin->setPlainText(
        "1234567890.1234567890 + 0xabcdef01 * 0b11111100110010101111110011001010 / 0o12345670\n"
        "function(label1, label2) = sin(label1)**2 + cos(label2)**2\n"
        "stringlabel = \"this is a string\""
    );
    on_comboBoxColors_currentIndexChanged(comboBoxColors->currentIndex());
}

void OptionsDlg::setShlSettings(const SyntaxHighlighter::Settings& s)
{
    shl_->setSettings(s);
    updateValues();
}

void OptionsDlg::setFontSize(int fontsize)
{
    QFont newFont(font());
    newFont.setPointSize(fontsize);
    outputWin->setFont(newFont);
}

void OptionsDlg::on_buttonBox_clicked(QAbstractButton *button)
{
    if (buttonBox->buttonRole(button)==QDialogButtonBox::ResetRole)
    {
        switch(tabWidget->currentIndex())
        {
            case 0:
                checkBoxTrayIcon->setCheckState(Qt::Unchecked);
                break;
            case 1:
                shl_->restoreDefaults();
                updateValues();
                break;
            default:
            /* empty */;
        }
    }
}

void OptionsDlg::on_comboBoxColors_currentIndexChanged(int index)
{
    int r=0,g=0,b=0;
    int colorgroup=colorgroups[index].group;
    switch(colorgroup)
    {
        case Colorgroups::OP:
            QColor(shl_->settings().opColor_).getRgb(&r,&g,&b);
            break;
        case Colorgroups::FUNC:
            QColor(shl_->settings().funcColor_).getRgb(&r,&g,&b);
            break;
        case Colorgroups::LABEL:
            QColor(shl_->settings().labelColor_).getRgb(&r,&g,&b);
            break;
        case Colorgroups::STRING:
            QColor(shl_->settings().stringColor_).getRgb(&r,&g,&b);
            break;
        default:
            // NUMBER
            if(	Colorgroups::NUM0 <= colorgroup &&
                Colorgroups::NUM0+SyntaxHighlighter::NUM_NUMFORMATS > colorgroup
              )
            QColor(shl_->settings().numColor_[colorgroup-Colorgroups::NUM0]).getRgb(&r,&g,&b);
    }
    spinBoxRed  ->setValue(r);
    spinBoxGreen->setValue(g);
    spinBoxBlue ->setValue(b);
}

void OptionsDlg::colorChanged()
{
    QRgb rgb = 	QColor(	spinBoxRed->value(),
                        spinBoxGreen->value(),
                        spinBoxBlue->value()).rgb();

    int index = comboBoxColors->currentIndex();

    SyntaxHighlighter::Settings stmp(shl_->settings());

    int colorgroup = colorgroups[index].group;
    switch(colorgroup)
    {
        case Colorgroups::OP:
            stmp.opColor_=rgb;
            break;
        case Colorgroups::FUNC:
            stmp.funcColor_=rgb;
            break;
        case Colorgroups::LABEL:
            stmp.labelColor_=rgb;
            break;
        case Colorgroups::STRING:
            stmp.stringColor_=rgb;
            break;
        default:
            // NUMBER
            if(	Colorgroups::NUM0 <= colorgroup &&
                Colorgroups::NUM0+SyntaxHighlighter::NUM_NUMFORMATS > colorgroup
              )
            stmp.numColor_[colorgroup-Colorgroups::NUM0]=rgb;
    }
    shl_->setSettings(stmp);
}

