/***************************************************************************
                          Config.cpp  -  description
                             -------------------
    begin                : dim déc 21 2003
    copyright            : (C) 2003 by Alain Gibaud
    email                : alain.gibaud@univ-valenciennes.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "Config.h"
#include "FNU.h"
#include <kapplication.h>
#include <kconfig.h>

#include <iostream>
using namespace std ;

Config::Config()
{}


Config::~Config()
{}


// -------------------------------------------------------------- ASM group
/** No descriptions */
void Config::getAsmConfig(QString &proc, QString &hex, QString &include, QString& radix,
                          QString &warning, QString &other)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("asm") ;
    proc  = conf->readEntry( "proc", "p12c508" ) ;
    hex =  conf->readEntry( "hexfmt", "inhx32" ) ;
    include =   conf->readEntry( "include", "$(SRCPATH)" ) ;
    radix =  conf->readEntry( "radix", "dec" ) ;
    warning =   conf->readEntry( "warning", "2" ) ;
    other =  conf->readEntry("others", "" ) ;
}


/** No descriptions */
void Config::setAsmConfig(const QString &proc,const  QString &hexformat,const  QString &include,const  QString& radix,
                          const 	QString &warnlevel,const  QString &others)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("asm") ;
    conf->writeEntry("proc", proc) ;
    conf->writeEntry("hexfmt", hexformat);
    conf->writeEntry("include", include) ;
    conf->writeEntry("radix", radix) ;
    conf->writeEntry("warning", warnlevel) ;
    conf->writeEntry("others", others) ;
}


// ---------------------- port configuration (hardware group)
/** No descriptions */
//++Mirko!!
void Config::getCurrentPortConfig(QString &type, QString& port, int& vpp, int& vdd,
                                  int& clock, int& dataout, int& datain, int& drw, int& clkdelay)
//--Mirko!!
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("hardware") ;
    type = conf->readEntry("port-type", "parallel") ;
    if(type == "parallel" )
    {
        getParPortConfig(port, vpp, vdd, clock, dataout, datain, drw , clkdelay);
    }
    else if(type == "serial")  // serial port
    {
        getSerPortConfig(port, vpp, vdd, clock, dataout, datain, drw , clkdelay);
    }
    else if(type == "boot555")  // serial port
    {
        getSer555PortConfig(port, vpp, vdd, clock, dataout, datain, drw , clkdelay);
    }
}


void Config::setPortConfig(const QString &type, const QString& port, int vpp,
                           int vdd, int clock, int dataout, int datain, int drw, int clkdelay )
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("hardware") ;
    conf->writeEntry("port-type",type) ;

    conf->setGroup(type) ;
    conf->writeEntry("device",port) ;
    conf->writeEntry("vpp" , vpp ) ;
    conf->writeEntry("vdd" ,vdd ) ;
    conf->writeEntry("clock" ,clock ) ;
    conf->writeEntry("datao" , dataout ) ;
    conf->writeEntry("datai" , datain ) ;
    conf->writeEntry("drw" , drw ) ;
    conf->writeEntry("clkdelay" , clkdelay ) ;
    conf->sync() ;
}


/** No descriptions */
void Config::getParPortConfig(QString &port, int &vpp, int& vdd, int &clock,
                              int &dataout, int& datain, int&drw, int& clkdelay )
{
    KConfig *conf = kapp->config() ;

    // tait's std
    conf->setGroup("parallel") ;
    clock     = conf->readNumEntry("clock",3) ;
    datain    = conf->readNumEntry("datai", 10 ) ;
    dataout   = conf->readNumEntry("datao", 2 ) ;
    //Default RW Line not used...
    drw       = conf->readNumEntry("drw", 25 ) ;  // 25 = GND
    vdd       = conf->readNumEntry("vdd", -4 ) ;
    vpp       = conf->readNumEntry("vpp", -5 ) ;
    clkdelay  = conf->readNumEntry("clkdelay", 0 ) ;
    port      = conf->readEntry("device", "/dev/parport0" ) ;
}


void Config::getSerPortConfig(QString &port, int &vpp, int& vdd, int &clock,
                              int &dataout, int& datain, int& drw, int& clkdelay )
{
    KConfig *conf = kapp->config() ;

    // JDM
    conf->setGroup("serial") ;
    clock     = conf->readNumEntry("clock",7) ;
    datain    = conf->readNumEntry("datai", 8 ) ;
    dataout   = conf->readNumEntry("datao", 4 ) ;
    //Default RW Line not used...
    drw       = conf->readNumEntry("drw", 5 ) ; // 5 = GND
    vdd       = conf->readNumEntry("vdd", 5 ) ;
    vpp       = conf->readNumEntry("vpp", 3 ) ;
    clkdelay  = conf->readNumEntry("clkdelay", 0 ) ;
    port      = conf->readEntry("device", "/dev/ttyS0" ) ;
}

void Config::getSer555PortConfig(QString &port, int &vpp, int& vdd, int &clock,
                                 int &dataout, int& datain, int& drw, int& clkdelay )
{
    KConfig *conf = kapp->config() ;

    // JDM like
    conf->setGroup("boot555") ;
    clock     = conf->readNumEntry("clock",7) ;
    datain    = conf->readNumEntry("datai", 8 ) ;
    dataout   = conf->readNumEntry("datao", 4 ) ;
    drw       = conf->readNumEntry("drw", 5 ) ; // 5 = GND
    vdd       = conf->readNumEntry("vdd", 5 ) ;
    vpp       = conf->readNumEntry("vpp", 3 ) ;
    clkdelay  = conf->readNumEntry("clkdelay", 0 ) ;
    port      = conf->readEntry("device", "/dev/ttyUSB0" ) ;
}

/** Write informations about  known standard programming cards */
void Config::writeStdHardwares()
{
    //     int vpp, int vdd, int clock, int dataout, int datain, int drw
    setHardConfig("Tait classic","parallel", -5,-4,3,2,10,25 ,  0) ;
    setHardConfig("Tait 7405/7406","parallel", 5,4,-3,-2,-10,25 ,  0) ;
    setHardConfig("P16PRO40 classic","parallel", 5,4,-3,-2,-10,25 ,  0) ;
    setHardConfig("P16PRO40 7407","parallel", -5,-4,3,2,10,25,  0 ) ;
    setHardConfig("P16PRO40-VPP40 classic","parallel", 6,4,-3,-2,-10,25 ,  0) ;
    setHardConfig("P16PRO40-VPP40 7407","parallel", -6,-4,3,2,10,25 ,  0) ;
    setHardConfig("EPIC+ (You must disconnect 7407 pin 2)","parallel", -5,-4,3,2,10,25,  0 ) ;


    setHardConfig("JDM classic","serial", 3,5,7,4,8,5,  0 ) ;
    setHardConfig("JDM classic (delay 10)","serial", 3,5,7,4,8,5,  10 ) ;
    setHardConfig("JDM classic (delay 20)","serial", 3,5,7,4,8,5,  20 ) ;
    setHardConfig("PIC Elmer","serial", -3,5,-7,-4,-8,5 ,  0) ;
    setHardConfig("Velleman K8048","serial", -3,5,-7,-4,-8,5 ,  0) ;
    setHardConfig("BAJ's boot 555","boot555", 3,5,7,4,8,5,  0 ) ;

    //++Mirko!!
    //Added by Mirko Panciri 10/03/2004...
    //Visit http://www.pic-tools.com
    //I have tested only the "Asix Piccolo" version...
    //I think the lines is the same of "Asix Piccolo Grande"...
    //Who have "Asix Piccolo Grande" contact panciom@libero.it for info / result of test!!!
    setHardConfig("Asix Piccolo","parallel",-6,-7,-5,-3,-10,-2,  0) ;
    setHardConfig("Asix Piccolo Grande","parallel",-6,-7,-5,-3,-10,-2,  0) ;
    //--Mirko!!
    setHardConfig("Propic2 Vpp-1","parallel",-5,-4,3,2,10,25,  0) ;
    setHardConfig("Propic2 Vpp-2","parallel",-6,-4,3,2,10,25,  0) ;
    setHardConfig("Propic2 Vpp-3","parallel",-7,-4,3,2,10,25,  0) ;
    setHardConfig("Myke's EL Cheapo","parallel",16, 25, -1,-17,13,25,  0) ;
    setHardConfig("EL Cheapo classic (not tested)","parallel",16, 25, 1,17,-13,25,  0) ;
    setHardConfig("Monty-Robot programmer","parallel", -5,4,2,3,10,25,  0 ) ;
    setHardConfig("HOODMICRO (k9spud.com/hoodmicro/)","serial", 4,5,7,3,8,5,  0 ) ;

}


//++Mirko!!
void Config::setHardConfig(const QString& name, const QString &type, int vpp,
                           int vdd, int clock, int dataout, int datain, int drw, int clkdelay)
//--Mirko!!
{
    KConfig *conf = kapp->config() ;
    QStringList h =  Config::getStdHardwares() ;
    if( h.findIndex(name) == -1)
    {
        conf->setGroup("hardware") ;
        conf->writeEntry("std-programmers", h+=name) ;
    }
    conf->setGroup("hardware-"+name) ;
    conf->writeEntry("vpp" , vpp ) ;
    conf->writeEntry("vdd" ,vdd ) ;
    conf->writeEntry("clock" ,clock ) ;
    conf->writeEntry("datao" , dataout ) ;
    conf->writeEntry("datai" , datain ) ;
    conf->writeEntry("port-type" , type ) ;
    //++Mirko!!
    conf->writeEntry("drw" , drw ) ;
    //--Mirko!!
    conf->writeEntry("clkdelay" , clkdelay ) ;
}


/** Return the list of std known programmers */
QStringList Config::getStdHardwares()
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("hardware") ;
    return conf->readListEntry( "std-programmers") ;
}


/** Read the pin configuration for the hardware "name"
*/
void Config::getHardConfig(const QString& name, QString &type, int& vpp, int& vdd,
                           int& clock, int& dataout, int& datain, int& drw, int& clkdelay)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("hardware-"+name) ;

    // returned values are defaulted to Tait if the specified hardware does not exist
    vpp = conf->readNumEntry("vpp", -5 ) ;
    vdd = conf->readNumEntry("vdd", -4  ) ;
    clock = conf->readNumEntry("clock", 3 ) ;
    dataout = conf->readNumEntry("datao", 2  ) ;
    drw = conf->readNumEntry("drw", 25  ) ;
    datain = conf->readNumEntry("datai", 10 ) ;
    type = conf->readEntry("port-type","parallel" ) ;
    clkdelay =  conf->readNumEntry("clkdelay", 0 ) ;
}

/* -------------- end of port configuration stuff */

/** No descriptions */
void Config::getDAsmConfig(QString& proc, bool& shortlist, QString& other)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("dasm") ;
    proc  = conf->readEntry( "proc", "p12c508" ) ;
    shortlist =  conf->readBoolEntry( "shortlist", true ) ;
    other =  conf->readEntry("others", "" ) ;
}
void Config::setDAsmConfig(const QString& proc, bool shortlist, const QString& other)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("dasm") ;
    conf->writeEntry("proc", proc) ;
    conf->writeEntry("shortlist", shortlist ) ;
    conf->writeEntry("others", other) ;
    conf->sync() ;
}
/** No descriptions */
void Config::getGlobal(QString &version)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    version  = conf->readEntry( "version", "<Unknown>" ) ;
}


/** No descriptions */
void Config::setGlobal(const QString& version)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    conf->writeEntry("version", version) ;
    conf->sync() ;
}
/** Saves the currently opened project and files  names
   */
void Config::setOpened(const QString& project, const QStringList& files)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("opened-files") ;
    conf->writePathEntry("project", project) ;
    //   Only available since KDE 3.3
    // f->writePathEntry("files", files) ;
    // The following code emulates the write path list functionnality
    // under older versions of KDE
    QStringList::const_iterator p ;
    int i ;
    QString f="file%1" ;

    for(p=files.begin(), i=0 ; p != files.end() ; ++p,++i)
    {
        conf->writePathEntry(f.arg(i), *p) ;
    }
    conf->writePathEntry(f.arg(i), QString("")) ;  // empty entry  == end of file list
    conf->sync() ;


}
/** Reads the previously opened project and files names for restauration purpose */
void Config::getOpened(QString& project, QStringList& files)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("opened-files") ;
    project = conf->readPathEntry("project", "") ;

    files.clear() ;
    QString file, name = "file%1" ;
    int i ;
    for( i=0 ;  (file = conf->readPathEntry(name.arg(i),"") ) != "" ; ++i)
        files += file ;
}
/** get current programmer name  */
void Config::setCurrentProgrammer(const QString &name)
{

    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    conf->writeEntry("programmer-engine", name ) ;
}
/** set current version  */
void Config::getCurrentProgrammer(QString& name)
{

    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    name = conf->readEntry("programmer-engine", "Builtin" ) ;
}
/** 	get current tool path for tool
*/
void Config::getToolPath(const QString& toolname, QString& path)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("xtool-" + toolname) ;

    path = conf->readEntry("path","" ) ;
}
/**
	set tool path for toolname
*/
void Config::setToolPath(const QString& toolname, const QString& path )
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("xtool-" + toolname) ;
    conf->writeEntry("path", path ) ;
}

/**
	create a tool entry, try to locate executable
	but keep old location if already defined
*/
void Config::createToolEntry(const QString& toolname, const QString& info, const QString& URL, bool mand)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    QStringList toollist = conf->readListEntry("xtools" ) ;
    if( toollist.findIndex(toolname) == -1)
    {
        // does not exist
        toollist += toolname ;
        conf->writeEntry("xtools" , toollist) ;
    }

    conf->setGroup("xtool-" + toolname) ;
    conf->writeEntry("info", info) ;
    conf->writeEntry("URL", URL) ;
    conf->writeEntry("mandatory", mand) ;

    // try to locate tool, if path does not exist
    QString path = conf->readEntry("path", "" ) ;
    if( path == "" && FNU::appFound( toolname, path))
        conf->writeEntry("path", path) ;
}
/** get a tool entry */
void Config::getToolEntry(const QString& toolname, QString& path,  QString& info,  QString& URL, bool& mand)
{
    path = info = URL = "" ;
    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    QStringList toollist = conf->readListEntry("xtools" ) ;
    if( toollist.findIndex(toolname) == -1)
        return ; // tool does not exist
    conf->setGroup("xtool-" + toolname) ;
    path = conf->readEntry("path","" ) ;
    info = conf->readEntry("info","" ) ;
    URL = conf->readEntry("URL","" ) ;
    mand = conf->readBoolEntry("mandatory",false ) ;
}

void Config::getToolNames(QStringList& namelist)
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    namelist = conf->readListEntry("xtools" ) ;
}
void Config::removeToolList()
{
    KConfig *conf = kapp->config() ;
    conf->setGroup("global-settings") ;
    QStringList toollist  ;
    conf->writeEntry("xtools" , toollist) ;
}
