/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */

#include "ihxtprofile.h"
#ifdef _MAC_UNIX
#include <Carbon/Carbon.h>
#endif
#include "hxcom.h"

// standard includes
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include "filewriter.h"

CFileWriter::CFileWriter() :
m_bInit(FALSE),
m_pStatsFile(NULL),
m_ulnTabs(0)
{
}


HX_RESULT CFileWriter::Init(const char *pszFileName)
{
    
    if (m_pStatsFile)
	fclose(m_pStatsFile);
    
    
    m_pStatsFile = fopen(pszFileName, "wt");
    if (m_pStatsFile)
    {
	m_bInit = TRUE;
	return HXR_OK;
    }
    else
    {
	m_bInit = FALSE;
	return HXR_FAIL;
    }
}

HX_RESULT CFileWriter::Close()
{
    if(!m_bInit)
	return HXR_FAIL;
    
    if (m_pStatsFile)
	fclose(m_pStatsFile);
    
    return HXR_OK;
}

HX_RESULT CFileWriter::WriteBag( const char *pszName, IHXTPropertyBag *pStatsBag )
{
    HX_RESULT res = HXR_OK;
    BOOL bStatsPresent = FALSE;
    if(!m_bInit)
	return HXR_FAIL;
    
    ++ m_ulnTabs;
    if (pStatsBag)
    {
	// Get the property enumerator
	IHXTPropertyEnumerator* pEnum = NULL;
	res = pStatsBag->GetPropertyEnumerator(&pEnum);
	
	// Get the first prop
	IHXTProperty* pProp = NULL;
	HX_RESULT resEnum = HXR_OK;		
	if (SUCCEEDED(res))			
	    resEnum = pEnum->First(&pProp);
	
	if (SUCCEEDED(resEnum)&& resEnum != HXR_ELEMENT_NOT_FOUND)
	{
	    bStatsPresent = TRUE;
	    fprintf(m_pStatsFile,"<%s>\n",pszName);
	    //fprintf(m_pStatsFile,"<Name type=\"string\">%s</Name>\n",pszName);
	}
	
	// Dump each property key to the string
	while (SUCCEEDED(resEnum) && resEnum != HXR_ELEMENT_NOT_FOUND && SUCCEEDED(res))
	{
	    for (UINT32 i=0; i<m_ulnTabs;++i)
	    {
		fprintf(m_pStatsFile,"\t");
	    }
	    
	    //CPNString strTemp;
	    switch (pProp->GetType())
	    {				
	    case eTypeBOOL:
		{
		    BOOL bValue = FALSE;
		    res = pStatsBag->GetBool(pProp->GetKey(), &bValue);
		    
		    if (SUCCEEDED(res))						
			fprintf(m_pStatsFile,"<%s type=\"bool\">%ld</%s>\n", pProp->GetKey(), bValue, pProp->GetKey());
		    
		    break;
		}
	    case eTypeINT32:
		{
		    INT32 lValue = 0;
		    res = pStatsBag->GetInt(pProp->GetKey(), &lValue);
		    
		    if (SUCCEEDED(res))
			fprintf(m_pStatsFile,"<%s type=\"int\">%ld</%s>\n", pProp->GetKey(), lValue ,pProp->GetKey());
		    
		    break;
		}
	    case eTypeUINT32:
		{
		    UINT32 ulValue = 0;
		    res = pStatsBag->GetUint(pProp->GetKey(), &ulValue);
		    
		    if (SUCCEEDED(res))
			fprintf(m_pStatsFile,"<%s type=\"uint\">%ld</%s>\n", pProp->GetKey(), ulValue,pProp->GetKey());
		    
		    break;
		}
		
	    case eTypeUintRange:
		{
		    IHXTUintRange* pRange = NULL;
		    res = pStatsBag->GetUintRange(pProp->GetKey(), &pRange);
		    
		    if (SUCCEEDED(res))
		    {
			fprintf(m_pStatsFile,"<%sMin type=\"uint\">%ld</%sMin>\n", pProp->GetKey(), pRange->GetMin(), pProp->GetKey());
			for (UINT32 i=0; i<m_ulnTabs;++i)
			{
			    fprintf(m_pStatsFile,"\t");
			}
			fprintf(m_pStatsFile,"<%sMax type=\"uint\">%ld</%sMax>\n", pProp->GetKey(), pRange->GetMax(), pProp->GetKey());
			HX_RELEASE(pRange);
		    }
		    
		    break;
		}
		
	    case eTypeINT64:
		{
		    INT64 llValue = 0;
		    res = pStatsBag->GetInt64(pProp->GetKey(), &llValue);
		    
		    if (SUCCEEDED(res))
			fprintf(m_pStatsFile,"<%s type=\"int\">%ld</%s>\n", pProp->GetKey(),(UINT32)llValue,pProp->GetKey());
		    
		    break;
		}
		
	    case eTypeDouble:
		{
		    double dValue = 0;
		    res = pStatsBag->GetDouble(pProp->GetKey(), &dValue);
		    
		    if (SUCCEEDED(res))
			fprintf(m_pStatsFile,"<%s type=\"double\">%10.3f</%s>\n", pProp->GetKey(), dValue ,pProp->GetKey());
		    break;
		}
		
	    case eTypeCString:
		{
		    const char* szValue = NULL;
		    res = pStatsBag->GetString(pProp->GetKey(), &szValue);
		    
		    // Handle arbitrarily long strings
		    if (SUCCEEDED(res))
		    {
			fprintf(m_pStatsFile,"<%s type=\"string\">%s</%s>\n",pProp->GetKey(),szValue,pProp->GetKey());
		    }
		    
		    break;
		}
	    case eTypeComposite:
		{
		    IHXTPropertyBag*  pTempBag = NULL;
		    res = pStatsBag->GetPropertyBag( pProp->GetKey(), &pTempBag );
		    if (SUCCEEDED(res))
		    {
			const char* pName = pProp->GetKey();
			res = WriteBag(pName,pTempBag);
		    }
		    HX_RELEASE(pTempBag);
		    break;
		}
	    }
	    
	    HX_RELEASE(pProp);
	    
	    if (SUCCEEDED(res))
		resEnum = pEnum->Next(&pProp);
		}
		
		HX_RELEASE(pEnum);
	}		
	
	--m_ulnTabs;
	
	if (bStatsPresent)
	{
	    for (UINT32 i=0; i<m_ulnTabs;++i)
	    {
		fprintf(m_pStatsFile,"\t");
	    }
	    fprintf(m_pStatsFile,"</%s>\n",pszName );
	}
	
	if (m_ulnTabs == 0 && bStatsPresent )
	{
	    fprintf(m_pStatsFile,"\n\n\n",pszName );
	}
	
	return res;	
	
}
