// $Id:
//  Lttle cms Profiler
// Copyright (C) 2005 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

#include "profileid.h"
#include <lprofmain.h>
#include <qvariant.h>
#include <qdialog.h>
#include  <qwidget.h>
#include <qlineedit.h>
#include <q3multilineedit.h>
#include <q3filedialog.h>
#include <qfileinfo.h>
#include <qmessagebox.h>
#include <qmutex.h>
#include <qpushbutton.h>
//Added by qt3to4:
#include <QTranslator>
#include "lprofmain.h"
// #include <qfile.h>
#include <string.h>
#include <lcmsprf.h>
#include "main.h"

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

// static QAssistantClient* help;

static PROFILERDATA sys;
static bool fileNameOK = FALSE;
static bool descriptionOK = FALSE;
static bool validate = TRUE;
static bool validateDescription = TRUE;
static QMutex mutex, mutexDescription;

QString ID_get_QTDIR()
{
    // qDebug("get_home_dir");
    const char* qtdir= "QTDIR";
    return QString::fromLocal8Bit(getenv(qtdir));
}

ProfileID::ProfileID( QWidget *parent)
    : QDialog(parent, "", 0, Qt::WStyle_SysMenu | Qt::WStyle_MinMax | Qt::WStyle_Title)
{
    setupUi(this);
    
    QObject::connect(buttonCancel, SIGNAL(released()), this, SLOT(close()));
    QObject::connect(buttonHelp, SIGNAL(clicked()), this, SLOT(slotHelpButton()));
    QObject::connect(OutputFileSelBtn, SIGNAL(clicked()), this, SLOT(slotSelectOutputFile()));
    QObject::connect(OutputFileEdit, SIGNAL(lostFocus()), this, SLOT(slotFileNameChanged()));
    QObject::connect(buttonOk, SIGNAL(pressed()), this, SLOT(slotUpdateValues()));
    QObject::connect(buttonCancel, SIGNAL(pressed()), this, SLOT(slotCancelDontCheck()));
    QObject::connect(DescriptionEdit, SIGNAL(lostFocus()), this, SLOT(slotDescriptionLostFocus()));
    QObject::connect(DescriptionEdit, SIGNAL(textChanged(QString)), this, SLOT(slotDescriptionChanged()));

    mainLabel -> setAutoFillBackground ( true ); 
    QPalette pal = mainLabel-> palette();
    pal.setColor(mainLabel ->  backgroundRole(), Qt::white);
    mainLabel -> setPalette(pal);

    passSys a;

    a.get(&sys);
    switch (sys.hdr.ProfilerTab)
    {
        case 0:
            OutputFileEdit -> setText(QString::fromLocal8Bit(sys.hdr.OutputProfileFile));
            break;
        case 1:
            OutputFileEdit -> setText(QString::fromLocal8Bit(sys.hdr.mon_profile_file_name));
            break;
    }
    ManufacturerEdit->setText(QString::fromLocal8Bit(sys.hdr.Manufacturer));
    ModelEdit -> setText(QString::fromLocal8Bit(sys.hdr.Model));
    CopyrightEdit -> setText(QString::fromLocal8Bit(sys.hdr.Copyright));
    DescriptionEdit -> setText(QString::fromLocal8Bit(sys.hdr.Description));
   // CommentsEdit->setText(sys.hdr.Comments);
}

ProfileID::~ProfileID()
{
    dialogSize ds;
    ds.put(profID, this -> height(), this -> width());
}

void ProfileID::slotUpdateValues()
{
    passSys a;
    dialogSize ds;
    QString fn;

    ds.put(profID, this -> height(), this -> width());
    
    slotOKCheck();

    if (fileNameOK && descriptionOK)
    {
        strcpy(sys.hdr.Manufacturer, ManufacturerEdit->text().toLocal8Bit());
        strcpy(sys.hdr.Model, ModelEdit -> text().toLocal8Bit());
        strcpy(sys.hdr.Copyright, CopyrightEdit -> text().toLocal8Bit());
        strcpy(sys.hdr.Description, DescriptionEdit -> text().toLocal8Bit());
    
        switch (sys.hdr.ProfilerTab)
        {
            case 0:
                strcpy(sys.hdr.OutputProfileFile, OutputFileEdit -> text().toLocal8Bit());
                break;
            case 1:
                strcpy(sys.hdr.mon_profile_file_name, OutputFileEdit -> text().toLocal8Bit());
                break;
            default: ;
        }
        // strcpy(sys.hdr.Comments, CommentsEdit->text());
        a.put(sys);
        accept();
    } 
    buttonOk -> setEnabled(TRUE); 
}

void ProfileID::slotHelpButton()
{
    QString path = get_global_help_path() + QString::fromLocal8Bit("/help/profile-id.html");
     // qDebug(path);
     getHelp()->openAssistant ();
     getHelp()->showPage(path);
}

void ProfileID::slotSelectOutputFile()
{
    // qDebug("lprofMain::slotSelectOutputFile");
    
    QString outprofile;
   
    outprofile = OutputFileEdit -> text();

    QString fn = Q3FileDialog::getSaveFileName( outprofile,
                           tr("icc profiles (*.icc *.icm)\nAll files (*.*)"),
                              this, 
                              "",
                           tr("Select output profile filename"));
    if (fn != QString::null)
    {
        // bool fileNameOK = 
        validateFileName(fn);
        OutputFileEdit -> setText(fn);
    }
}

void ProfileID::slotOKCheck()
{
    // qDebug("ProfileID::slotOKCheck()");
    
    mutex.lock();
    validate = FALSE;
    mutex.unlock();
    
    mutexDescription.lock();
    validateDescription = FALSE;
    mutexDescription.unlock();

    QString fn;
    fn = OutputFileEdit -> text();
    validateFileName(fn);
    OutputFileEdit -> setText(fn);
    
    checkDescription();
}
    
void ProfileID::slotCancelDontCheck()
{
    mutex.lock();
    validate = FALSE;
    mutex.unlock();
    mutexDescription.lock();
    validateDescription = FALSE;
    mutexDescription.unlock();
}

void ProfileID::slotFileNameChanged()
{
    // qDebug("ProfileID::slotFileNameChanged()");
    if (validate)
    {
        QString fn;
        fn = OutputFileEdit -> text();
        validateFileName(fn);
        OutputFileEdit -> setText(fn); 
    }
    else
    {
        mutex.lock();
        validate = TRUE;
        mutex.unlock(); 
    }  
}

void ProfileID::validateFileName(QString &fn)

{
    int pos;
    // bool fileNameOK;
    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  
    
    // qDebug("ProfileID::validateFileName");
    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)
        fileNameOK = 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())
                    fileNameOK = TRUE;
                else 
                    fileNameOK = FALSE;
            }
            else 
                fileNameOK = FALSE;
        }
        else  // user using current path.
            fileNameOK = TRUE;
    }
    if (fileNameOK)  // path is valid and writable now check file extension
    { 
        // check to make sure extension is some form of .icm or .icc
        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
            fileNameOK = 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
            {  
                // not really OK but we don't want to clobber the user entered file name
                QMessageBox::critical(this, QTranslator::tr("Error incorrect file extension."), 
                                      QTranslator::tr("File name must have either an icc or icm file extenstion. \n\nPlease correct."));
                fileNameOK = FALSE;
                return;
            }
            else
            {
                // No extesion add it
                fn = fn + QString::fromLocal8Bit(".icc");
                fileNameOK = TRUE;
            }
        }
    }
    if (!fileNameOK)
        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.\n\nPlease correct this condition."));
}


void ProfileID::checkDescription()
{
    // qDebug("checkDescription");
    
    if (DescriptionEdit->text().left(14) == QString::fromLocal8Bit("no description"))
    {
       QMessageBox mb( QTranslator::tr("Description is System Default"),
                        QTranslator::tr("The profile discription is still the system default.  "
                        "The profile description is used by many applications to list profiles.  "
                        "You should enter a meanfull description for this profile.  "
                        "Use the existing description?"),
                                QMessageBox::Warning,
                                QMessageBox::Yes,
                                QMessageBox::No | QMessageBox::Default,
                                Qt::NoButton );
        mb.setButtonText( QMessageBox::Yes, QTranslator::tr("Yes"));
        mb.setButtonText( QMessageBox::No, QTranslator::tr("No"));
        switch( mb.exec() )
        {
            case QMessageBox::Yes:
                descriptionOK = TRUE;
                break;
            case QMessageBox::No:
                descriptionOK = FALSE;
                break;
        }
    }
    else
       descriptionOK = TRUE;
}

void ProfileID::slotDescriptionLostFocus()
{
    // qDebug("ProfileID::slotLostFocus()");

    if (!descriptionOK && validateDescription)
    {
        checkDescription();
    }
    else
    {
        mutexDescription.lock();
        validateDescription = TRUE;
        mutexDescription.unlock(); 
    } 
}

void ProfileID::slotDescriptionChanged()
{
    // if it chaged force a revalidation when it loses focus
    validateDescription = TRUE;
    descriptionOK = FALSE;
}
