/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/****************************************************************************
**
**  Name:  ERRTEXT.CPP
**
**  Description:
**      Entry points for error handling.
**
**  Status:  CODED
**
**  Date:    15 Mar. 1996 8:30:00am   by:  Jamoon Zhou
** Initial revision.
**
**  Copyright (C) 1996 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdafx.h"
#include <stdio.h>
#include <stdarg.h>
#include <search.h>

#include "hosterrs.h"
#include "errtrans.h"
#include "resource.h"

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
static char chErrorText[E_ERRSIZE];

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern  HINSTANCE hTextInst;

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/
BOOL bCallInternal = FALSE;

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

int compare( const void *elem1, const void *elem2 )
{
	U16 offset =((ErrTrans*)elem2)->offset;
	U16 key =  *( (U16*) elem1 );
	int cmpval = ( key > offset ) ?  1 :
    			 ( key < offset ) ? -1 : 0;

   	return cmpval;
}

RETCODE ErrGetFullId(U16 uErrCode, U32& dwErrCode)
{
//	dwErrCode = uErrCode;
	ErrTrans *result;
    result = (ErrTrans *)bsearch( &uErrCode, ErrTranslation, 
   				MAX_ERR_TRANS, sizeof( ErrTrans ), 
                (int (*)(const void*, const void*))compare );
    if ( result == NULL ) return FAILURE;
    dwErrCode = result->errcode;
    return GOOD;
}

void ErrGetProperty(U32 errCode,CString& strCaption)
{
	U16 nError = E_ERRORID( errCode );
	
	ErrGetFullId(nError,errCode);
	
	if ( nError >= 0x8000 ) {
		strCaption = "";		// "Suggestion: ";
		return;
	}

//	UINT fuStyle = 0;
	char szText[31];
	switch ( errCode & E_SEVERITY_MASK ) {
		case E_WARNING 	:
//			fuStyle = MB_ICONINFORMATION;
			LoadString(hTextInst,ID_STYLE_WARNING,szText,30);
			strCaption = szText;
//			strCaption = "Warning: ";
			break;
		case E_ERROR	 	:
//			fuStyle = MB_ICONEXCLAMATION;
			LoadString(hTextInst,ID_STYLE_ERROR,szText,30);
			strCaption = szText;
//			strCaption = "Error: ";
			break;
		case E_FATAL	 	:
//			fuStyle = MB_ICONQUESTION;
			LoadString(hTextInst,ID_STYLE_FATAL,szText,30);
			strCaption = szText;
//			strCaption = "Fatal Error: ";
			break;
		case E_SEVERE	 	:
//			fuStyle = MB_ICONSTOP;
			LoadString(hTextInst,ID_STYLE_SEVERE,szText,30);
			strCaption = szText;
//			strCaption = "Severe Error: ";
			break;
		case E_INFORMATIVE	:
			strCaption = "";
			break;
		default :
//			fuStyle = MB_ICONEXCLAMATION;
			strCaption = "";
	}
}

/***************************************************************************
**
**   ErrGetStyle
**      get MessageBox  style from error code
**   Input:   error code
**   Output:  style
**
***************************************************************************/
UINT EXPORT ErrGetStyle(U32 errCode)
{
	UINT fuStyle = 0;

	U16 nError = E_ERRORID( errCode );
	ErrGetFullId(nError,errCode);
	
	switch ( errCode & E_SEVERITY_MASK ) {
		case E_INFORMATIVE	:
		case E_WARNING 	:
			fuStyle = MB_ICONINFORMATION;
			break;
		case E_ERROR	 	:
			fuStyle = MB_ICONEXCLAMATION;
			break;
		case E_FATAL	 	:
			fuStyle = MB_ICONQUESTION;
			break;
		case E_SEVERE	 	:
			fuStyle = MB_ICONSTOP;
			break;
		default :
			fuStyle = MB_ICONEXCLAMATION;
	}
	
	fuStyle |= MB_OK;
    return fuStyle;
}

/*****************************************************************************
** ErrGetErrorText
**
** Description:
**   Retrieve error text or recover text and plug in optional arguments.  
**	 The *caller* is expected to have allocated storage for the return 
**	 string of size E_ERRSIZE if LPSTR is used. 
**	 Optional arguments must fit with the error format string. Refer to 
**	 wvsprintf() window function for the format-control character sequences.
**
** Parameters:
**    input :
**       errCode :   error type, and error number 
**					 or recover type, and recover number
**    output :
**       lpszError : error string
**       strError 
** Return :
**		GOOD(0) for success    FAILURE(-1) for failure	
*****************************************************************************/
RETCODE EXPORT ErrGetErrorText(U32 errorCode, LPSTR lpszError, ...)
{
	char chError[E_ERRSIZE+256];
	U16 nError = E_ERRORID( errorCode );

	CString strCaption;
	ErrGetProperty(errorCode,strCaption);
//	CString strFormat;
//	if ( !strFormat.LoadString( nError ) ) return FAILURE;
	if ( !LoadString(hTextInst, nError , chErrorText, E_ERRSIZE-1) ) {
//		*lpszError = 0;
//		wsprintf( lpszError, "Error code %lx not exist", errorCode );
		return FAILURE;
	}
	strCaption += chErrorText;
   	va_list marker;
   	va_start( marker, lpszError );     // Initialize variable arguments.
//	wvsprintf( lpszError, chErrorText, marker );
	if (!bCallInternal)
		wvsprintf( chError, strCaption, marker );
	else {
		void FAR *lpvArglis = va_arg( marker, void FAR*);
		wvsprintf( chError, strCaption, lpvArglis );
	}
	va_end( marker );
	lstrcpyn( lpszError, chError, E_ERRSIZE-1 );
	return GOOD;
}


/*****************************************************************************
** ErrGetErrorText
**
** Description:
**   Retrieve error text and recover text and plug in optional arguments.  
**	 The *caller* is expected to have allocated storage for the return 
**	 string of size E_ERRSIZE if LPSTR is used
**	 Optional arguments must fit with the error format string. Refer to 
**	 wvsprintf() window function for the format-control character sequences.
**
** Parameters:
**    input :
**       errCode :   error type, and error number 
**		 recCode :	 recover type, and recover number
**    output :
**       lpszError : error string 
**		 lpszRecov : recover string
**       strError  : error CString
**		 strRecov  : recover CString
** Return :
**		GOOD(0) for success    FAILURE(-1) for failure	
*****************************************************************************/
RETCODE EXPORT 
ErrGetErrorText(U32 errCode,U32 recCode,LPSTR lpszError, LPSTR lpszRecov ...)
{
	RETCODE retCode;
	
   	va_list marker;
   	va_start( marker, lpszRecov );     // Initialize variable arguments.

	if (!bCallInternal) {
		bCallInternal = TRUE;
		retCode = ErrGetErrorText( errCode, lpszError, marker );
		bCallInternal = FALSE;
	}
	else {
		void FAR *lpvArglis = va_arg( marker, void FAR*);
		retCode = ErrGetErrorText( errCode, lpszError, lpvArglis );
	}	
	
	va_end( marker );
	if( retCode != GOOD ) return FAILURE;
	
//	if( recCode && ErrGetRecoverText( recCode, lpRecov ) != GOOD )
	if( recCode && ErrGetErrorText( recCode, lpszRecov ) != GOOD ) {
		*lpszRecov = 0;
		return FAILURE;
	}
	return GOOD;
}


	