//=============================================================================
//  MuseScore
//  Music Composition & Notation
//
//  Copyright (C) 2013 Werner Schweer
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License version 2
//  as published by the Free Software Foundation and appearing in
//  the file LICENCE.GPL
//=============================================================================

#include "testing/qtestsuite.h"
#include "testbase.h"

#include "libmscore/score.h"
#include "libmscore/excerpt.h"

#include "modularity/ioc.h"
#include "importexport/guitarpro/iguitarproconfiguration.h"

static const QString GUITARPRO_DIR("data/");

using namespace Ms;

//---------------------------------------------------------
//   TestGuitarPro
//---------------------------------------------------------

class TestGuitarPro : public QObject, public MTest
{
    Q_OBJECT

    void gpReadTest(const char* file,  const char* ext);

private slots:
    void initTestCase();
    void gpTestIrrTuplet() { gpReadTest("testIrrTuplet", "gp"); }
    void gpxTestIrrTuplet() { gpReadTest("testIrrTuplet", "gpx"); }
    void gp4TestIrrTuplet() { gpReadTest("testIrrTuplet", "gp4"); }
    void gpSforzato() { gpReadTest("sforzato", "gp"); }
    void gpxSforzato() { gpReadTest("sforzato", "gpx"); }
    void gp4Sforzato() { gpReadTest("sforzato", "gp4"); }
    void gpHeavyAccent() { gpReadTest("heavy-accent", "gp"); }
    void gpxHeavyAccent() { gpReadTest("heavy-accent", "gpx"); }
    void gp5HeavyAccent() { gpReadTest("heavy-accent", "gp5"); }
    void gpTremolos() { gpReadTest("tremolos", "gp"); }
    void gpxTremolos() { gpReadTest("tremolos", "gpx"); }
    void gp5Tremolos() { gpReadTest("tremolos", "gp5"); }
    void gpTrill() { gpReadTest("trill", "gp"); }
    void gpxTrill() { gpReadTest("trill", "gpx"); }
    void gp4Trill() { gpReadTest("trill", "gp4"); }
    void gpDynamic() { gpReadTest("dynamic", "gp"); }
    void gpxDynamic() { gpReadTest("dynamic", "gpx"); }
    void gp5Dynamic() { gpReadTest("dynamic", "gp5"); }
//      void gpGraceNote()      { gpReadTest("grace", "gp"); }
//      void gpxGraceNote()     { gpReadTest("grace", "gpx"); }
    void gp5GraceNote() { gpReadTest("grace", "gp5"); }
//      void gpVolta()          { gpReadTest("volta", "gp"); }
//      void gpxVolta()         { gpReadTest("volta", "gpx"); }
    void gp5Volta() { gpReadTest("volta", "gp5"); }
    void gp4Volta() { gpReadTest("volta", "gp4"); }
    void gp3Volta() { gpReadTest("volta", "gp3"); }
    void gpcopyright() { gpReadTest("copyright", "gp"); }
    void gpxcopyright() { gpReadTest("copyright", "gpx"); }
    void gp5copyright() { gpReadTest("copyright", "gp5"); }
    void gp4copyright() { gpReadTest("copyright", "gp4"); }
    void gp3copyright() { gpReadTest("copyright", "gp3"); }
    void gpTempo() { gpReadTest("tempo", "gp"); }
    void gpxTempo() { gpReadTest("tempo", "gpx"); }
    void gp5Tempo() { gpReadTest("tempo", "gp5"); }
    void gp4Tempo() { gpReadTest("tempo", "gp4"); }
    void gp3Tempo() { gpReadTest("tempo", "gp3"); }
    void gpBasicBend() { gpReadTest("basic-bend", "gp"); }
    void gpxBasicBend() { gpReadTest("basic-bend", "gpx"); }
    void gp5BasicBend() { gpReadTest("basic-bend", "gp5"); }
//      void gpBend()           { gpReadTest("bend", "gp"); }
//      void gpxBend()          { gpReadTest("bend", "gpx"); }
//      void gp5Bend()          { gpReadTest("bend", "gp5"); }
//      void gp4Bend()          { gpReadTest("bend", "gp4"); }
//      void gp3Bend()          { gpReadTest("bend", "gp3"); }
    void gpKeysig() { gpReadTest("keysig", "gp"); }
    void gpxKeysig() { gpReadTest("keysig", "gpx"); }
    void gp5Keysig() { gpReadTest("keysig", "gp5"); }
    void gp4Keysig() { gpReadTest("keysig", "gp4"); }
    void gpDottedTuplets() { gpReadTest("dotted-tuplets", "gp"); }
    void gpxDottedTuplets() { gpReadTest("dotted-tuplets", "gpx"); }
    void gp5DottedTuplets() { gpReadTest("dotted-tuplets", "gp5"); }
//      void gpTupletSlur()     { gpReadTest("tuplet-with-slur", "gp"); }
//      void gpxTupletSlur()    { gpReadTest("tuplet-with-slur", "gpx"); }
//      void gp4TupletSlur()    { gpReadTest("tuplet-with-slur", "gp4"); }
//      void gpBeamsStemsLL()   { gpReadTest("beams-stems-ledger-lines", "gp"); }
//      void gpxBeamsStemsLL()  { gpReadTest("beams-stems-ledger-lines", "gpx"); }
//      void gp5BeamsStemsLL()  { gpReadTest("beams-stems-ledger-lines", "gp5"); }
//      void gpFretDiagram_2Instr()  { gpReadTest("fret-diagram_2instruments", "gp"); }
//      void gpxFretDiagram_2Instr() { gpReadTest("fret-diagram_2instruments", "gpx"); }
//      void gpFretDiagram()    { gpReadTest("fret-diagram", "gp"); }
//      void gpxFretDiagram()   { gpReadTest("fret-diagram", "gpx"); }
//      void gp5FretDiagram()   { gpReadTest("fret-diagram", "gp5"); }
//      void gp4FretDiagram()   { gpReadTest("fret-diagram", "gp4"); }
    void gpFadeIn() { gpReadTest("fade-in", "gp"); }
    void gpxFadeIn() { gpReadTest("fade-in", "gpx"); }
    void gp5FadeIn() { gpReadTest("fade-in", "gp5"); }
    void gp4FadeIn() { gpReadTest("fade-in", "gp4"); }
//      void gpSlurNoteMask()   { gpReadTest("slur-notes-effect-mask", "gp"); }
//      void gpxSlurNoteMask()  { gpReadTest("slur-notes-effect-mask", "gpx"); }
    void gp5SlurNoteMask() { gpReadTest("slur-notes-effect-mask", "gp5"); }
    void gpCentered() { gpReadTest("rest-centered", "gp"); }
    void gpxCentered() { gpReadTest("rest-centered", "gpx"); }
    void gp5Centered() { gpReadTest("rest-centered", "gp5"); }
    void gp4Centered() { gpReadTest("rest-centered", "gp4"); }
//      void gpSlideInAbove()   { gpReadTest("slide-in-above", "gp"); }
//      void gpxSlideInAbove()  { gpReadTest("slide-in-above", "gpx"); }
//      void gp5SlideInAbove()  { gpReadTest("slide-in-above", "gp5"); }
    void gp4SlideInAbove() { gpReadTest("slide-in-above", "gp4"); }
//      void gpSlideInBelow()   { gpReadTest("slide-in-below", "gp"); }
//      void gpxSlideInBelow()  { gpReadTest("slide-in-below", "gpx"); }
//      void gp5SlideInBelow()  { gpReadTest("slide-in-below", "gp5"); }
//      void gp4SlideInBelow()  { gpReadTest("slide-in-below", "gp4"); }
//      void gpSlideOutUp()     { gpReadTest("slide-out-up", "gp"); }
//      void gpxSlideOutUp()    { gpReadTest("slide-out-up", "gpx"); }
//      void gp5SlideOutUp()    { gpReadTest("slide-out-up", "gp5"); }
//      void gp4SlideOutUp()    { gpReadTest("slide-out-up", "gp4"); }
//      void gpSlideOutDown()   { gpReadTest("slide-out-down", "gp"); }
//      void gpxSlideOutDown()  { gpReadTest("slide-out-down", "gpx"); }
//      void gp5SlideOutDown()  { gpReadTest("slide-out-down", "gp5"); }
//      void gp4SlideOutDown()  { gpReadTest("slide-out-down", "gp4"); }
//      void gpLegatoSlide()    { gpReadTest("legato-slide", "gp"); }
//      void gpxLegatoSlide()   { gpReadTest("legato-slide", "gpx"); }
//      void gp5LegatoSlide()   { gpReadTest("legato-slide", "gp5"); }
//      void gp4LegatoSlide()   { gpReadTest("legato-slide", "gp4"); }
//      void gpShiftSlide()     { gpReadTest("shift-slide", "gp"); }
//      void gpxShiftSlide()    { gpReadTest("shift-slide", "gpx"); }
//      void gp5ShiftSlide()    { gpReadTest("shift-slide", "gp5"); }
    void gp4ShiftSlide() { gpReadTest("shift-slide", "gp4"); }
    void gpDoubleBar() { gpReadTest("double-bar", "gp"); }
    void gpxDoubleBar() { gpReadTest("double-bar", "gpx"); }
    void gpCrecDim() { gpReadTest("crescendo-diminuendo", "gp"); }
    void gpxCrecDim() { gpReadTest("crescendo-diminuendo", "gpx"); }
    void gpDeadNote() { gpReadTest("dead-note", "gp"); }
    void gpxDeadNote() { gpReadTest("dead-note", "gpx"); }
    void gpWah() { gpReadTest("wah", "gp"); }
    void gpxWah() { gpReadTest("wah", "gpx"); }
    void gpAccent() { gpReadTest("accent", "gp"); }
    void gpxAccent() { gpReadTest("accent", "gpx"); }
    void gpArpeggio() { gpReadTest("arpeggio", "gp"); }
    void gpxArpeggio() { gpReadTest("arpeggio", "gpx"); }
    void gpTurn() { gpReadTest("turn", "gp"); }
    void gpxTurn() { gpReadTest("turn", "gpx"); }
    void gpMordents() { gpReadTest("mordents", "gp"); }
    void gpxMordents() { gpReadTest("mordents", "gpx"); }
    void gpPickUpDown() { gpReadTest("pick-up-down", "gp"); }
    void gpxPickUpDown() { gpReadTest("pick-up-down", "gpx"); }
    void gp5PickUpDown() { gpReadTest("pick-up-down", "gp5"); }
    void gp4PickUpDown() { gpReadTest("pick-up-down", "gp4"); }
    void gpFingering() { gpReadTest("fingering", "gp"); }
    void gpxFingering() { gpReadTest("fingering", "gpx"); }
    void gp5Fingering() { gpReadTest("fingering", "gp5"); }
    void gp4Fingering() { gpReadTest("fingering", "gp4"); }
    void gpBrush() { gpReadTest("brush", "gp"); }
    void gpxBrush() { gpReadTest("brush", "gpx"); }
    void gp5Brush() { gpReadTest("brush", "gp5"); }
    void gp4Brush() { gpReadTest("brush", "gp4"); }
    void gpRepeats() { gpReadTest("repeats", "gp"); }
    void gpxRepeats() { gpReadTest("repeats", "gpx"); }
//      void gpGraceBefore()    { gpReadTest("grace-before-beat", "gp"); }
//      void gpxGraceBefore()   { gpReadTest("grace-before-beat", "gpx"); }
//      void gpGraceOn()        { gpReadTest("grace-on-beat", "gp"); }
//      void gpxGraceOn()       { gpReadTest("grace-on-beat", "gpx"); }
    void gpPalmMute() { gpReadTest("palm-mute", "gp"); }
    void gpxPalmMute() { gpReadTest("palm-mute", "gpx"); }
    void gp5PalmMute() { gpReadTest("palm-mute", "gp5"); }
    void gp4PalmMute() { gpReadTest("palm-mute", "gp4"); }
    void gpLetRing() { gpReadTest("let-ring", "gp"); }
    void gpxLetRing() { gpReadTest("let-ring", "gpx"); }
    void gp5LetRing() { gpReadTest("let-ring", "gp5"); }
    void gp4LetRing() { gpReadTest("let-ring", "gp4"); }
    void gpTapSlapPop() { gpReadTest("tap-slap-pop", "gp"); }
    void gpxTapSlapPop() { gpReadTest("tap-slap-pop", "gpx"); }
    void gp5TapSlapPop() { gpReadTest("tap-slap-pop", "gp5"); }
//      void gpBarre()          { gpReadTest("barre", "gp"); }
//      void gpxBarre()         { gpReadTest("barre", "gpx"); }
//      void gpTimer()          { gpReadTest("timer", "gp"); }
//      void gpxTimer()         { gpReadTest("timer", "gpx"); }
    void gpText() { gpReadTest("text", "gp"); }
    void gpxText() { gpReadTest("text", "gpx"); }
    void gpArtHarmonic() { gpReadTest("artificial-harmonic", "gp"); }
    void gpxArtHarmonic() { gpReadTest("artificial-harmonic", "gpx"); }
//      void gpGhost()          { gpReadTest("ghost-note", "gp"); }
//      void gpxGhost()         { gpReadTest("ghost-note", "gpx"); }
    void gp3GhostNote() { gpReadTest("ghost_note", "gp3"); }
//      void gpRasg()           { gpReadTest("rasg", "gp"); }
//      void gpxRasg()          { gpReadTest("rasg", "gpx"); }
//      void gpPercussion()     { gpReadTest("all-percussion", "gp"); }
//      void gpxPercussion()    { gpReadTest("all-percussion", "gpx"); }
//      void gp5Percussion()    { gpReadTest("all-percussion", "gp5"); }
//      void gpFermata()        { gpReadTest("fermata", "gp"); }
//      void gpxFermata()       { gpReadTest("fermata", "gpx"); }
//      void gpDirections()     { gpReadTest("directions", "gp"); }
////ws: no idea why this does not work      void gpxDirections()   { gpReadTest("directions", "gpx"); }
    void gpSlur() { gpReadTest("slur", "gp"); }
    void gpxSlur() { gpReadTest("slur", "gpx"); }
    void gp4Slur() { gpReadTest("slur", "gp4"); }
    void gpSlurHS() { gpReadTest("slur_hammer_slur", "gp"); }
    void gpxSlurHS() { gpReadTest("slur_hammer_slur", "gpx"); }
    void gpSlur3M() { gpReadTest("slur_over_3_measures", "gp"); }
    void gpxSlur3M() { gpReadTest("slur_over_3_measures", "gpx"); }
    void gpSlurSH() { gpReadTest("slur_slur_hammer", "gp"); }
    void gpxSlurSH() { gpReadTest("slur_slur_hammer", "gpx"); }
    void gpSlurV() { gpReadTest("slur_voices", "gp"); }
    void gpxSlurV() { gpReadTest("slur_voices", "gpx"); }
    void gpVibrato() { gpReadTest("vibrato", "gp"); }
    void gpxVibrato() { gpReadTest("vibrato", "gpx"); }
    void gp5Vibrato() { gpReadTest("vibrato", "gp5"); }
    void gpVolumeSwell() { gpReadTest("volume-swell", "gp"); }
    void gpxVolumeSwell() { gpReadTest("volume-swell", "gpx"); }
//      void gpTremoloBar()     { gpReadTest("tremolo-bar", "gp"); }
//      void gpxTremoloBar()    { gpReadTest("tremolo-bar", "gpx"); }
    void gpFreeTime() { gpReadTest("free-time", "gp"); }
    void gpxFreeTime() { gpReadTest("free-time", "gpx"); }
    void gpRepeatBar() { gpReadTest("repeated-bars", "gp"); }
    void gpxRepeatBar() { gpReadTest("repeated-bars", "gpx"); }
    void gpDottedGliss() { gpReadTest("dotted-gliss", "gp"); }
    void gpxDottedGliss() { gpReadTest("dotted-gliss", "gpx"); }
    void gp3DottedGliss() { gpReadTest("dotted-gliss", "gp3"); }
    void gpHighPitch() { gpReadTest("high-pitch", "gp"); }
    void gpxHighPitch() { gpReadTest("high-pitch", "gpx"); }
    void gp3HighPitch() { gpReadTest("high-pitch", "gp3"); }
    void gpMultiVoices() { gpReadTest("multivoices", "gp"); }
    void gpxMultiVoices() { gpReadTest("multivoices", "gpx"); }
    void gpOttava1() { gpReadTest("ottava1", "gp"); }
    void gpxOttava1() { gpReadTest("ottava1", "gpx"); }
    void gpOttava2() { gpReadTest("ottava2", "gp"); }
    void gpxOttava2() { gpReadTest("ottava2", "gpx"); }
    void gpOttava3() { gpReadTest("ottava3", "gp"); }
    void gpxOttava3() { gpReadTest("ottava3", "gpx"); }
    void gpOttava4() { gpReadTest("ottava4", "gp"); }
    void gpxOttava4() { gpReadTest("ottava4", "gpx"); }
    void gpOttava5() { gpReadTest("ottava5", "gp"); }
    void gpxOttava5() { gpReadTest("ottava5", "gpx"); }
//      void gpChornamesKeyboard()  { gpReadTest("chordnames_keyboard", "gp"); }
//      void gpxChornamesKeyboard() { gpReadTest("chordnames_keyboard", "gpx"); }
    void gpClefs() { gpReadTest("clefs", "gp"); }
    void gpxClefs() { gpReadTest("clefs", "gpx"); }
    void gpxTuplets() { gpReadTest("tuplets", "gpx"); }
    void gpxTuplets2() { gpReadTest("tuplets2", "gpx"); }
    void gp3CapoFret() { gpReadTest("capo-fret", "gp3"); }
    void gp4CapoFret() { gpReadTest("capo-fret", "gp4"); }
    void gp5CapoFret() { gpReadTest("capo-fret", "gp5"); }
    void gpxUncompletedMeasure() { gpReadTest("UncompletedMeasure", "gpx"); }
};

//---------------------------------------------------------
//   initTestCase
//---------------------------------------------------------

void TestGuitarPro::initTestCase()
{
    initMTest(QString(iex_guitarpro_tests_DATA_ROOT));

    using namespace mu::iex::guitarpro;

    std::shared_ptr<IGuitarProConfiguration> conf = mu::framework::ioc()->resolve<IGuitarProConfiguration>("");
    conf->setImportGuitarProCharset("");
}

//---------------------------------------------------------
//   gpReadTest
//   import file, write to a MuseScore file and verify against reference
//---------------------------------------------------------

void TestGuitarPro::gpReadTest(const char* file, const char* ext)
{
    MasterScore* score = readScore(GUITARPRO_DIR + file + "." + ext);
    QVERIFY(score);

    QVERIFY(saveCompareScore(score, QString("%1.%2.mscx").arg(file).arg(ext),
                             GUITARPRO_DIR + QString("%1.%2-ref.mscx").arg(file).arg(ext)));
    delete score;
}

QTEST_MAIN(TestGuitarPro)
#include "tst_guitarpro.moc"
