/*!
	Copyright (c) 2006-2007, Matevž Jekovec, Canorus development team
	All Rights Reserved. See AUTHORS for a complete list of authors.

	Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE.GPL for details.
*/

#ifndef MUSELEMENT_H_
#define MUSELEMENT_H_

#include <QString>
#include <QList>
#include <QColor>

class CAContext;
class CAMusElement;
class CAPlayable;
class CAMark;

class CAMusElement {
public:
	enum CAMusElementType {
		Undefined = 0,
		Note,
		Rest,
		MidiNote,
		Barline,
		Clef,
		TimeSignature,
		KeySignature,
		Slur,
		Tuplet,
		Syllable,
		FunctionMark,
		FiguredBassMark,
		Mark
	};

	CAMusElement(CAContext *context, int timeStart, int timeLength=0);
	virtual ~CAMusElement();

	virtual CAMusElement* clone(CAContext* context=0) = 0;
	virtual int compare(CAMusElement *elt) = 0;

	CAMusElementType musElementType() { return _musElementType; }

	inline CAContext *context() { return _context; }
	inline void setContext(CAContext *context) { _context = context; }

	inline virtual int timeStart() { return _timeStart; }
	inline void setTimeStart(int time) { _timeStart = time; }
	inline virtual int timeLength() { return _timeLength; }
	inline void setTimeLength(int length) { _timeLength = length; }
	inline int timeEnd() { return timeStart() + timeLength(); }

	inline virtual int realTimeStart() { return _timeStart; } // TODO: calculates and returns time in miliseconds
	inline virtual int realTimeLength() { return _timeLength; } // TODO: calculates and returns time in miliseconds
	inline int realTimeEnd() { return realTimeStart() + realTimeLength(); } // TODO: calculates and returns time in miliseconds

	inline const QString name() { return _name; }
	inline void setName(const QString name) { _name = name; }

	inline const bool isVisible() { return _visible; }
	inline void setVisible( const bool v ) { _visible = v; }

	inline const QColor color() { return _color; }
	inline void setColor( const QColor c ) { _color = c; }

	inline const QList<CAMark*> markList() { return _markList; }
	void addMark( CAMark *mark );
	void addMarks( QList<CAMark*> marks );
	inline void removeMark( CAMark* mark ) { _markList.removeAll(mark); }

	bool isPlayable();

	static const QString musElementTypeToString(CAMusElementType);
	static CAMusElementType musElementTypeFromString(const QString);

protected:
	inline void setMusElementType( CAMusElementType type ) { _musElementType = type; }

	QList< CAMark* > _markList;
	CAMusElementType _musElementType;
	CAContext *_context;
	int _timeStart;
	int _timeLength;
	bool _visible;
	QColor _color;
	QString _name;
};
#endif /* MUSELEMENT_H_ */
