/***************************************************************************
 * ktabedit.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 "ktabedit.h"

#include <QAction>
#include <QApplication>
#include <QCloseEvent>
#include <QComboBox>
#include <QCoreApplication>
#include <QFileDialog>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QPrinter>
#include <QPrintDialog>
#include <QStatusBar>
#include <QToolBar>
#include <QUndoStack>
#include <KMessageBox>

#include "assistant/assistant.h"
#include "assistant/timiditylauncher.h"
#include "fileImporter/convertascii.h"
#include "fileImporter/guitarpro.h"
#include "fileImporter/guitarpro4.h"
#include "fileImporter/kguitartab.h"
#include "fileImporter/lilypond.h"
#include "fileImporter/midi.h"
#include "fileImporter/powertab.h"
#include "fileImporter/texnotes.h"
#include "fileImporter/textab.h"
#include "fileImporter/xmlmusic.h"
#include "tablature/tabduration.h"
#include "tablature/tabsong.h"
#include "global.h"
#include "settings.h"
#include "songview.h"

#include "util/assert.h"

QString drum_abbr[128];

//TODO: What is this? Why is this here?
void initDrum()
{
	drum_abbr[35] = QString("BD1");
	drum_abbr[36] = QString("BD2");
	drum_abbr[38] = QString("SD1");
	drum_abbr[40] = QString("SD2");
	
	drum_abbr[39] = QString("HCL"); // Hand clap
	
	drum_abbr[42] = QString("CHH");
	drum_abbr[44] = QString("PHH");
	drum_abbr[46] = QString("OHH");
	
	drum_abbr[49] = QString("CR1"); // Crash cymbal
	drum_abbr[57] = QString("CR2");
	
	drum_abbr[51] = QString("RI1"); // Ride cymbal
	drum_abbr[59] = QString("RI2");
	
	drum_abbr[54] = QString("TBR"); // Tamborine
	drum_abbr[55] = QString("SPL"); // Splash cymbal
	
	drum_abbr[41] = QString("TL2");
	drum_abbr[43] = QString("TL1");
	drum_abbr[45] = QString("TM2");
	drum_abbr[47] = QString("TM1");
	drum_abbr[48] = QString("TH2");
	drum_abbr[50] = QString("TH1");
}

/**
@brief Constructor
*/
KTabEdit::KTabEdit()
: QMainWindow(),
  mSettings(Settings::getInstance()),
  mFactory(),
  mScheduler(0x0),
  mTimidityLauncher(0x0)
{
	mUndoStack = new QUndoStack;
	createSettings();
	createMidiScheduler();
	mSongView = new SongView(mScheduler, mUndoStack);
	createActions();
	createMenus();
	createToolBars();
	createStatusBar();
	connectSongViewActions();
	createCentralWidget();
	initDrum();
	setCaption(tr("Unnamed"));
}


/**
@brief Destructor
*/
KTabEdit::~KTabEdit()
{
	delete mSongView;
	delete mUndoStack;
	
	if (mScheduler != 0x0)
		delete mScheduler;
}


void KTabEdit::createSettings()
{
	QCoreApplication::setOrganizationName("KTabEdit");
	QCoreApplication::setOrganizationDomain("ktabedit.sourceforge.net");
	QCoreApplication::setApplicationName("KTabEdit");
}


void KTabEdit::createMidiScheduler()
{
	if (mSettings->assistant() == false) {
		Assistant assistant(mFactory, this);
		assistant.exec();
		
		mTimidityLauncher = assistant.timidityLauncher();
		mScheduler        = assistant.midiScheduler();
	} else {
		if (mScheduler)
			delete mScheduler;
		
		try {
			mScheduler = mFactory.createScheduler();
		} catch (TSE3::MidiSchedulerError e) {
			QString temp = e.what();
			
			qDebug() << "error while creating the midi scheduler !!\n" << temp << "\n";
			KMessageBox::error(0, tr("TSE3 error"), tr("Could not create a MidiScheduler for this platform ") + temp);
			mScheduler = 0;
			
			return ;
		}
		
		if (mSettings->midiTimidity() == true) {
			mTimidityLauncher = new TimidityLauncher();
			
			if (!mTimidityLauncher->launchTimidity())
				KMessageBox::error(0, "Could not launch timidity " + mTimidityLauncher->errorMsg());
		}
	}
}


/**
@brief Create the actions
*/
void KTabEdit::createActions()
{
	// File actions
	mNewAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
	mNewAct->setShortcut(tr("Ctrl+N"));
	mNewAct->setStatusTip(tr("Create a new file"));
	connect(mNewAct, SIGNAL(triggered()), this, SLOT(fileNew()));
	
	mOpenAct = new QAction(QIcon(":/images/open.png"), tr("&Open"), this);
	mOpenAct->setShortcut(tr("Ctrl+O"));
	mOpenAct->setStatusTip(tr("Open an existing file"));
	connect(mOpenAct, SIGNAL(triggered()), this, SLOT(fileOpen()));
	
	mSaveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
	mSaveAct->setShortcut(tr("Ctrl+S"));
	mSaveAct->setStatusTip(tr("Save the file to disk"));
	connect(mSaveAct, SIGNAL(triggered()), this, SLOT(fileSave()));
	
	mSaveAsAct = new QAction(QIcon(":/images/saveas.png"), tr("Save &As..."), this);
	mSaveAsAct->setStatusTip(tr("Save the file under a new name"));
	connect(mSaveAsAct, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
	
	mPrintAct = new QAction(QIcon(":/images/print.png"), tr("&Print"), this);
	mPrintAct->setShortcut(tr("Ctrl+P"));
	mPrintAct->setStatusTip(tr("Print the currently displayed page"));
	connect(mPrintAct, SIGNAL(triggered()), this, SLOT(filePrint()));
	
	mExitAct = new QAction(tr("E&xit"), this);
	mExitAct->setShortcut(tr("Ctrl+Q"));
	mExitAct->setStatusTip(tr("Exit the application"));
	connect(mExitAct, SIGNAL(triggered()), this, SLOT(close()));


	// Edit actions
	mCutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
	mCutAct->setShortcut(tr("Ctrl+X"));
	mCutAct->setStatusTip(tr("Cut the current selection's contents to the clipboard"));
	connect(mCutAct, SIGNAL(triggered()), mSongView, SLOT(cut()));
	
	mCopyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
	mCopyAct->setShortcut(tr("Ctrl+C"));
	mCopyAct->setStatusTip(tr("Copy the current selection's contents to the clipboard"));
	connect(mCopyAct, SIGNAL(triggered()), mSongView, SLOT(copy()));
	
	mPasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
	mPasteAct->setShortcut(tr("Ctrl+V"));
	mPasteAct->setStatusTip(tr("Paste the clipbaord's contents into the current selection"));
	connect(mPasteAct, SIGNAL(triggered()), mSongView, SLOT(paste()));
	
	mSelectAllAct = new QAction(QIcon(":/images/selectall.png"), tr("Select All"), this);
	mSelectAllAct->setShortcut(tr("Ctrl+A"));
	mSelectAllAct->setStatusTip(tr("Select all the current document"));
	connect(mSelectAllAct, SIGNAL(triggered()), mSongView, SLOT(selectAll()));
	
	mUndoAct = mUndoStack->createUndoAction(this);
	mUndoAct->setShortcut(tr("Ctrl+Z"));
	
	mRedoAct = mUndoStack->createRedoAction(this);
	mRedoAct->setShortcut(tr("Ctrl+R"));


	// View actions
	mZoomInAct = new QAction(tr("Zoom In"), this);
	connect(mZoomInAct, SIGNAL(triggered()), mSongView, SLOT(zoomIn()));
	
	mZoomOutAct = new QAction(tr("Zoom Out"), this);
	connect(mZoomOutAct, SIGNAL(triggered()), mSongView, SLOT(zoomOut()));
	
	mMelodyEditorAct = new QAction(tr("Show Melody Editor"), this);
	mMelodyEditorAct->setCheckable(true);
	connect(mMelodyEditorAct, SIGNAL(toggled(bool)), mSongView, SLOT(showMelodyEditor(bool)));
	
	mScoreAct = new QAction(tr("Show Score"), this);
	mScoreAct->setCheckable(true);
	connect(mScoreAct, SIGNAL(toggled(bool)), mSongView, SLOT(showScore(bool)));


	// Song actions
	mSongPropertiesAct = new QAction(tr("Song properties"), this);
	connect(mSongPropertiesAct, SIGNAL(triggered()), mSongView, SLOT(songProperties()));


	// Track actions
	mNewTrackAct = new QAction(QIcon(":/images/newtrack.png"), tr("New track"), this);
	connect(mNewTrackAct, SIGNAL(triggered()), mSongView, SLOT(trackNew()));
	
	mDeleteTrackAct = new QAction(QIcon(":/images/deletetrack.png"), tr("Delete track"), this);
	connect(mDeleteTrackAct, SIGNAL(triggered()), mSongView, SLOT(trackDelete()));
	
	mPropertiesTrackAct = new QAction(QIcon(":/images/propertiestrack.png"), tr("Properties of track"), this);
	connect(mPropertiesTrackAct, SIGNAL(triggered()), mSongView, SLOT(trackProperties()));


	// Bar actions
	mAddBarAct = new QAction(QIcon(":/images/addbar.png"), tr("Add a bar"), this);
	connect(mAddBarAct, SIGNAL(triggered()), mSongView, SLOT(addBar()));
	
	mDeleteBarAct = new QAction(QIcon(":/images/deletebar.png"), tr("Delete bar"), this);
	connect(mDeleteBarAct, SIGNAL(triggered()), mSongView, SLOT(deleteBar()));
	
	mKeySignatureAct = new QAction(QIcon(":/images/keysignature.png"), tr("Key signature"), this);
	connect(mKeySignatureAct, SIGNAL(triggered()), mSongView, SLOT(keySignature()));
	
	mTimeSignatureAct = new QAction(QIcon(":/images/timesignature.png"), tr("Time signature"), this);
	connect(mTimeSignatureAct, SIGNAL(triggered()), mSongView, SLOT(timeSignature()));


	// Time actions
	mAddTimeAct = new QAction(tr("Add a time"), this);
	connect(mAddTimeAct, SIGNAL(triggered()), mSongView, SLOT(addTime()));
	
	mDeleteTimeAct = new QAction(tr("Delete a time"), this);
	connect(mDeleteTimeAct, SIGNAL(triggered()), mSongView, SLOT(deleteTime()));
	
	mChordAct = new QAction(tr("Add a chord"), this);
	connect(mChordAct, SIGNAL(triggered()), mSongView, SLOT(addChord()));
	
	mDurationWholeAct = new QAction(tr("Whole"), this);
	connect(mDurationWholeAct, SIGNAL(triggered()), mSongView, SLOT(setLengthWhole()));
	
	mDurationHalfAct = new QAction(tr("1/2"), this);
	connect(mDurationHalfAct, SIGNAL(triggered()), mSongView, SLOT(setLengthHalf()));
	
	mDurationQuarterAct = new QAction(tr("1/4"), this);
	connect(mDurationQuarterAct, SIGNAL(triggered()), mSongView, SLOT(setLengthQuarter()));
	
	mDurationEighthAct = new QAction(tr("1/8"), this);
	connect(mDurationEighthAct, SIGNAL(triggered()), mSongView, SLOT(setLengthEighth()));
	
	mDurationSixteenthAct = new QAction(tr("1/16"), this);
	connect(mDurationSixteenthAct, SIGNAL(triggered()), mSongView, SLOT(setLengthSixteenth()));
	
	mDurationThirtySecondAct = new QAction(tr("1/32"), this);
	connect(mDurationThirtySecondAct, SIGNAL(triggered()), mSongView, SLOT(setLengthThirtySecond()));
	
	mDurationSixtyFourthAct = new QAction(tr("1/64"), this);
	connect(mDurationSixtyFourthAct, SIGNAL(triggered()), mSongView, SLOT(setLengthSixtyFourth()));


	// Effects actions
	mDottedTimeAct = new QAction(tr("Dotted"), this);
	connect(mDottedTimeAct, SIGNAL(triggered()), mSongView, SLOT(setDotted()));
	
	mRestAct = new QAction(tr("Rest"), this);
	connect(mRestAct, SIGNAL(triggered()), mSongView, SLOT(setRest()));
	
	mLinkPrevAct = new QAction(tr("Link"), this);
	connect(mLinkPrevAct, SIGNAL(triggered()), mSongView, SLOT(setLinkPrev()));
	
	mLegatoAct = new QAction(tr("Legato"), this);
	connect(mLegatoAct, SIGNAL(triggered()), mSongView, SLOT(setLegato()));
	
	mSlideAct = new QAction(tr("Slide"), this);
	connect(mSlideAct, SIGNAL(triggered()), mSongView, SLOT(setSlide()));
	
	mLetRingAct = new QAction(tr("Let Ring"), this);
	connect(mLetRingAct, SIGNAL(triggered()), mSongView, SLOT(setLetRing()));
	
	mHarmonicAct = new QAction(tr("Harmonic"), this);
	connect(mHarmonicAct, SIGNAL(triggered()), mSongView, SLOT(setHarmonic()));
	
	mPalmMutingAct = new QAction(tr("Palm Muting"), this);
	connect(mPalmMutingAct, SIGNAL(triggered()), mSongView, SLOT(setPalmMuting()));
	
	mTupletAct = new QAction(tr("Tuplet"), this);
	connect(mTupletAct, SIGNAL(triggered()), mSongView, SLOT(setTuplet()));
	
	mBendAct = new QAction(tr("Bend"), this);
	connect(mBendAct, SIGNAL(triggered()), mSongView, SLOT(setBend()));
	
	mVibratoAct = new QAction(tr("Vibrato"), this);
	connect(mVibratoAct, SIGNAL(triggered()), mSongView, SLOT(setVibrato()));
	
	mTrillAct = new QAction(tr("Trill"), this);
	connect(mTrillAct, SIGNAL(triggered()), mSongView, SLOT(setTrill()));
	
	mTappingAct = new QAction(tr("Tapping"), this);
	connect(mTappingAct, SIGNAL(triggered()), mSongView, SLOT(setTapping()));
	
	mTremoloAct = new QAction(tr("Temolo"), this);
	connect(mTremoloAct, SIGNAL(triggered()), mSongView, SLOT(setTremolo()));


	// Help actions
	mAboutAct = new QAction(QIcon(":/images/ktabedit.png"), tr("&About"), this);
	mAboutAct->setStatusTip(tr("Show the application's About box"));
	connect(mAboutAct, SIGNAL(triggered()), this, SLOT(showAboutBox()));
	
	mAboutQtAct = new QAction(tr("About &Qt"), this);
	mAboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
	connect(mAboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}


/**
@brief Create the menus
*/
void KTabEdit::createMenus()
{
	// File menu
	mFileMenu = menuBar()->addMenu(tr("&File"));
	mFileMenu->addAction(mNewAct);
	mFileMenu->addSeparator();
	mFileMenu->addAction(mOpenAct);
	mFileMenu->addSeparator();
	mFileMenu->addAction(mSaveAct);
	mFileMenu->addAction(mSaveAsAct);
	mFileMenu->addSeparator();
	mFileMenu->addAction(mPrintAct);
	mFileMenu->addSeparator();
	mFileMenu->addAction(mExitAct);

	// Edit menu
	mEditMenu = menuBar()->addMenu(tr("&Edit"));
	mEditMenu->addAction(mUndoAct);
	mEditMenu->addAction(mRedoAct);
	mEditMenu->addSeparator();
	mEditMenu->addAction(mCutAct);
	mEditMenu->addAction(mCopyAct);
	mEditMenu->addAction(mPasteAct);
	mEditMenu->addSeparator();
	mEditMenu->addAction(mSelectAllAct);

	// View menu
	mViewMenu = menuBar()->addMenu(tr("&View"));
	mViewMenu->addAction(mZoomInAct);
	mViewMenu->addAction(mZoomOutAct);
	mViewMenu->addSeparator();
	mViewMenu->addAction(mMelodyEditorAct);
	mViewMenu->addAction(mScoreAct);

	// Song menu
	mSongMenu = menuBar()->addMenu(tr("&Song"));
	mSongMenu->addAction(mSongPropertiesAct);

	// Track menu
	mTrackMenu = menuBar()->addMenu(tr("&Track"));
	mTrackMenu->addAction(mNewTrackAct);
	mTrackMenu->addAction(mDeleteTrackAct);
	mTrackMenu->addAction(mPropertiesTrackAct);

	// Bar menu
	mBarMenu = menuBar()->addMenu(tr("&Bar"));
	mBarMenu->addAction(mAddBarAct);
	mBarMenu->addAction(mDeleteBarAct);
	mBarMenu->addAction(mKeySignatureAct);
	mBarMenu->addAction(mTimeSignatureAct);

	// Duration menu
	mDurationMenu = new QMenu(tr("Duration"));
	mDurationMenu->addAction(mDurationWholeAct);
	mDurationMenu->addAction(mDurationHalfAct);
	mDurationMenu->addAction(mDurationQuarterAct);
	mDurationMenu->addAction(mDurationEighthAct);
	mDurationMenu->addAction(mDurationSixteenthAct);
	mDurationMenu->addAction(mDurationThirtySecondAct);
	mDurationMenu->addAction(mDurationSixtyFourthAct);
	mDurationMenu->addSeparator();
	mDurationMenu->addAction(mDottedTimeAct);
	mDurationMenu->addAction(mTupletAct);

	// Effects menu
	mEffectMenu = new QMenu(tr("Effects"));
	mEffectMenu->addAction(mLinkPrevAct);
	mEffectMenu->addAction(mLegatoAct);
	mEffectMenu->addAction(mSlideAct);
	mEffectMenu->addAction(mLetRingAct);
	mEffectMenu->addAction(mHarmonicAct);
	mEffectMenu->addAction(mPalmMutingAct);
	mEffectMenu->addSeparator();
	mEffectMenu->addAction(mBendAct);
	mEffectMenu->addSeparator();
	mEffectMenu->addAction(mVibratoAct);
	mEffectMenu->addAction(mTrillAct);
	mEffectMenu->addAction(mTappingAct);
	mEffectMenu->addAction(mTremoloAct);
	
	// Time menu
	mTimeMenu = menuBar()->addMenu(tr("&Time"));
	mTimeMenu->addAction(mAddTimeAct);
	mTimeMenu->addAction(mDeleteTimeAct);
	mTimeMenu->addSeparator();
	mTimeMenu->addAction(mRestAct);
	mTimeMenu->addSeparator();
	mTimeMenu->addMenu(mDurationMenu);
	mTimeMenu->addMenu(mEffectMenu);
	mTimeMenu->addSeparator();
	mTimeMenu->addAction(mChordAct);

	// Help menu
	mHelpMenu = menuBar()->addMenu(tr("&Help"));
	mHelpMenu->addAction(mAboutAct);
	mHelpMenu->addAction(mAboutQtAct);
}


/**
@brief Create toolbars
*/
void KTabEdit::createToolBars()
{
// 	createFileToolBar();
// 	createEditToolBar();
// 	createViewToolBar();
// 	createTrackToolBar();
// 	createBarToolBar();
// 	createTimeToolBar();
	// File toolbar
	mFileToolBar = addToolBar(tr("File"));
	mFileToolBar->addAction(mNewAct);
	mFileToolBar->addAction(mOpenAct);
	mFileToolBar->addAction(mSaveAct);
	mFileToolBar->addAction(mSaveAsAct);

	// Edit toolbar
	mEditToolBar = addToolBar(tr("Edit"));
	mEditToolBar->addAction(mCutAct);
	mEditToolBar->addAction(mCopyAct);
	mEditToolBar->addAction(mPasteAct);

	// View toolbar
	mViewToolBar = addToolBar(tr("View"));
	mViewToolBar->addAction(mZoomInAct);
	mViewToolBar->addAction(mZoomOutAct);

	// Track toolbar
	mTrackToolBar = addToolBar(tr("Track"));
	mTrackToolBar->addAction(mNewTrackAct);
	mTrackToolBar->addAction(mDeleteTrackAct);

	// Bar toolbar
	mBarToolBar = addToolBar(tr("Bar"));
	mBarToolBar->addAction(mAddBarAct);
	mBarToolBar->addAction(mDeleteBarAct);
	mBarToolBar->addAction(mKeySignatureAct);
	mBarToolBar->addAction(mTimeSignatureAct);

	createDurationComboBoxForToolBar();
	createTupletComboBoxForToolBar();

	// Time toolbar	
	mTimeToolBar = addToolBar(tr("Time"));
	mTimeToolBar->addAction(mAddTimeAct);
	mTimeToolBar->addAction(mDeleteTimeAct);
	mTimeToolBar->addWidget(mDurationValues);
	mTimeToolBar->addAction(mTupletAct);
	mTimeToolBar->addWidget(mTupletValues);
}


void KTabEdit::createStatusBar()
{
	statusBar()->showMessage(tr("Bar: ") + '1');
}


void KTabEdit::connectSongViewActions()
{
	/*connect(mSongView, SIGNAL(isAccentuated(bool)), 
	connect(mSongView, SIGNAL(isGhostNote(bool)), */
	connect(mSongView, SIGNAL(isTieNote(bool)), mLegatoAct, SLOT(setChecked(bool)));
	connect(mSongView, SIGNAL(isHammerOnPullOff(bool)), mLinkPrevAct, SLOT(setChecked(bool)));
	connect(mSongView, SIGNAL(isSlide(bool)), mSlideAct, SLOT(setChecked(bool)));
	connect(mSongView, SIGNAL(isLetRing(bool)), mLetRingAct, SLOT(setChecked(bool)));
	/*connect(mSongView, SIGNAL(isDynamic(bool))
	connect(mSongView, SIGNAL(isFingeringLeft(bool))
	connect(mSongView, SIGNAL(isFingeringRight(bool))
	connect(mSongView, SIGNAL(isLeftHandVibrato(bool))
	connect(mSongView, SIGNAL(isPalmMute(bool))
	connect(mSongView, SIGNAL(isStaccato(bool))
	connect(mSongView, SIGNAL(isTremoloPicking(bool))*/
	connect(mSongView, SIGNAL(isHarmonic(bool)), mHarmonicAct, SLOT(setChecked(bool)));
	connect(mSongView, SIGNAL(isBend(bool)), mBendAct, SLOT(setChecked(bool)));
	//connect(mSongView, SIGNAL(isGraceNote(bool))
	connect(mSongView, SIGNAL(isTrill(bool)), mTrillAct, SLOT(setChecked(bool)));
	//connect(mSongView, SIGNAL(isRasgueado(bool))
	//connect(mSongView, SIGNAL(isPickStroke(bool))
	connect(mSongView, SIGNAL(isTremolo(bool)), mTremoloAct, SLOT(setChecked(bool)));
	connect(mSongView, SIGNAL(isTapping(bool)), mTappingAct, SLOT(setChecked(bool)));
	//connect(mSongView, SIGNAL(isPopping(bool))
	//connect(mSongView, SIGNAL(isSlapping(bool))
	//connect(mSongView, SIGNAL(isStroke(bool))
	connect(mSongView, SIGNAL(isVibrato(bool)), mVibratoAct, SLOT(setChecked(bool)));
	//connect(mSongView, SIGNAL(isFadeIn(bool))
}


void KTabEdit::createCentralWidget()
{
	setCentralWidget(mSongView);
}


void KTabEdit::createDurationComboBoxForToolBar()
{
	QString temp;
	
	mDurationValues = new QComboBox;
	mDurationValues->setEditable(false);
	connect(mDurationValues, SIGNAL(activated(int)), this, SLOT(setDefaultDuration(int)));
	
	mDurationValues->insertItem(1, tr("Whole"));
	mDurationValues->insertItem(2, tr("Half"));
	mDurationValues->insertItem(3, tr("Quarter"));
	mDurationValues->insertItem(4, tr("Eighth"));
	mDurationValues->insertItem(5, tr("Sixteenth"));
	mDurationValues->insertItem(6, tr("Thirty second"));
	mDurationValues->insertItem(7, tr("Sixty fourth"));
}


void KTabEdit::createTupletComboBoxForToolBar()
{
	QString temp;
	
	mTupletValues = new QComboBox;
	mTupletValues->setEditable(false);
	for (int i = 1; i < 13; i++)
		mTupletValues->insertItem(i, temp.setNum(i));
}


bool KTabEdit::exportOptionsDialog(const QString& ext)
{
	PRECONDITION( ext == "tab" || ext == "tex" );
	
	/*bool res = false;
	
	// Skip dialog if user set appopriate option
	//
	//if (!Settings::getInstance()->config->readBoolEntry("AlwaysShow", true))
	//	return true;
	
	KDialogBase opDialog(0, 0, true, tr("Additional Export Options"),
				KDialogBase::Help|KDialogBase::Default|KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok);
	
	QVBox* box = opDialog.makeVBoxMainWidget();
	OptionsPage* op;
	
	if (ext == "tab")
		op = new OptionsExportAscii(Settings::getInstance()->config, dynamic_cast<QFrame*>(box));
	else if (ext == "tex")
		op = new OptionsExportMusixtex(Settings::getInstance()->config, dynamic_cast<QFrame*>(box));
	
	connect(&opDialog, SIGNAL(defaultClicked()), op, SLOT(defaultBtnClicked()));
	connect(&opDialog, SIGNAL(okClicked()), op, SLOT(applyBtnClicked()));
	
	res = (opDialog.exec() == QDialog::Accepted);
	
	delete op;
	
	return res;*/
	
	return false;
}


/**
@brief Loads a file
*/
void KTabEdit::load(const QString& filename)
{
	FileImport* fileImporter = 0x0;
	QFile file(filename);
	QFileInfo fileInfo(file);
	QString extension = fileInfo.extension();
	
	if (!fileInfo.isFile()) {
		QMessageBox::critical(0, "KTabEdit", tr("No file specified, please select a file."));
	} else if (!fileInfo.isReadable()) {
		QMessageBox::critical(0, "KTabEdit", tr("You have no permission to read this file."));
	} else {
		extension = extension.lower();
		
		if (extension == "ptb")
			fileImporter = new PowerTab;
		else if (extension == "kg")
			fileImporter = new KGuitarTab;
		else if (extension == "tab")
			;//fileImporter = new ConvertAscii();
		else if (extension == "gtp")
			fileImporter = new GuitarPro;
		else if (((extension[0] == 'g') && (extension[1] == 'p') && (extension[2] == '3'))  && (extension.length() == 3))
			fileImporter = new GuitarPro;
		else if (extension == "xml")
			fileImporter = new XMLMusic;
		else if (((extension[0] == 'g') && (extension[1] == 'p') && (extension[2] == '4'))  && (extension.length() == 3))
			fileImporter = new GuitarPro4;
		else if (extension == "mid")
			fileImporter = new Midi;
		
		try {
			if (fileImporter) {
				if (fileImporter->loadFile(filename))
					mSongView->setTabSong(fileImporter->tabSong());
				
				delete fileImporter;
			}
		} catch(const char *msg) {
			setCaption(tr("Unnamed"));
			QMessageBox::critical(0, "KTabEdit", tr("Impossible to load the song. "
										"It may be a damaged/wrong file format or, "
										"if you are trying experimental importers "
										"it may be a flaw with the import code.") + msg);
		}
	}
}


/**
@brief Saves the file
*/
void KTabEdit::save(const QString& filename)
{
	FileExport* fileExporter = 0x0;
	QFile file(filename);
	QFileInfo* fileInfo = new QFileInfo(file);
	QString ext = fileInfo->extension().lower();
	
	if (ext == "kg") {
		fileExporter = new KGuitarTab;
	} else if (ext == "tab") {
		//Settings::getInstance()->config->setGroup("ASCII");
		
		if (exportOptionsDialog(ext))
			fileExporter = new ConvertAscii();
	} else if (ext == "gtp")
		fileExporter = new GuitarPro;
	else if ((ext[0] == 'g') && (ext[1] == 'p') && ((ext[2] == '3') || (ext[2] == '4'))  && (ext.length() == 3))
		fileExporter = new GuitarPro;
	else if (ext == "tex") {
		//Settings::getInstance()->config->setGroup("MusiXTeX");
		
		if (exportOptionsDialog(ext)) {
			switch (Settings::getInstance()->texExportMode()) {
			case 0:
				fileExporter = new TexTab;
				break;
			case 1:
				fileExporter = new TexNotes;
				break;
			}
		}
	} else if (ext == "xml")
		fileExporter = new XMLMusic;
	else if (ext == "li")
		fileExporter = new Lilypond;
	
	if (fileExporter) {
		try {
			fileExporter->saveFile(filename, *mSongView->tabSong());
			setCaption(filename);
			mUndoStack->clear();
		}
		catch (const char *msg) {
			QMessageBox::critical(0, "KTabEdit", tr("Impossible to save the song in %0 format").arg(ext));
		}
		
		delete fileExporter;
	}
}


void KTabEdit::fileNew()
{
//	if (!mKtabEditPart->url().isEmpty() || mKtabEditPart->isModified())
//		(new KTabEdit)->show();
}


void KTabEdit::fileOpen()
{
	QString filename = QFileDialog::getOpenFileName( this, tr("Open file - KTabEdit"), QString(),
					"*.kg *.gtp *.gp? *.mid *.tab *.xml *.ptb|" + tr("All music files") + '\n' +
					"*.kg|" + tr("KGuitar files") + " (*.kg)\n"
					"*.tab|" + tr("ASCII files") + " (*.tab)\n"
					"*.mid|" + tr("MIDI files") + " (*.mid)\n"
					"*.ptb|" + tr("PowerTab files") + " (*.ptb)\n"
					"*.gtp|" + tr("Guitar Pro files") + " (*.gtp)\n"
					"*.gp?|" + tr("Guitar Pro files") + " (*.gp?)\n"
					"*.xml|" + tr("MusicXML files") + " (*.xml)\n"
					"*|" + tr("All files"));
	
	if (filename.isEmpty() == false) {
		load(filename);
		/*if (mKtabEditPart->url().isEmpty() && !mKtabEditPart->isModified()) {
			load(file);
		} else {
			KGuitar* newWin = new KGuitar;
			
			newWin->load(KUrl(file));
			newWin->show();
		}*/
	}
}


void KTabEdit::fileSave()
{
}


void KTabEdit::fileSaveAs()
{
	QString filter =
		"*.kg|" + tr("KGuitar files") + " (*.kg)\n"
		"*.tab|" + tr("ASCII files") + " (*.tab)\n"
		"*.mid|" + tr("MIDI files") + " (*.mid)\n"
		"*.tse3|" + tr("TSE3MDL files") + " (*.tse3)\n"
		"*.gtp|" + tr("Guitar Pro files") + " (*.gtp)\n"
		"*.gp3|" + tr("Guitar Pro 3 files") + " (*.gp3)\n"
		"*.gp4|" + tr("Guitar Pro 4 files") + " (*.gp4)\n"
		"*.xml|" + tr("MusicXML files") + " (*.xml)\n"
		"*.li|" + tr("Lilypond files") + " (*.li)\n"
		"*.tex|" + tr("MusiXTeX") + " (*.tex)\n"
		"*|" + tr("All files");
	
	QString filename = QFileDialog::getSaveFileName(this, tr("Save file - KTabEdit"), QString(), filter);
	
	if (filename.isEmpty() == false)
		save(filename);
}


void KTabEdit::filePrint()
{
	QPrinter printer(QPrinter::HighResolution);
	QPrintDialog printDialog(&printer, this);
	//mSongView->print(&printer);
}


void KTabEdit::setDefaultDuration(int durationNumber)
{
	PRECONDITION(durationNumber >= 1 && durationNumber <= 8);
	
	switch(durationNumber) {
	case 1:
		mSongView->setDefaultDuration(Whole);
		break;
	case 2:
		mSongView->setDefaultDuration(Half);
		break;
	case 3:
		mSongView->setDefaultDuration(Quarter);
		break;
	case 4:
		mSongView->setDefaultDuration(Eighth);
		break;
	case 5:
		mSongView->setDefaultDuration(Sixteenth);
		break;
	case 6:
		mSongView->setDefaultDuration(ThirthSecond);
		break;
	case 7:
		mSongView->setDefaultDuration(SixtyFourth);
		break;
	case 8:
		mSongView->setDefaultDuration(HundredTwentyEighth);
		break;
	}
}


void KTabEdit::closeEvent(QCloseEvent* event)
{
	event->accept();
	delete this;
}

/**
@brief The application's About Message Box
*/
void KTabEdit::showAboutBox()
{
	KMessageBox::about(this, tr("<b>KTabEdit</b> is a tablature viewer, editor and player for the KDE desktop environment."));
}

#include "ktabedit.moc"
