/***************************************************************************
 * tabtrackmodel.cpp
 *
 * This file is part of KTabEdit, a KDE tabulature editor
 *
 * copyright (C) 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 "tabtrackmodel.h"
#include "util/assert.h"

#include <QtDebug>

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


TabTrackModel::TabTrackModel()
: mTrack(0x0)
{
}

TabTrackModel::TabTrackModel(TabTrack* track)
: mTrack(track)
{
	POSTCONDITION( mTrack != 0x0 );
}

TabTrackModel::~TabTrackModel()
{
	if (mTrack != 0x0)
		delete mTrack;
}

void TabTrackModel::clone(const TabTrack* track)
{
	PRECONDITION( track != 0x0 );
	
	mTrack->clone(track);
}

void TabTrackModel::setTabTrack(TabTrack* track)
{
	PRECONDITION( track != 0x0 );
	
	mTrack = track;
}

TabTrack* TabTrackModel::tabTrack() const
{
	POSTCONDITION( mTrack != 0x0 );
	
	return mTrack;
}

bool TabTrackModel::hasTrack() const
{
	return (mTrack != 0x0);
}

TabBar* TabTrackModel::bar(int barNumber) const
{
	return mTrack->bar(barNumber);
}

void TabTrackModel::addBar(TabBar* bar)
{
	mTrack->addBar(bar);
	notifyTrackChanged();
}

void TabTrackModel::insertBar(int barNumber, TabBar* bar)
{
	mTrack->insertBar(barNumber, bar);
	notifyTrackChanged();
}

void TabTrackModel::insertEmptyBar(const TrackPos& position)
{
	mTrack->insertEmptyBar(position);
	notifyTrackChanged();
}

void TabTrackModel::insertEmptyBar(int barNumber)
{
	mTrack->insertEmptyBar(barNumber);
	notifyTrackChanged();
}

void TabTrackModel::setBar(int barNumber, TabBar* bar)
{
	mTrack->setBar(barNumber, bar);
	notifyTrackChanged();
}

void TabTrackModel::deleteBar(int barNumber)
{
	mTrack->deleteBar(barNumber);
	notifyTrackChanged();
}

uint TabTrackModel::barSize(int barNumber) const
{
	return mTrack->barSize(barNumber);
}

uint TabTrackModel::numeratorOfBar(int barNumber) const
{
	return mTrack->numeratorOfBar(barNumber);
}

uint TabTrackModel::denominatorOfBar(int barNumber) const
{
	return mTrack->denominatorOfBar(barNumber);
}

bool TabTrackModel::areTimesSignaturesEquals(int barNumber1, int barNumber2) const
{
	return mTrack->areTimesSignaturesEquals(barNumber1, barNumber2);
}

TabTime* TabTrackModel::time(const TrackPos& position) const
{
	return mTrack->time(position);
}

TabTime* TabTrackModel::time(int barNumber, uint timeNumber) const
{
	return mTrack->time(barNumber, timeNumber);
}

void TabTrackModel::setTime(const TrackPos& position, TabTime* tabTime)
{
	mTrack->setTime(position, tabTime);
	notifyBarChanged(position.bar());
}

void TabTrackModel::setTime(int barNumber, uint timeNumber, TabTime* tabTime)
{
	mTrack->setTime(barNumber, timeNumber, tabTime);
	notifyBarChanged(barNumber);
}

void TabTrackModel::insertTime(const TrackPos& position, TabTime* tabTime)
{
	mTrack->insertTime(position, tabTime);
	notifyBarChanged(position.bar());
}

void TabTrackModel::insertTime(int barNumber, TabTime* tabTime)
{
	mTrack->insertTime(barNumber, tabTime);
	notifyBarChanged(barNumber);
}

void TabTrackModel::deleteTime(int barNumber, uint timeNumber)
{
	mTrack->deleteTime(barNumber, timeNumber);
	notifyBarChanged(barNumber);
}

void TabTrackModel::deleteTime(const TrackPos& position)
{
	mTrack->deleteTime(position);
	notifyBarChanged(position.bar());
}

void TabTrackModel::setTimeDuration(const TrackPos& position, Duration duration)
{
	mTrack->setTimeDuration(position, duration);
	notifyBarChanged(position.bar());
}

void TabTrackModel::setTimeDuration(int barNumber, uint timeNumber, Duration duration)
{
	mTrack->setTimeDuration(barNumber, timeNumber, duration);
	notifyBarChanged(barNumber);
}

Duration TabTrackModel::timeDuration(const TrackPos& position) const
{
	return mTrack->timeDuration(position);
}

Duration TabTrackModel::timeDuration(int barNumber, uint timeNumber) const
{
	return mTrack->timeDuration(barNumber, timeNumber);
}

uint TabTrackModel::size() const
{
	return mTrack->size();
}

bool TabTrackModel::isEmptyTime(const TrackPos& position) const
{
	return mTrack->isEmptyTime(position);
}

bool TabTrackModel::isEmptyTime(int barNumber, uint timeNumber) const
{
	return mTrack->isEmptyTime(barNumber, timeNumber);
}

void TabTrackModel::setRest(int barNumber, uint timeNumber, bool b)
{
	mTrack->setRest(barNumber, timeNumber, b);
	notifyTimeChanged(barNumber, timeNumber);
}

void TabTrackModel::setRest(const TrackPos& position, bool b)
{
	mTrack->setRest(position, b);
	notifyTimeChanged(position.bar(), position.times());
}

void TabTrackModel::setDotted(int barNumber, uint timeNumber, bool b)
{
	mTrack->setDotted(barNumber, timeNumber, b);
	notifyTimeChanged(barNumber, timeNumber);
}

void TabTrackModel::setDotted(const TrackPos& position, bool b)
{
	mTrack->setDotted(position, b);
	notifyTimeChanged(position.bar(), position.times());
}

void TabTrackModel::setNote(const TrackPos& position, TabNote* tabNote)
{
	mTrack->setNote(position, tabNote);
	notifyTimeChanged(position.bar(), position.times());
}

void TabTrackModel::setNote(int barNumber, uint timeNumber, uint stringNumber, TabNote* tabNote)
{
	mTrack->setNote(barNumber, timeNumber, stringNumber, tabNote);
	notifyTimeChanged(barNumber, timeNumber);
}

TabNote* TabTrackModel::note(const TrackPos& position) const
{
	return mTrack->note(position);
}

TabNote* TabTrackModel::note(int barNumber, uint timeNumber, uint stringNumber) const
{
	return mTrack->note(barNumber, timeNumber, stringNumber);
}

void TabTrackModel::deleteNote(int barNumber, uint timeNumber, uint stringNumber)
{
	mTrack->deleteNote(barNumber, timeNumber, stringNumber);
}

void TabTrackModel::deleteNote(const TrackPos& position)
{
	mTrack->deleteNote(position);
	notifyTimeChanged(position.bar(), position.times());
}

void TabTrackModel::setFret(const TrackPos& position, uint fret)
{
	mTrack->setFret(position, fret);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

void TabTrackModel::setFret(int barNumber, uint timeNumber, uint stringNumber, uint fret)
{
	mTrack->setFret(barNumber, timeNumber, stringNumber, fret);
	notifyNoteChanged(barNumber, timeNumber, stringNumber);
}

char TabTrackModel::fret(const TrackPos& position) const
{
	return mTrack->fret(position);
}

char TabTrackModel::fret(int barNumber, uint timeNumber, uint stringNumber) const
{
	return mTrack->fret(barNumber, timeNumber, stringNumber);
}

void TabTrackModel::deleteFret(int barNumber, uint timeNumber, uint stringNumber)
{
	mTrack->deleteFret(barNumber, timeNumber, stringNumber);
	notifyNoteChanged(barNumber, timeNumber, stringNumber);
}

void TabTrackModel::deleteFret(const TrackPos& position)
{
	mTrack->deleteFret(position);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isEmptyNote(int barNumber, uint time, uint note) const
{
	return mTrack->isEmptyNote(barNumber, time, note);
}

bool TabTrackModel::isEmptyNote(const TrackPos& position) const
{
	return mTrack->isEmptyNote(position);
}

bool TabTrackModel::isTieNote(int barNumber, uint time, uint string) const
{
	return mTrack->isTieNote(barNumber, time, string);
}

bool TabTrackModel::isRest(int barNumber, uint time) const
{
	return mTrack->isRest(barNumber, time);
}

bool TabTrackModel::isRest(const TrackPos& position) const
{
	return mTrack->isRest(position);
}

bool TabTrackModel::isDotted(int barNumber, uint time) const
{
	return mTrack->isDotted(barNumber, time);
}

bool TabTrackModel::isDotted(const TrackPos& position) const
{
	return mTrack->isDotted(position);
}

bool TabTrackModel::isLastBar(uint bar) const
{
	return mTrack->isLastBar(bar);
}

void TabTrackModel::setProperties(TrackProperties* properties)
{
	mTrack->setProperties(properties);
	notifyTrackPropertyChanged();
}

TrackProperties* TabTrackModel::properties() const
{
	return mTrack->properties();
}

bool TabTrackModel::hasProperties() const
{
	return mTrack->hasProperties();
}

void TabTrackModel::setMode(TrackMode mode)
{
	mTrack->setMode(mode);
	notifyTrackPropertyChanged();
}

TrackMode TabTrackModel::mode() const
{
	return mTrack->mode();
}

void TabTrackModel::setName(const QString &string)
{
	mTrack->setName(string);
	notifyTrackPropertyChanged();
}

QString TabTrackModel::name() const
{
	return mTrack->name();
}

void TabTrackModel::setColor(const QColor& c)
{
	mTrack->setColor(c);
	notifyTrackPropertyChanged();
}

QColor TabTrackModel::color() const
{
	return mTrack->color();
}

void TabTrackModel::setNbStrings(uchar newStringNumber)
{
	mTrack->setNbStrings(newStringNumber);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::nbStrings() const
{
	return mTrack->nbStrings();
}

void TabTrackModel::setNbFrets(uchar i)
{
	mTrack->setNbFrets(i);
}

uchar TabTrackModel::nbFrets() const
{
	return mTrack->nbFrets();
}

void TabTrackModel::setTune(uchar i, uchar j)
{
	mTrack->setTune(i, j);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::tune(uchar i) const
{
	return mTrack->tune(i);
}

void TabTrackModel::setCapo(uchar c)
{
	mTrack->setCapo(c);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::capo() const
{
	return mTrack->capo();
}

void TabTrackModel::setMidiProperties(TrackMidiProperties* midiProperties)
{
	mTrack->setMidiProperties(midiProperties);
	notifyTrackPropertyChanged();
}

TrackMidiProperties* TabTrackModel::midiProperties() const
{
	return mTrack->midiProperties();
}

bool TabTrackModel::hasMidiProperties() const
{
	return mTrack->hasMidiProperties();
}

void TabTrackModel::setPatch(uchar i)
{
	mTrack->setPatch(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::patch() const
{
	return mTrack->patch();
}

void TabTrackModel::setChannel(uchar i)
{
	mTrack->setChannel(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::channel() const
{
	return mTrack->channel();
}

void TabTrackModel::setChannelEffects(uchar i)
{
	mTrack->setChannelEffects(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::channelEffects() const
{
	return mTrack->channelEffects();
}

void TabTrackModel::setMidiPort(int i)
{
	mTrack->setMidiPort(i);
	notifyTrackPropertyChanged();
}

int TabTrackModel::midiPort() const
{
	return mTrack->midiPort();
}

void TabTrackModel::setBank(unsigned int i)
{
	mTrack->setBank(i);
	notifyTrackPropertyChanged();
}

unsigned int TabTrackModel::bank() const
{
	return mTrack->bank();
}

void TabTrackModel::setVolume(uchar i)
{
	mTrack->setVolume(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::volume() const
{
	return mTrack->volume();
}

void TabTrackModel::setBalance(char i)
{
	mTrack->setBalance(i);
	notifyTrackPropertyChanged();
}

char TabTrackModel::balance() const
{
	return mTrack->balance();
}

void TabTrackModel::setChorus(uchar i)
{
	mTrack->setChorus(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::chorus() const
{
	return mTrack->chorus();
}

void TabTrackModel::setReverb(uchar i)
{
	mTrack->setReverb(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::reverb() const
{
	return mTrack->reverb();
}

void TabTrackModel::setPhaser(uchar i)
{
	mTrack->setPhaser(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::phaser() const
{
	return mTrack->phaser();
}

void TabTrackModel::setTremolo(uchar i)
{
	mTrack->setTremolo(i);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::tremolo() const
{
	return mTrack->tremolo();
}

void TabTrackModel::setTimeSignature(TimeSignature* timeSignature)
{
	mTrack->setTimeSignature(timeSignature);
	notifyTrackPropertyChanged();
}

TimeSignature* TabTrackModel::timeSignature() const
{
	return mTrack->timeSignature();
}

bool TabTrackModel::hasTimeSignature() const
{
	return mTrack->hasTimeSignature();
}

void TabTrackModel::setNumerator(uchar c)
{
	mTrack->setNumerator(c);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::numerator() const
{
	return mTrack->numerator();
}

void TabTrackModel::setDenominator(uchar c)
{
	mTrack->setDenominator(c);
	notifyTrackPropertyChanged();
}

uchar TabTrackModel::denominator() const
{
	return mTrack->denominator();
}

uint TabTrackModel::timeLigatures() const
{
	return mTrack->timeLigatures();
}

void TabTrackModel::setDeadNote(const TrackPos& position, bool b)
{
	mTrack->setDeadNote(position, b);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isDeadNote(const TrackPos& position) const
{
	return mTrack->isDeadNote(position);
}

bool TabTrackModel::isAccentuated(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isGhostNote(const TrackPos& position) const
{
	return mTrack->isGhostNote(position);
}

void TabTrackModel::setTieNote(const TrackPos& position, bool b)
{
	mTrack->setTieNote(position, b);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isTieNote(const TrackPos& position) const
{
	return mTrack->isTieNote(position);
}

void TabTrackModel::setHammerOnPullOff(const TrackPos& position, bool b)
{
	mTrack->setHammerOnPullOff(position, b);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isHammerOnPullOff(const TrackPos& position) const
{
	return mTrack->isHammerOnPullOff(position);
}

void TabTrackModel::setLetRing(const TrackPos& position, bool b)
{
	mTrack->setLetRing(position, b);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isLetRing(const TrackPos& position) const
{
	return mTrack->isLetRing(position);
}

bool TabTrackModel::isDynamic(const TrackPos& position) const
{
	return mTrack->isDynamic(position);
}

bool TabTrackModel::isFingeringLeft(const TrackPos& position) const
{
	return mTrack->isFingeringLeft(position);
}

bool TabTrackModel::isFingeringRight(const TrackPos& position) const
{
	return mTrack->isFingeringRight(position);
}

bool TabTrackModel::isPalmMute(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isStaccato(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isTremoloPicking(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isHarmonic(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

void TabTrackModel::setGhostNote(const TrackPos& position, bool b)
{
	mTrack->setGhostNote(position, b);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isGraceNote(const TrackPos& position) const
{
	return mTrack->isGhostNote(position);
}

TabBend* TabTrackModel::bend(const TrackPos& position) const
{
	return mTrack->bend(position);
}

void TabTrackModel::setBend(const TrackPos& position, TabBend* bend)
{
	mTrack->setBend(position, bend);
	notifyNoteChanged(position.bar(), position.times(), position.chord());
}

bool TabTrackModel::isBend(const TrackPos& position) const
{
	return mTrack->isBend(position);
}

bool TabTrackModel::isTrill(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isRasgueado(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::hasPickStroke(const TrackPos& position) const
{
	return mTrack->hasPickStroke(position);
}

bool TabTrackModel::hasTremolo(const TrackPos& position) const
{
	return mTrack->hasTremolo(position);
}

bool TabTrackModel::isTapping(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isPopping(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isSlapping(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isStroke(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isVibrato(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::isFadeIn(const TrackPos& position) const
{
	return mTrack->isAccentuated(position);
}

bool TabTrackModel::operator==(const TabTrack& tabTrack) const
{
	return mTrack->operator==(tabTrack);
}

bool TabTrackModel::operator!=(const TabTrack& tabTrack) const
{
	return mTrack->operator!=(tabTrack);
}
