/*******************************************************************************************************
 DkTransferToolBar.h
 Created on:	13.02.2012
 
 nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
 
 Copyright (C) 2011-2013 Markus Diem <markus@nomacs.org>
 Copyright (C) 2011-2013 Stefan Fiel <stefan@nomacs.org>
 Copyright (C) 2011-2013 Florian Kleber <florian@nomacs.org>

 This file is part of nomacs.

 nomacs 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.

 nomacs 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/>.

 *******************************************************************************************************/

#pragma once

#pragma warning(push, 0)	// no warnings from includes - begin
#include <QToolBar>
#include <QWidget>
#include <QObject>
#include <QPainter>
#include <QLinearGradient>
#include <QImage>
#include <QPainterPath>
#include <QDebug>
#include <QMouseEvent>
#include <QColorDialog>
#include <QColor>
#include <QGradientStops>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QCheckBox>
#include <QHBoxLayout>
#include <QLayout>
#include <QIcon>
#include <QAction>
#include <QTranslator>
#include <QDoubleSpinBox>
#include <QMenu>

#include <QGridLayout>
#include <QGraphicsOpacityEffect>
#pragma warning(pop)		// no warnings from includes - end

namespace nmc {

class DkTransferToolBar;
class DkVector;

class DkColorSlider : public QWidget {
	Q_OBJECT
	
public:
	//DkColorSlider(QWidget *parent);
	DkColorSlider(QWidget *parent, QColor color);
	DkColorSlider(QWidget *parent, qreal normedPos, QColor color, int sliderWidth);
	~DkColorSlider();
	QColor getColor();
	qreal getNormedPos();
	void setNormedPos(qreal pos);
	void setActive(bool isActive);
	void updatePos(int parentWidth);

	//void paintSlider(QPainter *painter);

signals:
	void sliderMoved(DkColorSlider *sender, int dragDistX, int yPos);
	void sliderActivated(DkColorSlider *sender);
	void colorChanged(DkColorSlider *slider);
				
public slots:
	virtual void paintEvent(QPaintEvent* event);

protected:
	virtual void mousePressEvent(QMouseEvent *event);
	virtual void mouseMoveEvent(QMouseEvent *event);
	virtual void mouseDoubleClickEvent(QMouseEvent *event);

private:
	int sliderWidth, sliderHeight, sliderHalfWidth;
	bool isActive;
	int dragStartX;
	QColor color;
	qreal normedPos;
};

class DkGradient : public QWidget {
	Q_OBJECT

public:
	DkGradient(QWidget *parent);
	~DkGradient();
	QGradientStops getGradientStops();
	void insertSlider(qreal pos, QColor col = QColor());
	void reset();
	QLinearGradient getGradient();
	void setGradient(const QLinearGradient& gradient);

signals:
	void gradientChanged();
		
public slots:
	virtual void paintEvent(QPaintEvent* event);
	//virtual void setEnabled(bool enabled);
	void moveSlider(DkColorSlider* sender, int dragDistX, int yPos);
	void changeColor(DkColorSlider *slider);
	void activateSlider(DkColorSlider *sender);

protected:
	virtual void mousePressEvent(QMouseEvent *event);
	virtual void mouseReleaseEvent(QMouseEvent *event);
	virtual void resizeEvent ( QResizeEvent * event );
		
private:
	void init();
	void addSlider(qreal pos, QColor color);
	void clearAllSliders();
	void updateGradient();
	qreal getNormedPos(int pos);
	int getAbsolutePos(qreal pos);

	int clickAreaHeight;
	int deleteSliderDist;
	QVector<DkColorSlider*> sliders;
	bool isSliderDragged;
	QLinearGradient gradient;
	int sliderWidth, halfSliderWidth;

	DkColorSlider *activeSlider;
	bool isActiveSliderExisting;
};

enum toolBarIcons {
	icon_toolbar_reset,
	icon_toolbar_pipette,
	icon_toolbar_save,
	icon_toolbar_end,	// nothing beyond this point
};

enum toolBarActions {
	toolbar_save,
	toolbar_reset,
	toolbar_pipette,
	toolbar_end,	// nothing beyond this point
};

enum imageModes {
	mode_uninitialized,
	mode_invalid_format,
	mode_gray,
	mode_rgb,
};


class DkTransferToolBar : public QToolBar {
	Q_OBJECT

public:
	DkTransferToolBar(QWidget *parent);
	~DkTransferToolBar();
		

signals:
	void pickColorRequest(bool enabled);
	void colorTableChanged(QGradientStops stops);
	void channelChanged(int channel);
	void transferFunctionChanged(int channel, QGradientStops stops);
	void tFEnabled(bool);
	void gradientChanged();

public slots:
	virtual void paintEvent(QPaintEvent* event);
	void insertSlider(qreal pos);
	void setImageMode(int mode);
	void saveGradient();
	void deleteGradientMenu(QPoint pos);
	void deleteGradient();
	void resetGradient();

protected slots:
	void applyTF();
	void pickColor(bool enabled);
	void changeChannel(int index);
	void enableTFCheckBoxClicked(int state);
	void switchGradient(int idx);

protected:
	virtual void resizeEvent ( QResizeEvent * event );
	void loadSettings();
	void saveSettings();
	void updateGradientHistory();

private:
	void createIcons();
	void applyImageMode(int mode);
	void enableToolBar(bool enable);
	QCheckBox *enableTFCheckBox;
		
	QImage m_shade;
	QImage sliderImg, activeSliderImg;

	QVector<QAction *> toolBarActions;
	QVector<QIcon> toolBarIcons;
		
	DkGradient *gradient;
	QComboBox *channelComboBox;

	QComboBox* historyCombo;
	QVector<QLinearGradient> oldGradients;

	QGraphicsOpacityEffect *effect;
	int imageMode;

};

class DkCropToolBar : public QToolBar {
	Q_OBJECT

public:

	enum {
		crop_icon = 0,
		pan_icon,
		cancel_icon,
		invert_icon,
		info_icon,

		icons_end,

	};

	DkCropToolBar(const QString & title, QWidget * parent = 0);
	virtual ~DkCropToolBar();

	QColor getColor() {
		return bgCol;
	};

	void loadSettings();

public slots:
	void setAspectRatio(const QPointF& aRatio);
	void on_cropAction_triggered();
	void on_cancelAction_triggered();
	void on_swapAction_triggered();
	void on_ratioBox_currentIndexChanged(const QString& text);
	void on_guideBox_currentIndexChanged(int idx);
	void on_horValBox_valueChanged(double val);
	void on_verValBox_valueChanged(double val);
	void on_angleBox_valueChanged(double val);
	void on_bgColButton_clicked();
	void on_panAction_toggled(bool checked);
	void on_invertAction_toggled(bool checked);
	void on_infoAction_toggled(bool checked);
	void angleChanged(double val);
	virtual void setVisible(bool visible);

signals:
	void panSignal(bool checked);
	void cropSignal();
	void cancelSignal();
	void aspectRatio(const DkVector& diag);
	void angleSignal(double angle);
	void colorSignal(const QBrush& brush);
	void paintHint(int paintMode);
	void shadingHint(bool invert);
	void showInfo(bool show);

protected:
	void createLayout();
	void createIcons();
	void saveSettings();

	QComboBox* ratioBox;
	QComboBox* guideBox;
	QAction* invertAction;
	QDoubleSpinBox* horValBox;
	QDoubleSpinBox* verValBox;
	QDoubleSpinBox* angleBox;
	QPushButton* bgColButton;
	QColorDialog* colorDialog;
	QColor bgCol;
	QAction* panAction;
	QAction* infoAction;

	QVector<QIcon> icons;		// needed for colorizing
};


};
