/***************************************************************************
 * trackproperties.h: implementation of TrackProperties 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 "trackproperties.h"
#include "util/assert.h"

TrackProperties::TrackProperties()
: mMidiProperties(0x0),
  mTimeSignature(0x0)
{
	mMidiProperties = new TrackMidiProperties();
	mTimeSignature = new TimeSignature();
	
	connectObjects();
}

TrackProperties::TrackProperties(TrackMode mode, const QString& name, uchar channel, unsigned int bank, uchar patch, uchar strings, uchar frets)
:trackMode(mode),
 nameProp(name),
 nbStringsProp(strings),
 nbFretsProp(frets),
 tuneProp(strings),
 mMidiProperties(0x0),
 mTimeSignature(0x0)
{
	mMidiProperties = new TrackMidiProperties();
	mTimeSignature = new TimeSignature();
	
	setChannel(channel);
	setBank(bank);
	setPatch(patch);
	
	connectObjects();
}

TrackProperties::~TrackProperties()
{
	if (hasMidiProperties() == true)
		delete midiProperties();
	
	if (hasTimeSignature() == true)
		delete timeSignature();
}

void TrackProperties::clone(const TrackProperties* properties)
{
	if (hasMidiProperties() == true)
		delete midiProperties();
	
	if (hasTimeSignature() == true)
		delete timeSignature();
	
	trackMode = properties->trackMode;
	nameProp = properties->nameProp;
	nbStringsProp = properties->nbStringsProp;
	nbFretsProp = properties->nbFretsProp;
	tuneProp = properties->tuneProp;
	
	mMidiProperties = new TrackMidiProperties();
	if (properties->hasMidiProperties() == true)
		mMidiProperties->clone(properties->midiProperties());
	
	mTimeSignature = new TimeSignature();
	if (properties->hasTimeSignature() == true)
		mTimeSignature->clone(properties->timeSignature());
	
	connectObjects();
}

void TrackProperties::setMode(TrackMode mode)
{
	trackMode = mode;
	
	emit trackPropertyChanged();
}

TrackMode TrackProperties::mode() const
{
	return trackMode;
}

void TrackProperties::setName(const QString& string)
{
	nameProp = string;
	
	emit trackPropertyChanged();
}

QString TrackProperties::name() const
{
	return nameProp;
}

void TrackProperties::setColor(const QColor& c)
{
	colorTrack = c;
	
	emit trackPropertyChanged();
}

QColor TrackProperties::color() const
{
	return colorTrack;
}

void TrackProperties::setNbStrings(uchar i)
{
	tuneProp.resize(i);
	
	nbStringsProp = i;
	
	emit trackPropertyChanged();
}

unsigned char TrackProperties::nbStrings() const
{
	return nbStringsProp;
}

void TrackProperties::setNbFrets(uchar i)
{
	nbFretsProp = i;
	
	emit trackPropertyChanged();
}

unsigned char TrackProperties::nbFrets() const
{
	return nbFretsProp;
}

void TrackProperties::setTune(uchar i, uchar j)
{
	if (i > nbStringsProp)
		return;

	tuneProp[i] = j;
	
	emit trackPropertyChanged();
}

uchar TrackProperties::tune(uchar i) const
{
	if (i > nbStringsProp)
		return 0;

	return tuneProp[i];
}

void TrackProperties::setCapo(uchar c)
{
	if (c > nbFretsProp)
		return ;
	
	capoFret = c;
	
	emit trackPropertyChanged();
}

uchar TrackProperties::capo() const
{
	return capoFret;
}

void TrackProperties::setMidiProperties(TrackMidiProperties* midiProperties)
{
	PRECONDITION( midiProperties != 0x0 );
	
	if (mMidiProperties != 0x0)
		delete mMidiProperties;
	
	mMidiProperties = midiProperties;
	
	connectObjects();
}

TrackMidiProperties* TrackProperties::midiProperties() const
{
	PRECONDITION( mMidiProperties != 0x0 );
	
	return mMidiProperties;
}

bool TrackProperties::hasMidiProperties() const
{
	return (mMidiProperties != 0x0);
}

void TrackProperties::setPatch(uchar i)
{
	midiProperties()->setPatch(i);
}

uchar TrackProperties::patch() const
{
	return midiProperties()->patch();
}

void TrackProperties::setChannel(uchar i)
{
	midiProperties()->setChannel(i);
}

uchar TrackProperties::channel() const
{
	return midiProperties()->channel();
}

void TrackProperties::setChannelEffects(uchar i)
{
	midiProperties()->setChannelEffects(i);
}

uchar TrackProperties::channelEffects() const
{
	return midiProperties()->channelEffects();
}

void TrackProperties::setMidiPort(int i)
{
	midiProperties()->setMidiPort(i);
}

int TrackProperties::midiPort() const
{
	return midiProperties()->midiPort();
}

void TrackProperties::setBank(unsigned int i)
{
	midiProperties()->setBank(i);
}

unsigned int TrackProperties::bank() const
{
	return midiProperties()->bank();
}

void TrackProperties::setVolume(uchar i)
{
	midiProperties()->setVolume(i);
}

uchar TrackProperties::volume() const
{
	return midiProperties()->volume();
}

void TrackProperties::setBalance(char i)
{
	midiProperties()->setBalance(i);
}

char TrackProperties::balance() const
{
	return midiProperties()->balance();
}

void TrackProperties::setChorus(uchar i)
{
	midiProperties()->setChorus(i);
}

uchar TrackProperties::chorus() const
{
	return midiProperties()->chorus();
}

void TrackProperties::setReverb(uchar i)
{
	midiProperties()->setReverb(i);
}

uchar TrackProperties::reverb() const
{
	return midiProperties()->reverb();
}

void TrackProperties::setPhaser(uchar i)
{
	midiProperties()->setPhaser(i);
}

uchar TrackProperties::phaser() const
{
	return midiProperties()->phaser();
}

void TrackProperties::setTremolo(uchar i)
{
	midiProperties()->setTremolo(i);
}

uchar TrackProperties::tremolo() const
{
	return midiProperties()->tremolo();
}

void TrackProperties::setTimeSignature(TimeSignature* timeSignature)
{
	PRECONDITION( timeSignature != 0x0 );
	
	if (mTimeSignature != 0x0)
		delete mTimeSignature;
	
	mTimeSignature = timeSignature;
	
	connectObjects();
}

TimeSignature* TrackProperties::timeSignature() const
{
	PRECONDITION( mTimeSignature != 0x0 );
	
	return mTimeSignature;
}

bool TrackProperties::hasTimeSignature() const
{
	return (mTimeSignature != 0x0);
}

void TrackProperties::setNumerator(uchar c)
{
	timeSignature()->setNumerator(c);
}

uchar TrackProperties::numerator() const
{
	return timeSignature()->numerator();
}

void TrackProperties::setDenominator(uchar c)
{
	timeSignature()->setDenominator(c);
}

uchar TrackProperties::denominator() const
{
	return timeSignature()->denominator();
}

uint TrackProperties::timeLigatures() const
{
	return timeSignature()->timeLigatures();
}

bool TrackProperties::operator==(const TrackProperties& trackProperties) const
{
	bool midiOp;
	bool timeSigOp;
	
	if (hasMidiProperties() == true && trackProperties.hasMidiProperties() == true)
		if (midiProperties()->operator==(*trackProperties.midiProperties()))
			midiOp = true;
		else
			midiOp = false;
	else
		midiOp = true;
	
	if (hasTimeSignature() == true && trackProperties.hasTimeSignature() == true)
		if (timeSignature()->operator==(*trackProperties.timeSignature()))
			timeSigOp = true;
		else
			timeSigOp = false;
	else
		timeSigOp = true;
	
	return (trackMode == trackProperties.trackMode && nameProp == trackProperties.nameProp &&
			colorTrack == trackProperties.colorTrack && nbStringsProp == trackProperties.nbStringsProp &&
			nbFretsProp == trackProperties.nbFretsProp && capoFret == trackProperties.capoFret &&
			tuneProp == trackProperties.tuneProp && midiOp == true && timeSigOp == true);
}

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

void TrackProperties::connectObjects()
{
	connect(mMidiProperties, SIGNAL(midiPropertyChanged()), this, SIGNAL(trackPropertyChanged()));
	connect(mTimeSignature, SIGNAL(timeSignatureChanged()), this, SIGNAL(trackPropertyChanged()));
}

#include "trackproperties.moc"
