#include "AsmConfigWidget.h"
#include <stdio.h>
#include <qhbox.h>
#include <qvbox.h>
#include <qstringlist.h>
#include <qcombobox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
#include <qlayout.h>
#include <klocale.h>
#include <kiconloader.h>
#include <qtooltip.h>
#include <qcheckbox.h>
#include <kapplication.h>

#include "PicFactory.hh"
#include "Config.h"
#include "PikMain.h"
#include "Project.h"


#include <iostream>
using namespace std ;

AsmConfigWidget::AsmConfigWidget() :
        ConfigWidget(0)
{
    QString p,h,i,r,w,o ;
    QString dp, dother ;
    bool ds ;
    int  k;
    
    KApplication *ka = KApplication::kApplication() ;
    main_widget = dynamic_cast<PikMain *>(ka->mainWidget()) ;


    QStringList procs =  main_widget->getProcList() ;
    QStringList hfmt ;
    (((hfmt += "inhx8m") += "inhx8s") += "inhx16") += "inhx32" ;
    QStringList rad ;
    (rad += "dec") += "hex" ;
    QStringList warn ;
    ((warn +="0") += "1") += "2" ;

    QVBox  *central = new QVBox(this) ;
    central->setSpacing(8) ;
    central->setFrameStyle( QFrame::Panel | QFrame::Sunken );
    central->setLineWidth( 2 );
    central->setMargin(8) ;

    // disable asm configurator in project mode
    if( main_widget && main_widget->projectWid()->getProject() )
    {

        configurator_valid = false ;
        new QLabel(i18n("<b>A project is currently open</b><br>"
                        "Please use project configurator (<i>project->edit project</i>) for project-specific "
                        "assembler configuration."), central) ;
    }
    else
    {
        configurator_valid = true ;

        // get config from config file
        Config::getAsmConfig(p,h,i,r,w,o) ;

        QGroupBox *asmbox = new QGroupBox(2, Qt::Horizontal, i18n("Assembler") ,  central ) ;

        // 1) Processor choice
        QLabel *labpr = new QLabel(asmbox) ;
        labpr->setText(i18n("Processor")) ;
        pr = new QComboBox(asmbox) ;
        pr->insertItem("*") ;     // allows to use the device specified in sourcefile
        pr->insertStringList(procs);

        ((k=procs.findIndex(p)) == -1) && ((k=procs.findIndex(p+" (P)")) == -1);
        pr->setCurrentItem(k+1) ;
        QToolTip::add(pr,i18n("PiKdev can only program processors marked with (P).\n"
                                  "For the development of new programming drivers, please see\n"
                                  "http://pikdev.free.fr, or contact the author.\n"
                                  "* means that processor is specified by PROCESSOR or LIST directive"	)) ;

        // 2) hex file format
        labpr = new QLabel(asmbox) ;
        labpr->setText(i18n("Hex file format")) ;
        ff = new QComboBox(asmbox) ;
        ff->insertItem("*") ;
        ff->insertStringList(hfmt);
        k=hfmt.findIndex(h) ;
        ff->setCurrentItem(k+1) ;
        QToolTip::add(ff,i18n("CAUTION: inhx8s format is currently not supported by the PiKdev programmer.\n"
                                  "If you need this support, please contact the author.\n"
                                  "* means that format is specified by LIST directive" )) ;

        // 3) radix
        labpr = new QLabel(asmbox) ;
        labpr->setText(i18n("Radix")) ;
        ra = new QComboBox(asmbox) ;
        QToolTip::add(ra,i18n("Choose the default radix used by gpasm to parse integer constants\n"
                                  "* means that radix is specified by LIST directive"));
        ra->insertItem("*") ;
        ra->insertStringList(rad);
        k=rad.findIndex(r) ;
        ra->setCurrentItem(k+1) ;


        // 4) Warning level
        labpr = new QLabel(asmbox) ;
        labpr->setText(i18n("Warning level")) ;
        wa = new QComboBox(asmbox) ;
        wa->insertItem("*") ;
        wa->insertStringList(warn);
        k=warn.findIndex(w) ;
        wa->setCurrentItem(k+1) ;
        QToolTip::add(wa,i18n("For cleaner code, always prefer warning level 0.\n"
                                  "* means that warning level is specified by LIST directive")) ;


        // 5) Include Directories
        labpr = new QLabel(asmbox) ;
        labpr->setText(i18n("Include directories")) ;
        id = new QLineEdit(asmbox) ;
        id->setText(i) ;
        QToolTip::add(id,i18n("By using the pseudovariable $(SRCPATH), you can specify an include directory\n"
                                  "relative to the source file directory:\n"
                                  "ie: compiling /home/alain/bar/x.asm with the include directory set to $(SRCPATH)/foo\n"
                                  "will set the gpasm include directory to /home/alain/bar/foo"	)) ;

        // 6) other option
        labpr = new QLabel(asmbox) ;
        labpr->setText(i18n("Other options")) ;
        oo = new QLineEdit(asmbox) ;
        oo->setText(o) ;
        QToolTip::add(oo,i18n("This item allows you to manually specify a gpasm \"exotic\" option.\n"
                                  "The $(SRCPATH) pseudo variable if supported in this item as it is "
                                  "in the \"Include Directories\" one.")) ;
        asmbox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed) ;
    }
    // END of assembler groupbox




    // gpdasm group box
    QStringList dprocs =  main_widget->getDProcList() ;
    Config::getDAsmConfig(dp,ds,dother) ;

    QGroupBox *dasmbox = new QGroupBox(2, Qt::Horizontal, i18n("Disassembler") ,  central ) ;
    // A)  processor list
    QLabel *dlabpr = new QLabel(dasmbox) ;
    dlabpr->setText(i18n("Processor")) ;
    dpr = new QComboBox(dasmbox) ;
    dpr->insertStringList(dprocs);
    k=dprocs.findIndex(dp) ; // -1 if not found
    if( k == -1 ) k = 0 ;
    dpr->setCurrentItem(k) ;
    QToolTip::add(dpr,i18n("Choose here the target processor"	)) ;

    // B) short option
    (new QLabel(dasmbox))->setText(i18n("Plain source code")) ;
    dshort = new QCheckBox( dasmbox ) ;
    dshort->setChecked(ds) ;
    QToolTip::add(dshort,i18n("Output a source file reassemblable by gpasm"	)) ;

    // C) Custom options
    (new QLabel(dasmbox))->setText(i18n("Other options")) ;
    doo = new QLineEdit(dasmbox) ;
    doo->setText(dother) ;
    QToolTip::add(doo,i18n("This item allows you to manually specify a gpdasm \"exotic\" option.")) ;

    dasmbox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed) ;

    // END of gpdasm configuration

    show() ;
}
void  AsmConfigWidget::doApply()
{

    // update asm config if not in project mode
    if(  configurator_valid )
    {
        // remove the (P) suffix
        QString proc(pr->currentText()) ;
        if( proc.right(4) == " (P)") proc.remove(proc.length()-4, 4 ) ;
        Config::setAsmConfig(proc,
                             ff->currentText(),
                             id->text(),
                             ra->currentText(),
                             wa->currentText(),
                             oo->text())   ;
    }
    Config::setDAsmConfig(dpr->currentText(),
                          dshort->isChecked(),
                          doo->text() ) ;


}

QString AsmConfigWidget::configName()
{
    return i18n("Assembler") ;
}
QString AsmConfigWidget::configTitle()
{
    return i18n("Assembler configuration") ;
}
/** No descriptions */
QPixmap AsmConfigWidget::icon()
{
    KIconLoader loader;
    return loader.loadIcon("pikdev_config_asm", KIcon::Toolbar, KIcon::SizeMedium) ;
}
