/*
  Rosegarden
  A sequencer and musical notation editor.
 
  This program is Copyright 2000-2008
  Guillaume Laurent   <glaurent@telegraph-road.org>,
  Chris Cannam        <cannam@all-day-breakfast.com>,
  Richard Bown        <bownie@bownie.com>
 
  The moral right of the authors to claim authorship of this work
  has been asserted.
 
  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 included with this distribution for more information.
*/

#include "MappedDevice.h"
#include "MappedInstrument.h"
#include <iostream>

namespace Rosegarden
{

MappedDevice::MappedDevice():
        std::vector<MappedInstrument*>(),
        m_id(Device::NO_DEVICE),
        m_type(Device::Midi),
        m_name("Unconfigured device"),
        m_connection(""),
        m_direction(MidiDevice::Play),
        m_recording(false)
{}

MappedDevice::MappedDevice(DeviceId id,
                           Device::DeviceType type,
                           std::string name,
                           std::string connection):
        std::vector<MappedInstrument*>(),
        m_id(id),
        m_type(type),
        m_name(name),
        m_connection(connection),
        m_direction(MidiDevice::Play),
        m_recording(false)
{}

MappedDevice::~MappedDevice()
{}

MappedDevice::MappedDevice(const MappedDevice &mD):
        std::vector<MappedInstrument*>()
{
    clear();

    for (MappedDeviceConstIterator it = mD.begin(); it != mD.end(); it++)
        this->push_back(new MappedInstrument(**it));

    m_id = mD.getId();
    m_type = mD.getType();
    m_name = mD.getName();
    m_connection = mD.getConnection();
    m_direction = mD.getDirection();
    m_recording = mD.isRecording();
}

void
MappedDevice::clear()
{
    MappedDeviceIterator it;

    for (it = this->begin(); it != this->end(); it++)
        delete (*it);

    this->erase(this->begin(), this->end());
}

MappedDevice&
MappedDevice::operator+(const MappedDevice &mD)
{
    for (MappedDeviceConstIterator it = mD.begin(); it != mD.end(); it++)
        this->push_back(new MappedInstrument(**it));

    return *this;
}

MappedDevice&
MappedDevice::operator=(const MappedDevice &mD)
{
    if (&mD == this)
        return * this;

    clear();

    for (MappedDeviceConstIterator it = mD.begin(); it != mD.end(); it++)
        this->push_back(new MappedInstrument(**it));

    m_id = mD.getId();
    m_type = mD.getType();
    m_name = mD.getName();
    m_connection = mD.getConnection();
    m_direction = mD.getDirection();
    m_recording = mD.isRecording();

    return *this;
}


TQDataStream&
operator>>(TQDataStream &dS, MappedDevice *mD)
{
    int instruments = 0;
    dS >> instruments;

    MappedInstrument mI;
    while (!dS.atEnd() && instruments) {
        dS >> mI;
        mD->push_back(new MappedInstrument(mI));
        instruments--;
    }

    TQString name;
    unsigned int id, dType;
    TQString connection;
    unsigned int direction;
    unsigned int recording;

    dS >> id;
    dS >> dType;
    dS >> name;
    dS >> connection;
    dS >> direction;
    dS >> recording;
    mD->setId(id);
    mD->setType(Device::DeviceType(dType));
    mD->setName(std::string(name.ascii()));
    mD->setConnection(connection.ascii());
    mD->setDirection(MidiDevice::DeviceDirection(direction));
    mD->setRecording((bool)recording);

#ifdef DEBUG_MAPPEDDEVICE

    if (instruments) {
        std::cerr << "MappedDevice::operator>> - "
        << "wrong number of events received" << std::endl;
    }
#endif

    return dS;
}


TQDataStream&
operator>>(TQDataStream &dS, MappedDevice &mD)
{
    int instruments;
    dS >> instruments;

    MappedInstrument mI;

    while (!dS.atEnd() && instruments) {
        dS >> mI;
        mD.push_back(new MappedInstrument(mI));
        instruments--;
    }

    unsigned int id, dType;
    TQString name;
    TQString connection;
    unsigned int direction;
    unsigned int recording;

    dS >> id;
    dS >> dType;
    dS >> name;
    dS >> connection;
    dS >> direction;
    dS >> recording;
    mD.setId(id);
    mD.setType(Device::DeviceType(dType));
    mD.setName(std::string(name.ascii()));
    mD.setConnection(connection.ascii());
    mD.setDirection(MidiDevice::DeviceDirection(direction));
    mD.setRecording((bool)recording);

#ifdef DEBUG_MAPPEDDEVICE

    if (instruments) {
        std::cerr << "MappedDevice::operator>> - "
        << "wrong number of events received" << std::endl;
    }
#endif

    return dS;
}

TQDataStream&
operator<<(TQDataStream &dS, MappedDevice *mD)
{
    dS << (int)mD->size();

    for (MappedDeviceIterator it = mD->begin(); it != mD->end(); it++)
        dS << (*it);

    dS << (unsigned int)(mD->getId());
    dS << (int)(mD->getType());
    dS << TQString(mD->getName().c_str());
    dS << TQString(mD->getConnection().c_str());
    dS << mD->getDirection();
    dS << (unsigned int)(mD->isRecording());

#ifdef DEBUG_MAPPEDDEVICE

    std::cerr << "MappedDevice::operator>> - wrote \"" << mD->getConnection() << "\""
    << std::endl;
#endif

    return dS;
}

TQDataStream&
operator<<(TQDataStream &dS, const MappedDevice &mD)
{
    dS << (int)mD.size();

    for (MappedDeviceConstIterator it = mD.begin(); it != mD.end(); it++)
        dS << (*it);

    dS << (unsigned int)(mD.getId());
    dS << (int)(mD.getType());
    dS << TQString(mD.getName().c_str());
    dS << TQString(mD.getConnection().c_str());
    dS << mD.getDirection();
    dS << (unsigned int)(mD.isRecording());

#ifdef DEBUG_MAPPEDDEVICE

    std::cerr << "MappedDevice::operator>> - wrote \"" << mD.getConnection() << "\""
    << std::endl;
#endif

    return dS;
}

}

