// $Id: qtlcmswidgets.h,v 1.15 2008/03/06 21:18:58 hvengel Exp $
//  Little cms - profiler construction set
//  Copyright (C) 1998-2001 Marti Maria
// Copyright (C) 2005-2006 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.08a


// Some shared widgets for trolltech Qt

#ifndef __qtlcmswidgets_H
#define __qtlcmswidgets_H

#include <q3hbox.h>
#include <QLabel>
#include <QComboBox>
#include <QPushButton>
#include <q3table.h>
#include <QLineEdit>
#include <QPainter>

#include "lcmsprf.h"

// Base selector implements a selector for IT8 files and icc profiles
// This is not intended to be a good hierarchy but a flexible widget
// It has bed designed to never be extended anymore

class BaseSelector: public Q3HBox {


     Q_OBJECT
     Q_PROPERTY(QString FileMask        READ ReadFileMask       WRITE WriteFileMask);
     Q_PROPERTY(QString Dir             READ ReadDir            WRITE WriteDir);
     Q_PROPERTY(QString Prompt          READ getPrompt          WRITE setPrompt);
     Q_PROPERTY(int     lUseDescriptor  READ getUseDescriptor   WRITE setUseDescriptor);
     Q_PROPERTY(int     lForOutput      READ getForOutput       WRITE setForOutput);;

public:

    BaseSelector(QString ThePrompt, QString DefaultDir, QString Mask = "*.*", BOOL lUseLineEdit = FALSE,  BOOL showFileDialog = TRUE,
                 QWidget* parent=0, const char* name=0, Qt::WFlags f=0);

    QString  getFilename() const;
    void     setFilename(const QString name);

    QString getPrompt() const           { return Prompt->text(); }
    void    setPrompt(QString text)     { Prompt->setText(text); }


    QString ReadFileMask() const        { return FileMask; }
    void    WriteFileMask(QString Mask) { FileMask = Mask; }

    QString ReadDir() const             { return Dir;  }
    void    WriteDir(QString TheDir)    { Dir= TheDir; }

    void    setCurrItem(int n)          { Combo->setCurrentItem(n); }
    int     getCurrItem()               { return Combo->currentItem(); }
    int     count() {return Combo->count();}

    void    setUseDescriptor(int n)     { lUseDescriptor = n;    }
    int     getUseDescriptor() const    { return lUseDescriptor; }

    void    setForOutput(int n)         { lUseDescriptor = n;    }
    int     getForOutput() const        { return lUseDescriptor; }


    void    setDirCaption(QString text) { PickButton->setText(text); }


    QString Dir;
    QString FileMask;
    int lUseDescriptor;
    int lUseLineEdit;
    int lForOutput;

    virtual void FillValues() = 0;

protected:

    QStringList  Descriptions, FileNames;
    QLabel*      Prompt;
    QComboBox*   Combo;
    QLineEdit*   LineEdit;
    QPushButton* PickButton;

    QPushButton*  NewButtonPtr;

protected slots:

    void slotButtonClicked();
    void slotValueChanged();

signals:

     void valueChanged();


};


// Selects a IT8/CGATS.5 file using a combo box

class IT8Selector: public BaseSelector {

    Q_OBJECT

public:

    IT8Selector(QWidget* parent=0, const char* name=0, Qt::WFlags f=0) :
        BaseSelector(tr("Target"), QString::fromLocal8Bit(""), QString::fromLocal8Bit("*.txt *.TXT *.IT8 *.it8 *.q60 *.Q60"), FALSE, FALSE, parent, name, f) {}



    virtual void FillValues();

};

class IT8SelectorWithFileDialog: public BaseSelector {

    Q_OBJECT

    public:

    IT8SelectorWithFileDialog(QWidget* parent=0, const char* name=0, Qt::WFlags f=0) :
        BaseSelector(tr("IT8 Target"), QString::fromLocal8Bit(""), QString::fromLocal8Bit("*.txt *.TXT *.IT8 *.it8 *.q60 *.Q60"), FALSE, TRUE, parent, name, f) {}



    virtual void FillValues();
    
    private:
        bool HCT(QString FileName, QString &Description);
        bool Logo(QString FileName, QString &Description);
        bool CGATS(QString FileName);

};


// Selects a IT8/CGATS.5 file by filename

class IT8FileSelector: public BaseSelector {

    Q_OBJECT

public:

    IT8FileSelector(QWidget* parent=0, const char* name=0, Qt::WFlags f=0) :
        BaseSelector(tr("IT8 target"), QString::fromLocal8Bit(""), QString::fromLocal8Bit("*.*"), TRUE, TRUE, parent, name, f) {}



    virtual void FillValues();

};


// Selects an ICC profile

class ICCProfileSelector: public BaseSelector {

    Q_OBJECT

public:

        ICCProfileSelector(QWidget* parent=0, const char* name=0, Qt::WFlags f=0) :
            BaseSelector(tr("ICC Profile"), QString::fromLocal8Bit(""), QString::fromLocal8Bit("*.icc *.icm *.ICC *.ICM"), FALSE, TRUE,  parent, name, f)
                { RestrictClass = -1; RestrictColorspace = -1;}


        virtual void FillValues();

        int RestrictClass;
        int RestrictColorspace;
};

// ---------- Chromaticity tonge Custom Qt4 Widget ------------------

class cmsxCIETonge : public QLabel
{
    Q_OBJECT

    public:

        cmsxCIETonge(QWidget *parent = 0);
        virtual ~cmsxCIETonge();

    public slots:
        void DrawTonge(LPcmsCIExyYTRIPLE inPrimaries, LPcmsCIEXYZ inWhitePoint, LPMEASUREMENT inM);

    private:
        
        cmsxCIETonge& operator=( const cmsxCIETonge& rhs );
        void DrawColorantTriangle(QPainter &painter);
        void DrawWhitePoint(QPainter &painter);
        void DrawPatches(QPainter &painter);
        void MapPoint(int& icx, int& icy, cmsCIExyY xyY);
        void BiasedLine(QPainter &painter, int x1, int y1, int x2, int y2);
        void BiasedText(QPainter &painter, int x, int y, const char* Txt);
        void Sweep_sRGB(QPainter &painter);
        int  Grids(double d) const		{ return (int) floor(d * gridside + .5); }

        void OutlineTonge(QPainter &painter);
        void FillTonge(QPainter &painter);
        void DrawTongeAxis(QPainter &painter);
        void DrawTongeGrid(QPainter &painter);
        void DrawLabels(QPainter &painter);

        QRgb ColorByCoord(double x, double y);
        void DrawSmallElipse(QPainter &painter, cmsCIExyY xyY, int r, int g, int b, int sz);
        void paintEvent(QPaintEvent *);
        void paintBackground();

        double gridside;
        int xBias, yBias;
        int pxcols, pxrows;
        int scale;
        cmsHPROFILE hMonitorProfile;
        cmsHPROFILE hXYZProfile;
        cmsHTRANSFORM hXFORM;
        // QPainter painter;
        LPcmsCIExyYTRIPLE Primaries; 
        LPcmsCIEXYZ WhitePoint; 
        LPMEASUREMENT m;
        bool drawCalled;
        
        QPolygon tongePoly;
        QPainterPath path;
};

// ------------------------------------------------------------------------ Curves

class cmsxDrawCurve {

public:

	cmsxDrawCurve(QPixmap& Pix);
	virtual ~cmsxDrawCurve();


	void DrawGammaCurve(LPGAMMATABLE Gamma, const char*Label, QRgb color, int Pos);



protected:
    cmsxDrawCurve& operator=( const cmsxDrawCurve& rhs );
	int pixcols, pixrows;

	QPainter Pnt;
	QPixmap& Pix;

};


// -------------------------------------------- Helper class dealing with statistics

class Statistics {

public:

    Statistics() { ClearStatistics(); }


    void ClearStatistics(void) {

            dE = n = x = x2 = Peak = sd_x = sd_y = sd_z =
            m_de = s_de = chi_sq = chi_sq_SUM = chi_sq_peak = 0.0;
            Min = 1E10;     // dE can never reach this!
    }


    void AddOnePatch(double The_dE) {

            dE = The_dE;
            x += dE; x2 += (dE * dE); n  += 1.0;
            if (dE > Peak) Peak = dE;
            if (dE < Min)  Min= dE;
    }


    void  EstimateTargetError(double The_s_de) {    // Via Chi-Squared

            s_de = The_s_de;
            chi_sq = 3.35 * s_de;   // chi-squared dE
            chi_sq_SUM += chi_sq;

            if (chi_sq > chi_sq_peak) chi_sq_peak = chi_sq;
    }


    double  dE;             // The dE of actual patch
    double  Min, Peak;      // Peaks up to date

    double  Std(void)  { return sqrt((n * x2 - x * x) / (n*(n-1))); }
    double  Mean(void) { return x/n; }


    double  TargetError(void)              { return chi_sq; }
    double  TargetErrorMean(void)          { return chi_sq_SUM / n; }
    double  TargetErrorMax(void)           { return chi_sq_peak; }

protected:

    double n, x, x2;
    double sd_x, sd_y, sd_z;
    double m_de, s_de;
    double chi_sq;
    double chi_sq_SUM;
    double chi_sq_peak;
};


// -------------------------------------------------------------- Checks results


class CheckProfile {

public:

    typedef enum {
	CHK_CORR_NONE = 0,	// check the uncorrected profile as is
	CHK_CORR_LUMINANCE = 1,	// check the profile after doing a luminace correction
	CHK_CORR_MATRIX = 2,	// check the profile after doing a matrix correction
	CHK_CORR_WP_WVK = 3,	// check white point corrected profile (wrong von Kries)
	CHK_CORR_WP_BDF = 4,	// check white point corrected profile (Bradford)
    } CheckerCorrection;

private:

    QComboBox *CorrectionCombo;
    CheckerCorrection CorrByItem[5];

    void CreateFancyReport(QString& Report, Statistics& st, Statistics& st94,
                           CheckerCorrection corr, double params[]);

public:

    CheckProfile(QComboBox *corrCombo = NULL);

    void cdecl Results(Q3Table* ResultsGrid,
		       QString& ResultsText,
		       LPMEASUREMENT m,
		       const char *OutputProfileFile,
		       const char *ProofProfile);

};

#endif

