/***************************************************************************
 * trackbarview.cpp: implementation of TrackBarView class
 *
 * This file is part of KTabEdit, a KDE tabulature editor
 *
 * copyright (C) 2003-2007 the KTabEdit 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.
 ***************************************************************************/


#include "trackbarview.h"
#include <limits>

#include <QDebug>

#include "settings.h"

#include "qcanvascm/qcanvastextcm.h"
#include "qcanvascm/qcanvaslinecm.h"

#include "trackbarlineview.h"
#include "trackclassicalclefview.h"
#include "tracktabclefview.h"
#include "tracktimesignatureview.h"
#include "tracktimesclassicalview.h"
#include "tracktimesview.h"
#include "trackdurationview.h"

#include "tablature/trackpos.h"
#include "tablature/tabnote.h"
#include "tablature/tabtimes.h"

bool TrackBarView::DefaultFontInit = false;
QFont TrackBarView::DefaultTextFont;
QFontMetrics TrackBarView::DefaultTextFontInfo(DefaultTextFont);
Cm TrackBarView::DefaultTextWidth(0, 72);
Cm TrackBarView::DefaultTextHeight(0, 72);

TrackBarView::TrackBarView(uint nb, const TabBar* bar, const TrackProperties* properties, uint strings, uint dpi)
: DrawingItem(dpi),
  WholeSize(Cm(0, dpi)),
  HalfSize(Cm(0, dpi)),
  QuarterSize(Cm(0, dpi)),
  EighthSize(Cm(0, dpi)),
  SixteenthSize(Cm(0, dpi)),
  ThirthSecondSize(Cm(0, dpi)),
  SixtyFourthSize(Cm(0, dpi)),
  HundredTwentyEighthSize(Cm(0, dpi)),
  mTabBar(bar),
  trackProperties(properties),
  nbStrings(strings),
  clef(false),
  armor(false),
  time(false),
  tempo(false),
  mMinimalBarWidth(Cm(0, dpi)),
  mBarWidth(Cm(0, dpi)),
  partitionView(0),
  tablatureView(0),
  classicalClefView(0),
  tablatureClefView(0),
  timeSignatureView(0),
  partition(false),
  partitionClef(false),
  tablature(false),
  tablatureClef(false),
  displayBarNumberView(false),
  mBarNumber(nb),
  barNumberView(0),
  textFont(DefaultTextFont),
  textFontInfo(DefaultTextFontInfo),
  mTextWidth(DefaultTextWidth),
  mTextHeight(DefaultTextHeight),
  effects(true),
  mSpaceBetweenTimes(0, dpi),
  mPreviousDuration(NoneDuration)
{
	initDefaultFont();
	
	mTextWidth = DefaultTextWidth;
	mTextHeight = DefaultTextHeight;
	
	linkView[0] = linkView[1] = 0;
	
	initObjects();
	calcDurationSize();
	
	mMinimalBarWidth = minimalWidth();
}

void TrackBarView::initDefaultFont()
{
	if (DefaultFontInit == false) {
		DefaultTextFont = QFont(Settings::getInstance()->textAndTabFont());
		DefaultTextFontInfo = QFontMetrics(DefaultTextFont);
		
		Pixel pixelWidth(DefaultTextFontInfo.boundingRect("8").width(), dpi());
		Pixel pixelHeight(DefaultTextFontInfo.boundingRect("8").height(), dpi());
		
		pixelWidth.fromOtherDpi(75);
		pixelHeight.fromOtherDpi(75);
		
		DefaultTextWidth = pixelWidth.toCm();
		DefaultTextHeight = pixelHeight.toCm();
		
		textFont = DefaultTextFont;
		textFontInfo = DefaultTextFontInfo;
		
		DefaultFontInit = true;
	}
}

void TrackBarView::initObjects()
{
	QString temp;
	QFont clefFont(Settings::getInstance()->timeSignatureFont());
	QFont timeFont(Settings::getInstance()->timeSignatureFont());
	
	barNumberView = new QCanvasTextCm(temp.setNum(mBarNumber));
	
	partitionView = new TrackBarLineView(5, mTextHeight + Cm(0.1, dpi())/** 0.85 + Cm(0.05, dpi())*/, dpi());
	classicalClefView = new TrackClassicalClefView(dpi());
	
	tablatureView = new TrackBarLineView(nbStrings, mTextHeight /*+ Cm(0.05, dpi())*/, dpi());
	tablatureClefView = new TrackTabClefView(clefFont, tablatureView->height(), dpi());
	timeSignatureView = new TrackTimeSignatureView(mTabBar->timeSignature(), timeFont, tablatureView->height(), dpi());
	
	linkView[0] = new QCanvasLineCm();
	linkView[1] = new QCanvasLineCm();
}

void TrackBarView::deleteObjects()
{
	for (classical_it it = noteClassicalView.begin(); it != noteClassicalView.end(); ++it)
		delete *it;
	
	for (time_it it = fretView.begin(); it != fretView.end(); ++it)
		delete *it;
	
	for (duration_it it = mDurationViewList.begin(); it != mDurationViewList.end(); ++it)
		delete *it;
	
	noteClassicalView.clear();
	fretView.clear();
	mDurationViewList.clear();
}

TrackBarView::~TrackBarView()
{
	delete barNumberView;
	delete partitionView;
	delete classicalClefView;
	delete linkView[0];
	delete linkView[1];
	delete tablatureView;
	delete tablatureClefView;
	delete timeSignatureView;
	
	deleteObjects();
}

void TrackBarView::setTabBar(const TabBar* tabBar)
{
	mTabBar = tabBar;
	
	calcDurationSize();
	
	mMinimalBarWidth = minimalWidth();
}

bool TrackBarView::isBarNumber(uint barNumber) const
{
	return (barNumber == mBarNumber - 1);
}

void TrackBarView::calcDurationSize()
{
	Duration smallDuration = Whole;
	Cm cmWidth(mTextWidth * 1.5);
	
	for (uint i = 0; i < mTabBar->size(); i++) {
		Duration d = mTabBar->timeDuration(i);
		
		if (d != NoneDuration && d < smallDuration)
			smallDuration = d;
	}
	
	Cm fontSize = cmWidth;
	Cm step     = fontSize * 1.20;

	switch (smallDuration) {
	case NoneDuration:
	case Whole:
	case Half:
	case Quarter:
		QuarterSize = fontSize * 2.5;
		HalfSize = QuarterSize + step;
		WholeSize = HalfSize + step;
		break;
	case Eighth:
		EighthSize = fontSize * 2.5;
		QuarterSize = EighthSize + step;
		HalfSize = QuarterSize + step;
		WholeSize = HalfSize + step;
		break;
	case Sixteenth:
		SixteenthSize = fontSize * 2.5;
		EighthSize = SixteenthSize + step;
		QuarterSize = EighthSize + step;
		HalfSize = QuarterSize + step;
		WholeSize = WholeSize + step;
		break;
	case ThirthSecond:
		ThirthSecondSize = fontSize * 2.5;
		SixteenthSize = ThirthSecondSize + step;
		EighthSize = SixteenthSize + step;
		QuarterSize = EighthSize + step;
		HalfSize = QuarterSize + step;
		WholeSize = HalfSize + step;
		break;
	case SixtyFourth:
		SixtyFourthSize = fontSize * 2.5;
		ThirthSecondSize = SixtyFourthSize + step;
		SixteenthSize = ThirthSecondSize + step;
		EighthSize = SixteenthSize + step;
		QuarterSize = EighthSize + step;
		HalfSize = QuarterSize + step;
		WholeSize = HalfSize + step;
		break;
	case HundredTwentyEighth:
		HundredTwentyEighthSize = fontSize * 2.5;
		SixtyFourthSize = HundredTwentyEighthSize + step;
		ThirthSecondSize = SixtyFourthSize + step;
		SixteenthSize = ThirthSecondSize + step;
		EighthSize = SixteenthSize + step;
		QuarterSize = EighthSize + step;
		HalfSize = QuarterSize + step;
		break;
	}
}

uint TrackBarView::clefSize() const
{
	uint size = 0;
	
	if (clef) {
		Cm clefSize(0.4, dpi());
		
		size = clefSize.toPixel().value();
		
		size+=clefSize.toPixel().value();
	}
	
	return size;
}

Cm TrackBarView::armorSize() const
{
	Cm size(0.0, dpi());
	
	if (armor) {
		Cm armorSize(0.1, dpi());
		
		char armorNb = mTabBar->asciiCodeOfKey();
		
		if (armorNb < 0)
			armorNb = -armorNb;
		
		size = (armorSize * armorNb) + armorSize;
	}
	
	return size;
}

Cm TrackBarView::timesSize() const
{
	Cm size(0, dpi());
	
	for (uchar i = 0; i < mTabBar->size(); i++)
		size+=timeSpace(*mTabBar->time(i));
	
	return size;
}

Cm TrackBarView::timeSpace(const TabTime& time) const
{
	Cm timeSize(0.0, dpi());
	
	switch (time.duration()) {
	case NoneDuration:
		break;
	case Whole:
		timeSize = WholeSize;
		break;
	case Half:
		timeSize = HalfSize;
		break;
	case Quarter:
		timeSize = QuarterSize;
		break;
	case Eighth:
		timeSize = EighthSize;
		break;
	case Sixteenth:
		timeSize = SixteenthSize;
		break;
	case ThirthSecond:
		timeSize = ThirthSecondSize;
		break;
	case SixtyFourth:
		timeSize = SixtyFourthSize;
		break;
	case HundredTwentyEighth:
		timeSize = HundredTwentyEighthSize;
		break;
	default:
		break;
	}
	
	if (time.isDotted())
		timeSize+=(timeSize / 2.0);
	
// 	Cm time(timeSize, dpi());
	return timeSize /*time + ((mBarWidth - mMinimalBarWidth) / mTabBar->size())*/;
}

QPoint TrackBarView::classicalPosition(const QPoint& position) const
{
	return position;
}

QPointCm TrackBarView::tablaturePosition(const QPointCm& position) const
{
	QPointCm temp(position);
	
	if (partition)
		temp.setY(temp.y() + partitionView->height() + Cm(1.0, dpi()));
	
	return temp;
}

void TrackBarView::hideClassicalAndTablatureLink()
{
	linkView[0]->hide();
	linkView[1]->hide();
}

void TrackBarView::drawClassicalAndTablatureLink(const QPointCm& position)
{
	if (linkView[0]) {
		delete linkView[0];
		delete linkView[1];
	}
	
	linkView[0] = new QCanvasLineCm();
	linkView[1] = new QCanvasLineCm();
	
	
	linkView[0]->setPoints(position.x(), position.y(), position.x(), position.y() + Cm(1, dpi()));
	linkView[1]->setPoints(position.x() + mBarWidth, position.y(), position.x() + mBarWidth, position.y() + Cm(1, dpi()));
	
	linkView[0]->show();
	linkView[1]->show();
}

void TrackBarView::hidePartitionBody()
{
	if (displayBarNumberView) {
		barNumberView->hide();
	}
	
	if (partition == true) {
		partitionView->hide();
		
		if (partitionClef)
			classicalClefView->hide();
	}
	
	if (tablature == true) {
		if (partition == true)
			hideClassicalAndTablatureLink();
		
		tablatureView->hide();
	}
}

void TrackBarView::showPartitionBody()
{
	tablatureView->setGraphicsScene(graphicsScene());
	tablatureClefView->setGraphicsScene(graphicsScene());
	timeSignatureView->setGraphicsScene(graphicsScene());
	partitionView->setGraphicsScene(graphicsScene());
	classicalClefView->setGraphicsScene(graphicsScene());
	
	if (displayBarNumberView) {
		QString temp;
		
		barNumberView->moveBy(positionX(), positionY() - (mTextHeight * 2));
		addItemToScene(barNumberView);
	}
	
	if (partition == true) {
		partitionView->setBarLength(mBarWidth);
		drawCanvas(position(), partitionView);
		
		if (partitionClef)
			drawCanvas(position(), classicalClefView);
	}
	
	if (tablature == true) {
		QPointCm temp(position());
		
		if (partition) {
			temp.setY(temp.y() + partitionView->height());
			drawClassicalAndTablatureLink(temp);
			temp.setY(temp.y() + Cm(1, dpi()));
		}
		
		tablatureView->setBarLength(mBarWidth);
		drawCanvas(temp, tablatureView);
		
		if (tablatureClef && tablatureClefView)
			drawCanvas(temp, tablatureClefView);
		
		if (time && timeSignatureView) {
			if (tablatureClefView)
				temp.setX(temp.x() + tablatureClefView->width());
			
			drawCanvas(temp, timeSignatureView);
		}
	}
}

void TrackBarView::drawDuration(TrackTimesClassicalView* classicalView, TrackDurationView* durationView, const TabTime* tabTime,
								const QPointCm& position, uint barNumber, double* durationCount, const Cm& space)
{
	bool hasNextDuration = barNumber + 1 < mTabBar->size();
	bool isGreater = (hasNextDuration) && (*durationCount + mTabBar->timeRealDuration(barNumber + 1) > mTabBar->timeLigatures());
	Duration nextDuration = NoneDuration;
	QPointCm temp(tablaturePosition(position));
	temp.setX(temp.x() + mTextWidth / 2);
	//temp.setX(temp.x() + space / 2);
	
	if (mPreviousDuration >= Quarter)
		mPreviousDuration = NoneDuration;
	
	if (partition) {
 		//classicalView->setPreviousDuration(mPreviousDuration);
 		//classicalView->setNextDuration(nextDuration);
 		//drawCanvas(position, classicalView);
	}
	
	if (tablature == true) {
// 		kdDebug() << "hasNextDuration = " << hasNextDuration << " isGreater " << isGreater << "\n";
		
		if (hasNextDuration && isGreater == false)
			nextDuration = mTabBar->timeDuration(barNumber + 1);
		
		durationView->setPreviousDuration(mPreviousDuration);
		durationView->setNextDuration(nextDuration);
		
		if (barNumber > 0)
			durationView->setPositionOfPreviousDuration(mDurationViewList.at(barNumber - 1)->positionX());
		
		drawCanvas(temp, durationView);
	}
	
	mPreviousDuration = tabTime->duration();
	
	if (mTabBar->timeRealDuration(barNumber) > mTabBar->timeLigatures())
		*durationCount-=mTabBar->timeRealDuration(barNumber);
	
	if (hasNextDuration && isGreater) {
		*durationCount = 0;
		mPreviousDuration = NoneDuration;
	}
}

void TrackBarView::hide()
{
	hidePartitionBody();
	
	deleteObjects();
}

void TrackBarView::show()
{
	Cm space(0, dpi());
	double durationCount = 0.0;
	QPointCm tempPosition(position());
	TabTime* tabTime;
	TrackTimesClassicalView* classicalView(0);
	TrackDurationView* durationView(0);
	TrackTimesView* timesView(0);
	Cm classicalLineHeight = partitionView->lineSpace();
	
	if (partition == false && tablature && false)
		return ;
	
	showPartitionBody();
	
	tempPosition.setX(tempPosition.x() + tablatureBodyWidth());
	
	spacesBetweenTimes();
	
	mPreviousDuration = NoneDuration;
	
	for (uint i = 0; i < mTabBar->size(); i++) {
		tabTime = mTabBar->time(i);
		space = timeSpace(*tabTime);
		durationCount+=tabTime->realDuration();
		
		if (partition) {
			classicalView = new TrackTimesClassicalView(tabTime, trackProperties, textFont, nbStrings, classicalLineHeight, space, dpi());
			
			noteClassicalView.push_back(classicalView);
		}
		
		if (tablature) {
			durationView = new TrackDurationView(tabTime, nbStrings, mTextHeight, space + mSpaceBetweenTimes, dpi());
			timesView = new TrackTimesView(tabTime, textFont, nbStrings, space + mSpaceBetweenTimes, dpi());
			timesView->setGraphicsScene(graphicsScene());
			
			durationView->setGraphicsScene(graphicsScene());
			drawCanvas(tablaturePosition(tempPosition), timesView);
			fretView.push_back(timesView);
			mDurationViewList.push_back(durationView);
		}
		
		drawDuration(classicalView, durationView, tabTime, tempPosition, i, &durationCount, space);
		
		tempPosition.setX(tempPosition.x() + space + mSpaceBetweenTimes);
	}
}

void TrackBarView::refresh()
{
	hide();
	show();
}

void TrackBarView::refreshTimeAt(int time, const TabTime* tabTime)
{
	PRECONDITION( time < fretView.size() );
	
	fretView.at(time)->refreshTime(tabTime);
}

void TrackBarView::refreshNoteAt(int time, int note, const TabNote* tabNote)
{
	PRECONDITION( time < fretView.size() );
	
	fretView.at(time)->refreshNoteAt(note, tabNote);
}

void TrackBarView::drawTuplet(const Cm& ntupletLength, unsigned int ntuplet, const QPointCm& position)
{
	Cm queueLength = (mTextHeight * nbStrings) + Cm(0.5, dpi());
	QString s;
	
	// Draw the tuplet line
	//
	QCanvasLineCm *temp = new QCanvasLineCm();
/*	temp->setPoints(position.x().toPixel().value() ,
					(position.y() + queueLength).toPixel().value(),
					ntupletLength.toPixel().value(),
					(position.y() + queueLength).toPixel().value());
	temp->show();*/
	
// 	drawText(position.x() + (ntupletLength - position.x()) / 2, position.y() + queueLength + textWidth,
// 		 s.setNum(ntuplet + 1));
}

void TrackBarView::drawAllTuplets(const TabBar& tabBar, const QPointCm& position)
{
	uint i = 0;
	uint j = 0;
	uint tuplet = 0;
	uint tupletCount = 0;
	Cm x = position.x();
	float timeCount = 0.0;
	QString temp;
	QPointCm drawPosition(position);

	// For each times in the bar
	//
	for (i = 0; i < tabBar.size(); i++) {
		TabTime* tempTimes = tabBar.time(i);
		
		x = x + timeSpace(*tempTimes);
		
		// Draw the old tuplet
		//
		if (tempTimes->nTuplet() != tuplet) {
			// Is it a tuplet ?
			//
			if (tuplet != 0) {
				if (tupletCount > tuplet) {
					drawTuplet(x, tuplet, drawPosition);
				} else {
					// Draw only the tuplet number
					//
					for (j = 0; j < tupletCount; j++) {
						unsigned int queueLength = nbStrings * 8 + 2;
						
// 						drawText(x, position.y() + queueLength + textWidth, temp.setNum(tuplet + 1));
					}
				}
			}
			
			if ((tuplet = tempTimes->nTuplet()) != 0) {
				// Set the postion of the new tuplet
				//
				drawPosition.setX(x);

				tupletCount = 1;
				timeCount+=tempTimes->duration();
				
				if (tempTimes->isDotted() == true)
					timeCount+=(tempTimes->duration() / 2);
			} else {
				tupletCount = 0;
				timeCount = 0.0;
			}
		} else if (tuplet != 0) {
			tupletCount++;
			
			// Check the number of tuplet times
			//
			timeCount+=tempTimes->duration();
			
			if (tempTimes->isDotted() == true)
				timeCount+=(tempTimes->duration() / 2);
			
			// Need at least tuplet + 1 elements for a complete tuplet
			//
			if (tuplet != 0 && tupletCount >= tuplet + 1) {
				if (timeCount == 15 * (tuplet + 1)   || timeCount == 30 * (tuplet + 1)   ||
					timeCount == 60 * (tuplet + 1)   || timeCount == 120 * (tuplet + 1)  ||
					timeCount == 240 * (tuplet + 1)  || timeCount == 480 * (tuplet + 1)  ||
					timeCount == 22.5 * (tuplet + 1) || timeCount == 45 * (tuplet + 1)   ||
					timeCount == 90 * (tuplet + 1)   || timeCount == 180 * (tuplet + 1)  ||
					timeCount == 360 * (tuplet + 1)  || timeCount == 720 * (tuplet + 1)) {
					drawTuplet(x, tuplet, drawPosition);
					
					timeCount = 0.0;
					tupletCount = 0;
				}
			}
		}
	}
	
	// Draw the last tuplets
	//
	if (tuplet != 0) {
		if (tupletCount >= tuplet + 1) {
// 			drawTuplet(tupletCount, tuplet, drawPosition);
		} else {
			// Draw only the tuplet number
			//
			for (uint j = 0; j < tupletCount; j++) {
				unsigned int queueLength = nbStrings * 8 + 2;
				
// 				drawText(x, position.y() + queueLength + textWidth, temp.setNum(tuplet + 1));
			}
		}
	}
}

void TrackBarView::displayPartition(bool t)
{
	partition = t;
}

bool TrackBarView::isDisplayPartition() const
{
	return partition;
}

void TrackBarView::displayPartitionClef(bool t)
{
	partitionClef = t;
}

bool TrackBarView::isDisplayPartitionClef() const
{
	return partitionClef;
}

void TrackBarView::displayTablature(bool t)
{
	tablature = t;
}

bool TrackBarView::isDisplayTablature() const
{
	return tablature;
}

void TrackBarView::displayTablatureClef(bool t, const QFont& clefFont)
{
	tablatureClef = t;
}

bool TrackBarView::isDisplayTablatureClef() const
{
	return tablatureClef;
}

void TrackBarView::displayTimeSignature(bool t, const QFont& timeFont)
{
	time = t;
}

bool TrackBarView::isDisplayTimeSignature() const
{
	return time;
}

void TrackBarView::displayBarNumber(bool t)
{
	displayBarNumberView = t;

}

bool TrackBarView::isDisplayBarNumber() const
{
	return displayBarNumberView;
}

QPointCm TrackBarView::positionTablature(const TrackPos& cursorPos) const
{
	if (!tablature || cursorPos.times() > mTabBar->size())
		return QPointCm();
	
	QPointCm temp(position());
	
	if (partition)
		temp.setY(temp.y() + partitionView->height() + Cm(1.0, dpi()));
	
	temp.setY(temp.y() + (mTextHeight * cursorPos.chord()) - (mTextHeight * Cm(0.5, dpi())));
	
	temp.setX(temp.x() + Cm(0.1, dpi()));
	
	if (tablatureClef && tablatureClefView)
		temp.setX(temp.x() + tablatureClefView->width() + Cm(0.1, dpi()));
	
	if (time && timeSignatureView)
		temp.setX(temp.x() + timeSignatureView->width() + Cm(0.1, dpi()));
	
	if (tablatureClef && !time)
		temp.setX(temp.x() + Cm(0.1, dpi()));
	
	for (uint i = 0; i < cursorPos.times(); i++)
		temp.setX(temp.x() + timeSpace(*mTabBar->time(i)));
	
	return temp;
}

QPointCm TrackBarView::positionPartiton(const TrackPos& ) const
{
	if (!partition)
		return QPointCm();
	
	return position();
}

QPointCm TrackBarView::positionViewer() const
{
	return position();
}

TrackPos TrackBarView::cursorPositionAt(const QPointCm& point)
{
	TrackPos result;
	int time = 0;
	time_it it = fretView.begin();
	
	result.setBar(mBarNumber - 1);
	
	while (it != fretView.end() && (*it)->isPointInTime(point) == false) {
		time++;
		++it;
	}
	
	if (it != fretView.end() && (*it)->isPointInTime(point) == true) {
		//qDebug() << "[TrackBarView::cursorPositionAt] " << mBarNumber << "\n";
		result.setTimes(time);
		result.setChord((*it)->cursorPositionAt(point));
	}
	
	return result;
}

bool TrackBarView::isPointInBar(const QPointCm& point) const
{
	QRectCm rect = boundingRect();
	
	//qDebug() << point.x().value() << " " << point.y().value() << "\n";
	//qDebug() << rect.left().value() << " " << rect.right().value() << " " << rect.top().value() << " " << rect.bottom().value() << "\n";
	
	return point.x() >= rect.left() && point.x() <= rect.right() && point.y() >=  rect.top() && point.y() <= rect.bottom();
}

QRectCm TrackBarView::boundingRect() const
{
	return QRectCm(positionX(), positionY(), width(), height());
}

void TrackBarView::setWidth(const Cm& width)
{
	mBarWidth = width;
}

Cm TrackBarView::width() const
{
	return mBarWidth;
}

Cm TrackBarView::tablatureBodyWidth() const
{
	return tablatureClefView->width() + timeSignatureView->width();
}

Cm TrackBarView::minimalWidth() const
{
	Cm minimal(0, dpi());
	Cm tablatureSize(0, dpi());
	Cm partitionSize(std::numeric_limits<double>::min(), dpi());
	
	if (tablature) {
		tablatureSize = tablatureBodyWidth();
		tablatureSize+=timesSize();
	}
	
	if (partition) {
	}
	
	minimal = (tablatureSize < partitionSize ? partitionSize : tablatureSize);
	
	if (minimal < Cm(4.75, dpi()))
			minimal = Cm(4.75, dpi());
	
	return minimal;
}

Cm TrackBarView::height() const
{
	Cm height(0, dpi());
	
	if (partition)
		height+=partitionView->height();
	
	if (tablature)
		height+=tablatureView->height();
	
	if (tablature && partition)
		height+=Cm(1.0, dpi());
	
	height+=Cm(1.5,dpi());
	
	return height;
}

void TrackBarView::spacesBetweenTimes()
{
	mSpaceBetweenTimes = Cm(0, dpi());
	
	if ((tablatureBodyWidth() + timesSize()) > mBarWidth)
		mSpaceBetweenTimes = Cm(((tablatureBodyWidth() + timesSize()) - mBarWidth) / mTabBar->size());
	else
		mSpaceBetweenTimes = Cm((mBarWidth - (tablatureBodyWidth() + timesSize())) / mTabBar->size());
}
