// -*- c-basic-offset: 4 -*-

/*
    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.
*/

#ifndef ROSEDEBUG_H
#define ROSEDEBUG_H

#include <string>
#include <iostream>
#include <kdebug.h>
#include <tdeversion.h>

#if TDE_VERSION < TDE_MAKE_VERSION(3,2,0)
class TQDateTime;
class TQDate;
class TQTime;
class TQPoint;
class TQSize;
class TQRect;
class TQRegion;
class KURL;
class TQStringList;
class TQColor;
class TQPen;
class TQBrush;
#endif

namespace Rosegarden { class Event; class Segment; class RealTime; class Colour; namespace Guitar { class Chord; } }

#define KDEBUG_AREA                 200000
#define KDEBUG_AREA_NOTATION        200001
#define KDEBUG_AREA_MATRIX          200002
#define KDEBUG_AREA_SEQUENCER       200003
#define KDEBUG_AREA_SEQUENCEMANAGER 200004

#define RG_DEBUG        kdDebug(KDEBUG_AREA)
#define NOTATION_DEBUG  kdDebug(KDEBUG_AREA_NOTATION)
#define MATRIX_DEBUG    kdDebug(KDEBUG_AREA_MATRIX)
#define SEQUENCER_DEBUG kdDebug(KDEBUG_AREA_SEQUENCER)
#define SEQMAN_DEBUG    kdDebug(KDEBUG_AREA_SEQUENCEMANAGER)

#ifndef NDEBUG

kdbgstream&
operator<<(kdbgstream&, const std::string&);

kdbgstream&
operator<<(kdbgstream&, const Rosegarden::Event&);

kdbgstream&
operator<<(kdbgstream&, const Rosegarden::Segment&);

kdbgstream&
operator<<(kdbgstream&, const Rosegarden::RealTime&);

kdbgstream&
operator<<(kdbgstream&, const Rosegarden::Colour&);

kdbgstream&
operator<<(kdbgstream&, const Rosegarden::Guitar::Chord&);

#else

inline kndbgstream&
operator<<(kndbgstream &s, const std::string&) { return s; }

inline kndbgstream&
operator<<(kndbgstream &s, const Rosegarden::Event&) { return s; }

inline kndbgstream&
operator<<(kndbgstream &s, const Rosegarden::Segment&) { return s; }

inline kndbgstream&
operator<<(kndbgstream &s, const Rosegarden::RealTime&) { return s; }

inline kndbgstream&
operator<<(kndbgstream &s, const Rosegarden::Colour&) { return s; }

inline kndbgstream&
operator<<(kndbgstream &s, const Rosegarden::Guitar::Chord&) { return s; }

#endif

#ifndef NO_TIMING

#include <iostream>
#include <ctime>

#define START_TIMING \
  clock_t dbgStart = clock();
#define ELAPSED_TIME \
  ((clock() - dbgStart) * 1000 / CLOCKS_PER_SEC)
#define PRINT_ELAPSED(n) \
  RG_DEBUG << n << ": " << ELAPSED_TIME << "ms elapsed" << endl;

#else

#define START_TIMING
#define ELAPSED_TIME  0
#define PRINT_ELAPSED(n)

#endif




// This doesn't work - keeping it just in case I somehow get it
// working someday

#ifdef NOT_DEFINED

// can't be bothered to even get this to compile with gcc-3.0 at the
// moment

class kdbgostreamAdapter : public std::ostream
{
public:
    kdbgostreamAdapter(kdbgstream &e) : m_kdbgStream(e) {}

    std::ostream& operator<<(bool i);
    std::ostream& operator<<(short i);
    std::ostream& operator<<(unsigned short i);
    std::ostream& operator<<(char i);
    std::ostream& operator<<(unsigned char i);
    std::ostream& operator<<(int i);
    std::ostream& operator<<(unsigned int i);
    std::ostream& operator<<(long i);
    std::ostream& operator<<(unsigned long i);
    std::ostream& operator<<(const TQString& str);
    std::ostream& operator<<(const char *str);
    std::ostream& operator<<(const TQCString& str);
    std::ostream& operator<<(void * p);
    std::ostream& operator<<(KDBGFUNC f);
    std::ostream& operator<<(double d);

    kdbgstream& dbgStream() { return m_kdbgStream; }

protected:
    kdbgstream &m_kdbgStream;
};

#endif

// std::ostream& endl(std::ostream& s);

void DBCheckThrow();


#endif
