/******************************************************************************
 *
 * Copyright (C) 1997-2019 by Dimitri van Heesch.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby 
 * granted. No representations are made about the suitability of this software 
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
 */

#ifndef WIZARD_H
#define WIZARD_H

#include <OSplitter>
#include <OHash>
#include <QDialog>

class Input;
class QGGreeWidget;
class QGGreeWidgetItem;
class OStackedWidget;
class QCheckBox;
class QLineEdit;
class OPushButton;
class QRadioButton;
class QGroupBox;
class QButtonGroup;
class Wizard;
class QImage;
class QLabel;

class TuneColorDialog : public QDialog
{
    Q_OBJECT

  public:
    TuneColorDialog(int hue,int sat,int gamma,QWidget *parent=nullptr);
    int getHue() const;
    int getSaturation() const;
    int getGamma() const;

  private slots:
    void updateImage(int hue,int sat,int val);

  private:
    QImage *m_image = nullptr;
    QLabel *m_imageLab = nullptr;
    int m_hue = 0;
    int m_sat = 0;
    int m_gam = 0;
};

class ColorPicker : public QWidget
{
    Q_OBJECT
public:
    enum Mode { Hue, Saturation, Gamma };
    ColorPicker(Mode m);
    ~ColorPicker();

public slots:
    void setCol(int h, int s, int g);
    //void setCol(int h, int s);

signals:
    void newHsv(int h, int s, int g);

protected:
    void paintEvent(OPaintEvent*);
    void mouseMoveEvent(QMouseEvent *);
    void mousePressEvent(QMouseEvent *);

private:
    enum { foff = 3, coff = 4 }; //frame and contents offset
    int y2hue(int y);
    int y2sat(int y);
    int y2gam(int y);
    int hue2y(int hue);
    int sat2y(int sat);
    int gam2y(int gamma);
    void setHue(int v);
    void setSat(int v);
    void setGam(int v);

    OPixmap *m_pix = nullptr;
    Mode m_mode = Hue;
    int m_gam = 0;
    int m_hue = 0;
    int m_sat = 0;

};


class Step1 : public QWidget
{
    Q_OBJECT

  public:
    Step1(Wizard *parent,const OHash<OString,Input*> &modelData);
    void init();

  private slots:
    void selectSourceDir(); 
    void selectDestinationDir(); 
    void selectProjectIcon();
    void setProjectName(const OString &name);
    void setProjectBrief(const OString &desc);
    void setProjectNumber(const OString &num);
    void setSourceDir(const OString &dir);
    void setDestinationDir(const OString &dir);
    void setRecursiveScan(int);

  private:
    QLineEdit *m_projName = nullptr;
    QLineEdit *m_projBrief = nullptr;
    QLineEdit *m_projNumber = nullptr;
    QLineEdit *m_sourceDir = nullptr;
    QLineEdit *m_destDir = nullptr;
    QLabel    *m_projIconLab = nullptr;
    QCheckBox *m_recursive = nullptr;
    OPushButton *m_srcSelectDir = nullptr;
    OPushButton *m_dstSelectDir = nullptr;
    Wizard    *m_wizard = nullptr;
    const OHash<OString,Input *> &m_modelData;
};

class Step2 : public QWidget
{
    Q_OBJECT
  public:
    Step2(Wizard *parent,const OHash<OString,Input*> &modelData);
    void init();

  private slots:
    void optimizeFor(int choice);
    void extractMode(int choice);
    void changeCrossRefState(int choice);

  private:
    QGroupBox    *m_extractMode = nullptr;
    QGroupBox    *m_optimizeLang = nullptr;
    QButtonGroup *m_extractModeGroup = nullptr;
    QButtonGroup *m_optimizeLangGroup = nullptr;
    QCheckBox    *m_crossRef = nullptr;
    Wizard       *m_wizard = nullptr;
    const OHash<OString,Input *> &m_modelData;
};

class Step3 : public QWidget
{
    Q_OBJECT

  public:
    Step3(Wizard *parent,const OHash<OString,Input*> &modelData);
    void init();

  private slots:
    void setHtmlEnabled(bool);
    void setLatexEnabled(bool);
    void setManEnabled(int);
    void setRtfEnabled(int);
    void setXmlEnabled(int);
    void setDocbookEnabled(int);
    void setSearchEnabled(int);
    void setHtmlOptions(int);
    void setLatexOptions(int);
    void tuneColorDialog();

  private:
    QGroupBox *m_texOptions = nullptr;
    QButtonGroup *m_texOptionsGroup = nullptr;
    QGroupBox *m_htmlOptions = nullptr;
    QButtonGroup *m_htmlOptionsGroup = nullptr;
    QCheckBox *m_htmlEnabled = nullptr;
    QCheckBox *m_latexEnabled = nullptr;
    QCheckBox *m_manEnabled = nullptr;
    QCheckBox *m_rtfEnabled = nullptr;
    QCheckBox *m_xmlEnabled = nullptr;
    QCheckBox *m_docbookEnabled = nullptr;
    QCheckBox *m_searchEnabled = nullptr;
    OPushButton *m_tuneColor = nullptr;
    Wizard    *m_wizard = nullptr;
    const OHash<OString,Input *> &m_modelData;
};

class Step4 : public QWidget
{
    Q_OBJECT

  public:
    Step4(Wizard *parent,const OHash<OString,Input*> &modelData);
    void init();

  private slots:
    void diagramModeChanged(int);
    void setClassGraphEnabled(int state);
    void setCollaborationGraphEnabled(int state);
    void setGraphicalHierarchyEnabled(int state);
    void setIncludeGraphEnabled(int state);
    void setIncludedByGraphEnabled(int state);
    void setCallGraphEnabled(int state);
    void setCallerGraphEnabled(int state);

  private:
    QGroupBox *m_diagramMode = nullptr;
    QButtonGroup *m_diagramModeGroup = nullptr;
    QGroupBox *m_dotGroup = nullptr;
    QCheckBox *m_dotClass = nullptr;
    QCheckBox *m_dotCollaboration = nullptr;
    QCheckBox *m_dotInclude = nullptr;
    QCheckBox *m_dotIncludedBy = nullptr;
    QCheckBox *m_dotInheritance = nullptr;
    QCheckBox *m_dotCall = nullptr;
    QCheckBox *m_dotCaller = nullptr;
    Wizard    *m_wizard = nullptr;
    const OHash<OString,Input *> &m_modelData;
};

class Wizard : public OSplitter
{
    Q_OBJECT
  public:
    Wizard(const OHash<OString,Input*> &modelData, QWidget *parent=nullptr);
   ~Wizard();

  public slots:
    void refresh();

  private slots:
    void activateTopic(QGGreeWidgetItem *item,QGGreeWidgetItem *);
    void nextTopic();
    void prevTopic();

  signals:
    void done();

  private:
    const OHash<OString,Input *> &m_modelData;
    QGGreeWidget    *m_treeWidget = nullptr;
    OStackedWidget *m_topicStack = nullptr;
    Step1          *m_step1 = nullptr;
    Step2          *m_step2 = nullptr;
    Step3          *m_step3 = nullptr;
    Step4          *m_step4 = nullptr;
    OPushButton    *m_next = nullptr;
    OPushButton    *m_prev = nullptr;
};

#endif
