/***************************************************************************
 * tabnoteeffect.h: implementation of TabNoteEffect
 *
 * This file is part of KGuitar, 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 "tabnoteeffect.h"
#include "util/assert.h"

#include <QString>

TabNoteEffect::TabNoteEffect()
: mAccentuated(false),
  mGhostNote(false),
  mTieNote(false),
  mHammerOnPullOff(false),
  mLetRing(false),
  mDynamic(NoneDynamic),
  mFingeringLeft(NoneFingering),
  mFingeringRight(NoneFingering),
  mTremolo(0),
  mSlide(NoneSlide),
  mLeftHandVibrato(false),
  mPalmMute(false),
  mStaccato(false),
  mHarmonic(NoneHarmonic),
  mGraceNote(0x0),
  mBend(0x0),
  mTrill(0x0)
{
	mGraceNote = new TabGraceNote;
	mBend = new TabBend;
	mTrill = new TabTrill;
}

TabNoteEffect::~TabNoteEffect()
{
	if (hasGraceNote())
		delete graceNote();
	
	if (hasBend())
		delete bend();
	
	if (hasTrill())
		delete trill();
}

void TabNoteEffect::clone(const TabNoteEffect* effect)
{
	mAccentuated = effect->mAccentuated;
	mGhostNote = effect->mGhostNote;
	mTieNote = effect->mTieNote;
	mHammerOnPullOff = effect->mHammerOnPullOff;
	mLetRing = effect->mLetRing;
	mDynamic = effect->mDynamic;
	mFingeringLeft = effect->mFingeringLeft;
	mFingeringRight = effect->mFingeringRight;
	mTremolo = effect->mTremolo;
	mSlide = effect->mSlide;
	mLeftHandVibrato = effect->mLeftHandVibrato;
	mPalmMute = effect->mPalmMute;
	mStaccato = effect->mStaccato;
	mHarmonic = effect->mHarmonic;
	
	mGraceNote = new TabGraceNote();
	if (effect->hasGraceNote() == true)
		mGraceNote->clone(effect->graceNote());
	
	mBend = new TabBend();
	if (effect->hasBend() == true)
		mBend->clone(effect->bend());
	
	mTrill = new TabTrill();
	if (effect->hasTrill() == true)
		mTrill->clone(effect->trill());
}

void TabNoteEffect::setAccentuated(bool b)
{
	mAccentuated = b;
}

bool TabNoteEffect::isAccentuated() const
{
	return mAccentuated;
}

void TabNoteEffect::setGhostNote(bool b)
{
	mGhostNote = b;
}

bool TabNoteEffect::isGhostNote() const
{
	return mGhostNote;
}

void TabNoteEffect::setTieNote(bool b)
{
	mTieNote = b;
}

bool TabNoteEffect::isTieNote() const
{
	return mTieNote;
}

void TabNoteEffect::setHammerOnPullOff(bool b)
{
	mHammerOnPullOff = b;
}

bool TabNoteEffect::isHammerOnPullOff() const
{
	return mHammerOnPullOff;
}

void TabNoteEffect::setLetRing(bool b)
{
	mLetRing = b;
}

bool TabNoteEffect::isLetRing() const
{
	return mLetRing;
}

bool TabNoteEffect::hasDynamic() const
{
	return mDynamic != NoneDynamic;
}

void TabNoteEffect::setDynamic(Dynamic d)
{
	mDynamic = d;
}

Dynamic TabNoteEffect::dynamic() const
{
	return mDynamic;
}

bool TabNoteEffect::hasFingeringLeft() const
{
	return mFingeringLeft != NoneFingering;
}

void TabNoteEffect::setFingeringLeft(TabFingering f)
{
	mFingeringLeft = f;
}

TabFingering TabNoteEffect::fingeringLeft() const
{
	return mFingeringLeft;
}

bool TabNoteEffect::hasFingeringRight() const
{
	return mFingeringRight != NoneFingering;
}

void TabNoteEffect::setFingeringRight(TabFingering f)
{
	mFingeringRight = f;
}

TabFingering TabNoteEffect::fingeringRight() const
{
	return mFingeringRight;
}

void TabNoteEffect::setLeftHandVibrato(bool b)
{
	mLeftHandVibrato = b;
}

bool TabNoteEffect::isLeftHandVibrato() const
{
	return mLeftHandVibrato;
}

void TabNoteEffect::setPalmMute(bool b)
{
	mPalmMute = b;
}

bool TabNoteEffect::isPalmMute() const
{
	return mPalmMute;
}

void TabNoteEffect::setStaccato(bool b)
{
	mStaccato = b;
}

bool TabNoteEffect::isStaccato() const
{
	return mStaccato;
}

void TabNoteEffect::setSlide(Slide s)
{
	mSlide = s;
}

Slide TabNoteEffect::slide() const
{
	return mSlide;
}

bool TabNoteEffect::hasTremoloPicking() const
{
	return mTremolo != 0;
}

void TabNoteEffect::setTremoloPicking(char c)
{
	mTremolo = c;
}

char TabNoteEffect::tremoloPicking() const
{
	return mTremolo;
}

bool TabNoteEffect::hasHarmonic() const
{
	return mHarmonic != NoneHarmonic;
}

void TabNoteEffect::setHarmonic(Harmonic h)
{
	mHarmonic = h;
}

Harmonic TabNoteEffect::harmonic() const
{
	return mHarmonic;
}

void TabNoteEffect::setGraceNote(TabGraceNote* graceNote)
{
	PRECONDITION( graceNote != 0x0 );
	
	if (mGraceNote != 0x0)
		delete mGraceNote;
	
	mGraceNote = graceNote;
}

TabGraceNote* TabNoteEffect::graceNote() const
{
	PRECONDITION( mGraceNote != 0x0 );
	
	return mGraceNote;
}

bool TabNoteEffect::hasGraceNote() const
{
	return (mGraceNote != 0x0);
}

void TabNoteEffect::setGraceNoteDuration(int i)
{
	graceNote()->setGraceNoteDuration(i);
}

int TabNoteEffect::graceNoteDuration() const
{
	return graceNote()->graceNoteDuration();
}

void TabNoteEffect::setGraceNoteDynamic(Dynamic d)
{
	graceNote()->setGraceNoteDynamic(d);
}

Dynamic TabNoteEffect::graceNoteDynamic() const
{
	return graceNote()->graceNoteDynamic();
}

void TabNoteEffect::setGraceNoteFret(int i)
{
	graceNote()->setGraceNoteFret(i);
}

int TabNoteEffect::graceNoteFret() const
{
	return graceNote()->graceNoteFret();
}

void TabNoteEffect::setGraceNoteTransition(GraceNoteTransition g)
{
	graceNote()->setGraceNoteTransition(g);
}

GraceNoteTransition TabNoteEffect::graceNoteTransition() const
{
	return graceNote()->graceNoteTransition();
}

void TabNoteEffect::setBend(TabBend* bend)
{
	PRECONDITION( bend != 0x0 );
	
	if (mBend != 0x0)
		delete mBend;
	
	mBend = bend;
}

TabBend* TabNoteEffect::bend() const
{
	PRECONDITION( mBend != 0x0 );
	return mBend;
}

bool TabNoteEffect::hasBend() const
{
	return (mBend != 0x0);
}

void TabNoteEffect::setBendType(TabBend::BendType b)
{
	bend()->setBendType(b);
}

TabBend::BendType TabNoteEffect::bendType() const
{
	return bend()->bendType();
}

void TabNoteEffect::setBendValue(int i)
{
	bend()->setBendValue(i);
}

int TabNoteEffect::bendValue() const
{
	return bend()->bendValue();
}

QString TabNoteEffect::bendValueToString() const
{
	return bend()->bendValueToString();
}

int TabNoteEffect::sizeOfBendPoints() const
{
	return bend()->sizeOfBendPoints();
}

void TabNoteEffect::addBendPoint(TabBendPoint* point)
{
	bend()->addBendPoint(point);
}

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

void TabNoteEffect::removeBendPoint(uint i)
{
	bend()->removeBendPoint(i);
}

TabBendPoint* TabNoteEffect::bendPoint(uint i) const
{
	return bend()->bendPoint(i);
}

void TabNoteEffect::setTrill(TabTrill* trill)
{
	PRECONDITION( mTrill != 0x0 );
	
	if (mTrill != 0x0)
		delete mTrill;
	
	mTrill = trill;
}

TabTrill* TabNoteEffect::trill() const
{
	PRECONDITION( mTrill != 0x0 );
	
	return mTrill;
}

bool TabNoteEffect::hasTrill() const
{
	return (mTrill != 0x0);
}

void TabNoteEffect::setFretTrill(char c)
{
	trill()->setFretTrill(c);
}

char TabNoteEffect::fretTrill() const
{
	return trill()->fretTrill();
}

void TabNoteEffect::setPeriod(char c)
{
	trill()->setPeriod(c);
}

char TabNoteEffect::period() const
{
	return trill()->period();
}

bool TabNoteEffect::operator==(const TabNoteEffect& effect) const
{
	return (mAccentuated == effect.mAccentuated && mGhostNote == effect.mGhostNote &&
			mTieNote == effect.mTieNote && mHammerOnPullOff == effect.mHammerOnPullOff &&
			mLetRing == effect.mLetRing &&
			mDynamic == effect.mDynamic && mFingeringLeft == effect.mFingeringLeft &&
			mFingeringRight == effect.mFingeringRight && mTremolo == effect.mTremolo &&
			mSlide == effect.mSlide && mLeftHandVibrato == effect.mLeftHandVibrato &&
			mPalmMute == effect.mPalmMute && mStaccato == effect.mStaccato &&
			mHarmonic == effect.mHarmonic && mGraceNote == effect.mGraceNote &&
			mBend == effect.mBend && mTrill == effect.mTrill);
}

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