/*
* Copyright (C) 2004 TES Electronic Solutions GmbH,
* All Rights Reserved.
* This source code and any compilation or derivative thereof is the
* proprietary information of TES Electronic Solutions GmbH
* and is confidential in nature.
* Under no circumstances is this software to be exposed to or placed
* under an Open Source License of any type without the expressed
* written permission of TES Electronic Solutions GmbH
*
*############################################################
*/

#include "StreamRuntimeConfig.h"

#ifdef GUILIANI_STREAM_GUI
#include "GUIStreamReaderXML.h"
#endif

#include "GUIAutoPtr.h"
#include "GUIFactoryManager.h"
#include "GUIResourceFileHandler.h"
#include "GUIStreamingException.h"
#include "GUITrace.h"

#include "GUIMemLeakWatcher.h"

#define CONFIGURATOR_MAX_FILE_VERSION 5

namespace NStreamRuntime
{
    Configurator::Configurator() :
        m_kConfigFileName(""),
        m_uiVersion(0),
        m_iScreenWidth(0),
        m_iScreenHeight(0),
        m_bResizable(false),
        m_kResourcePathPrefix(""),
        m_kAnimationsResFile(""),
        m_kImageResFile(""),
        m_kFontResFile(""),
        m_kSoundResFile(""),
        m_kGenResFile(""),
        m_kDataPoolFile(""),
        m_kPropResFile(""),
        m_kLanguageFile(""),
        m_bBkgEnabled(false),
        m_uiBkgColor(0xff000000),
        m_kDialogFile(""),
#ifdef GUILIANI_STREAM_GUI
        m_eStreamingMode(),
#endif
        m_bProfilingActive(false),
        m_uiMemoryAvailable(0),
        m_uiMemoryUsageWarning(0),
        m_uiMemoryUsageAlert(0),
        m_eGfxWrap(CGUICommonEnums::EGML),
        m_eFntWrap(CGUICommonEnums::FREETYPE),
        m_uiFTCacheSize(0),
        m_uiFTMaxFaces(0)
    {
        m_kLayerConfig.SetQuantity(0, false);
    }

    Configurator::~Configurator()
    {
    }

    eC_Bool Configurator::LoadConfiguration(const eC_String &rkFileName)
    {
        eC_Bool bRes = false;

#ifdef GUILIANI_STREAM_GUI
        // do not parse if empty
        if (rkFileName.IsEmpty())
            return true;

        // StreamRuntimeConfig is always XML format!
        CGUIStreamReaderXML kStreamReader;
        eC_File* pkFile = GETRESHANDLER.Open(rkFileName);
        if (pkFile == NULL || !pkFile->IsOpen())
        {
            GUILOG(GUI_TRACE_ERROR, "Configurator::LoadConfiguration: Could not open file \"" + rkFileName + "\".\n");
            return false;
        }
        else
        {
            GUILOG(GUI_TRACE_DEBUG, "Configurator::LoadConfiguration: Opened file \"" + rkFileName + "\".\n");
        }
        GETINPUTSTREAM.SetStreamingFile(pkFile);
        
        GUI_TRY
        {
            GETINPUTSTREAM.DELETE_COMMENT_TAG("Configuration");
            eC_Int uiFileVersion = GETINPUTSTREAM.ReadStreamingFileHeader();
            if (uiFileVersion > CONFIGURATOR_MAX_FILE_VERSION)
            {
                CGUIStreamingException kEx(rkFileName, GETINPUTSTREAM.GetCurLine());
                GUILOG_THROW_EXCEPTION(kEx,
                    "Configurator::LoadConfiguration: Invalid file version " + eC_String(uiFileVersion) + ".\n");
            }

            m_uiVersion = uiFileVersion;

            if (uiFileVersion >= 5)
                GETINPUTSTREAM.DELETE_COMMENT_TAG("Display");
            m_iScreenWidth = GETINPUTSTREAM.READ_INT("ScreenWidth");
            m_iScreenHeight = GETINPUTSTREAM.READ_INT("ScreenHeight");
            if (uiFileVersion >= 2)
                m_bResizable = GETINPUTSTREAM.READ_BOOL("Resizable");
            if (uiFileVersion >= 5)
                GETINPUTSTREAM.DELETE_COMMENT_TAG("/Display");

            if (uiFileVersion >= 5)
            {
                GETINPUTSTREAM.DELETE_COMMENT_TAG("Layers");
                eC_UInt uiLayerCount = GETINPUTSTREAM.READ_UINT("LayerCount");
                for (eC_UInt uiLayerIndex = 0; uiLayerIndex < uiLayerCount; ++uiLayerIndex)
                {
                    LayerConfiguration_t kConfig;
                    GETINPUTSTREAM.DELETE_COMMENT_TAG("Layer");
                    kConfig.m_uiLayerID = GETINPUTSTREAM.READ_UINT("ID");
                    kConfig.m_uiWidth = GETINPUTSTREAM.READ_UINT("Width");
                    kConfig.m_uiPaddedWidth = GETINPUTSTREAM.READ_UINT("PaddedWidth");
                    kConfig.m_uiHeight = GETINPUTSTREAM.READ_UINT("Height");
                    kConfig.m_ePixFormat = static_cast<CGUICommonEnums::ImageType_t>(GETINPUTSTREAM.READ_UINT("ColorFormat"));
                    kConfig.m_uiNumBuffers = GETINPUTSTREAM.READ_UINT("BufferCount");
                    GETINPUTSTREAM.DELETE_COMMENT_TAG("/Layer");
                    m_kLayerConfig.AddElement(kConfig);
                }
                GETINPUTSTREAM.DELETE_COMMENT_TAG("/Layers");
            }

            m_kResourcePathPrefix = GETINPUTSTREAM.READ_STRING("ResourcePathPrefix");

            if (uiFileVersion >= 5)
                GETINPUTSTREAM.DELETE_COMMENT_TAG("Resources");
            if (uiFileVersion >= 3)
                m_kAnimationsResFile = GETINPUTSTREAM.READ_STRING("Animations");
            m_kImageResFile = GETINPUTSTREAM.READ_STRING("Images");
            m_kFontResFile = GETINPUTSTREAM.READ_STRING("Fonts");
            m_kSoundResFile = GETINPUTSTREAM.READ_STRING("Sounds");
            m_kGenResFile = GETINPUTSTREAM.READ_STRING("GeneralResources");
            m_kDataPoolFile = GETINPUTSTREAM.READ_STRING("DataPool");
            m_kPropResFile = GETINPUTSTREAM.READ_STRING("Properties");
            m_kLanguageFile = GETINPUTSTREAM.READ_STRING("Language");
            if (uiFileVersion >= 5)
                GETINPUTSTREAM.DELETE_COMMENT_TAG("/Resources");

            m_bBkgEnabled = GETINPUTSTREAM.READ_BOOL("BackgroundEnabled");
            m_uiBkgColor = GETINPUTSTREAM.READ_HEX("BackgroundColor");
            m_kDialogFile = GETINPUTSTREAM.READ_STRING("Dialog");
            m_eStreamingMode = static_cast<FileType_t>(GETINPUTSTREAM.READ_INT("StreamingMode"));

            if (uiFileVersion >= 5)
            {
                m_bProfilingActive = GETINPUTSTREAM.READ_BOOL("ProfilingActive");
                if (m_bProfilingActive)
                {
                    GETINPUTSTREAM.DELETE_COMMENT_TAG("Profiling");
                    m_uiMemoryAvailable = GETINPUTSTREAM.READ_UINT("MemoryAvailable");
                    m_uiMemoryUsageWarning = GETINPUTSTREAM.READ_UINT("MemoryUsageWarning");
                    m_uiMemoryUsageAlert = GETINPUTSTREAM.READ_UINT("MemoryUsageAlert");
                    GETINPUTSTREAM.DELETE_COMMENT_TAG("/Profiling");
                }

                m_eGfxWrap = static_cast<CGUICommonEnums::GraphicsWrapper_t>(GETINPUTSTREAM.READ_UINT("GfxWrap"));
                m_eFntWrap = static_cast<CGUICommonEnums::FontWrapper_t>(GETINPUTSTREAM.READ_UINT("FntWrap"));
                m_uiFTCacheSize = GETINPUTSTREAM.READ_UINT("FTCacheSize");
                m_uiFTMaxFaces = GETINPUTSTREAM.READ_UINT("FTMaxFaces");
            }
            GETINPUTSTREAM.DELETE_COMMENT_TAG("/Configuration");
        }
        GUI_CATCH_ALL
        {
            GETINPUTSTREAM.ResetStreamingFile(); // because else it clashes with the AutoPtr
            GETRESHANDLER.Close(pkFile);

            CGUIStreamingException kEx(rkFileName, GETINPUTSTREAM.GetCurLine());
            GUILOG(GUI_TRACE_ERROR, kEx.Report());
            GUILOG_THROW_EXCEPTION(kEx, "Configurator::LoadConfiguration: Caught an exception while reading the configuration file.\n");
            return false;
        }

        GETINPUTSTREAM.ResetStreamingFile();
        GETRESHANDLER.Close(pkFile);

        bRes = true;
#endif

        return bRes;
    }

    eC_Int Configurator::GetScreenWidth() const
    {
        return m_iScreenWidth;
    }

    eC_Int Configurator::GetScreenHeight() const
    {
        return m_iScreenHeight;
    }

    eC_Bool Configurator::IsWindowResizable() const
    {
        return m_bResizable;
    }

    eC_UInt Configurator::GetLayerCount() const
    {
        return m_kLayerConfig.GetQuantity();
    }

    const LayerConfiguration_t& Configurator::GetLayerConfig(const eC_UInt& uiLayerIndex)
    {
        if (uiLayerIndex < m_kLayerConfig.GetQuantity())
            return m_kLayerConfig[uiLayerIndex];
        else
            GUILOG_THROW_EXCEPTION(CGUIException(), "Configurator::GetLayerConfig: requested index is out of bounds.\n");
    }

    const eC_String& Configurator::GetResourcePathPrefix() const
    {
        return m_kResourcePathPrefix;
    }

    const eC_String& Configurator::GetImageFileName() const
    {
        return m_kImageResFile;
    }

    const eC_String& Configurator::GetFontFileName() const
    {
        return m_kFontResFile;
    }

    const eC_String& Configurator::GetSoundFileName() const
    {
        return m_kSoundResFile;
    }

    const eC_String& Configurator::GetGenResFileName() const
    {
        return m_kGenResFile;
    }

    const eC_String& Configurator::GetDataPoolFileName() const
    {
        return m_kDataPoolFile;
    }

    const eC_String& Configurator::GetPropertyFileName() const
    {
        return m_kPropResFile;
    }

    const eC_String& Configurator::GetLanguageFileName() const
    {
        return m_kLanguageFile;
    }

    const eC_String& Configurator::GetAnimationsFileName() const
    {
        return m_kAnimationsResFile;
    }

    eC_Bool Configurator::IsBackgroundEnabled() const
    {
        return m_bBkgEnabled;
    }

    eC_UInt Configurator::GetBackgroundColor() const
    {
        return m_uiBkgColor;
    }

    eC_String Configurator::GetDialogFileName() const
    {
        return m_kDialogFile;
    }

#ifdef GUILIANI_STREAM_GUI
    FileType_t Configurator::GetStreamingMode() const
    {
        return m_eStreamingMode;
    }
#endif

    eC_Bool Configurator::IsProfilingActive() const
    {
        return m_bProfilingActive;
    }

    eC_UInt Configurator::GetMemoryAvailable() const
    {
        return m_uiMemoryAvailable;
    }

    eC_UInt Configurator::GetMemoryUsageWarning() const
    {
        return m_uiMemoryUsageWarning;
    }

    eC_UInt Configurator::GetMemoryUsageAlert() const
    {
        return m_uiMemoryUsageAlert;
    }

    CGUICommonEnums::GraphicsWrapper_t Configurator::GetGfxWrap() const
    {
        return m_eGfxWrap;
    }

    CGUICommonEnums::FontWrapper_t Configurator::GetFntWrap() const
    {
        return m_eFntWrap;
    }

    eC_UInt Configurator::GetFTCacheSize() const
    {
        return m_uiFTCacheSize;
    }

    eC_UInt Configurator::GetFTMaxFaces() const
    {
        return m_uiFTMaxFaces;
    }

    eC_UInt Configurator::GetVersion() const
    {
        return m_uiVersion;
    }
}
