// vim: set tabstop=4 shiftwidth=4 noexpandtab
/*
Gwenview - A simple image viewer for KDE
Copyright 2000-2004 Aurélien Gâteau

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 2
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

*/


#ifndef IMAGEVIEW_H
#define IMAGEVIEW_H

// TQt
#include <tqmap.h>
#include <tqscrollview.h>
#include <tqtimer.h>
#include <tqvaluelist.h>

// Local
#include "busylevelmanager.h"
#include "imageutils/imageutils.h"
#include "libgwenview_export.h"
class TQEvent;
class TQLabel;
class TQMouseEvent;
class TQPainter;
class TQTimer;
class TQWheelEvent;
class KAction;
class KActionCollection;
class KToggleAction;
typedef TQValueList<KAction *> KActionPtrList;

namespace Gwenview {
class Document;

class LIBGWENVIEW_EXPORT ImageView : public TQScrollView {
Q_OBJECT
  TQ_OBJECT

public:
	class ToolBase;
	class ZoomTool;
	class ScrollTool;
	class EventFilter;
#if __GNUC__ < 3
	friend class ToolBase;
	friend class ZoomTool;
	friend class ScrollTool;
#endif
	friend class EventFilter;

	enum ToolID { SCROLL, ZOOM };
	enum ZoomMode { ZOOM_FIT, ZOOM_FIT_WIDTH, ZOOM_FIT_HEIGHT, ZOOM_FREE };
	typedef TQMap<ToolID,ToolBase*> Tools;

	ImageView(TQWidget* parent,Document*,KActionCollection*);
	~ImageView();

	// Properties
	double zoom() const; 
	void setZoom(double zoom, int centerX=-1, int centerY=-1);
	bool fullScreen() const; 
	void setFullScreen(bool);

	int brightness() const;
	int contrast() const;
	int gamma() const;

public slots:
	void setBrightness(int);
	void setContrast(int);
	void setGamma(int);
	void updateFromSettings();

signals:
	void selectPrevious();
	void selectNext();
    void doubleClicked();
	void requestContextMenu(const TQPoint&);

    // Emitted whenever an hint should be displayed
    void requestHintDisplay(const TQString& hint);

	// Emitted whenever brightness, contrast or gamma changes
	void bcgChanged();

protected:
	virtual void contentsDragEnterEvent(TQDragEnterEvent*);
	virtual void contentsDropEvent(TQDropEvent*);
	virtual void keyPressEvent(TQKeyEvent*);
	
private:
	struct Private;
	Private* d;

	struct PendingPaint {
		PendingPaint( bool s, const TQRect& r ) : rect( r ), smooth( s ) {};
		PendingPaint() {}; // stupid TQt containers
		TQRect rect;
		bool smooth;
	};
	enum Operation { CHECK_OPERATIONS = 0, SMOOTH_PASS = 1 << 0 };

	void addPendingPaint( bool smooth, TQRect rect = TQRect());
	void addPendingPaintInternal( bool smooth, TQRect rect = TQRect());
	void performPaint( TQPainter* painter, int clipx, int clipy, int clipw, int cliph, bool smooth );
	void limitPaintSize( PendingPaint& paint );
	void fullRepaint();
	void cancelPending();
	void scheduleOperation( Operation operation );
	void checkPendingOperationsInternal();
	void updateBusyLevels();

	void updateZoom(ZoomMode, double value=0, int centerX=-1, int centerY=-1);
	double computeZoom(bool in) const;
	double computeZoomToFit() const;
	double computeZoomToWidth() const;
	double computeZoomToHeight() const;
	
	void updateImageOffset();
	void updateScrollBarMode();
	void updateContentSize();
	void updateFullScreenLabel();
	void updateZoomActions();
	void selectTool(ButtonState, bool force);
	void restartAutoHideTimer();

	void emitRequestHintDisplay();

	// Used by the scroll tool
	void emitSelectPrevious() { emit selectPrevious(); }
	void emitSelectNext() { emit selectNext(); }

	// Used by the zoom tool
	TQPoint offset() const;
	bool canZoom(bool in) const;
	KToggleAction* zoomToFit() const;

private slots:
	void slotLoaded();
	void slotModified();
	void slotZoomIn();
	void slotZoomOut();
	void slotResetZoom();
	void slotSelectZoom();
	void setZoomToFit(bool);
	void setZoomToWidth(bool);
	void setZoomToHeight(bool);
	void setLockZoom(bool);
	void increaseGamma();
	void decreaseGamma();
	void increaseBrightness();
	void decreaseBrightness();
	void increaseContrast();
	void decreaseContrast();
	void slotImageSizeUpdated();
	void slotImageRectUpdated(const TQRect&);
	void checkPendingOperations();
	void loadingStarted();
	void slotBusyLevelChanged(BusyLevel);
	void showBCGDialog();
	
protected:
	// Overloaded methods
	bool eventFilter(TQObject*, TQEvent*);
	void viewportMousePressEvent(TQMouseEvent*);
	void viewportMouseMoveEvent(TQMouseEvent*);
	void viewportMouseReleaseEvent(TQMouseEvent*);
	bool viewportKeyEvent(TQKeyEvent*); // This one is not inherited, it's called from the eventFilter
	void wheelEvent(TQWheelEvent* event);
	void resizeEvent(TQResizeEvent* event);
	void drawContents(TQPainter* p,int clipx,int clipy,int clipw,int cliph);
};

} // namespace
#endif

