/***************************************************************************
 * tabcolumn.h: implementation of TabColumn class
 *
 * This file is part of KTabEdit, a KDE tabulature editor
 *
 * copyright (C) 2003-2006 the KTabEdit development team <mrgwen@gmail.com>
 * copyright (C) 2002-2003 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 TABCOLUMN_H
#define TABCOLUMN_H

#include <QPoint>

#include "global.h"
#include "accidentals.h"

// Durations as in MIDI:
// 480 = whole
// 240 = half
// 120 = quarter
// 60  = eighth
// 30  = 16th
// 15  = 32nd

#define FLAG_ARC        1
#define FLAG_DOT        2
#define FLAG_PM         4
#define FLAG_TRIPLET	8

#define EFFECT_HARMONIC 1
#define EFFECT_ARTHARM  2
#define EFFECT_LEGATO   3
#define EFFECT_SLIDE    4
#define EFFECT_LETRING	5
#define EFFECT_STOPRING	6

#define NULL_NOTE       -1
#define DEAD_NOTE       -2

/***************************************************************************
 * struct StemInfo
 ***************************************************************************/

/*!
	this struct holds info about a note stem:
		- where it is attached
		- if it has beams
*/
struct StemInfo {
	//! attach point
	QPoint bp;
	//! level 1 beam
	char l1;
	//! level 2 beam
	char l2;
	//! level 3 beam
	char l3;
};

/*!
	Represents one column on tabulature song.
	!! REMOVE THIS !!
 */
class TabColumn {
private:
	//! Duration of note or chord
	int l;
	//! Number of fret
	char a[MAX_STRINGS];
	//! Effect parameter
	char e[MAX_STRINGS];
	//! Various flags
	uint flags;
	
	// TabColumn "volatile" data is calculated when needed,
	// see musicxml.cpp, songprint.cpp and tabtrack.cpp.
	// Used by MusicXML export and PostScript output.
	
	//! Lower stems
	StemInfo stl;
	//! Upper stems
	StemInfo stu;
	//! Voice assigned to note
	char v[MAX_STRINGS];
	// Step
	char stp[MAX_STRINGS];
	// Alter
	char alt[MAX_STRINGS];
	// Octave
	char oct[MAX_STRINGS];
	// Accidental
	Accidentals::Accid acc[MAX_STRINGS];
	
	// End of volatile data
public:
	/*!
		I DON'T KNOW !!
	*/
	int getDuration() const {
		return l;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setDuration(int i) {
		l = i;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const char getNbFret(uint i) const {
		return a[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setNbFret(uint i, char c) {
		a[i] = c;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const char getEffect(uint i) const {
		return e[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setEffect(uint i, char c) {
		e[i] = c;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const uint getFlags() const {
		return flags;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setFlags(uint i) {
		flags = i;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const StemInfo & getLowerStems() const {
		return stl;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setLowerStems(const StemInfo &i) {
		stl = i;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const StemInfo & getUpperStems() const {
		return stu;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setUpperStems(const StemInfo &i) {
		stu = i;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const char getVoiceToNote(uint i) const {
		return v[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setVoiceToNote(uint i, char c) {
		v[i] = c;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const char getStep(uint i) const {
		return stp[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setStep(uint i, char c) {
		stp[i] = c;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const char getAlter(uint i) const {
		return alt[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setAlter(uint i, char c) {
		alt[i] = c;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const char getOctave(uint i) const {
		return oct[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setOctave(uint i, char c) {
		oct[i] = c;
	}
	
	/*!
		I DON'T KNOW !!
	*/
	const Accidentals::Accid & getAccidental(uint i) const {
		return acc[i];
	}
	
	/*!
		I DON'T KNOW !!
	*/
	void setAccidental(uint i, const Accidentals::Accid &c) {
		acc[i] = c;
	}
	
	/*!
	 * Calculates and returns full duration of this column,
	 * i.e. multiplied by all necessary 2/3, 3/2 coffiecients.
	 */
	quint16 fullDuration() const;

	/*!
	 * Sets full duration (i.e. "l" + determines automatically all
	 * necessary flags for 2/3 and 3/2 coefficients.
	 */
	void setFullDuration(quint16 len);
	
	/*!
		I DON'T KNOW !!
	*/
	uint effectFlags() const;
};

#endif
