//////////////////////////////////////////////////////////////////////////////
//
// Tools_OS.cpp
//
// Created by Morgan Parry.
//
// Copyright (c) 2002 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

// Standard PC.
#include <windows.h>

// Engine independent.
#include "Debugging/Asura_Assert.h"

// Project independent.
#include "PC/OS/Tools_OS.h"

// G L O B A L S /////////////////////////////////////////////////////////////

static char* g_szLastSystemError;
static DWORD g_uLastSystemErrorCode;
static bool g_bLastSystemErrorCodeIsValid;

// P R O T O T Y P E S   A N D   I N L I N E   F U N C T I O N S /////////////

static void FreeErrorString( void );

// C L A S S   I M P L E M E N T A T I O N S /////////////////////////////////

const char* Tools_OS::GetLastSystemError( void )
{
    const DWORD uErrorCode = GetLastError();

    if( g_bLastSystemErrorCodeIsValid )
    {
        Asura_Assert( g_szLastSystemError, "" );
        if( uErrorCode == g_uLastSystemErrorCode )
        {
            return g_szLastSystemError;
        }
    }

    // Free last error message, if necessary.
    FreeErrorString();

    // Get error message from system.
    DWORD uFormattedOK = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                        NULL,
                                        uErrorCode,
                                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                        reinterpret_cast<LPTSTR>(&g_szLastSystemError),
                                        0,
                                        NULL );

    // Check that succeeded.
    if( !uFormattedOK || !g_szLastSystemError )
    {
        FreeErrorString();
        return "*** couldn't get last error from system ***";
    }
    else
    {
        g_uLastSystemErrorCode = uErrorCode;
        g_bLastSystemErrorCodeIsValid = true;
        return g_szLastSystemError;
    }    
}

void Tools_OS::Initalise( void )
{
    g_szLastSystemError = NULL;
    g_bLastSystemErrorCodeIsValid = false;
}

void Tools_OS::Shutdown( void )
{
    FreeErrorString();
}

// F U N C T I O N   I M P L E M E N T A T I O N S ///////////////////////////

static void FreeErrorString( void )
{
    if( g_szLastSystemError )
    {
        LocalFree( g_szLastSystemError );
        g_szLastSystemError = NULL;
    }

    g_bLastSystemErrorCodeIsValid = false;
}
