//
// C++ Implementation: midiinput
//
// Description: 
//
//
// Author: Predrag Viceic <viceic@net2000.ch>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "midiinput.h"
#ifdef HAS_PORTMIDI
    #include "portmidimidiinput.h"
#endif
#ifdef HAS_ALSA
    #include "alsaseqmidiinput.h"
#endif

MidiInput::MidiInput(QObject *parent, const char *name)
 : QObject(parent, name)
{
}
#ifdef HAS_PORTMIDI
MidiInput* MidiInput::instantiatePortMidi(){
    return new PortMidiMidiInput();
}
#endif

#ifdef HAS_ALSA
MidiInput* MidiInput::instantiateAlsaSeq(){
    return new AlsaSeqMidiInput();
}
#endif


MidiInput::~MidiInput()
{
    if(noteAssignements) zaparr(noteAssignements);
}


/*!
    \fn MidiInput::setSoundPlayer(SoundPlayer* sp)
 */
void MidiInput::setSoundPlayer(SoundPlayer* sp)
{
    soundPlayer=sp;
    if(soundPlayer->getOutputType()==SoundPlayer::OUTPUT_DEVDSP){
                if(!soundPlayer->running())
                    soundPlayer->start();
            }
}


/*!
    \fn MidiInput::setBeatlineData(QValueList <beatline_data> bld)
 */
void MidiInput::setBeatlineData(QValueList <beatline_data> bld)
{
    for (uint i=0;i<bld.count()-1;i++){
        if(bld[i].midiNote!=-1){
            noteAssignements[bld[i].midiNote].start=bld[i].position;
            noteAssignements[bld[i].midiNote].stop=bld[i+1].position;
        }
    }
}


/*!
    \fn MidiInput::playNote(int note)
 */
void MidiInput::playNote(int note)
{
    //cout<<"playing note "<<note<<" from: "<<noteAssignements[note].start<<" to: "<<noteAssignements[note].stop<<"\n";
    if(soundPlayer->getOutputType()==SoundPlayer::OUTPUT_DEVDSP ||
              soundPlayer->getOutputType()==SoundPlayer::OUTPUT_ALSA){
                if(!soundPlayer->running())
                    soundPlayer->start();
            }
    if (noteAssignements[note].start!=-1){
        soundPlayer->setOneTimeLoop(noteAssignements[note].start,noteAssignements[note].stop);
        soundPlayer->setPlayingOnce(TRUE);
        soundPlayer->setPlaying(TRUE);
    }
}


/*!
    \fn MidiInput::addMidiMonitor(QObject* mm)
 */
void MidiInput::addMidiMonitor(QObject* mm)
{
    if (!midiMonitors.containsRef(mm)){
        midiMonitors.append(mm);
    }
}


/*!
    \fn MidiInput::removeMidiMonitor(QObject* mm)
 */
void MidiInput::removeMidiMonitor(QObject* mm)
{
    if (midiMonitors.containsRef(mm)){
        midiMonitors.remove(mm);
    }
}

/*!
    \fn MidiInput::emitMidiNote(int onoff, int note, int velocity)
 */
void MidiInput::emitMidiNote(int onoff, int note, int velocity)
{
    QObject* midiMonitor;
    //cout<<"Postinig midi input event 1\n";
    for ( midiMonitor = midiMonitors.first(); midiMonitor; midiMonitor = midiMonitors.next() ){
        //cout<<"Postinig midi input event 2\n";
        MidiInputEvent* myevent=new MidiInputEvent(onoff,note,velocity);
        QApplication::postEvent(midiMonitor,myevent);
    }
}
