/*
 * DirectX 8 error routines
 *
 * Copyright 2004-2005 Robert Reif
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>
#include <stdio.h>

#define COM_NO_WINDOWS_H
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"

#include "mmsystem.h"
#include "dsound.h"
#include "dmerror.h"
#include "ddraw.h"
#include "dinput.h"
#include "vfwmsgs.h"

#include "dxerr8.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dxerr);

typedef struct {
    HRESULT      hr;
    const CHAR*  resultA;
    const WCHAR* resultW;
    const CHAR*  descriptionA;
    const WCHAR* descriptionW;
} error_info;

#include "errors.h"

const char * WINAPI DXGetErrorString8A(HRESULT hr)
{
    unsigned int i, j, k = 0;
    TRACE("(0x%08lx)\n", hr);

    for (i = sizeof(info)/sizeof(info[0]); i != 0; i /= 2) {
        j = k + (i / 2);
        if (hr == info[j].hr)
            return info[j].resultA;
        if ((unsigned int)hr > (unsigned int)info[j].hr) {
            k = j + 1;
            i--;
        }
    }

    return "Unknown";
}

const WCHAR * WINAPI DXGetErrorString8W(HRESULT hr)
{
    static const WCHAR unknown[] = { 'U', 'n', 'k', 'n', 'o', 'w', 'n', 0 };
    unsigned int i, j, k = 0;
    TRACE("(0x%08lx)\n", hr);

    for (i = sizeof(info)/sizeof(info[0]); i != 0; i /= 2) {
        j = k + (i / 2);
        if (hr == info[j].hr)
            return info[j].resultW;
        if ((unsigned int)hr > (unsigned int)info[j].hr) {
            k = j + 1;
            i--;
        }
    }

    return unknown;
}

const char * WINAPI DXGetErrorDescription8A(HRESULT hr)
{
    unsigned int i, j, k = 0;
    TRACE("(0x%08lx)\n", hr);

    for (i = sizeof(info)/sizeof(info[0]); i != 0; i /= 2) {
        j = k + (i / 2);
        if (hr == info[j].hr)
            return info[j].descriptionA;
        if ((unsigned int)hr > (unsigned int)info[j].hr) {
            k = j + 1;
            i--;
        }
    }

    return "n/a";
}

const WCHAR * WINAPI DXGetErrorDescription8W(HRESULT hr)
{
    static const WCHAR na[] = { 'n', '/', 'a', 0 };
    unsigned int i, j, k = 0;
    TRACE("(0x%08lx)\n", hr);

    for (i = sizeof(info)/sizeof(info[0]); i != 0; i /= 2) {
        j = k + (i / 2);
        if (hr == info[j].hr)
            return info[j].descriptionW;
        if ((unsigned int)hr > (unsigned int)info[j].hr) {
            k = j + 1;
            i--;
        }
    }

    return na;
}

HRESULT WINAPI DXTraceA(const char* strFile, DWORD dwLine, HRESULT hr, const char*  strMsg, BOOL bPopMsgBox)
{
    char msg[1024];
    TRACE("(%p,%ld,0x%08lx,%p,%d)\n", strFile, dwLine, hr, strMsg, bPopMsgBox);

    if (bPopMsgBox) {
        snprintf(msg, sizeof(msg), "File: %s\nLine: %ld\nError Code: %s (0x%08lx)\nCalling: %s",
            strFile, dwLine, DXGetErrorString8A(hr), hr, strMsg);
        MessageBoxA(0, msg, "Unexpected error encountered", MB_OK|MB_ICONERROR);
    } else {
        snprintf(msg, sizeof(msg), "%s(%ld): %s (hr=%s (0x%08lx))", strFile,
            dwLine, strMsg, DXGetErrorString8A(hr), hr);
        OutputDebugStringA(msg);
    }

    return hr;
}

HRESULT WINAPI DXTraceW(const char* strFile, DWORD dwLine, HRESULT hr, const WCHAR* strMsg, BOOL bPopMsgBox)
{
    WCHAR msg[1024];
    TRACE("(%p,%ld,0x%08lx,%p,%d)\n", strFile, dwLine, hr, strMsg, bPopMsgBox);

    if (bPopMsgBox) {
        static const WCHAR format[] = { 'F','i','l','e',':',' ','%','s','\\','n','L','i','n',
            'e',':',' ','%','l','d','\\','n','E','r','r','o','r',' ','C','o',
            'd','e',':',' ','%','s',' ','(','0','x','%','0','8','l','x',')',
            '\\','n','C','a','l','l','i','n','g',':',' ','%','s',0 };
        static const WCHAR caption[] = { 'U','n','e','x','p','e','c','t','e','d',' ','e','r',
            'r','o','r',' ','e','n','c','o','u','n','t','e','r','e','d',0 };
        /* FIXME: should use wsnprintf */
        wsprintfW(msg, format, strFile, dwLine,
                  DXGetErrorString8W(hr), hr, strMsg);
        MessageBoxW(0, msg, caption, MB_OK|MB_ICONERROR);
    } else {
        static const WCHAR format[] = { '%','s','(','%','l','d',')',':',' ','%','s',' ','(',
            'h','r','=','%','s',' ','(','0','x','%','0','8','l','x',')',')',' ',
            0 };
        /* FIXME: should use wsnprintf */
        wsprintfW(msg, format, strFile, dwLine, strMsg,
                  DXGetErrorString8W(hr), hr);
        OutputDebugStringW(msg);
    }

    return hr;
}
