/***************************************************************************
 * tabnote.h: implementation of TabNote class
 *
 * This file is part of KTabEdit, a KDE tabulature editor
 *
 * copyright (C) 2003-2006 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 "tabnote.h"
#include "util/assert.h"

#include <QString>

TabNote::TabNote(uchar chord)
: mChord(chord),
  mEmptyFret(true),
  mFret(0),
  mDuration(Quarter),
  mDotted(false),
  mTuplet(0),
  mDeadNote(false),
  mEffect(0x0)
{
	mEffect = new TabNoteEffect;
}

TabNote::~TabNote()
{
	if (hasEffect() == true)
		delete effect();
}

void TabNote::clone(const TabNote* note)
{
	if (hasEffect() == true)
		delete mEffect;
	
	mChord = note->mChord;
	mEmptyFret = note->mEmptyFret;
	mFret = note->mFret;
	mDuration = note->mDuration;
	mDotted = note->mDotted;
	mTuplet = note->mTuplet;
	mDeadNote = note->mDeadNote;
	
	mEffect = new TabNoteEffect;
	if (note->hasEffect() == true)
		mEffect->clone(note->effect());
}

uchar TabNote::chord() const
{
	return mChord;
}

void TabNote::setFret(uchar c)
{
	mEmptyFret = false;
	
	mFret = c;
}

uchar TabNote::fret() const
{
	return mFret;
}

void TabNote::setEmpty(bool b)
{
	mEmptyFret = b;
}

bool TabNote::isEmpty() const
{
	return mEmptyFret;
}

void TabNote::setDuration(Duration c)
{
	mDuration = c;
}

Duration TabNote::duration() const
{
	return mDuration;
}

void TabNote::setDotted(bool b)
{
	mDotted = b;
}

bool TabNote::isDotted() const
{
	return mDotted;
}

void TabNote::setNTuplet(uchar c)
{
	mTuplet = c;
}

uchar TabNote::nTuplet() const
{
	return mTuplet;
}

void TabNote::setDeadNote(bool b)
{
	mEmptyFret = !b;
	
	mDeadNote = b;
}

bool TabNote::isDeadNote() const
{
	return mDeadNote;
}

void TabNote::setEffect(TabNoteEffect* effect)
{
	PRECONDITION( effect != 0x0 );
	
	if (mEffect != 0x0)
		delete mEffect;
	
	mEffect = effect;
}

TabNoteEffect* TabNote::effect() const
{
	POSTCONDITION( mEffect != 0x0 );
	
	return mEffect;
}

bool TabNote::hasEffect() const
{
	return (mEffect != 0x0);
}

void TabNote::setAccentuated(bool b)
{
	effect()->setAccentuated(b);
}

bool TabNote::isAccentuated() const
{
	return effect()->isAccentuated();
}

void TabNote::setGhostNote(bool b)
{
	effect()->setGhostNote(b);
}

bool TabNote::isGhostNote() const
{
	return effect()->isGhostNote();
}

void TabNote::setTieNote(bool b)
{
	effect()->setTieNote(b);
}

bool TabNote::isTieNote() const
{
	return effect()->isTieNote();
}

void TabNote::setHammerOnPullOff(bool b)
{
	effect()->setHammerOnPullOff(b);
}

bool TabNote::isHammerOnPullOff() const
{
	return effect()->isHammerOnPullOff();
}

void TabNote::setLetRing(bool b)
{
	effect()->setLetRing(b);
}

bool TabNote::isLetRing() const
{
	return effect()->isLetRing();
}

bool TabNote::hasDynamic() const
{
	return effect()->hasDynamic();
}

void TabNote::setDynamic(Dynamic d)
{
	effect()->setDynamic(d);
}

Dynamic TabNote::dynamic() const
{
	return effect()->dynamic();
}

bool TabNote::hasFingeringLeft() const
{
	return effect()->hasFingeringLeft();
}

void TabNote::setFingeringLeft(TabFingering f)
{
	effect()->setFingeringLeft(f);
}

TabFingering TabNote::fingeringLeft() const
{
	return effect()->fingeringLeft();
}

bool TabNote::hasFingeringRight() const
{
	return effect()->hasFingeringRight();
}

void TabNote::setFingeringRight(TabFingering f)
{
	effect()->setFingeringRight(f);
}

TabFingering TabNote::fingeringRight() const
{
	return effect()->fingeringRight();
}

void TabNote::setLeftHandVibrato(bool b)
{
	effect()->setLeftHandVibrato(b);
}

bool TabNote::isLeftHandVibrato() const
{
	return effect()->isLeftHandVibrato();
}

void TabNote::setPalmMute(bool b)
{
	effect()->setPalmMute(b);
}

bool TabNote::isPalmMute() const
{
	return effect()->isPalmMute();
}

void TabNote::setStaccato(bool b)
{
	effect()->setStaccato(b);
}

bool TabNote::isStaccato() const
{
	return effect()->isStaccato();
}

void TabNote::setSlide(Slide s)
{
	effect()->setSlide(s);
}

Slide TabNote::slide() const
{
	return effect()->slide();
}

bool TabNote::hasTremoloPicking() const
{
	return effect()->hasTremoloPicking();
}

void TabNote::setTremoloPicking(char c)
{
	effect()->setTremoloPicking(c);
}

char TabNote::tremoloPicking() const
{
	return effect()->tremoloPicking();
}

bool TabNote::hasHarmonic() const
{
	return effect()->hasHarmonic();
}

void TabNote::setHarmonic(Harmonic h)
{
	effect()->setHarmonic(h);
}

Harmonic TabNote::harmonic() const
{
	return effect()->harmonic();
}

bool TabNote::hasGraceNote() const
{
	return effect()->hasGraceNote();
}

void TabNote::setGraceNote(TabGraceNote* graceNote)
{
	effect()->setGraceNote(graceNote);
}

TabGraceNote* TabNote::graceNote() const
{
	return effect()->graceNote();
}

void TabNote::setGraceNoteDuration(int i)
{
	effect()->setGraceNoteDuration(i);
}

int TabNote::graceNoteDuration() const
{
	return effect()->graceNoteDuration();
}

void TabNote::setGraceNoteDynamic(Dynamic d)
{
	effect()->setGraceNoteDynamic(d);
}

Dynamic TabNote::graceNoteDynamic() const
{
	return effect()->graceNoteDynamic();
}

void TabNote::setGraceNoteFret(int i)
{
	effect()->setGraceNoteFret(i);
}

int TabNote::graceNoteFret() const
{
	return effect()->graceNoteFret();
}

void TabNote::setGraceNoteTransition(GraceNoteTransition g)
{
	effect()->setGraceNoteTransition(g);
}

GraceNoteTransition TabNote::graceNoteTransition() const
{
	return effect()->graceNoteTransition();
}

bool TabNote::hasBend() const
{
	return effect()->hasBend();
}

void TabNote::setBend(TabBend* bend)
{
	effect()->setBend(bend);
}

TabBend* TabNote::bend() const
{
	return effect()->bend();
}

void TabNote::setBendType(TabBend::BendType b)
{
	effect()->setBendType(b);
}

TabBend::BendType TabNote::bendType() const
{
	return effect()->bendType();
}

void TabNote::setBendValue(int i)
{
	effect()->setBendValue(i);
}

int TabNote::bendValue() const
{
	return effect()->bendValue();
}

QString TabNote::bendValueToString() const
{
	return effect()->bendValueToString();
}

int TabNote::sizeOfBendPoints() const
{
	return effect()->sizeOfBendPoints();
}

void TabNote::addBendPoint(TabBendPoint* point)
{
	effect()->addBendPoint(point);
}

void TabNote::setBendPoint(uint i, TabBendPoint* point)
{
	effect()->setBendPoint(i, point);
}

void TabNote::removeBendPoint(uint i)
{
	effect()->removeBendPoint(i);
}

TabBendPoint* TabNote::bendPoint(uint i) const
{
	return effect()->bendPoint(i);
}

bool TabNote::hasTrill() const
{
	return effect()->hasTrill();
}

void TabNote::setTrill(TabTrill* trill)
{
	effect()->setTrill(trill);
}

TabTrill* TabNote::trill() const
{
	return effect()->trill();
}

void TabNote::setFretTrill(char c)
{
	effect()->setFretTrill(c);
}

char TabNote::fretTrill() const
{
	return effect()->fretTrill();
}

void TabNote::setPeriod(char c)
{
	effect()->setPeriod(c);
}

char TabNote::period() const
{
	return effect()->period();
}

bool TabNote::operator==(const TabNote& note) const
{
	return (mEmptyFret == note.mEmptyFret && mFret == note.mFret &&
			mDuration == note.mDuration && mDotted == note.mDotted &&
			mTuplet == note.mTuplet && mDeadNote == note.mDeadNote &&
			mEffect == note.mEffect);
}

bool TabNote::operator!=(const TabNote& note) const
{
	return !this->operator==(note);
}
