//@copyright_begin
// ================================================================
// Copyright Notice
// Copyright (C) 1998-2004 by Joe Linoff
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL JOE LINOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// 
// Comments and suggestions are always welcome.
// Please report bugs to http://ccdoc.sourceforge.net/ccdoc
// ================================================================
//@copyright_end

// MULTIPLE INCLUSION GUARD
#ifndef ccdoc_log_h
#define ccdoc_log_h

/**
 * This variable allows the header version
 * to be queried at runtime.
 */
namespace {
   char ccdoc_log_h_rcsid[] = "$Id: log.h,v 1.6 2004/09/30 04:16:06 jlinoff Exp $";
}

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 4251 )
#endif

#include "exceptions.h"
#include <string>
#include <vector>
#include <iostream>

using namespace std;

namespace ccdoc {
  /**
   * Log stream.
   * @author Joe Linoff
   * @version $Id: log.h,v 1.6 2004/09/30 04:16:06 jlinoff Exp $
   */
  class log {
  public:
    log();
    ~log();
    log& operator << (const char*);
    log& operator << (const string&);
    log& operator << (const vector<string>&);
    log& operator << (char);
    log& operator << (unsigned char);
    log& operator << (int);
    log& operator << (unsigned int);
    log& operator << (long);
    log& operator << (unsigned long);
    log& operator << (ostream& (fct)(ostream&));
    log& operator << (log& x) {return x;}
    log& flush();
    void insert(ostream*);
    void insert(string&);
    void remove(ostream*);
    void remove(string&);
  public:
    /**
     * Disable the output log.
     * Nothing gets written.
     * @returns The log stream.
     */
    log& disable() {m_output_flag = false; return *this;}
    /**
     * Enable the output log.
     * Everything gets written.
     * @returns The log stream.
     */
    log& enable() {m_output_flag = true; return *this;}
  public:
    bool warnings_enabled() const {return m_warnings_flag;}
    void disable_warnings() {m_warnings_flag = false;}
    void enable_warnings() {m_warnings_flag = true;}
    void warnings(unsigned n) {m_warnings=n;}
    unsigned warnings() const {return m_warnings;}
    log& warning();
  public:
    void errors(unsigned n) {m_errors=n;}
    unsigned errors() const {return m_errors;}
    log& error();
  private:
    vector<ostream*> m_os;
    bool m_output_flag;
    bool m_warnings_flag;
    unsigned m_warnings;
    unsigned m_errors;
  };
  /**
   * Global log variable.
   */
  extern log s_log;
};

/**
 * Debugging aid.
 * It can be sprinkled throughout the code to
 * determine whether a statement was reached.
 * It is only used during development.
 */
#define CCDOC_DEBUG_MADE_IT \
  ccdoc::s_log << "DEBUG:" << __FILE__ << ":" << __LINE__ << "\n"

#endif
