// $Id: lprofmain.cpp,v 1.187 2008/03/08 22:31:11 hvengel Exp $
//  
//  Lttle cms Profiler
//  Copyright (C) 1998-2001 Marti Maria
// Copyright (C) 2005 - 2007 Hal Engel
//
// THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
// INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
// LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
//
// 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.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Version 1.11

#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
#define __WIN32__
#endif

#include <profileparms.h>
#include <profilechecker.h>
#include <qtlcmswidgets.h>
//Added by qt3to4:
#include <Q3PtrList>
#include "lprofmain.h"
#include "lprofmain-priv.h"
#include "lcmsprf.h"

#include <string.h>
#include <stdlib.h>

#include <qstringlist.h>
#include <q3buttongroup.h>
#include <qlayout.h>
#include <qradiobutton.h>
#include <qcheckbox.h>
#include <q3groupbox.h>
#include <qpushbutton.h>
#include <qspinbox.h>
#include <qcombobox.h>
#include <qlabel.h>
#include <qslider.h>
#include <q3filedialog.h>
#include <q3multilineedit.h>
#include <qtabwidget.h>
#include <q3textview.h>
#include <q3progressbar.h>
#include <qdir.h>
#include <q3table.h>
#include <qtooltip.h>
#include <qfileinfo.h>

#include <qvariant.h>
#include <qpixmap.h>
#include <q3mainwindow.h>
#include <q3filedialog.h>
#include <qcombobox.h>
#include <qtabwidget.h>
#include <q3canvas.h>
#include <qimage.h>
#include <qpainter.h>
#include <q3multilineedit.h>
#include <q3textstream.h>
#include <qapplication.h>
#include <qspinbox.h>
#include <qstatusbar.h>
#include <qmessagebox.h>
#include <qradiobutton.h>
#include <qassistantclient.h>
#include <qsettings.h>
#include <qtranslator.h>
#include <qthread.h>

#include <qapplication.h>
#include <q3textbrowser.h>
#include <qlineedit.h>
#include <qlist.h>
#include <qsettings.h>
#include <qcolor.h>
#include <qtextcodec.h>
#include <q3listview.h>
#include <qfileinfo.h>
#include <qvalidator.h>
#include <qregexp.h>
#include <QTranslator>

#include "ui_lprofmainbase.h"

#include "vigra/imageiterator.hxx"
#include "vigra/rgbvalue.hxx"
#include "vigra/accessor.hxx"
#include "vigra/impex.hxx"
#include "vigra/stdimage.hxx"
#include "vigra/inspectimage.hxx"

// ArgyllCMS instrument support stuff

#define DATA_TYPES_ONLY
extern "C"
{
#include "xspect.h"
#include "config.h"
#include "icoms.h"
#include "inst.h"
#include "icc.h"
#include "insttypes.h"
#include "ioerrorhandler.h"
}


#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
#define __WIN32__
#endif

QSettings* lprofSettings;

void populatePortArray()
{
    icoms *coms;
    coms = new_icoms();
    QString /* instName, */ port, temp;
    int start, end;
    int position, j=0, k=0;
    serialInsts tempInst;

    sys.hdr.validPorts = 0;
    if (setjmp(ioErrorJumpBuffer))
    {
        // There was a problem in the call to init_coms below
        // It was trapped and we need to bypass the call
        // after issuing an error message fo the user.
        QString message;
        message = QString::fromLocal8Bit(getErrorMessage()); 
        QMessageBox mb( QTranslator::tr("Problem Getting List of Measurement Devices."),
                        message + QTranslator::tr("This error indicates some type of problem with accessing the devices or the Serial or USB ports on this machine.  A likely cause is not having access rights to the device.   Check your permissions to make sure you have USB, serial port access and access rights to these device."),
                                QMessageBox::Critical,
                                QMessageBox::Ok | QMessageBox::Default,
                                Qt::NoButton,  Qt::NoButton);

        mb.exec();
        return;
    }
    coms -> paths = coms -> get_paths(coms);
    if (coms -> paths !=  NULL)
    {
        // allocate the array memory
        for (position=0; position < coms -> npaths; position++)
        {
            if (coms -> paths[position]-> dev == NULL)
            {   // not USB device
                sys.hdr.validPorts++;
            }
        }
        if (sys.hdr.instArray)
            delete[] sys.hdr.instArray;
        sys.hdr.instArray = new serialInsts[sys.hdr.validPorts];
        
        // Now get port info
        // sys.hdr.validInst = lprofSettings->readNumEntry( "/LPROF/numbers/instCount", 0);
        // qDebug("lprofMain::populatePortArray() instCount = %i", sys.hdr.validInst);
        
        
        for (position=0; position < coms -> npaths; position++)
        {
            
            if (coms -> paths[position]-> dev == NULL)
            {   // not USB device
                
                temp = QString::fromLocal8Bit(coms -> paths[position]->path);
                start = temp.find(QChar::fromAscii('('), 0, TRUE) + 1;
                end = temp.find(QChar::fromAscii(')'), 0, TRUE);
                port = temp.mid(0, start -1);
                
                strcpy(sys.hdr.instArray[k].port, port.ascii());
                sys.hdr.instArray[k].pos = position;
                sys.hdr.instArray[k].inst = instUnknown;

                //check port to see if it has an allready installed device
                for (j=0; j < sys.hdr.validPorts; j++)
                {
                    temp.sprintf("/LPROF/serial_instruments/port%i", j);
                    strcpy(tempInst.port, lprofSettings->readEntry(temp, QString::fromLocal8Bit("")).toLocal8Bit());
                    if (QString::fromLocal8Bit(sys.hdr.instArray[k].port) ==
                        QString::fromLocal8Bit(tempInst.port))
                    {
                        sys.hdr.instArray[k].inst = instUnknown;
                        temp.sprintf("/LPROF/serial_instruments/instType%i", j);
                        sys.hdr.instArray[k].inst = instType (lprofSettings->readNumEntry(temp, instUnknown));
                    }
                }
                k++;
            }
        }
    }
    else
        qDebug("Something wrong with call to coms -> get_paths(coms)");

    // updateInstSettings();
}

void CheckType(instCapClass instCap, instData &instD)
{
    if (instD.Inst != instUnknown)
    {
        if (instCap == emission)
        {
            if (instD.Inst == instDTP92      ||
                instD.Inst == instDTP94       ||
                instD.Inst == instSpectrolino ||
                instD.Inst == instI1Display   ||
                instD.Inst == instI1Pro       ||
                instD.Inst == instHCFR        ||
                instD.Inst == instSpyder2     ||
                instD.Inst == instHuey        ||
                instD.Inst ==  instSpectrocam)
            {
                instD.name = instD.port + QString::fromLocal8Bit(" ") + QString::fromLocal8Bit(inst_name(instD.Inst));
            }
            else 
            {
                instD.name = instD.port + QString::fromLocal8Bit(" ") + QString::fromLocal8Bit(inst_name(instD.Inst)) + QTranslator::tr(" - Wrong type");
                instD.deviceFlag = wrongType;
            }
        }
        else if (instCap == reflective)
        { 
            if (instD.Inst == instDTP20        ||
                instD.Inst == instDTP22         ||
                instD.Inst == instDTP41         ||
                instD.Inst == instDTP51         ||
                instD.Inst == instSpectrolino   ||
                instD.Inst == instSpectroScan   ||
                instD.Inst == instSpectroScanT  ||
                instD.Inst == instSpectrocam    ||
                instD.Inst ==  instI1Pro)
            {
                instD.name = instD.port + QString::fromLocal8Bit(" ") + QString::fromLocal8Bit(inst_name(instD.Inst));
            }
            else
            {
                instD.name = instD.port + QString::fromLocal8Bit(" ") + QString::fromLocal8Bit(inst_name(instD.Inst)) + QTranslator::tr(" - Wrong type");
                instD.deviceFlag = wrongType;
            }
        }
        else if (instCap == all)
            instD.name = instD.port + QString::fromLocal8Bit(" ") + QString::fromLocal8Bit(inst_name(instD.Inst));
    }
    else
    {
        instD.name = instD.port + QTranslator::tr(" - Not installed");
        instD.deviceFlag = noDevice;
    } 
    if (instD.deviceFlag == missingFirmware)
        instD.name = instD.name + QTranslator::tr(" Firmware missing! Device disabled."); 
}

void fillListedInsts(instData (&instlist)[instArraySize], bool &spyd2FirmwareOK, bool &instListChanged, instCapClass instCap)
{
    // qDebug("fillListedInsts start");
    icoms *coms;
    coms = new_icoms();
    QString instName, port, temp, exec;
    int start, end, i, count;
    int number;

    sys.hdr.validInst = lprofSettings->readNumEntry( QString::fromLocal8Bit("/LPROF/numbers/instCount"), 0);
    populatePortArray();
    spyd2FirmwareOK = TRUE;
    for (int k=0; k<instArraySize; k++)
        instlist[k].listSize = 0;
    if (setjmp(ioErrorJumpBuffer))
    {
        // There was a problem in the call to init_coms below
        // It was trapped and we need to bypass the call
        // after issuing an error message fo the user.
        QString message;
        message = QString::fromLocal8Bit( getErrorMessage()); 
        QMessageBox mb( QTranslator::tr("Problem Getting List of Measurement Devices."),
                        message + QTranslator::tr("This error indicates some type of problem with accessing the devices or the Serial or USB ports on this machine.  A likely cause is not having access rights to the device.   Check your permissions to make sure you have USB, serial port access and access rights to these device."),
                                QMessageBox::Critical,
                                QMessageBox::Ok | QMessageBox::Default,
                                Qt::NoButton,  Qt::NoButton);

        mb.exec();
        return;
    }
    coms -> paths = coms -> get_paths(coms);    
    if (coms -> paths !=  NULL)
    {
        number=coms -> npaths;
        instListChanged = TRUE;
        for (int k=0; k<instArraySize; k++)
            instlist[k].listSize = number;
        for (i=0; i < number; i++)
        {
            temp = QString::fromLocal8Bit(coms -> paths[i]->path);
            start = temp.find(QString::fromLocal8Bit("("), 0, TRUE) + 1;
            end = temp.find(QString::fromLocal8Bit(")"), 0, TRUE);
            instName = temp.mid(start, end - start);
            port = temp.mid(0, start -1);
            instlist[i].deviceFlag = OK;
            if ((coms -> paths[i]-> dev != NULL) || (coms -> paths[i]-> hev != NULL))
            {   // USB device
                // qDebug(port + " " + instName);
                instlist[i].port = port;
                instlist[i].position = i;
                instlist[i].dupType = FALSE;
                instlist[i].Inst = coms -> paths[i]-> itype;
                if (instName == QString::fromLocal8Bit("ColorVision Spyder2"))
                {
                    // check Spyder 2 to make sure the firmware is available
                    if (!checkSpyd2OK())
                    {
                        // Device will not work.
                        spyd2FirmwareOK = FALSE;
                        instlist[i].deviceFlag = missingFirmware;
                    }
                }
                CheckType(instCap, instlist[i]);
            }
            else
            {   // serial device get name and type if installed
                instlist[i].Inst = instUnknown;
                instlist[i].position = i;
                instlist[i].dupType = FALSE;
                count = sys.hdr.validPorts;
                instlist[i].deviceFlag = noDevice;
                for (int j=0; j < count; j++)
                {
                    if (QString::fromLocal8Bit(sys.hdr.instArray[j].port) == port)
                    { 
                        instlist[i].Inst = sys.hdr.instArray[j].inst;
                        instlist[i].port = port;
                        instlist[i].deviceFlag = OK;
                        CheckType(instCap, instlist[i]);
                        break;
                    }
                }
            }
        }
        for (int j=0;j<i;j++)
        {
            for (int k=0; k<i; k++)
            {
                if (instlist[k].Inst == instlist[j].Inst)
                {
                    if (k != j)
                    {
                        instlist[k].dupType = TRUE;
                        instlist[j].dupType = TRUE;
                    }
                }
            }
        }
    }
    coms->del(coms);
    // qDebug("fillListedInsts done");
}

// To use this mapping add 1 to instType

static const int mapInst2Combo[14] =
{
    9,  // instUnknown
    0,   // instDTP20 not serial
    1,   // instDTP22},
    2,   // instDTP41},
    3,   // instDTP51},
    4,   // instDTP92},
    9,  // instDTP94 not serial
    5,   // instSpectrolino
    6,   // instSpectroScan
    7,   // instSpectroScanT
    8,   // instSpectrocam
    9,  // instI1Display not serial
    9,  // instI1Pro not serial
    9   // instHCFR not serial
};

static const instType mapCombo2Inst[10] =
{
    instDTP20,         // instDTP20
    instDTP22,         // instDTP22},
    instDTP41,         // instDTP41},
    instDTP51,         // instDTP51},
    instDTP92,         // instDTP92},
    instSpectrolino,   // instSpectrolino
    instSpectroScan,   // instSpectroScan
    instSpectroScanT,  // instSpectroScanT
    instSpectrocam,    // instSpectrocam
    instUnknown        // instUnknown
};


void lprofMain::slotEnablecomboBoxDevice()
{
    ui->comboBoxDevice -> setEnabled(TRUE);
}

bool validateIntrument(QString newPort, instType &insttype)
{    
    inst *it;
    int position=0, j=0;
    inst_code rv;
    instType itype;
    bool found = FALSE, notOK = FALSE, OK = FALSE;
        
    sys.hdr.validInst = lprofSettings->readNumEntry( QString::fromLocal8Bit("/LPROF/numbers/instCount"), 0);
    populatePortArray();

    // find position of port
    for (j=0; j < sys.hdr.validPorts; j++)
    { 
        if (QString::fromLocal8Bit(sys.hdr.instArray[j].port) == newPort)
        {
            position = sys.hdr.instArray[j].pos;
            found = TRUE;
            break;
        }
    }
    // now test it to make sure it is a valid device
    // and that it is the one the user specified
    if (found)
    {
        if (setjmp(ioErrorJumpBuffer))
        {
            // There was a problem in the calls below
            // It was trapped and we need to bypass the call
            if (it)
                it -> del(it);
            return notOK;
        }
        it = new_inst(position + 1, insttype, 0, 0);
        if (it != NULL)
        {
            // check to see if device type is available at this point
            // this will work for most serial devices and fail for DTP92s
            // For those that work here this will be faster for others
            // there needs to be additional steps to setup the port and
            // initialize the device to be able to get the device type
            itype = insttype;
            itype = it -> get_itype(it);
            if (itype == insttype)
            {
                OK = TRUE;
            }
            else if (itype == instUnknown)
            {
                // This appears to be needed only for the DTP92 since the 
                // same code also handles the DTP94 and the new_inst(...)
                // code sets the inst_type to instUnkown since it does 
                // not know which device is being used at that point
                // All other serial devices are correctly setup after the 
                // call to new_inst()
                
                // Establish communications and initialize the device
                if ((rv = it->init_coms(it, position + 1, baud_2400, fc_nc, 15.0)) == inst_ok)
                {
                    if (it->init_inst(it) == inst_ok)
                    {
                        OK =  it -> get_itype(it) == insttype;
                    }
                }
                else
                {
                    qDebug("Establishing communications with instrument failed with message '%s' (%s)",
                        it->inst_interp_error(it, rv), it->interp_error(it, rv));
                }
            }
            it->del(it);
        }
    }

    return OK;
}

void lprofMain::slotUpdateInst()
{
    QString charInstType;
    int index;
    bool OK;
    instType itype;

    Q3ListViewItem *item = ui->listViewPortsInsts -> selectedItem ();
    itype = mapCombo2Inst[ui->comboBoxDevice -> currentItem()];
    
    if (validateIntrument(item -> text(1), itype))
    {
        item -> setText(2, ui->comboBoxDevice -> currentText());
        item -> setText(3, tr("Device verified"));
        charInstType.sprintf("%i", itype);
        item -> setText(4, charInstType);
        index = item -> text(0).toInt(&OK) - 1;
    
        if (OK)
        {
            sys.hdr.instArray[index].inst = itype;
            strcpy(sys.hdr.instArray[index].port, item -> text(1).toLocal8Bit());
        }
        else
            qDebug("problem with conversion of index in slotUpdateInst");
    
        // get number of installed devices
        sys.hdr.validInst = 0;
        for (int j=0; j < sys.hdr.validPorts; j++)
        {
            if (sys.hdr.instArray[j].inst != instUnknown)
                sys.hdr.validInst++;
        }
        updateInstSettings();
    }
    else
    {
        item -> setText(3, tr("Device failed verification."));
        QMessageBox::critical(this, QTranslator::tr("Error installing measurement device."), 
                              QTranslator::tr("The measurement device was not found.  It either it does not exist or does not match the device you selected.  Please correct this condition and retry the operation")); 
    }
}

void lprofMain::updateInstSettings()
{
    QString temp;
    
    // qDebug("instCount = %i", sys.hdr.validInst);

    lprofSettings->writeEntry( QString::fromLocal8Bit("/LPROF/numbers/instCount"), sys.hdr.validInst);

    // qDebug("save settings for serial devices and ports");
    for (int j=0; j < sys.hdr.validPorts; j++)
    {
        temp.sprintf("/LPROF/serial_instruments/port%i", j);
        lprofSettings->writeEntry(temp, sys.hdr.instArray[j].port);
        temp.sprintf("/LPROF/serial_instruments/instType%i", j);
        lprofSettings->writeEntry(temp, sys.hdr.instArray[j].inst);
    }
}

void lprofMain::populatePortandInstListView()
{
    sys.hdr.validInst = lprofSettings->readNumEntry( QString::fromLocal8Bit("/LPROF/numbers/instCount"), 0);
    populatePortArray();
    QString portnum, insttype;
    QString device, status;

    ui->listViewPortsInsts -> setSelectionMode(Q3ListView::Single);
    ui->listViewPortsInsts -> setAllColumnsShowFocus(TRUE);
    ui->listViewPortsInsts -> setColumnWidthMode (0, Q3ListView::Manual);
    ui->listViewPortsInsts -> setColumnWidth (0, 0);
    ui->listViewPortsInsts -> setColumnWidthMode (1, Q3ListView::Maximum );
    ui->listViewPortsInsts -> setColumnWidth (1, 200);
    ui->listViewPortsInsts -> setColumnWidthMode (2, Q3ListView::Maximum );
    ui->listViewPortsInsts -> setColumnWidth (2, 200);
    ui->listViewPortsInsts -> setColumnWidthMode (3, Q3ListView::Maximum );
    ui->listViewPortsInsts -> setColumnWidth (3, 350);
    ui->listViewPortsInsts -> setColumnWidthMode (4, Q3ListView::Manual);
    ui->listViewPortsInsts -> setColumnWidth (4, 0);

    for (int i=0; i < sys.hdr.validPorts; i++)
    {
        portnum.sprintf("%i", i + 1);
        insttype.sprintf("%i", sys.hdr.instArray[i].inst);
        ui->comboBoxDevice -> setCurrentItem(mapInst2Combo[sys.hdr.instArray[i].inst + 1]);
        if (sys.hdr.instArray[i].inst != instUnknown)
        {
            if (validateIntrument(QString::fromLocal8Bit(sys.hdr.instArray[i].port), sys.hdr.instArray[i].inst))
                status = tr("Device verified.");
            else
                status = tr("Device failed verification.");
        }
        else
            status = tr("No device installed.");
        (void) new Q3ListViewItem(ui->listViewPortsInsts, portnum,
         QString::fromLocal8Bit(sys.hdr.instArray[i].port),
         ui->comboBoxDevice -> currentText(), status, insttype);
    }
}
void add_target(target_template &in)
{
    // qDebug("add_target");
    BOOL found;
    target_template* item;
    QString temp;

    // qDebug(temp.sprintf("before add number of items in target list = %i", targetList->count()));

    found = FALSE;
    // look to see if this target is already installed.
    // if it is update the template file
    if (targetList->count() > 0)  // taragetList has items so check it to see if this is a duplicate
    {   
        // qDebug("target list not empty");
        for (uint i = 0;  i < targetList->count();  i++)
        {
            // qDebug("targetList->at(i)->targetFile = " + targetList->at(i)->targetFile + " in.templateFile = " + in.templateFile);  
              if (targetList->at(i)->targetFile == in.targetFile)
              {
                   targetList->at(i)->templateFile = in.templateFile;
                   found=TRUE;
                   i = targetList->count();
              }
        }
    }
    if (!found) // not a dupicate target file so create new entry
    {
        // qDebug("target not found");
        item = new target_template;
        item->targetFile = in.targetFile;
        item->templateFile = in.templateFile;
        // place new target ref file in list of target ref files
        targetList->insert(targetList->count(), item);
    }
    // qDebug(temp.sprintf("after add number of items in target list = %i", targetList->count()));
}

int ConsolePrintf(const char *frm, int parms, char typ, ...)
{

    QString Buffer, temp;
    va_list args;
    
    /* TRANSLATOR Text displayed in the messages widget */
    QString Warn1 = lprofMain::tr("*** WARNING: Inconsistences found, profile may be wrong. Check the target!"),
    /* TRANSLATOR Text displayed in the messages widget */
    Load1 = lprofMain::tr("Loading sheets..."),
    /* TRANSLATOR Text displayed in the messages widget */
    RefSh1 = lprofMain::tr("Reference sheet: %1"),
    /* TRANSLATOR Text displayed in the messages widget */
    MeasSh = lprofMain::tr("Measurement sheet: %1"),
    /* TRANSLATOR Text displayed in the messages widget */
    PrimSh = lprofMain::tr("Primaries: R:%1, %2  G:%3, %4  B:%5, %6"),
    /* TRANSLATOR Text displayed in the messages widget */
    PrimSh2 = lprofMain::tr("Primaries (x-y): [Red: %1, %2] [Green: %3, %4] [Blue: %5, %6]"),
    /* TRANSLATOR Text displayed in the messages widget */
    ghullSh = lprofMain::tr("Gamut hull: %1 inside, %2 outside, %3 on boundaries"),
    /* TRANSLATOR Text displayed in the messages widget */
    estgamaSh = lprofMain::tr("Estimated gamma: [Red: %1] [Green: %2] [Blue: %3]"),
    /* TRANSLATOR Text displayed in the messages widget */
    LabPCSSh = lprofMain::tr("I have chosen CIE Lab as PCS"),
    /* TRANSLATOR Text displayed in the messages widget */
    XYZPCSSh = lprofMain::tr("I have chosen CIE XYZ as PCS"),
    /* TRANSLATOR Text displayed in the messages widget */
    WPnear = lprofMain::tr("White point near %1"),
    /* TRANSLATOR Text displayed in the messages widget */
    WPunknown = lprofMain::tr("Unknown white point %1"),
    FitError1 = lprofMain::tr("Fitting error (delta E CIELAB): mean=%1, RMS=%2, 95%%=%3, median=%4, MAD=%5"),
    FirError2 = lprofMain::tr("Fitting error (delta E CIE94): mean=%1, RMS=%2, 95%%=%3, median=%4, MAD=%5"),
    selFile = lprofMain::tr("select file name"),
    workhard = lprofMain::tr("Working hard..."),
    cantProfile = lprofMain::tr("** ERROR: Unable to profile."),
    done = lprofMain::tr("Profile '%1' DONE!"),
    compRGCV = lprofMain::tr("<b>Computing Randomized General Cross Validation ...</b>"),
    estOptFactor = lprofMain::tr("Will estimate optimal smoothness factor ...</b>"),
    smoothness = lprofMain::tr("smoothness=%1 => RGCV=%2 [%3 %4 %5]"),
    RGCVestRMSdE = lprofMain::tr("<b>RGCV:</b> estimated RMS dE=%1"),
    RGCVnumParms = lprofMain::tr("<b>RGCV:</b> effective number of parameters = [%1 %2 %3]"),
    bestSmooth = lprofMain::tr("<b>Best smoothness:</b> %1"),
    RGVCatBestSm = lprofMain::tr("<b>RGCV at best smoothness:</b> %1"),
    smoothOffset = lprofMain::tr("Using smoothness offset: %1"),
    twofCV = lprofMain::tr("<b>Performing 2-fold cross validation ...</b>"),
    twofCVdE1 = lprofMain::tr("<b>2-fold CV:</b> estimated RMS dE=%1, dE94=%2"),
    twofCVdE2 = lprofMain::tr("<b>2-fold adj. CV:</b> estimated RMS dE=%1, dE94=%2"),
    l10FoldCV = lprofMain::tr("<b>Performing 10-fold cross validation ...</b>"),
    l10FoldCV1 = lprofMain::tr("10-fold CV: estimated RMS dE=%g, dE94=%g\n"),
    l10FoldCV2 = lprofMain::tr("<b>10-fold CV:</b> estimated RMS dE=%1, dE94=%2"),
    lLooCV = lprofMain::tr("<b>Performing LOO cross validation ...</b>"),
    lLooCV1 = lprofMain::tr("<b>LOO CV:</b> estimated RMS dE=%1, dE94=%2"),
    lBootstrapCV = lprofMain::tr("<b>Performing bootstrap cross validation ...</b>"),
    lBootstrapCV1 = lprofMain::tr("<b>e0 bootstrap:</b> estimated RMS dE=%1, dE94=%2"),
    lBootstrapCV2 = lprofMain::tr("<b>0.632 bootstrap:</b> estimated RMS dE=%1, dE94=%2"),
    offset = lprofMain::tr("Adding user supplied offset: %1");

    Buffer = QTranslator::tr(frm);

    va_start(args, typ);

    while ( parms > 0) {
        switch(typ)
        {
            case 's':
                Buffer = Buffer.arg(QString::fromLocal8Bit(va_arg(args, char *)));
                break;
            case 'd':
                temp.sprintf("<font color=red>%i</font>",va_arg(args, int));
                Buffer = Buffer.arg(temp);
                break;
            case 'c':
                temp.sprintf("<font color=green>%i</font>",va_arg(args, int));
                Buffer = Buffer.arg(temp);
                break;
            case 'f':
                temp.sprintf("<font color=blue>%g</font>", va_arg(args, double));
                Buffer = Buffer.arg(temp);
                break;
            case ' ':
                break;
            default:
                qDebug("type not in cases");
                break;
        }
        parms = parms - 1;
    }

    Console -> append(Buffer);
    Console -> sync();
    va_end(args);
    lprofApp -> processEvents();
    return 1;
}

int Gauger(const char * /*Label*/, int nMin, int nMax, int Pos)
{

    // qDebug("Gauger");
    if (nMin < 0 && nMax < 0)
    {
        return 1;
    }
    ProgBar -> setRange(nMin, nMax);
    ProgBar -> setValue(Pos);
    lprofApp -> processEvents();
    return 1;
}

void lprofMain::Reload()
{
    // qDebug("lprof::Reload");
    TheImage -> Reload(fn, ui->MonitorProfileSelector ->getFilename(),
                           ui->InputProfileSelector->getFilename(),
                           Canvas);
}

void lprofMain::AddTemplate()
{
    // qDebug("lprofMain::AddTemplate");
    QString Template     = ui->SelectTemplate -> getFilename();
    double  SafeFrameVal = ui->SafeFrame->value();
    if ((TheImage != NULL) && (Template != QString::null)) {

        if (TheGrid != NULL)
            delete TheGrid;

       TheGrid = new GridItem(Canvas, Template, (int) SafeFrameVal);
       CurrentTemplate  = Template;
       CurrentSafeFrame = SafeFrameVal;
    }
}


/* void lprofMain::SaveIT8(const char *filename)
{
    // fix me raw edit no longer supported

    QString text = IT8Edit->text();
    QFile f( filename );
    if ( !f.open( IO_WriteOnly ) ) {
    return;
    }

    QTextStream t( &f );
    t << text;
    f.close();

    IT8Edit->setEdited( FALSE );
} */


void lprofMain::DumpResultsToIT8(QList<GridLayout>& Layout)
{
    // qDebug("lprofMain::DumpResultsToIT8");
    LCMSHANDLE it8 = cmsxIT8Alloc();

    cmsxIT8SetSheetType(it8, "LCMS/MEASUREMENT");
    cmsxIT8SetProperty(it8, "ORIGINATOR",   (const char *) "LPROF");
    cmsxIT8SetProperty(it8, "DESCRIPTOR",   (const char *) "hidden measurement sheet");
    cmsxIT8SetProperty(it8, "MANUFACTURER", (const char *) "LPROF");
    cmsxIT8SetProperty(it8, "CREATED",      (const char *) "");
    cmsxIT8SetProperty(it8, "SERIAL",       (const char *) "");
    cmsxIT8SetProperty(it8, "MATERIAL",     (const char *) "");

    cmsxIT8SetProperty(it8, "CHISQ_DOF",    "3");

    int nSets = 0;
    int nFields = 8;

    QList<GridLayout>::iterator itEnd = Layout.end();
    for ( QList<GridLayout>::iterator it = Layout.begin(); it != itEnd; ++it)
    {

	if ((*it).p.dwFlags != 0)
	    nSets++;
    }

    cmsxIT8SetPropertyDbl(it8, "NUMBER_OF_SETS", nSets);

    if (ui->RadioButtonRGB->isChecked())    nFields += 3;
    if (ui->RadioButtonLabXYZ->isChecked()) nFields += 3;

    cmsxIT8SetPropertyDbl(it8, "NUMBER_OF_FIELDS", nFields);

    nFields = 0;

    cmsxIT8SetDataFormat(it8, nFields++, "SAMPLE_ID");

    cmsxIT8SetDataFormat(it8, nFields++, "POS_X");
    cmsxIT8SetDataFormat(it8, nFields++, "POS_Y");
    cmsxIT8SetDataFormat(it8, nFields++, "PIXELS");

    if (ui->RadioButtonRGB -> isChecked())
    {
	cmsxIT8SetDataFormat(it8, nFields++, "RGB_R");
	cmsxIT8SetDataFormat(it8, nFields++, "RGB_G");
	cmsxIT8SetDataFormat(it8, nFields++, "RGB_B");

	cmsxIT8SetDataFormat(it8, nFields++, "STDEV_R");
	cmsxIT8SetDataFormat(it8, nFields++, "STDEV_G");
	cmsxIT8SetDataFormat(it8, nFields++, "STDEV_B");
    }

    if (ui->RadioButtonLab -> isChecked() ||
        ui->RadioButtonLabXYZ -> isChecked())
    {
	cmsxIT8SetDataFormat(it8, nFields++, "LAB_L");
	cmsxIT8SetDataFormat(it8, nFields++, "LAB_A");
	cmsxIT8SetDataFormat(it8, nFields++, "LAB_B");
    }

    if (ui->RadioButtonXYZ -> isChecked() ||
        ui->RadioButtonLabXYZ -> isChecked())
    {
	cmsxIT8SetDataFormat(it8, nFields++, "XYZ_X");
	cmsxIT8SetDataFormat(it8, nFields++, "XYZ_Y");
	cmsxIT8SetDataFormat(it8, nFields++, "XYZ_Z");
    }

    cmsxIT8SetDataFormat(it8, nFields++, "CHI_SQD_PAR");

    itEnd = Layout.end();
    for ( QList<GridLayout>::iterator it = Layout.begin(); it != itEnd; ++it)
    {
	GridLayout * const Patch = &(*it);
	if (Patch -> p.dwFlags != 0) {

	    cmsxIT8SetDataSet(it8, Patch->p.Name, "SAMPLE_ID", Patch->p.Name);

	    cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "POS_X", Patch->p.pos_x);
	    cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "POS_Y", Patch->p.pos_y);
	    cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "PIXELS", (double) Patch->p.npixels);

	    if (ui->RadioButtonRGB -> isChecked()) {

		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "RGB_R", Patch ->p.Colorant.RGB[0]);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "RGB_G", Patch ->p.Colorant.RGB[1]);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "RGB_B", Patch ->p.Colorant.RGB[2]);

		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "STDEV_R", Patch ->p.Stdev.RGB[0]);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "STDEV_G", Patch ->p.Stdev.RGB[1]);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "STDEV_B", Patch ->p.Stdev.RGB[2]);
	    }

	    if (ui->RadioButtonLab -> isChecked() || ui->RadioButtonLabXYZ -> isChecked()) {

		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "LAB_L", Patch ->p.Lab.L);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "LAB_A", Patch ->p.Lab.a);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "LAB_B", Patch ->p.Lab.b);
	    }

	    if (ui->RadioButtonXYZ -> isChecked() || ui->RadioButtonLabXYZ -> isChecked()) {

		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "XYZ_X", Patch ->p.XYZ.X * 100.);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "XYZ_Y", Patch ->p.XYZ.Y * 100.);
		cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "XYZ_Z", Patch ->p.XYZ.Z * 100.);
	    }

	    cmsxIT8SetDataSetDbl(it8, Patch->p.Name, "CHI_SQD_PAR", Patch ->p.ChiSq);
	}
    }

    cmsxIT8SaveToFile(it8, measfile.toLocal8Bit());
    cmsxIT8Free(it8);
}

void lprofMain::SetGoButton(QString Caption, BOOL lEnable)
{
    // qDebug("lprofMain::SetGoButton");
    QToolTip::remove( ui->TheGoButton );
    QToolTip::add( ui->TheGoButton, Caption );

    ui->TheGoButton -> setEnabled(TRUE);
    ui->TheGoButton -> setEnabled(lEnable);
    ui->TheGoButton -> repaint();
}

void lprofMain::SetGoButton_2(QString Caption, BOOL lEnable)
{
    // qDebug("lprofMain::SetGoButton");
    QToolTip::remove( ui->TheGoButton_2 );
    QToolTip::add( ui->TheGoButton_2, Caption );

    ui->TheGoButton_2 -> setEnabled(TRUE);
    ui->TheGoButton_2 -> setEnabled(lEnable);
    ui->TheGoButton_2 -> repaint();
}

 void lprofMain::SetOutputFile( const QString OutputFile )
{
     switch (ui->TabProfiler -> currentPageIndex()) 
     {

         case 0: ui->OutputFileEdit -> setText(OutputFile); break;
         case 1: ui->OutputFileEdit_Mon -> setText(OutputFile); break;

         default:;  // if not on a profiling tab do nothing
    }
}

bool lprofMain::validateFileName(QString &fn)

{
    int pos;
    bool OK;
    QDir d;
    QString message1, message2;
    QFileInfo fileInfo;
    
#ifdef __WIN32__
    pos = fn.findRev(QString::fromLocal8Bit("\\"), -1, FALSE);
#else
    pos = fn.findRev(QString::fromLocal8Bit("/"), -1, FALSE);
#endif  
    
    fileInfo.setFile(fn.left(pos));
    
    // not truely valid for a super user
    // but we should not allow writing to root
    // in any case
    if (fn.left(1) == QString::fromLocal8Bit("/") && pos < 1)
        OK = FALSE;
    else
    {
        if (pos > 0)  // slash was found so there is a directory 
                      // check to make sure the directory exists
                      // and is writable
        {
            if (d.exists(fn.left(pos)))
                // then ckeck to make sure it is a writable location
                if (fileInfo.isWritable())
                    OK = TRUE;
                else 
                    OK = FALSE;
        }
        else  // user using current path.
            OK = TRUE;
    }
    if (OK)
    { 
        if ((fn.findRev(QString::fromLocal8Bit(".i")) == (fn.length() - 4)  || 
             fn.findRev(QString::fromLocal8Bit(".I")) == (fn.length() - 4)) &&         // .i or ,I &&
             (fn.findRev(QString::fromLocal8Bit("C"), -2 ) == (fn.length() - 2) ||  
             fn.findRev(QString::fromLocal8Bit("c"), -2 ) == (fn.length() - 2)) && // c or C &&
             ((fn.findRev(QString::fromLocal8Bit("C") ) == (fn.length() - 1) ||  
                     fn.findRev(QString::fromLocal8Bit("c")) ==  (fn.length() - 1)) ||        // c  or C
             (fn.findRev(QString::fromLocal8Bit("M")) == (fn.length() - 1) ||  
                     fn.findRev(QString::fromLocal8Bit("m")) ==  (fn.length() -1 ))))         // or m or M
        {
            //  the directory and extension are OK
            OK = TRUE;
        }
        else
        {
            // direcotry OK but extesion is not
            if (!fn.find(QString::fromLocal8Bit("."), pos) == -1) // There is an extension so this is a user error that we can not fix
            {  
                OK = FALSE;
                QMessageBox::critical(this, QTranslator::tr("Error incorrect file extension."), 
                        QTranslator::tr("File name must have either an icc or icm file extenstion.   Please correct and retry the operation."));
            }
            else
            {
                // No extesion add it
                fn = fn + QString::fromLocal8Bit(".icc");
                OK = TRUE;
            }
        }
    }
    if (!OK)
        QMessageBox::critical(this, QTranslator::tr("Error directory not valid"), 
                        QTranslator::tr("The directory used for the output file is not valid.   It either it does not exist or is not a writable location.   Please correct this condition and retry the operation"));
    return OK;    
}

 // Main app constructor.
 ProfileParms* profP;

lprofMain::lprofMain( QWidget* parent)
    : QDialog( parent, "", 0, 
               Qt::WType_TopLevel | Qt::WStyle_SysMenu | Qt::WStyle_MinMax | Qt::WStyle_Title),
               FigEditor( 0 ), 
               Canvas( 0 ), 
               CanvasFrameLayout( 0 ), 
               TheGrid( 0 ), 
               TheImage( 0 ),
               CurrentTemplate( QString::fromLocal8Bit("")), 
               CurrentSafeFrame( 0 ), 
               fn( QString::fromLocal8Bit(""))
{
    // qDebug("lprofMain::lprofMain");
    ui = new Ui::lprofMainBase();
    ui->setupUi(this);
    profP = new ProfileParms(this);
    // ProfileParms profParms(this);
    profP -> setModal(FALSE);
    profP -> hide();

    connect(profP, SIGNAL(signalPickRGB()), this, SLOT(slotPickRGBPatch()));
    connect(profP, SIGNAL(profileParmsOK()), this, SLOT(slotUpdateProfileParmsText()));
    connect(this, SIGNAL(showProfileParms()), profP, SLOT(slotShow()));
    
    connect(ui->LoadBtn, SIGNAL(clicked()), this, SLOT(slotLoad()));
    connect(ui->ProfCheckpushButton, SIGNAL(clicked()), this, SLOT(ProfChecker_clicked()));
    connect(ui->ProfCheckpushButton_2, SIGNAL(clicked()), this, SLOT(ProfChecker_clicked()));
    connect(ui->ProfIDpushButton, SIGNAL(released()), this, SLOT(ProfIDpushButton_clicked()));
    connect(ui->ProfIDpushButton_mon, SIGNAL(released()), this, SLOT(ProfIDpushButton_clicked()));
    connect(ui->ProfParmspushButton, SIGNAL(clicked()), this, SLOT(ProfileParmsbutton()));
    connect(ui->ProfParmspushButton_mon, SIGNAL(clicked()), this, SLOT(ProfileParmsbutton()));
    connect(ui->ProofToggle, SIGNAL(toggled(bool)), this, SLOT(slotProof()));
    connect(ui->RadioAccurate, SIGNAL(toggled(bool)), this, SLOT(slotChangeStrategy()));
    connect(ui->RadioCoarse, SIGNAL(toggled(bool)), this, SLOT(slotChangeStrategy()));
    connect(ui->TabProfiler, SIGNAL(currentChanged(QWidget*)), this, SLOT(tabChanged()));
    connect(ui->TabProfiler, SIGNAL(currentChanged(QWidget*)), this, SLOT(slotIsAllReady()));
    connect(ui->TabProfiler, SIGNAL(currentChanged(QWidget*)), this, SLOT(slotChangeStrategy()));
    connect(ui->TheGoButton, SIGNAL(clicked()), this, SLOT(Go_button_clicked()));
    connect(ui->TheGoButton_2, SIGNAL(clicked()), this, SLOT(Go_button_clicked()));
    connect(ui->pushButtonHelp, SIGNAL(clicked()), this, SLOT(slotHelpButton()));
    connect(ui->pushButtonHelp_2, SIGNAL(clicked()), this, SLOT(slotHelpButton()));
    connect(ui->pushButtonHelp_3, SIGNAL(clicked()), this, SLOT(slotHelpButton()));
    connect(ui->pushButtonMeasure, SIGNAL(clicked()), this, SLOT(slotMeasure()));
    connect(ui->radioButtonCandM, SIGNAL(clicked()), this, SLOT(slotMeasureTypeChanged()));
    connect(ui->radioButtonCandMFile, SIGNAL(clicked()), this, SLOT(slotMeasureTypeChanged()));
    connect(ui->setMonitorValuesButton, SIGNAL(clicked()), this, SLOT(monitorvalues_clicked()));
    connect(ui->TargetSelector, SIGNAL(valueChanged()), this, SLOT(slotTargetRefChanged()));
    connect(ui->OutputFileEdit_Mon, SIGNAL(textChanged(QString)), this, SLOT(OutputFileNameChangedMon()));
    connect(ui->OutputFileEdit, SIGNAL(textChanged(QString)), this, SLOT(OutputFileNameChanged()));
    connect(ui->Reference_install, SIGNAL(clicked()), this, SLOT(slotInstallReference()));
    connect(ui->SafeFrame, SIGNAL(valueChanged(int)), this, SLOT(safeFarmeChanged()));
    connect(ui->listViewPortsInsts, SIGNAL(selectionChanged()), this, SLOT(slotEnablecomboBoxDevice()));
    connect(ui->comboBoxDevice, SIGNAL(activated(int)), this, SLOT(slotUpdateInst()));
    connect(ui->TargetSelector, SIGNAL(valueChanged()), this, SLOT(safeFarmeChanged()));

    connect( &urlOpTempFile, SIGNAL( finished( Q3NetworkOperation *) ), this, SLOT( templateFileCopied( Q3NetworkOperation * ) ) );

    connect(ui->MonMeasurementSheet, SIGNAL(valueChanged()), this, SLOT(slotChangeStrategy()));
    connect(ui->MonCalibrationSheet, SIGNAL(valueChanged()), this, SLOT(slotChangeStrategy()));
    
    connect(ui->InputProfileSelector, SIGNAL(valueChanged()), this, SLOT(slotProofProfilesChanged()));
    connect(ui->MonitorProfileSelector, SIGNAL(valueChanged()), this, SLOT(slotProofProfilesChanged()));

    init_env();
    Create_Config_Dir(QDir::currentDirPath());

    while (copyNumTempFile>0)
    {
        // qDebug("copyNumTempFile = %i", copyNumTempFile);
        lprofApp -> processEvents();
    }
    // qDebug("Done with file copy loop");

    templateFilesExist();
    SelectWPpatch = false;

    if (targetList) delete targetList;
    targetList = new Q3PtrList<target_template>;

    // Init the lcmsx engine, this always does success
    cmsxScannerProfilerInit(&sys);
    monitorValues.items.valid_mon=FALSE;

    sys.hdr.cmsprintf = ConsolePrintf;
    sys.hdr.Gauger = Gauger;

    QString per = ProfileChecker::tr("Perceptual"),
    relcolor = ProfileChecker::tr("Relative colorimetric"),
    sat = ProfileChecker::tr("Saturation"),
    Absolute = ProfileChecker::tr("Absolute");

    ui->ComboBoxIntent -> setEnabled(TRUE);

    ui->ComboBoxIntent -> clear();
    ui->ComboBoxIntent -> insertItem(per);
    ui->ComboBoxIntent -> insertItem(relcolor);
    ui->ComboBoxIntent -> insertItem(sat);
    ui->ComboBoxIntent -> insertItem(Absolute);

    init_mon();

    // Hide Printer_Tab until printer profiling is available
    ui->TabProfiler->removePage(ui->Printer_Tab);
    // Hidden tab is used for items that are no longer visible to users
    ui->TabProfiler->removePage(ui->Hidden);

    init_measurement_tool();

    ProgBar = ui->ProgressBar;
    LoadConfig();
    
    if (dsizes.lprofH > 0 && dsizes.lprofW > 0)
        this -> resize(dsizes.lprofW, dsizes.lprofH);

    // init_targetlist();
    last_tab=0;    
    // global_help_path = new QString;
    setupHelp(global_help_path);
    sys.hdr.ProfilerTab = ui->TabProfiler -> currentPageIndex();
    monCalOK = FALSE;
    monMeasOK = FALSE;
    slotMeasureTypeChanged();
    ReferenceFileExists();
    Console = ui->ProgressConsole;
    
    slotProofProfilesChanged();
    ui->comboBoxDevice -> setEnabled (FALSE);
    
    sys.hdr.instArray = new serialInsts[sys.hdr.validPorts];
    
    ui->Main_label -> setAutoFillBackground ( true ); 
    QPalette pal = ui->Main_label-> palette();
    pal.setColor(ui->Main_label ->  backgroundRole(), Qt::white);
    ui->Main_label -> setPalette(pal);
    // qDebug("lprofMain::lprofMain done");
}

lprofMain::~lprofMain(void)
{
    // qDebug("lprofMain::~lprofMain");
    SaveConfig();
    delete[] sys.hdr.instArray;
    delete ui;
}


void lprofMain::ControlsToValues()
{
    // qDebug("lprofMain::ControlsToValues");
    QString cTarget = ui->TargetSelector -> getFilename();

    if (cTarget != QString::null)
            strcpy(sys.hdr.ReferenceSheet, cTarget.toLocal8Bit());

    strcpy(sys.hdr.MeasurementSheet,  measfile.toLocal8Bit());
    if (ui->radioButtonCandMFile -> isOn())
    {
        strcpy(sys.hdr.MonMeasurementSheet, (const char*)ui->MonMeasurementSheet->getFilename().toLocal8Bit());
        strcpy(sys.hdr.MonCalibrationSheet, (const char*)ui->MonCalibrationSheet->getFilename().toLocal8Bit());
    }
    else
    {
        strcpy(sys.hdr.MonMeasurementSheet, monmeasFile);
        strcpy(sys.hdr.MonCalibrationSheet, moncalFile);
    }

    strcpy(sys.hdr.OutputProfileFile, (const char*) ui->OutputFileEdit -> text().toLocal8Bit());
    strcpy(sys.hdr.MonOutputProfileFile, (const char*) ui->OutputFileEdit_Mon -> text().toLocal8Bit());
    sys.hdr.cur_ref = ui->TargetSelector->getCurrItem();
    strcpy(sys.hdr.template_dir, templates.local8Bit());
    strcpy(sys.hdr.mon_profile_dir, (const char*) ui->MonitorProfileSelector->Dir.local8Bit());
    strcpy(sys.hdr.mon_profile_file_name, (const char*)ui->MonitorProfileSelector->getFilename().toLocal8Bit());
}

bool checkDescription()
{
   // qDebug(QString(sys.hdr.Description).left(14));
   if (QString::fromLocal8Bit(sys.hdr.Description).left(14) == QString::fromLocal8Bit("no description"))
   {
        QMessageBox mb( QTranslator::tr("LProf ICC Profiler"),
               QTranslator::tr("The profile discription is still the system default.  "
               "This value is used by many applications to list profiles.  "
               "You should go to the Profile ID dialog and  "
               "enter a meanfull description for this profile.  "
               "Create profile with existing description?"),
               QMessageBox::Warning,
               QMessageBox::Yes | QMessageBox::Default,
               QMessageBox::Abort,
               Qt::NoButton );
               mb.setButtonText( QMessageBox::Yes, QTranslator::tr("Yes") );
               mb.setButtonText( QMessageBox::No, QTranslator::tr("Abort"));
       switch( mb.exec() )
       {
          case QMessageBox::Yes:
             return true;
          case QMessageBox::Abort:
             return false;
       }

   }
   else return true;

}

// ------------------------------------------------------------------- Results

void lprofMain::DoScannerProfile()
{
    // qDebug("lprofMain::DoScannerProfile");
    if (!checkDescription()) return;
    Console    =  ui->ProgressConsole;
    Console -> setTextFormat( Qt::LogText);
    strcpy(sys.hdr.temp_file, WorkTempFileName.toLocal8Bit());

    SetGoButton(tr("Profiling... please wait"), FALSE);
    /* TRANSLATOR Text displayed in the messages widget */
    ConsolePrintf("Working hard...", 0, 'c');
    sys.hdr.DeviceClass = icSigInputClass;
    sys.hdr.ColorSpace  = icSigRgbData;
    sys.hdr.PCSType     = PT_Lab;
    sys.hdr.Medium = MEDIUM_REFLECTIVE_D50;

    QString cTarget = ui->TargetSelector -> getFilename();

    if (cTarget != QString::null)
            strcpy(sys.hdr.ReferenceSheet, cTarget.toLocal8Bit());
    strcpy(sys.hdr.MeasurementSheet, measfile.toLocal8Bit());
     // qDebug("about to call cmsxScannerProfilerDo");

    lprofApp -> setOverrideCursor( QCursor(Qt::WaitCursor) );
    if (!cmsxScannerProfilerDo(&sys))
    {
        /* TRANSLATOR Text displayed in the messages widget */
         ConsolePrintf("** ERROR: Unable to profile.", 0, 'c');
	 // qDebug("done failed");
        lprofApp -> restoreOverrideCursor();
        return;
     }
     else  // it worked finish up
     {
        Gauger("Init...", 0, 100, 100);
        ConsolePrintf("Profile '%1' DONE!", 1, 's', sys.hdr.OutputProfileFile);
        lprofApp -> restoreOverrideCursor();
     }
    SetGoButton(tr("Ready to GO!"), TRUE);


}

void lprofMain::DoMonitorProfile()
{

    if (!checkDescription()) return;
    // qDebug("lprofMain::DoMonitorProfile");

    Console    =  ui->ProgressConsole_mon;
    Console -> setTextFormat( Qt::LogText);
    
    strcpy(sys.hdr.temp_file, WorkTempFileName.toLocal8Bit());

    OutputFileNameChangedMon();

    SetGoButton(tr("Profiling... please wait"), FALSE);
    /* TRANSLATOR Text displayed in the messages widget */
    ConsolePrintf("Working hard...", 0, 'c');
    sys.hdr.DeviceClass = icSigDisplayClass;
    sys.hdr.ColorSpace  = icSigRgbData;
    sys.hdr.PCSType     = PT_Lab;
    sys.hdr.Medium      = MEDIUM_TRANSMISSIVE;
    strcpy(sys.hdr.ReferenceSheet, "");
    if (ui->RadioCoarse->isChecked())
    {
        strcpy(sys.hdr.MonMeasurementSheet, "");
        strcpy(sys.hdr.MonCalibrationSheet, "");
    }
    else if (ui->radioButtonCandMFile -> isOn())
    {
        strcpy(sys.hdr.MonMeasurementSheet, ui->MonMeasurementSheet->getFilename().toLocal8Bit());
        strcpy(sys.hdr.MonCalibrationSheet, ui->MonCalibrationSheet->getFilename().toLocal8Bit());
    }
    else
    {
        strcpy(sys.hdr.MonMeasurementSheet, monmeasFile);
        strcpy(sys.hdr.MonCalibrationSheet, moncalFile);
    }

    QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
    if (!cmsxMonitorProfilerDo(&sys))
    {
        /* TRANSLATOR Text displayed in the messages widget */
        ConsolePrintf("** ERROR: Unable to profile.", 0, 'c');
        lprofApp -> restoreOverrideCursor();
        return;  // it failed
    }
    else
    {  // it worked finish up
        Gauger("Init...", 0, 100, 100);
        /* TRANSLATOR Text displayed in the messages widget */
        ConsolePrintf("Profile '%1' DONE!", 1, 's', sys.hdr.MonOutputProfileFile);
        lprofApp -> restoreOverrideCursor();
    }

    SetGoButton_2(tr("Ready to GO!"), TRUE);
    if (sys.hdr.WhitePointParams.location==WP_LOC_RGB)
       slotUpdateProfileParmsText();
}

void lprofMain::zeroProgressBars()
{
    Gauger("Init...", 0, 100, 0);
}

