/***************************************************************************
 * trackprint.h: definition of TrackPrint class
 *
 * This file is part of KGuitar, a KDE tabulature editor
 *
 * copyright (C) 2003-2004 the KGuitar development team <mrgwen@gmail.com>
 ***************************************************************************/

/***************************************************************************
 * 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.
 *
 * See the file COPYING for more information.
 ***************************************************************************/

#ifndef TRACKPRINT_H
#define TRACKPRINT_H

#include <QPainter>
#include <QRect>
#include <QString>
#include <QFont>
#include <QPen>
#include <QPixmap>

class TabTrack;

//!TrackPrint prints the contents of a single bar
/*!
	It is used by both TrackView (draws onscreen) and SongPrint (prints on paper).
*/
class TrackPrint
{
public:
	/*
		TrackPrint constructor. Load some fonts and load some pixmaps used to draw
		the effects.
		Resolution is the DPI,
	*/
	TrackPrint(int resolution);
	~TrackPrint();
	
	// Set the painter for the drawing
	//
	inline void setPainter(QPainter* paint)
	{ painter = paint; }
	
	// Set the size of a page
	//
	inline void setPage(const QRect& pageSize)
	{ size = pageSize; }
	
	// Draw a margins page and the number of the page
	//
	void drawPage(uchar pageNb);
	
	// Print a title on the first page with the title font
	//
	void printTitle(const QString& title);
	
	// Print Words ... by and Music by ...
	//
	void printWordsAndMusic(const QString& words, const QString& music);
	
	// Print tuning
	//
	void printTuning(const TrackProperties& trackProperties);
	
	void setPosition(const QPoint&);
	QPoint getPosition() const;
	
	/*!
		draw bar bn's contents starting at xpos,ypostb adding extra space es
		also update selection x coordinates for trackview
	*/
	void drawBar(int, const TabBar&);
	
	/*!
		draw bar lines at xpos,ypostb width w for all strings of track trk
	*/
	void drawBarLines(int width, const TabTrack& track);
	
	/*
		Draw the single end bar or repeat end bar.
	*/
	void drawEndBarLines(int width);
	
	/*!
		draw:
		- key + keysig (if fbol or changed)
		- timesig      (if first bar of track or changed)
		return xpixels used
		actually draws only when doDraw is true
	*/
	void drawKeySigTimeSig(int barNumber, bool drawKey, bool drawSignature, const TabTrack& tabTrack);
	
	/*!
		Draw the tempo
	*/
	void drawTempo(uint tempo);
	
	void drawRepeatStart();
	void drawAlternateEndings(unsigned int, unsigned int);
	void drawRepetitions(unsigned int, unsigned int);
	void drawDoubleBar(unsigned int);
	
private:
	/*
		Converts mm units to pixels unit
	*/
	template <class T> inline T mmToPixel(double mm) const
	{ return static_cast<T>(dpi * (mm / 2.54)); }
	
	inline void drawText(unsigned int, unsigned int, const QString&);
	inline void drawText(unsigned int x, unsigned int y, QFont& font, const QString& string);
	
	void drawChanges(unsigned int, unsigned int, const TabBar&);
	void drawDuration(const TabTimes &, const TabTimes &);
	
	/*!
		Draw the vertical lines of a time.
	*/
	void drawVerticalLine(const TabTimes&);
	
	void drawTimes(const TabTimes &);
	
	void drawTriplet(unsigned int);
	/*!
		Draw a tuplet with the position and a tuplet number and the length
	*/
	void drawTuplet(unsigned int position, unsigned int ntupletLength ,unsigned int ntuplet);
	
	void drawEffect(const TabTimes &, const TabTimes &);
	void drawEndBar();
	
	void drawDotted(const TabTimes&);
	
	void drawRest(int, int, const TabTimes&) throw (const char*);
	void drawRest(int, int, const TabTimes&, const TabTimes&) throw (const char*);
	
	void drawBend(unsigned int, unsigned  int, const QString &);
	void drawBendAndRelease(unsigned int, unsigned  int, const QString &);
	void drawPreBend(unsigned int, unsigned int, const QString &);
	void drawPreBendAndRelease(unsigned int, unsigned int, const QString &);
	void drawUnisonBend(unsigned int, unsigned int);
	void drawVibrato(unsigned int, unsigned int);
	void drawWideVibrato(unsigned int, unsigned int);
	void drawLegato(unsigned int, unsigned int, const TabTimes &, const TabTimes &, unsigned int);
	void drawTieNote(unsigned int x, unsigned int y);
	void drawTrill(unsigned int, unsigned int, unsigned int);
	void drawNaturalHarmonic(unsigned int, unsigned int);
	void drawArtificialHarmonic(unsigned int, unsigned int);
	void drawTremoloBar(unsigned int, unsigned int);
	void drawMuffledStrings(unsigned int, unsigned int);
	void drawPickSlide(unsigned int, unsigned int);
	void drawTremoloPicking(unsigned int, unsigned int);
	void drawLetRing(unsigned int, unsigned int);
	void drawStopRing(unsigned int, unsigned int);
	
	void drawDip(unsigned int, unsigned int, const QString&);
	void drawDive(unsigned int, unsigned int, const QString&);
	void drawReleaseUp(unsigned int, unsigned int, const QString&);
	void drawInvertedDip(unsigned int, unsigned int, const QString&);
	void drawReturn(unsigned int, unsigned int, const QString&);
	void drawReleaseDown(unsigned int, unsigned int, const QString&);
	
	void drawPalmMute(unsigned int, unsigned int);
	void drawStaccato(unsigned int, unsigned int);
	
	void drawTapping(unsigned int, unsigned int);
	void drawSlapping(unsigned int, unsigned int);
	void drawPopping(unsigned int, unsigned int);
	
	void drawFadeIn(unsigned int, unsigned int);
	void drawAccentuated(unsigned int, unsigned int);
	void drawGraceNote(unsigned int, unsigned int, unsigned int);
	void drawUpStroke(unsigned int, unsigned int, bool);
	void drawDownStroke(unsigned int, unsigned int, bool);
	
	void drawSlide(unsigned int, unsigned int);
	void drawLegatoSlide(unsigned int, unsigned int);
	void drawOutDownwardSlide(unsigned int, unsigned int);
	void drawOutUpwardSlide(unsigned int, unsigned int);
	void drawSlideInBelow(unsigned int, unsigned int);
	void drawSlideInAbove(unsigned int, unsigned int);
	
	void drawTrillNote(unsigned int, unsigned int, unsigned int);
	
	void drawTremoloPicking(unsigned int, unsigned int, unsigned int);
	
	unsigned char tripletCount;
	unsigned char crocheCount;
	unsigned char dblCrocheCount;
	unsigned char trlCrocheCount;

	unsigned char time[2];
	unsigned int durationCount;

	unsigned char lineSpaces;
	unsigned char nbStrings;
	
	// Store the png rest files
	//
	QPixmap** silent;
	
	// png bend file
	//
	QPixmap* bend;
	
	// png bendrelease file
	//
	QPixmap* bendRelease;
	
	// png bendrelease file
	//
	QPixmap* preBendRelease;
	
	int drawKey(const TabTrack& tabTrack);
	int drawKeySig(TabTrack &, bool);
	int drawTimeSig(int barNumber, const TabTrack& tabTrack);
	
	// Almost all functions use a pointer to the same painter, instead of
	// making it a parameter for all functions make it a member variable
	//
	QPainter *painter;
	
	// Fonts used
	//
	QFont *fTBar1;				// used for notes on the tab bar
	QFont *fTBar2;				// used for notes on the tab bar
	QFont *fTSig;				// used for time signature
	QFont *fFeta;				// used for notes on the staff
	QFont *fFetaNr;				// used for time signature on the staff
	
	// The current position
	//
	QPoint position;
	
	// Pens used
	//
	QPen pLnBl;					// used for black lines & text
	QPen pLnWh;					// used for white lines
	
	// Resolution in dpi of the device
	//
	int dpi;
	
	// Size of a page
	//
	QRect size;
	
	// Font used for the titles
	//
	QFont* fontTitle;
	
	// Font used for the sub title
	//
	QFont* fontSubTitle;
	
	// Font used for the sub title
	//
	QFont* fontText;
};

#endif
