/***************************************************************************
 *   Copyright (C) 2004 by Predrag Viceic                                  *
 *   viceic@net2000.ch                                             *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "freecycle.h"

#include <qimage.h>
#include <qslider.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qpopupmenu.h>
#include <qmenubar.h>
#include <qtextedit.h>
#include <qfile.h>
#include <qfiledialog.h>
#include <qstatusbar.h>
#include <qmessagebox.h>
#include <qprinter.h>
#include <qapplication.h>
#include <qaccel.h>
#include <qtextstream.h>
#include <qpainter.h>
#include <qpaintdevicemetrics.h>
#include <qhbox.h>
#include <qpicture.h>
#include <qwhatsthis.h>
#include <qvbox.h>
#include <qcanvas.h>
#include <iostream>
#include 	<string.h>
#include <unistd.h>
#include <qspinbox.h>


#include "pics/filesave.xpm"
#include "pics/fileopen.xpm"
#include "pics/icons.h"

Freecycle::Freecycle()
    : QMainWindow( 0, RELEASE_NAME, WDestructiveClose )
{
    loadingProject=FALSE;
    QDir freecycle_dir(QDir::homeDirPath().append("/.freecycle"));
    if (!freecycle_dir.exists()) freecycle_dir.mkdir(freecycle_dir.absPath());
    helpManager=new HelpManager(freecycle_dir.path());

    soundManager=new SoundManager();
    soundManager->setHasEnvelope(TRUE);
    soundManager->loadEffects();
    fileManager=new FileManager();
    soundManager->setFileManager(fileManager);
    midiManager=new MidiManager();
    akpManager=new AKPManager();
#ifdef HAS_LIBINSTPATCH
    sf2Manager=new SF2Manager();
    gigaManager=new GigaManager();
#endif
    QPixmap openIcon, saveIcon, printIcon;
    openIcon = QPixmap( fileopen );
    saveIcon = QPixmap( filesave );
    QMimeSourceFactory::defaultFactory()->setPixmap( "fileopen", openIcon );
    filePopupMenu = new QPopupMenu( this );
    menuBar()->insertItem( tr("&File"), filePopupMenu );

    filePopupMenu->insertItem( openIcon, tr("&Open Wave..."),
			   this, SLOT(choose()), CTRL+Key_O );

    idsavedialog=filePopupMenu->insertItem( saveIcon, tr("Save Wave"),
			   this, SLOT(save()));

    idsaveasdialog= filePopupMenu->insertItem( tr("Save Wave &As..."), this, SLOT(saveAs()) );
    idsavechunksdialog=filePopupMenu->insertItem( tr("Save Audio Chunks..."), this, SLOT(saveChunks()) );
    idsaveprojectasdialog=filePopupMenu->insertItem( tr("Save Project As..."), this, SLOT(saveProjectAs()) );
    idsaveprojectdialog=filePopupMenu->insertItem( tr("&Save Project"), this, SLOT(saveProject()),CTRL+Key_S );
    idsaveloopmidifile=filePopupMenu->insertItem( tr("Export Loop &MIDI file..."), this, 
                                                    SLOT(saveLoopMidiFile()),CTRL+Key_M );
    idloadprojectdialog=filePopupMenu->insertItem( tr("Load Project..."), this, SLOT(loadProject()) );
    


    filePopupMenu->insertSeparator();

    filePopupMenu->insertItem( tr("&Close"), this, SLOT(close()), CTRL+Key_W );

    //file->insertItem( tr("&Quit"), qApp, SLOT( closeAllWindows() ), CTRL+Key_Q );
    filePopupMenu->insertItem( tr("&Quit"), this, SLOT( close()), CTRL+Key_Q );

    menuBar()->insertSeparator();

    QPopupMenu* editPopupMenu = new QPopupMenu( this );
    editPopupMenu->insertItem( tr("Crop"), this, SLOT(cropSelection()) );
    //editPopupMenu->insertItem( tr("Undo"), this, SLOT(undo()), CTRL+Key_Z);
    //editPopupMenu->insertItem( tr("Redo"), this, SLOT(redo()), CTRL+Key_R);
    menuBar()->insertItem( tr("&Edit"), editPopupMenu,1);
    menuBar()->setItemEnabled(1,FALSE);

    QPopupMenu* effectsPopupMenu = new QPopupMenu( this );
    effectsPopupMenu->insertItem( tr("Add LADSPA Plugin..."), this, SLOT(addEffect()) );
    effectsPopupMenu->insertItem( tr("Remove LADSPA Plugin"), this, SLOT(removeEffect()) );
    menuBar()->insertItem( tr("&Effects"), effectsPopupMenu,2);
    menuBar()->setItemEnabled(2,FALSE);


    configureAnalysisPopupMenu = new QPopupMenu( this );
    configureAnalysisPopupMenu->insertItem(tr("Amplitude Domain"),this,SLOT(setAmplitudeDomain()),0,1);
    configureAnalysisPopupMenu->insertItem(tr("Frequency Domain (Experimental)"),this,SLOT(setFrequencyDomain()),0,2);

#ifdef HAS_AUBIO
    configureAnalysisPopupMenu->insertItem(tr("(Aubio) Complex domain"),this,SLOT(setComplexDomain()),0,3);
    configureAnalysisPopupMenu->insertItem(tr("(Aubio) Phase based"),this,SLOT(setPhaseDomain()),0,4);
    configureAnalysisPopupMenu->insertItem(tr("(Aubio) Spectral difference"),this,SLOT(setSpectralDomain()),0,5);
    configureAnalysisPopupMenu->insertItem(tr("(Aubio) High Frequency Content"),this,SLOT(setHFCDomain()),0,6);
    configureAnalysisPopupMenu->insertItem(tr("(Aubio) Modified Kullback Liebler"),this,SLOT(setMKLDomain()),0,7);
    configureAnalysisPopupMenu->insertItem(tr("(Aubio) Weighted Kullback Liebler"),this,SLOT(setKLDomain()),0,8);
    //configureAnalysisPopupMenu->setItemEnabled(5,FALSE);

#endif // HAS_AUBIO
    configureAnalysisPopupMenu->setItemChecked(1,TRUE);
    configureAnalysisPopupMenu->insertSeparator();
#ifdef HAS_AUBIO
    configureAnalysisPopupMenu->insertItem(tr("DerivateSignal"),this,SLOT(setDerivateSignal()),0,9);
    configureAnalysisPopupMenu->setItemChecked(9,FALSE);
#else
    configureAnalysisPopupMenu->insertItem(tr("DerivateSignal"),this,SLOT(setDerivateSignal()),0,3);
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
#endif // HAS_AUBIO







    QPopupMenu* configurationPopupMenu=new QPopupMenu(this);
    configurationPopupMenu->insertItem( tr("Analysis method"),configureAnalysisPopupMenu,1);
    fftDialog=new FFTDialog(soundManager,this);
    configurationPopupMenu->insertItem(tr("Configure FFT ..."),this,SLOT(configureFFT()));
    ampDomainDialog=new AmpDomainDialog(soundManager,this);
    configurationPopupMenu->insertItem(tr("Configure Amplitude domain ..."),this,SLOT(configureAmpDomain()));
    
    #ifdef HAS_ALSA
        midiInput=MidiInput::instantiateAlsaSeq();
    #else
        #ifdef HAS_PORTMIDI
            midiInput=MidiInput::instantiatePortMidi();
        #endif
    #endif
    #ifdef HAS_MIDI
        midiConfigDialog=new MidiConfigDialog(midiInput,this);
        configurationPopupMenu->insertItem(tr("Configure MIDI ..."),this,SLOT(configureMIDI()));
    #endif
    


    menuBar()->insertItem( tr("&Configuration"), configurationPopupMenu,3);
    menuBar()->setItemEnabled(3,FALSE);




    resize( 1000, 800 );





    centralLayout=new QVBox(this);
    centralLayout->setSpacing(5);
    setCentralWidget(centralLayout);

    //Top status bar
    topBox=new QHBox(centralLayout,"File info");
    topBox->setSpacing(5);
    topBox->setMaximumHeight(50);
    topBox->setFrameStyle(QFrame::Panel | QFrame::Raised);
    topBox->hide();
    samplerateLabel=new QLabel(topBox);
    nbframesLabel=new QLabel(topBox);
    channelsLabel=new QLabel(topBox);
    zoomRatioLabel=new QLabel(topBox);
    zoomRatioLabel->hide();
    bpmLabel=new QLabel(topBox);
    //bpmModifSpin=new BPMModifierSpinBox(topBox);
    //connect(bpmModifSpin,SIGNAL(valueChanged(int)),this,SLOT(bpmModifierValueChanged()));
    bpmModifDropDown=new BPMModifierDropDown(topBox);
    connect(bpmModifDropDown,SIGNAL(valueChanged()),this,SLOT(bpmModifierValueChanged()));

    #ifdef HAS_SOUNDTOUCH
        resampleButton=new QPushButton("time stretch to:",topBox,"resample button");
        newBPM=new FloatSpinBox(topBox);
        newBPM->setMinValue(300);
        newBPM->setMaxValue(3000);
    #endif



    //End Top status Bar
    playAndBeatLinesControls=new QHBox(centralLayout,"Play and BeatLines");
    playAndBeatLinesControls->setSpacing(0);
    playAndBeatLinesControls->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Minimum);
    playAndBeatLinesControls->hide();
    //Play buttons bar
    playButtons=new QHBox(playAndBeatLinesControls,"Play buttons");
    playButtons->setMaximumHeight(50);
    playButtons->setFrameStyle(QFrame::Panel | QFrame::Raised);
    playButtons->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Minimum);

    playButton=new QPushButton(">",playButtons);
    playButton->setAccel(Key_Enter);
    playButton->setPixmap(QPixmap(qembed_findImage("player_play")));
    playButton->setToggleButton(TRUE);
    connect(playButton, SIGNAL(clicked()),SLOT(play()));

    pauseButton=new QPushButton("||",playButtons);
    pauseButton->setPixmap(QPixmap(qembed_findImage("player_pause")));
    pauseButton->setToggleButton(TRUE);
    connect(pauseButton, SIGNAL(clicked()),SLOT(pause()));

    stopButton=new QPushButton("S",playButtons);
    stopButton->setAccel(Key_0);
    stopButton->setPixmap(QPixmap(qembed_findImage("player_stop")));
    stopButton->setToggleButton(TRUE);
    stopButton->setOn(TRUE);
    connect(stopButton, SIGNAL(clicked()),SLOT(stopPlay()));

    /*
    loopCheckBox=new QCheckBox("Loop",playButtons);
    loopCheckBox->setPixmap(QPixmap(qembed_findImage("loop")));
    connect(loopCheckBox, SIGNAL(toggled(bool)),SLOT(toggleLoop(bool)));
    */
    loopToggle=new QPushButton("Loop",playButtons);
    loopToggle->setToggleButton(TRUE);
    loopToggle->setPixmap(QPixmap(qembed_findImage("reload")));
    loopToggle->setAccel(Key_Slash);
    connect(loopToggle, SIGNAL(toggled(bool)),SLOT(toggleLoop(bool)));

    playButtons->setSpacing(1);

    //End Play buttons bar

    beatLinesControl=new QHBox(playAndBeatLinesControls,"BeatLine controls");
    beatLinesControl->setFixedHeight(50);
    beatLinesControl->setFrameStyle(QFrame::Panel | QFrame::Raised);
    beatLinesControl->setSpacing(5);
    beatLinesControl->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Fixed);

    tresholdSlider=new VolumeSlider(beatLinesControl);
    tresholdSlider->setOrientation(Qt::Horizontal);
    tresholdSlider->setMinValue(11);
    tresholdSlider->setMaxValue(200);
    tresholdSlider->setValue(160);
    tresholdSlider->setTickmarks(QSlider::Both);
    tresholdSlider->setTickInterval(10);
    tresholdSlider->setLineStep(1);
    tresholdSlider->setPageStep(10);
    tresholdSlider->setFixedWidth(200);
    connect(tresholdSlider, SIGNAL(sliderReleased()), SLOT(changeTreshold()) );

    analyseWindowDivider=new QSlider(beatLinesControl);
    analyseWindowDivider->setMinValue(0);
    analyseWindowDivider->setMaxValue(4);
    analyseWindowDivider->setValue(2);
    analyseWindowDivider->setTickmarks(QSlider::Both);
    analyseWindowDivider->setTickInterval(1);
    analyseWindowDivider->setLineStep(1);
    analyseWindowDivider->setPageStep(1);
    analyseWindowDivider->setMaximumHeight(beatLinesControl->height());
    analyseWindowDivider->hide();//not needed
    connect(analyseWindowDivider, SIGNAL(sliderMoved(int)), SLOT(changeWindowDivider(int)) );

    viewOnly=new QPushButton("view only",beatLinesControl);
    viewOnly->setToggleButton(TRUE);
    viewOnly->setPixmap(QPixmap(qembed_findImage("frame_edit")));
    viewOnly->hide(); //not well implemented



    unlockBeatLinesButton=new QPushButton("Unlock All",beatLinesControl);
    unlockBeatLinesButton->setPixmap(QPixmap(qembed_findImage("decrypted-22")));

    lockBeatLinesButton=new QPushButton("Lock All",beatLinesControl);
    lockBeatLinesButton->setPixmap(QPixmap(qembed_findImage("encrypted-22")));

    envelopeControllerWidget=new EnvelopeControllerWidget(playAndBeatLinesControls);
    //envelopeControllerWidget->hide(); //for now..
    connect(envelopeControllerWidget,SIGNAL(envelopeChanged(EnvelopeData* )),
            soundManager,SLOT(envelopeChanged(EnvelopeData* )));

    sceneFrame=new SceneFrame(playAndBeatLinesControls);
    sceneFrame->setFixedHeight(50);
    sceneFrame->setFixedWidth(182);
    sceneFrame->setFrameStyle(QFrame::Panel | QFrame::Raised);
    sceneFrame->setSpacing(0);
    sceneFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed);
    

    big_and_small_wave_and_effects=new MySplitter(Qt::Vertical,centralLayout);
    //big_and_small_wave_and_effects->setOpaqueResize(TRUE);

    MySplitter* big_and_small_wave=new MySplitter(Qt::Vertical,big_and_small_wave_and_effects);
    big_and_small_wave_and_effects->setResizeMode(big_and_small_wave,QSplitter::Auto);

    QVBox* big_wave_and_zoom=new QVBox(big_and_small_wave);

    MySplitter* big_wave_and_env=new MySplitter(Qt::Vertical,big_wave_and_zoom);
    big_wave_and_env->setHandleWidth(2);

    drawSoundWidget=new DrawSoundWidget(big_wave_and_env,"central wave",soundManager);
    drawSoundWidget->enableClipper(TRUE);
    
    connect(sceneFrame,SIGNAL(sceneSwitchedS(int)),drawSoundWidget,SLOT(sceneSwitched(int )));
    connect(sceneFrame,SIGNAL(assignToSceneS(int)),drawSoundWidget,SLOT(assignToScene(int )));

    bpmLines=new QPushButton("bpm lines",topBox);
    bpmLines->setToggleButton(TRUE);
    bpmLines->setPixmap(QPixmap(qembed_findImage("kalarm")));
    bpmLines->setDisabled(TRUE);
    connect(drawSoundWidget,SIGNAL(hasLockedBeatLines(bool)),bpmLines,SLOT(setEnabled(bool)));
    
    #ifdef HAS_MIDI
        midiInput->addMidiMonitor(drawSoundWidget);
    #endif

    //replacedWaveHolder=new ReplacedWaveHolder(big_wave_and_env);
    //replacedWaveHolder->setMaximumHeight(55);
    //replacedWaveHolder->setMinimumHeight(55);
    //replacedWaveHolder->hide();
    /*
    connect(drawSoundWidget,
            SIGNAL(contentsMoving(int,int)),
            replacedWaveHolder,SLOT(setContentsPos(int,int)));
    connect(drawSoundWidget,
            SIGNAL(receivedWave(QPoint,QString)),
            replacedWaveHolder,SLOT(setWaveAt(QPoint,QString)));
    connect(drawSoundWidget,SIGNAL(zoomChangedS(long)),
            replacedWaveHolder,SLOT(setZoomRatio(long)));
    connect(soundManager,SIGNAL(nbFramesChanged(long)),
            replacedWaveHolder,SLOT(setFrames(long)));
    */
    //envelopeHolder->setHeight(0);

    zoomBox=new QHBox(big_wave_and_zoom);
    zoomBox->setSpacing(10);
    zoomBox->setMaximumHeight(50);
    zoomBox->setFrameStyle(QFrame::Panel | QFrame::Raised);
    zoomBox->hide();

    zoomSlider=new VolumeSlider(zoomBox);
    zoomSlider->setOrientation(Qt::Horizontal);
    zoomSlider->setMinValue(1);
    zoomSlider->setTickmarks(QSlider::Both);
    zoomSlider->setTickInterval(10000);
    zoomSlider->setLineStep(10);
    zoomSlider->setPageStep(10);
    connect(zoomSlider, SIGNAL(sliderReleased()), SLOT(changeZoom()));
    //connect(zoomSlider, SIGNAL(valueChanged(int)), SLOT(changeZoom()));

    zoomToSelButton=new QPushButton("zoom to sel",zoomBox);
    zoomToSelButton->setPixmap(QPixmap(qembed_findImage("viewmagfit")));
    connect(zoomToSelButton,SIGNAL(clicked()),SLOT(zoomToSel()));

    zoomAllButton=new QPushButton("zoom all",zoomBox);
    zoomAllButton->setPixmap(QPixmap(qembed_findImage("viewmag1")));
    connect(zoomAllButton,SIGNAL(clicked()),SLOT(zoomAll()));

    connect(unlockBeatLinesButton,
                    SIGNAL(clicked()),drawSoundWidget,SLOT(unlockBeatLines()));
    connect(lockBeatLinesButton,
            SIGNAL(clicked()),drawSoundWidget,SLOT(lockBeatLines()));
    connect(bpmLines,
                    SIGNAL(toggled(bool)),drawSoundWidget,SLOT(setBPMLines(bool)));



    connect(drawSoundWidget,
                    SIGNAL(bpmChange(const QString &)),
                    bpmLabel,SLOT(setText(const QString &)));

    connect(drawSoundWidget,
                    SIGNAL(loopChange()),
                    this,SLOT(loopChanged()));



    #ifdef HAS_SOUNDTOUCH
        connect(newBPM,
                    SIGNAL(valueChanged(const QString &)),
                    drawSoundWidget,SLOT(computeNewBPMLines(const QString &)));
        connect(resampleButton,
                      SIGNAL(clicked()),drawSoundWidget,SLOT(resample()));
    #endif


    MySplitter *small_waveAndSpectrum = new MySplitter(Qt::Horizontal, big_and_small_wave );
    small_waveAndSpectrum->setOpaqueResize(TRUE);

    scopeView=new ScopeView(small_waveAndSpectrum);
    scopeView->setSoundManager(soundManager);

    big_and_small_wave->setResizeMode(small_waveAndSpectrum,QSplitter::FollowSizeHint);
    big_and_small_wave->setResizeMode(big_wave_and_zoom,QSplitter::Auto);


    drawAllSoundWidget=new DrawAllSoundWidget(small_waveAndSpectrum,
                                                                                            "small wave", soundManager);


    connect(drawSoundWidget,
                    SIGNAL(visibleAreaChanged(long,long)),
                    drawAllSoundWidget,SLOT(visibleAreaChanged(long,long)));

    connect(drawAllSoundWidget,
                    SIGNAL(visibleAreaChangedS(long,long)),
                    drawSoundWidget,SLOT(zoomToSamplePos(long,long)));

    connect(drawSoundWidget,SIGNAL(playFromPoint(long)),this,SLOT(playFromPoint(long)));
    connect(drawSoundWidget,SIGNAL(playFromTo(long,long)),this,SLOT(playFromTo(long,long)));
    connect(drawSoundWidget,SIGNAL(stopPlay()),this,SLOT(stopPlay()));
    
    #ifdef HAS_MIDI
        connect(drawSoundWidget,SIGNAL(midiAssChanged(QValueList <beatline_data>)),
            midiInput, SLOT(setBeatlineData(QValueList <beatline_data>)));
    #endif


    spectrumView=new SpectrumView(small_waveAndSpectrum);

    small_waveAndSpectrum->setResizeMode(spectrumView,QSplitter::Stretch);
    small_waveAndSpectrum->setResizeMode(scopeView,QSplitter::Stretch);
    small_waveAndSpectrum->setResizeMode(drawAllSoundWidget,QSplitter::Stretch);
    spectrumView->setSoundManager(soundManager);
    statusBar()->message( tr("Ready"), 2000 );

    soundPlayer= new SoundPlayer();
    soundPlayer->init();
    soundPlayer->setSoundmanager(soundManager);
    soundPlayer->addSoundMonitor(drawSoundWidget); //Why QThread isn't QObject ?!?
    soundPlayer->addSoundMonitor(spectrumView);        //Why QThread isn't QObject ?!?
    soundPlayer->addSoundMonitor(scopeView);        //Why QThread isn't QObject ?!?
    #ifdef HAS_MIDI
        midiInput->setSoundPlayer(soundPlayer);
    #endif
    #ifdef HAS_ALSA
        if(soundPlayer->output==SoundPlayer::OUTPUT_ALSA || soundPlayer->output==SoundPlayer::OUTPUT_NONE){
            alsaConfigDialog=new AlsaConfigDialog(soundPlayer,this);
            configurationPopupMenu->insertItem(tr("Configure ALSA ..."),this,SLOT(configureALSA()));
        }
    #endif


    centralLayout->hide();
    ladspaDialog=new LADSPADialog(this);
    connect(ladspaDialog,SIGNAL(addEffect(int )),this,SLOT(addEffectFrame(int)));
    effectFrame=NULL;



    //connect(soundManager,SIGNAL(waveChanged()),this,SLOT(repaint()));  //why have I done this ?!

    connect(soundManager,SIGNAL(waveChanged()),drawSoundWidget,
                                                SLOT(zapWaveCanvasBuffers()));
    connect(soundManager,SIGNAL(waveChanged()),drawAllSoundWidget,
                                                SLOT(zapWaveCanvasBuffers()));
    connect(soundManager,SIGNAL(waveChanged(long,long)),
            drawSoundWidget,SLOT(zapWaveCanvasBuffers(long,long)));
    connect(soundManager,SIGNAL(waveChanged(long,long)),
            drawAllSoundWidget,SLOT(zapWaveCanvasBuffers(long,long)));

    connect(soundManager,SIGNAL(nbFramesChanged(long)),this,SLOT(updateNbFramesLabel()));
    connect(soundManager,SIGNAL(cropped(long,long)),drawSoundWidget,SLOT(cropped(long,long)));
    connect(soundManager,SIGNAL(cropped(long,long)),drawAllSoundWidget,SLOT(cropped()));
    connect(soundManager,SIGNAL(cropped(long,long)),this,SLOT(cropped(long,long)));

    connect(soundManager,SIGNAL(fftParamsChanged()),drawSoundWidget,
                                                    SLOT(zapWaveCanvasBuffers()));
    connect(soundManager,SIGNAL(analysisParamsChanged()),drawSoundWidget,SLOT(reinitCanvas()));


    configureViewPopupMenu = new QPopupMenu( this );
    configureViewPopupMenu->insertItem( tr("Wave"), this, SLOT(setWaveView()),0,1);
    configureViewPopupMenu->setItemChecked(1,TRUE);
    configureViewPopupMenu->insertItem( tr("Spectrum"), this, SLOT(setSpectrumView()),0,2);
    configureViewPopupMenu->insertSeparator(3);
    configureViewPopupMenu->insertItem( tr("Show BeatLines"), this, SLOT(showBeatLines()),0,4);
    configureViewPopupMenu->setItemChecked(4,TRUE);
    menuBar()->insertItem( tr("&View"), configureViewPopupMenu,4);
    menuBar()->setItemEnabled(4,FALSE);

    QPopupMenu* helpPopupMenu=new QPopupMenu( this );
    helpPopupMenu->insertItem( tr("Help"),this,SLOT(help()));
    helpPopupMenu->insertItem( tr("About"),this,SLOT(about()));
    menuBar()->insertItem( tr("&Help"), helpPopupMenu,5);


    openFileDialog=new MyOpenFileDialog(soundManager,soundPlayer,fileManager);
    saveFileDialog=new MySaveFileDialog();
    projectManager=new ProjectManager(soundManager,envelopeControllerWidget->getEnvData());
    projectManager->setLoopMarkers(drawSoundWidget->getLeftLoopMarker(),
                                                                    drawSoundWidget->getRightLoopMarker());

    connect(projectManager,SIGNAL(loadFile(const QString&)), this, SLOT(load(const QString&)));
    connect(projectManager,SIGNAL(envelopeDataChanged()),
                envelopeControllerWidget, SLOT(envDataChanged()));
    connect(projectManager,SIGNAL(addLadspa(int)),this,SLOT(addEffectFrame(int)));
    connect(projectManager,SIGNAL(addLockedBeatlines(QValueList<beatline_data>)),
            drawSoundWidget,SLOT(initLockedBeatLines(QValueList <beatline_data>)));
    connect(projectManager,SIGNAL(addStackElementS(long,long,QString,long,int,bool )),
            drawSoundWidget,SLOT(addStackElement(long,long,QString,long,int,bool )));
    connect(projectManager,SIGNAL(bpmModifierChangeS(QString )),
            bpmModifDropDown,SLOT(setStringModifier(QString)));

    saveProjectDialog=new MySaveProjectDialog(projectManager);
    loadProjectDialog=new MyLoadProjectDialog(projectManager);

    QAccel *accelerator = new QAccel( this );        // create accels for myWindow
    accelerator->connectItem( accelerator->insertItem(Key_Space),
                    this,
                    SLOT(spaceBarPressed()));
    accelerator->connectItem( accelerator->insertItem(Key_7),
                    this,
                    SLOT(numPad7Pressed()));
    accelerator->connectItem( accelerator->insertItem(Key_9),
                    this,
                    SLOT(numPad9Pressed()));
    accelerator->connectItem( accelerator->insertItem(Key_1),
                    this,
                    SLOT(numPad1Pressed()));

    //midiOutputThread=new MidiOutputThread();
    //midiOutputThread->start();
    
    
    
    #ifdef HAS_MIDI
        midiInputThread=new MidiInputThread(midiInput);
        midiInputThread->start();
    #endif

    connect(drawSoundWidget,SIGNAL(beatLinesChanged(QValueList< beatline_data > )),
        soundManager,SLOT(beatLinesChanged(QValueList< beatline_data > )));
    connect(drawSoundWidget,SIGNAL(lockedBeatLinesChanged(QValueList< beatline_data > )),
        soundManager,SLOT(lockedBeatLinesChanged(QValueList< beatline_data > )));

    filePopupMenu->setItemEnabled(idsavedialog,FALSE);
    filePopupMenu->setItemEnabled(idsaveasdialog,FALSE);
    filePopupMenu->setItemEnabled(idsavechunksdialog,FALSE);
    filePopupMenu->setItemEnabled(idsaveprojectasdialog,FALSE);
    filePopupMenu->setItemEnabled(idsaveprojectdialog,FALSE);
    filePopupMenu->setItemEnabled(idsaveloopmidifile,FALSE);
}

void Freecycle::changeZoom(int value){
	long zoomRatioDSW=(long)((double)soundManager->getFrames()/
                                                    ((double) value+drawSoundWidget->width()));
        drawSoundWidget->zoomToSamplePos(
                drawSoundWidget->getFirstVisibleSampleAfterZoom(zoomRatioDSW),
                drawSoundWidget->getLastVisibleSampleAfterZoom(zoomRatioDSW));
	zoomRatioLabel->setText(tr("zoom: %1 - %2").arg(zoomRatioDSW).arg(value));
}

void Freecycle::changeZoom(){
        changeZoom(zoomSlider->value());
}

void Freecycle::changeTreshold(int value){
	drawSoundWidget->setTreshold(value,viewOnly->isOn());
}

void Freecycle::changeTreshold(){
	drawSoundWidget->setTreshold(tresholdSlider->value(),viewOnly->isOn());
}



Freecycle::~Freecycle()
{

}




void Freecycle::choose()
{
    stopPlay();
    soundPlayer->removeSoundMonitor(drawSoundWidget); //Why QThread isn't QObject ?!?
    soundPlayer->removeSoundMonitor(spectrumView);        //Why QThread isn't QObject ?!?
    soundPlayer->removeSoundMonitor(scopeView);        //Why QThread isn't QObject ?!?
    QString fn=NULL;
     if ( openFileDialog->exec() == QDialog::Accepted )
            fn=openFileDialog->selectedFile();
    /*
    QString fn = QFileDialog::getOpenFileName( QString::null,
    						"Sound files ( *.wav , *.aiff )",
						this);
    */
     if ( !fn.isEmpty() ){
	load( fn );
     }else
	statusBar()->message( tr("Loading aborted"), 2000 );

    soundPlayer->addSoundMonitor(drawSoundWidget); //Why QThread isn't QObject ?!?
    soundPlayer->addSoundMonitor(spectrumView);        //Why QThread isn't QObject ?!?
    soundPlayer->addSoundMonitor(scopeView);        //Why QThread isn't QObject ?!?
}


void Freecycle::load( const QString &fileName)
{
        drawSoundWidget->unlockBeatLines(true);
        QFile f( fileName );
        if ( !f.open( IO_ReadOnly ) )	return;
        setCaption(RELEASE_NAME+QString(" - ")+fileName);

        if(effectFrame) effectFrame->reinit();
        if(!topBox->isVisible()) topBox->show();
        if(!playAndBeatLinesControls->isVisible()) playAndBeatLinesControls->show();
        if(!zoomBox->isVisible()) zoomBox->show();
        if(!centralLayout->isVisible()) centralLayout->show();
        menuBar()->setItemEnabled(1,TRUE);
        menuBar()->setItemEnabled(2,TRUE);
        menuBar()->setItemEnabled(3,TRUE);
        menuBar()->setItemEnabled(4,TRUE);
        menuBar()->setItemEnabled(5,TRUE);

        filePopupMenu->setItemEnabled(idsavedialog,TRUE);
        filePopupMenu->setItemEnabled(idsaveasdialog,TRUE);
        filePopupMenu->setItemEnabled(idsavechunksdialog,TRUE);
        filePopupMenu->setItemEnabled(idsaveprojectasdialog,TRUE);
        filePopupMenu->setItemEnabled(idsaveprojectdialog,TRUE);
        filePopupMenu->setItemEnabled(idsaveloopmidifile,TRUE);
        soundPlayer->setPosition(0);

        if(soundManager->getHasLADSPA()) removeEffect();
        fileManager->setFilename(fileName);
        soundManager->loadFile();
        zoomSlider->setMaxValue(soundManager->getFrames()/2);
        soundPlayer->initLoop();
        soundPlayer->setPosition(0);
        
        

        //zoomSlider->setValue(1);

        long zoomRatioDSW=(long)(soundManager->getFrames()/
                                                drawSoundWidget->visibleWidth());
        long zoomRatioDASW=(long)(soundManager->getFrames()/
                                                drawAllSoundWidget->visibleWidth());

        drawAllSoundWidget->setZoomRatio(zoomRatioDASW,!loadingProject);
        drawSoundWidget->putZoomRatio(zoomRatioDSW);
        
        if(!loadingProject){
            drawSoundWidget->fileLoaded();
            drawAllSoundWidget->fileLoaded();
        }

        statusBar()->message( tr("Loaded document %1").arg(fileName), 2000 );
        samplerateLabel->setText(tr("samplerate: %1 Hz").arg(soundManager->getRate()));
        nbframesLabel->setText(tr("frames: %1").arg(soundManager->getFrames()));
        channelsLabel->setText(tr("channels: %1").arg(soundManager->getChannels()));
        zoomRatioLabel->setText(tr("zoom: %1 - %2").arg(zoomRatioDSW).arg(1));
}

void Freecycle::playFromPoint(long x){
    soundPlayer->setOneTimeLoop(x,soundManager->getFrames()-1);
    play();
    soundPlayer->setPosition(x);
}

void Freecycle::playFromTo(long x1,long x2){
    soundPlayer->setOneTimeLoop(x1,x2);
    soundPlayer->setPlayingOnce(TRUE);
    play();
}

void Freecycle::play(){
            if(soundPlayer->getOutputType()==SoundPlayer::OUTPUT_DEVDSP ||
              soundPlayer->getOutputType()==SoundPlayer::OUTPUT_ALSA){
                if(!soundPlayer->running())
                    soundPlayer->start();
            }
            soundPlayer->setPlaying(TRUE);
            pauseButton->setOn(FALSE);
            stopButton->setOn(FALSE);
            playButton->setOn(TRUE);
            //midiOutputThread->continueQueue();
}

void Freecycle::pause(){
        soundPlayer->setPlaying(FALSE);
        playButton->setOn(FALSE);
        stopButton->setOn(FALSE);
        pauseButton->setOn(TRUE);
        //midiOutputThread->stopQueue();
}

void Freecycle::stopPlay(){
        soundPlayer->stopPlay();
        playButton->setOn(FALSE);
        pauseButton->setOn(FALSE);
        stopButton->setOn(TRUE);
        soundPlayer->resetLoop();
        //midiOutputThread->stopQueue();
}


void Freecycle::save()
{
    QString filename=fileManager->getOriginalFilename();
    if(filename){
        soundManager->saveSoundBufferTo(filename,SoundHolder::FOR_OUTPUT);
        statusBar()->message( tr( "File %1 saved" ).arg( filename ), 2000 );
    }else{
        statusBar()->message( tr( "Save what?!" ), 2000 );
    }
}


void Freecycle::saveAs()
{
    QString filename=QString::null;
    if(soundManager->hasSound()) filename=fileManager->getOriginalFilename();

    QString fn = QFileDialog::getSaveFileName( filename, QString::null,
					       this );

    if ( !fn.isEmpty() ) {
        soundManager->saveSoundBufferTo(fn,SoundHolder::FOR_OUTPUT);
        statusBar()->message( tr( "File %1 saved" ).arg( fn), 2000 );
    } else {
	statusBar()->message( tr("Saving aborted"), 2000 );
    }
}


void Freecycle::saveChunks()
{
    int size=drawSoundWidget->getNbLockedBeats();
    if(size==0){
        QMessageBox::critical(this,"Problem!","No locked beatlines, no chunks! (:P)",0);
    }else{
        QString fn=NULL;
        saveFileDialog->setBps(soundManager->getBps());
        if ( saveFileDialog->exec() == QDialog::Accepted )
            fn=saveFileDialog->selectedFile();
        if ( !fn.isEmpty() ) {
            long start=0;
            long end=soundManager->getFrames();
            QValueList <beatline_data> beatlinesVL;
            if(saveFileDialog->exportMode()==MySaveFileDialog::EXPORT_LOOP){
                if(drawSoundWidget->hasLoopSet()){
                    long left=drawSoundWidget->getLeftLoopMarkerSample();
                    long right=drawSoundWidget->getRightLoopMarkerSample();
                    beatlinesVL=drawSoundWidget->selectLockedBeatlinesList(left,right);
                    start=left;
                    end=right;
                }else{
                    QMessageBox::critical(this,"Problem!","Invalid loop!",0);
                    return;
                }
            }else{
                beatlinesVL=drawSoundWidget->getLockedBeatList();
            }
            cout<<"Export bits per sample: "<<saveFileDialog->getExportBitsPerSample()<<" code: "<<soundManager->toBpsCode(saveFileDialog->getExportBitsPerSample())<<"\n";
            /*
            if(saveFileDialog->getAttackTime()!=0){
                Envelope* env=new Envelope();
                env->setEnvDurationAndSamplerate(saveFileDialog->getAttackTime(),
                                                 soundManager->getRate());
                soundManager->addPostProcessEffect(env);
            }
            */
            
            QStringList* filenames=
                soundManager->saveChunksTo(fn,beatlinesVL,
                              soundManager->toBpsCode(saveFileDialog->getExportBitsPerSample()));
            if(saveFileDialog->assignMissingMIDINotes()){
                beatlinesVL=drawSoundWidget->assignMissingMidi(beatlinesVL);
            }
            if(saveFileDialog->exportMidifile()){
                midiManager->writeMidiFile(fn,beatlinesVL,drawSoundWidget->getUsedBPM());
            }
            if(saveFileDialog->exportAKP()){
                akpManager->writeAKPFile(fn,filenames,beatlinesVL);
            }
            #ifdef HAS_LIBINSTPATCH
                if(saveFileDialog->exportSF2()){
                    sf2Manager->writeSF2File(fn,filenames,beatlinesVL);
                }
                if(saveFileDialog->exportDLS()){
                    dlsManager->writeDLS2File(fn,filenames,beatlinesVL);
                }
                if(saveFileDialog->exportGiga()){
                    gigaManager->writeGigaFile(fn,filenames,beatlinesVL);
                }
                if(saveFileDialog->removeChunks()){
                    fileManager->deleteDir(fn);
                }
            #endif
            statusBar()->message( tr( "File %1 saved to chunks" ).arg( fn), 2000 );
            delete filenames;
        } else {
            statusBar()->message( tr("Saving aborted"), 2000 );
        }
    }
}




void Freecycle::closeEvent( QCloseEvent* ce )
{
        if(soundPlayer->running()){
            soundPlayer->exit(0);
        }
        #ifdef HAS_PORTMIDI
            QProgressDialog pd("Terminating midi thread",0,2,this,"progress",TRUE);
            cout<<"Terminating midi thread\n";
            pd.setMinimumDuration(0);
            pd.setProgress(0);
            mainApplication->processEvents();
            delete midiInputThread;
            pd.setProgress(1);
            cout<<"..ok\n";
        #endif
        delete soundPlayer;
        delete fileManager;
        ce->accept();
	return;
}


void Freecycle::about()
{
    QMessageBox::information( this, tr(RELEASE_NAME),
			tr("Developped under GNU Public Licence by:"
                        "\nPredrag Viceic <viceic@net2000.ch>"
                        "\n\nCredits:\n\n"
                        "JACK layer  and LADSPA control port init taken from the AlsaModularSynth project by Matthias Nagorni"
                            "\nhttp://alsamodular.sourceforge.net/\n\n"
                        "OSS layer borrowed from the libsndfile examples by Erik de Castro Lopo\n"
                            "http://www.mega-nerd.com/libsndfile/\n\n"
                        "Midi file generation code stolen from the Waon project\n"
                            "Copyright (C) 1998 Kengo ICHIKI (ichiki@geocities.com)\n\n"
                        "Beat analysis algorithms inspired on the [not fully understood] paper by Frederic Patin\n"
                            "http://www.yov408.com/\n\n"
                        "Aubio support by Piem\n"
                                "<piem@altern.org>\n\n"
                        "AKP export implementation based on the specifications by Seb Francis\n"
                            "http://www.sonicspot.com/guide/AKPspec.html\n\n"
                        "Icons from Crystal SVG Icon Theme by Everaldo\n"
                            "http://www.everaldo.com\n"
                            "(Icon modifications by me)")
                        ,"Enjoy!");
}





/*!
    \fn Freecycle::zoomToSel()
 */
void Freecycle::zoomToSel()
{
    long newZoomRatio=drawSoundWidget->zoomToSel();
    int newZoomSliderValue=(soundManager->getFrames()-(width()*newZoomRatio))/newZoomRatio;
    zoomSlider->blockSignals(true);
    zoomSlider->setValue(newZoomSliderValue);
    zoomSlider->blockSignals(false);
}


/*!
    \fn Freecycle::zoomAll()
 */
void Freecycle::zoomAll()
{
    long newZoomRatio=drawSoundWidget->zoomAll();
    //drawAllSoundWidget->zoomAll();
    int newZoomSliderValue=(soundManager->getFrames()-(width()*newZoomRatio))/newZoomRatio;
    zoomSlider->blockSignals(true);
    zoomSlider->setValue(newZoomSliderValue);
    zoomSlider->blockSignals(false);
}


/*!
    \fn Freecycle::changeWindowDivider(int)
 */
void Freecycle::changeWindowDivider(int value)
{
    drawSoundWidget->setWindowDivider(value,viewOnly->isOn());
}




void Freecycle::cropSelection(){
    long start=drawSoundWidget->getSelectionStartSample();
    long end=drawSoundWidget->getSelectionEndSample();
    if(start!=end && start!=-1 && end!=-1){
        soundManager->crop(start,end);
        //zoomAll();
        //drawSoundWidget->reinitCanvas();
    }
}

void Freecycle::undo(){
    if(soundManager->previousSoundBuffer(SoundHolder::ORIGINAL_WAVE)){
        zoomAll();
        drawSoundWidget->forceRepaint();
        drawAllSoundWidget->forceRepaint();
        drawSoundWidget->reinitCanvas();
    }
    repaint();
}

void Freecycle::redo(){
    if(soundManager->nextSoundBuffer()){
        zoomAll();
        drawSoundWidget->forceRepaint();
        drawAllSoundWidget->forceRepaint();
        drawSoundWidget->reinitCanvas();
    }
    repaint();
}

void Freecycle::addEffect(){
    ladspaDialog->setEffectsList(soundManager->getEffects());
    ladspaDialog->exec();
}

void Freecycle::configureFFT(){
    fftDialog->exec();
}

void Freecycle::configureAmpDomain(){
    ampDomainDialog->exec();
}

void Freecycle::removeEffect(){
    soundManager->setHasLadspa(false);
    if(effectFrame){
            effectFrame->close(TRUE);
            effectFrame=0;
        }
    if(!loadingProject){
        if(soundManager->getHasEnvelope())
            soundManager->applyEnvelope();
        else soundManager->zapInstantEBuffer();
        
        drawSoundWidget->zapWaveCanvasBuffers();
        drawAllSoundWidget->zapWaveCanvasBuffers();
    }
    projectManager->setLadspa(0);
    soundManager->getEffects()->setCurrent(0);
    
}

void Freecycle::addEffectFrame(int uniqueId){
    if(soundManager->getHasLADSPA()) removeEffect();
    LADSPAEffect* temp=soundManager->getEffects()->getEffect(uniqueId);
    soundManager->getEffects()->setCurrent(temp);
    soundManager->setHasLadspa(TRUE);
    effectFrame=new EffectFrame(temp,big_and_small_wave_and_effects);
    big_and_small_wave_and_effects->setResizeMode(effectFrame,QSplitter::Stretch);
    effectFrame->setZoomRatio(drawSoundWidget->getZoomRatio());
    effectFrame->setContentsPos(drawSoundWidget->contentsX(),0);
    effectFrame->show();
    connect(effectFrame,SIGNAL(applyMe(LADSPAEffect*)),
                    soundManager,SLOT(applyPlugin(LADSPAEffect* )));
    connect(effectFrame,SIGNAL(applyMe(LADSPAEffect*,long,long)),
                    soundManager,SLOT(applyPlugin(LADSPAEffect*,long,long)));
    connect(drawSoundWidget,SIGNAL(zoomChangedS(long)),
                   effectFrame,SLOT(setZoomRatio(long)));
    connect(drawSoundWidget,
                    SIGNAL(contentsMoving(int,int)),
                    effectFrame,SLOT(setContentsPos(int,int)));
    connect(soundManager,SIGNAL(reinitLADSPAValues()),effectFrame,SLOT(reinitLADSPAValues()));
    /*
    connect(drawSoundWidget,SIGNAL(beatLinesChanged(QValueList< beatline_data > )),
            effectFrame,SIGNAL(beatLinesChanged(QValueList< beatline_data > )));
    */
    connect(drawSoundWidget,SIGNAL(lockedBeatLinesChanged(QValueList< beatline_data > )),
            effectFrame,SLOT(lockedBeatLinesChanged(QValueList< beatline_data > )));

    connect(soundManager,SIGNAL(cropped(long, long )),effectFrame,SIGNAL(cropS(long, long )));
    effectFrame->lockedBeatLinesChanged(drawSoundWidget->getLockedBeatList());
    

    //load polylines and splines, if any
    if(projectManager->getPolylines().count()>0){
        ProjectManager::polylinesMapT polylines=projectManager->getPolylines();
        ProjectManager::polylinesMapT::Iterator it;
        for ( it = polylines.begin(); it != polylines.end(); ++it ) {
            effectFrame->setPolylineData(it.key(),it.data());
        }
    }

    if(projectManager->getSplines().count()>0){
        ProjectManager::splinesMapT splines=projectManager->getSplines();
        ProjectManager::splinesMapT::Iterator it;
        for ( it = splines.begin(); it != splines.end(); ++it ) {
            effectFrame->setSplineData(it.key(),it.data());
        }
    }
    projectManager->clearPolylinesSplines();
    effectFrame->updateDrawModeButton();
    //end load polylines and splines, if any

    soundManager->applyPlugin(temp);
    projectManager->setLadspa(effectFrame);
}

void Freecycle::updateNbFramesLabel(){
    nbframesLabel->setText(tr("frames: %1").arg(soundManager->getFrames()));
}

void Freecycle::setAmplitudeDomain(){
    soundManager->setAnalysisMethod(SoundManager::AMP_DOMAIN);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,TRUE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
#ifdef HAS_AUBIO
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
#endif
}
void Freecycle::setFrequencyDomain(){
    std::cout<<"set freq"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::FREQ_DOMAIN);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(2,TRUE);
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
#ifdef HAS_AUBIO
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
#endif
}

void Freecycle::setComplexDomain(){
     #ifdef HAS_AUBIO
    std::cout<<"set complex"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::COMPLEX_DOMAIN);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
    configureAnalysisPopupMenu->setItemChecked(3,TRUE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
    #endif
}
void Freecycle::setPhaseDomain(){
     #ifdef HAS_AUBIO
    std::cout<<"set phase"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::PHASE_DIFF);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,TRUE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
    #endif
}
void Freecycle::setSpectralDomain(){
     #ifdef HAS_AUBIO
    std::cout<<"set spectral"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::SPEC_DIFF);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,TRUE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
    #endif
}
void Freecycle::setHFCDomain(){
    #ifdef HAS_AUBIO
    std::cout<<"set hfc"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::HFC);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,TRUE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
    #endif
}
void Freecycle::setMKLDomain(){
    #ifdef HAS_AUBIO
    std::cout<<"set hfc"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::MKL);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,TRUE);
    configureAnalysisPopupMenu->setItemChecked(8,FALSE);
    #endif
}
void Freecycle::setKLDomain(){
    #ifdef HAS_AUBIO
    std::cout<<"set hfc"<<"\n";
    soundManager->setAnalysisMethod(SoundManager::KL);
    drawSoundWidget->reinitCanvas();
    configureAnalysisPopupMenu->setItemChecked(1,FALSE);
    configureAnalysisPopupMenu->setItemChecked(2,FALSE);
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
    configureAnalysisPopupMenu->setItemChecked(4,FALSE);
    configureAnalysisPopupMenu->setItemChecked(5,FALSE);
    configureAnalysisPopupMenu->setItemChecked(6,FALSE);
    configureAnalysisPopupMenu->setItemChecked(7,FALSE);
    configureAnalysisPopupMenu->setItemChecked(8,TRUE);
    #endif
}


void Freecycle::setDerivateSignal(){
#ifdef HAS_AUBIO
    if(configureAnalysisPopupMenu->isItemChecked(9))
#else
    if(configureAnalysisPopupMenu->isItemChecked(3))
#endif
    {
    soundManager->setDerivateSignal(FALSE);

#ifdef HAS_AUBIO
    configureAnalysisPopupMenu->setItemChecked(9,FALSE);
#else
    configureAnalysisPopupMenu->setItemChecked(3,FALSE);
#endif

    }else{
        soundManager->setDerivateSignal(TRUE);
#ifdef HAS_AUBIO
     configureAnalysisPopupMenu->setItemChecked(9,TRUE);
#else
       configureAnalysisPopupMenu->setItemChecked(3,FALSE);
#endif
    }
    drawSoundWidget->reinitCanvas();
}


/*!
    \fn Freecycle::toggleLoop(bool)
 */
void Freecycle::toggleLoop(bool toggle)
{
     if(toggle && drawSoundWidget->hasLoopSet()){
            soundPlayer->setLoop(drawSoundWidget->getLeftLoopMarkerSample(),
                                               drawSoundWidget->getRightLoopMarkerSample());
        }else{
            soundPlayer->setLoop(0,soundManager->getFrames()-1);
        }
}


/*!
    \fn Freecycle::loopChanged()
 */
void Freecycle::loopChanged()
{
    toggleLoop(loopToggle->isOn());
}

void Freecycle::cropped(long start,long end){
    soundPlayer->cropped(start,end);
}



/*!
    \fn Freecycle::setWaveView()
 */
void Freecycle::setWaveView()
{
    drawSoundWidget->getCanvas()->changeViewMode(WaveCanvas::WAVE_VIEWMODE);
    configureViewPopupMenu->setItemChecked(1,TRUE);
    configureViewPopupMenu->setItemChecked(2,FALSE);
}


/*!
    \fn Freecycle::setSpectrumView()
 */
void Freecycle::setSpectrumView()
{
    drawSoundWidget->getCanvas()->changeViewMode(WaveCanvas::SPECTRUM_VIEWMODE);
    configureViewPopupMenu->setItemChecked(2,TRUE);
    configureViewPopupMenu->setItemChecked(1,FALSE);
}


/*!
    \fn Freecycle::showBeatLines()
 */
void Freecycle::showBeatLines()
{
    if(configureViewPopupMenu->isItemChecked(4)){
        drawSoundWidget->showBeatLines(FALSE);
        configureViewPopupMenu->setItemChecked(4,FALSE);
    }else{
        drawSoundWidget->showBeatLines(TRUE);
        configureViewPopupMenu->setItemChecked(4,TRUE);
    }



}



/*!
    \fn Freecycle::bpmModifierValueChanged()
 */
void Freecycle::bpmModifierValueChanged()
{
    drawSoundWidget->setComputedBPMModifier(this->bpmModifDropDown->getModifier());
}


void Freecycle::spaceBarPressed() {
    if(playButton->isOn()) pause();
    else play();
}


/*!
    \fn Freecycle::numPad7Pressed()
 */
void Freecycle::numPad7Pressed()
{
    soundPlayer->setPosition(drawSoundWidget->getLeftLoopMarkerSample());
}


/*!
    \fn Freecycle::numPad9Pressed
 */
void Freecycle::numPad9Pressed()
{
    soundPlayer->setPosition(drawSoundWidget->getRightLoopMarkerSample());
}




/*!
    \fn Freecycle::numPad1Pressed()
 */
void Freecycle::numPad1Pressed()
{
    soundPlayer->setPosition(0);
}


/*!
    \fn Freecycle::saveProjectAs()
 */
void Freecycle::saveProjectAs()
{
    QString fn=NULL;
    if ( saveProjectDialog->exec() == QDialog::Accepted ){
        fn=saveProjectDialog->selectedFile();
        projectManager->setFilename(fn);
        projectManager->setLockedBeatLines(drawSoundWidget->getLockedBeatList());
        projectManager->setLockedBeatRects(drawSoundWidget->getLockedBeatRects());
        projectManager->setBpmModifier(bpmModifDropDown->getStringModifier());
        projectManager->saveProject();
    }
}


/*!
    \fn Freecycle::loadProject()
 */
void Freecycle::loadProject()
{
    QString fn=NULL;
    if ( loadProjectDialog->exec() == QDialog::Accepted ){
            fn=loadProjectDialog->selectedFile();
            loadProject(fn);
    }

}


/*!
    \fn Freecycle::configureMIDI()
 */
void Freecycle::configureMIDI()
{
#ifdef HAS_MIDI
        midiConfigDialog->exec();
#endif
}

/*!
    \fn Freecycle::configureALSA()
 */
void Freecycle::configureALSA()
{
#ifdef HAS_ALSA
        alsaConfigDialog->exec();
#endif
}


/*!
    \fn Freecycle::saveLoopMidiFile()
 */
void Freecycle::saveLoopMidiFile()
{
    QString filename="export.mid";

    QString fn = QFileDialog::getSaveFileName( filename, "MIDI files ( *.mid )",
					       this );

    if ( !fn.isEmpty() ) {
        QValueList <beatline_data> beatlinesVL;
        if(drawSoundWidget->hasLoopSet()){
            long left=drawSoundWidget->getLeftLoopMarkerSample();
            long right=drawSoundWidget->getRightLoopMarkerSample();
            beatlinesVL=drawSoundWidget->selectLockedBeatlinesList(left,right);
        }else{
            QMessageBox::critical(this,"Problem!","Invalid loop!",0);
            return;
        }
    
        midiManager->writeMidiFile(fn,beatlinesVL,drawSoundWidget->getUsedBPM());
        statusBar()->message( tr( "Midi File  %1 saved" ).arg( fn), 2000 );
    } else {
	statusBar()->message( tr("Saving aborted"), 2000 );
    }
}


/*!
    \fn Freecycle::saveProject()
 */
void Freecycle::saveProject()
{
    if(projectManager->getFilename()!=""){
        projectManager->setLockedBeatLines(drawSoundWidget->getLockedBeatList());
        projectManager->setLockedBeatRects(drawSoundWidget->getLockedBeatRects());
        projectManager->setBpmModifier(bpmModifDropDown->getStringModifier());
        projectManager->saveProject();
    }else saveProjectAs();
}


/*!
    \fn Freecycle::loadProject(QString fn)
 */
void Freecycle::loadProject(QString fn)
{
    if(fn!=NULL){
        soundManager->setLoadingProject(TRUE);
        loadingProject=TRUE;
        projectManager->loadProject(fn);
        loadingProject=FALSE;
        soundManager->setLoadingProject(FALSE);
        if(!soundManager->getHasLADSPA()) soundManager->applyEnvelope();
        setCaption(RELEASE_NAME+QString(" - ")+fn);
        drawSoundWidget->fileLoaded();
    }
}


/*!
    \fn Freecycle::help()
 */
void Freecycle::help()
{
    helpManager->open();
}


void Freecycle::setMainApplication(QApplication* theValue) {
    mainApplication = theValue;
    drawSoundWidget->setMainApplication(mainApplication);
    soundPlayer->setMainApplication(mainApplication);
    
}
