/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                   Copyright (c) 2002 Zanoza Software.                   *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler 2.x error-reporitng utils
 *--------------------------------------------------------------------------
 * @histroy: 26.09.2002. Created
 */
#ifndef zerror_h_included
#define zerror_h_included
#include <core/IErrorInfo.h>
#include <services/IMessageBoxService.h>
#include "zresult.h"

namespace core
{
  class DLL_LINKAGE CErrorInfo : public IErrorInfo
  {
  public:
    virtual ~CErrorInfo(){}
    // IErrorInfo methods
    virtual ZRESULT resetError(void);
    virtual ZRESULT reportError(IErrorInfo* pPrevError, const ZString strDesc);
    virtual ZRESULT hasErrors(void) const;
    virtual ZRESULT getErrorDescription(ZString& strDesc);
    virtual ZRESULT getPreviouseError(core::IErrorInfo** ppError);

  private:
    ZString           m_szDescription;
    ZPtr<IErrorInfo>  m_pPreviousError;
  };

}

//--------------------------------------------
//  util functions:
//--------------------------------------------
//"displays" errors in messaging service
DLL_LINKAGE ZRESULT ShowErrorMessage(ZUnknown* pHolder);
DLL_LINKAGE ZRESULT ShowErrorMessage(ZUnknown* pHolder, LPCTSTR  szDescription,...);

//"displays" message messaging service
DLL_LINKAGE ZRESULT ShowMessageDirect(core::eMessageType type, LPCTSTR  szDescription,...);

//"displays" custom zmodeler's message box
DLL_LINKAGE DWORD messageBox(LPCTSTR strText, LPCTSTR strCaption = NULL, DWORD dwButtons = MB_OK | MB_ICONINFORMATION);
DLL_LINKAGE ZRESULT messageBoxPrepare(core::ui::controls::IUIControl* pControl);
DLL_LINKAGE ZRESULT messageBoxPrepare(core::layout::IChildDialog* pChildDlg);
DLL_LINKAGE DWORD messageBoxDlg(core::layout::IChildDialog* pChildDlg, LPCTSTR strText, LPCTSTR strCaption = NULL, DWORD dwButtons = MB_OK | MB_ICONINFORMATION);

// displays pop-up error box via messaging service
DLL_LINKAGE ZRESULT DialogError(LPCTSTR szFileName,long nLine,
                                ZUnknown *pPreviousError,
                                LPCTSTR  szDescription,...);

//returns true if supplied interface has any errors reported
DLL_LINKAGE bool hasErrors(ZUnknown* pHolder);

//returns true if supplied interface has any errors reported
DLL_LINKAGE ZRESULT UtilReportError(core::IErrorInfo *pSource,
                                    LPCTSTR szFileName,long nLine,
                                    ZUnknown *pPreviousError,
                                    LPCTSTR  szDescription,...);

//--------------------------------------------
//  util macros:
//--------------------------------------------
#define REPORT_ERROR(prev,dsc) UtilReportError(this, _T(__FILE__),__LINE__,prev,dsc);
#define REPORT_ERROR1(prev,dsc,p1) UtilReportError(this, _T(__FILE__),__LINE__,prev,dsc,p1);
#define REPORT_ERROR2(prev,dsc,p1,p2) UtilReportError(this, _T(__FILE__),__LINE__,prev,dsc,p1,p2);
#define REPORT_ERROR3(prev,dsc,p1,p2,p3) UtilReportError(this, _T(__FILE__),__LINE__,prev,dsc,p1,p2,p3);

#define REPORT_ERROR_VIA(classname, prev,dsc) UtilReportError(static_cast<classname*>(this), _T(__FILE__),__LINE__,prev,dsc);
#define REPORT_ERROR_VIA1(classname, prev,dsc,p1) UtilReportError(static_cast<classname*>(this), _T(__FILE__),__LINE__,prev,dsc,p1);
#define REPORT_ERROR_VIA2(classname, prev,dsc,p1,p2) UtilReportError(static_cast<classname*>(this), _T(__FILE__),__LINE__,prev,dsc,p1,p2);
#define REPORT_ERROR_VIA3(classname, prev,dsc,p1,p2,p3) UtilReportError(static_cast<classname*>(this), _T(__FILE__),__LINE__,prev,dsc,p1,p2,p3);

#define REPORT_ERROR_TO(obj,prev,dsc) UtilReportError(obj, _T(__FILE__),__LINE__,prev,dsc);
#define REPORT_ERROR_TO1(obj,prev,dsc,p1) UtilReportError(obj, _T(__FILE__),__LINE__,prev,dsc,p1);
#define REPORT_ERROR_TO2(obj,prev,dsc,p1,p2) UtilReportError(obj, _T(__FILE__),__LINE__,prev,dsc,p1,p2);
#define REPORT_ERROR_TO3(obj,prev,dsc,p1,p2,p3) UtilReportError(obj, _T(__FILE__),__LINE__,prev,dsc,p1,p2,p3);

#define DIALOG_ERROR(prev,dsc) DialogError(_T(__FILE__),__LINE__,prev,dsc);
#define DIALOG_ERROR1(prev,dsc,p1) DialogError(_T(__FILE__),__LINE__,prev,dsc,p1);
#define DIALOG_ERROR2(prev,dsc,p1,p2) DialogError(_T(__FILE__),__LINE__,prev,dsc,p1,p2);
#define DIALOG_ERROR3(prev,dsc,p1,p2,p3) DialogError(_T(__FILE__),__LINE__,prev,dsc,p1,p2,p3);


// define a DEBUG_LOG_FILENAME string with filename for debug log
#ifndef DEBUG_LOG_FILENAME
# define DEBUG_LOG_FILENAME "zm_debug.log"
#endif//DEBUG_LOG_FILENAME
#ifndef NDEBUG
  #include <stdio.h>
  extern FILE* dbgFile;//file for debug text output
  class CAutoDebugFileWrapperClass
  {
  public:
    CAutoDebugFileWrapperClass()
    {
      m_ppFile = NULL;
    }
    CAutoDebugFileWrapperClass(FILE** ppFile)
    {
      m_ppFile = ppFile;
      (*m_ppFile) = fopen(DEBUG_LOG_FILENAME, "w");
    }
    ~CAutoDebugFileWrapperClass()
    {
      fclose((*m_ppFile)); 
      (*m_ppFile) = NULL;
    }
  private:
    FILE** m_ppFile;
  };

  #define DEBUG_FILE()       FILE* dbgFile = NULL;
  #define DEBUG_OPEN()       CAutoDebugFileWrapperClass _DBGFileWrapper(&dbgFile);
  #define DEBUG_FLUSH()      fflush(dbgFile);
  #define DEBUG_MESSAGE(fmt) fprintf(dbgFile, fmt);
  #define DEBUG_MESSAGE1(fmt,p1) fprintf(dbgFile, fmt, p1);
  #define DEBUG_MESSAGE2(fmt,p1,p2) fprintf(dbgFile, fmt, p1, p2);
  #define DEBUG_MESSAGE3(fmt,p1,p2,p3) fprintf(dbgFile, fmt, p1, p2, p3);
  #define DEBUG_MESSAGE4(fmt,p1,p2,p3,p4) fprintf(dbgFile, fmt, p1, p2, p3, p4);
  #define DEBUG_MESSAGE5(fmt,p1,p2,p3,p4,p5) fprintf(dbgFile, fmt, p1, p2, p3, p4, p5);
  #define DEBUG_MESSAGE6(fmt,p1,p2,p3,p4,p5,p6) fprintf(dbgFile, fmt, p1, p2, p3, p4, p5, p6);
  #define DEBUG_MESSAGE7(fmt,p1,p2,p3,p4,p5,p6,p7) fprintf(dbgFile, fmt, p1, p2, p3, p4, p5, p6, p7);
  #define DEBUG_MESSAGE8(fmt,p1,p2,p3,p4,p5,p6,p7,p8) fprintf(dbgFile, fmt, p1, p2, p3, p4, p5, p6, p7, p8);
#else //NDEBUG
  #define DEBUG_FILE()
  #define DEBUG_FLUSH()                               ;
  #define DEBUG_OPEN()                                ;
  #define DEBUG_CLOSE()                               ;
  #define DEBUG_MESSAGE(fmt)                          ;
  #define DEBUG_MESSAGE1(fmt,p1)                      ;
  #define DEBUG_MESSAGE2(fmt,p1,p2)                   ;
  #define DEBUG_MESSAGE3(fmt,p1,p2,p3)                ;
  #define DEBUG_MESSAGE4(fmt,p1,p2,p3,p4)             ;
  #define DEBUG_MESSAGE5(fmt,p1,p2,p3,p4,p5)          ;
  #define DEBUG_MESSAGE6(fmt,p1,p2,p3,p4,p5,p6)       ;
  #define DEBUG_MESSAGE7(fmt,p1,p2,p3,p4,p5,p6,p7)    ;
  #define DEBUG_MESSAGE8(fmt,p1,p2,p3,p4,p5,p6,p7,p8) ;
#endif//NDEBUG

#endif //zerror_h_included
