/*
 * This source file is part of KEOS (Free 3D Engine)
 * For the latest info, see http://www.keosengine.org/
 * E-mails : thierry.vouriot@keosengine.org, yeri@keosengine.org
 * 
 * This program 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 of the License, or (at your option) any later
 * version.
 *
 * This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
 * http://www.gnu.org/copyleft/lesser.txt.
 *
 */

#include "KeosException.h"
#include "KeosString.h"

namespace Keos
{
    //=======================================================================
    // CException implementation
    //=======================================================================

    CException* CException::ms_pLast = NULL;

    //-----------------------------------------------------------------------
    CException::CException(const String& strMessage) :
    m_strMessage(strMessage)
    {
        ms_pLast = this;
        m_strShortMessage = "EXCEPTION undefined";
    }

    //-----------------------------------------------------------------------
    CException::~CException()
    {
    }

    //-----------------------------------------------------------------------
    const char* CException::what() const
    {
        return m_strMessage.c_str();
    }

    //-----------------------------------------------------------------------
    const char* CException::what_short() const
    {
        return m_strShortMessage.c_str();
    }

    //-----------------------------------------------------------------------
    CException* CException::GetLastException(void) throw()
    {
        return ms_pLast;
    }

    //-----------------------------------------------------------------------
    void CException::SetFileLine(String strFile, int nLine)
    {
        std::ostringstream oss;
        oss << m_strMessage << std::endl << "File: '"<< strFile << "' Line: " 
            << CStringConverter::ToString(nLine);
        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << m_strShortMessage << " ("<< strFile << ", L" 
             << CStringConverter::ToString(nLine) << ")";
        m_strShortMessage = oss2.str();    
    }


    //=======================================================================
    // CAssertException implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    CAssertException::CAssertException(const String& strFile, int nLine, const String& strMessage)
    {
        // Format error message
        std::ostringstream oss;
        oss << strMessage << std::endl;
        oss << strFile << " (" << nLine << ")";

        m_strMessage = oss.str();
    }


    //=======================================================================
    // CBadDelete implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    CBadDelete::CBadDelete(const void* pPtr, const String& strFile, int nLine, bool bNewArray)
    {
        // Format error message
        std::ostringstream oss;
        oss << "EXCEPTION CBadDelete --> "
            << (bNewArray ? "new[] / delete" :  "new / delete[]")
            << " detectee" << std::endl
            << "Address : 0x" << pPtr << std::endl
            << "Source file : " << strFile << " (" << nLine << ")";

        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << "EXCEPTION CBadDelete --> " 
             << (bNewArray ? "new[] / delete" :  "new / delete[]")
             << " detectee";

        m_strShortMessage = oss2.str();
    }


    //=======================================================================
    // CLoadingFailed implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    CLoadingFailed::CLoadingFailed(const String& strFile, const String& strMessage, const String& strSource)
    {
        // Format error message
        std::ostringstream oss;
		oss << "EXCEPTION CLoadingFailed in " << strSource << std::endl 
			<< "Error in the load of '" << strFile << "'" << std::endl << strMessage;

        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << "EXCEPTION CLoadingFailed in " << strSource << " --> " 
             << "Error in the load of '" << strFile << "'";

        m_strShortMessage = oss2.str();
    }


    //=======================================================================
    // CDynLibError implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    CDynLibError::CDynLibError(const String& strFile, const String& strMessage, const String& strSource)
    {
        // Format error message
        std::ostringstream oss;
		oss << "EXCEPTION CDynLibError in " << strSource << std::endl
			<< "Error in the library '" << strFile << "'" << std::endl << strMessage;

        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << "EXCEPTION CDynLibError in " << strSource << " --> " 
             << "Error in the library '" << strFile << "'";

        m_strShortMessage = oss2.str();
    }


    //=======================================================================
    // COutOfMemory implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    COutOfMemory::COutOfMemory(const String& strMessage, const String& strSource)  
    {
		// Format error message
        std::ostringstream oss;
		oss << "EXCEPTION COutOfMemory in " << strSource << std::endl << strMessage;

        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << "EXCEPTION COutOfMemory in " << strSource;

        m_strShortMessage = oss2.str();
    }

    //=======================================================================
    // CUnsupported implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    CUnsupported::CUnsupported(const String& strFeature, const String& strSource)
    {
        // Format error message
        std::ostringstream oss;
		oss << "EXCEPTION CUnsupported in " << strSource << std::endl
			<< "Unsupported feature : " << strFeature;

        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << "EXCEPTION CUnsupported in " << strSource << " --> " 
            << "Unsupported feature : " << strFeature;

        m_strShortMessage = oss2.str();
    }

    //=======================================================================
    // CBadConversion implementation
    //=======================================================================

    //-----------------------------------------------------------------------
    CBadConversion::CBadConversion(const String& strError, const String& strSource)
    {
        // Format error message
        std::ostringstream oss;
		oss << "EXCEPTION CBadConversion in " << strSource << std::endl
			<< "Conversion error : " << strError;

        m_strMessage = oss.str();

        std::ostringstream oss2;
        oss2 << "EXCEPTION CBadConversion in " << strSource << " --> " 
            << "Conversion error : " << strError;

        m_strShortMessage = oss2.str();
    }
} // namespace Keos
