// SceneToImageDlg.cpp : implementation file
//

#include "stdafx.h"
#include "demopaja.h"
#include "SceneToImageDlg.h"
#include "SubSceneC.h"
#include "FileHandleC.h"
#include "ColorTypeInDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


using namespace PajaTypes;
using namespace Composition;
using namespace Import;



/////////////////////////////////////////////////////////////////////////////
// CSceneToImageDlg dialog


CSceneToImageDlg::CSceneToImageDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSceneToImageDlg::IDD, pParent)
	, m_i32BufferFileNum(0)
{
	//{{AFX_DATA_INIT(CSceneToImageDlg)
	m_sName = _T("");
	m_i32FileNum = -1;
	//}}AFX_DATA_INIT
	m_pHandle = 0;
	m_pBufferHandle = 0;
	m_pFileList = 0;
}


void CSceneToImageDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSceneToImageDlg)
	DDX_Control(pDX, IDC_COMBOSCENE, m_rComboScene);
	DDX_Control(pDX, IDOK, m_rOk);
	DDX_Control(pDX, IDCANCEL, m_rCancel);
	DDX_Control(pDX, IDC_STATIC_INFO, m_rStaticInfo);
	DDX_Text(pDX, IDC_EDITNAME, m_sName);
	DDX_CBIndex(pDX, IDC_COMBOSCENE, m_i32FileNum);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_COMBOBUFFER, m_rComboBuffer);
	DDX_CBIndex(pDX, IDC_COMBOBUFFER, m_i32BufferFileNum);
}


BEGIN_MESSAGE_MAP(CSceneToImageDlg, CDialog)
	//{{AFX_MSG_MAP(CSceneToImageDlg)
	ON_CBN_SELCHANGE(IDC_COMBOSCENE, OnSelchangeComboscene)
	//}}AFX_MSG_MAP
	ON_CBN_SELCHANGE(IDC_COMBOBUFFER, OnCbnSelchangeCombobuffer)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSceneToImageDlg message handlers

BOOL CSceneToImageDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	

	//
	// Scenes
	//
	std::string	sStr;
	char		szFname[_MAX_FNAME];
	char		szExt[_MAX_EXT];
	int32		i32Idx;
	int32		i32Sel = 0;

	i32Idx = m_rComboScene.AddString( "<Empty>" );
	m_rComboScene.SetItemData( i32Idx, 0xffffffff );

	for( uint32 i = 0; i < m_pFileList->get_file_count(); i++ ) {

		FileHandleC*	pHandle = m_pFileList->get_file( i );
		ImportableI*	pImp = 0;

		if( !pHandle )
			continue;
		
		pImp = pHandle->get_importable();
		if( !pImp )
			continue;

		_splitpath( pImp->get_filename(), 0, 0, szFname, szExt );
		sStr = szFname;
		sStr += szExt;
	
		if(  pImp->get_class_id() == CLASS_SUBSCENE_IMPORTABLE ) {
			i32Idx = m_rComboScene.AddString( sStr.c_str() );
			m_rComboScene.SetItemData( i32Idx, i );
		}

		if( m_pHandle == pHandle )
			i32Sel = i32Idx;
	}
	m_rComboScene.SetCurSel( i32Sel );
	m_i32FileNum = i32Sel;


	//
	// Buffers
	//

	i32Sel = 0;

	i32Idx = m_rComboBuffer.AddString( "<Automatic>" );
	m_rComboBuffer.SetItemData( i32Idx, 0xffffffff );

	for( uint32 i = 0; i < m_pFileList->get_file_count(); i++ ) {

		FileHandleC*	pHandle = m_pFileList->get_file( i );
		ImportableI*	pImp = 0;

		if( !pHandle )
			continue;
		
		pImp = pHandle->get_importable();
		if( !pImp )
			continue;

		_splitpath( pImp->get_filename(), 0, 0, szFname, szExt );
		sStr = szFname;
		sStr += szExt;
	
		if(  pImp->get_class_id() == CLASS_SHAREDBUFFER_IMPORTABLE ) {
			i32Idx = m_rComboBuffer.AddString( sStr.c_str() );
			m_rComboBuffer.SetItemData( i32Idx, i );
		}

		if( m_pBufferHandle == pHandle )
			i32Sel = i32Idx;
	}
	m_rComboBuffer.SetCurSel( i32Sel );
	m_i32BufferFileNum = i32Sel;


	m_rOk.SetFlat( FALSE );
	m_rCancel.SetFlat( FALSE );

	UpdateInfo();

	return TRUE;
}


inline
uint32
lowest_bit_mask( uint32 v )
{
	return (v & -v);
}

static
uint32
ceil_power2( uint32 ui32Num )
{
	uint32	i = lowest_bit_mask( ui32Num );
	while( i < ui32Num )
		i <<= 1;
	return i;
}

static
int32
nearest_power2( int32 i32Num )
{
	int32	i = ceil_power2( i32Num );	// bigger
	int32	j = i / 2;					// smaller

	int32	i32DiffI = i - i32Num;
	int32	i32DiffJ = i32Num - j;

	// diff J has to be twice as little as diffI to be chosen.
	i32DiffI /= 2;

	if( i32DiffJ < i32DiffI )
		return j;

	return i;
}

void CSceneToImageDlg::UpdateInfo()
{
	char									szMsg[256] = "";
	SceneC*								pScene = 0;
	SharedBufferImportC*	pBufferImp = 0;

	if( m_pHandle )
	{
		TRACE( "has handle\n" );
		SceneImportC*	pImp = (SceneImportC*)m_pHandle->get_importable();
		pScene = pImp->get_scene();
	}

	if( m_pBufferHandle )
	{
		TRACE( "has buffer handle\n" );
		pBufferImp = (SharedBufferImportC*)m_pBufferHandle->get_importable();
	}


	if( !pScene )
	{
		TRACE( "no scene\n" );
		m_rStaticInfo.SetWindowText( szMsg );
		return;
	}

	int32	i32Width = 0;
	int32	i32Height = 0;

	if( !pBufferImp )
	{
		TRACE( "auto buffer\n" );
		i32Width = nearest_power2( pScene->get_layout_width() );
		i32Height = nearest_power2( pScene->get_layout_height() );

		_snprintf( szMsg, 255, "Scene Size: %d x %d\nAutomatic Buffer: %d x %d", pScene->get_layout_width(), pScene->get_layout_height(), i32Width, i32Height );
	}
	else
	{
		TRACE( "manual buffer\n" );

		i32Width = (int32)pBufferImp->get_width();
		i32Height = (int32)pBufferImp->get_height();

		_snprintf( szMsg, 255, "Scene Size: %d x %d\nShared Buffer '%s': %d x %d", pScene->get_layout_width(), pScene->get_layout_height(), pBufferImp->get_filename(), i32Width, i32Height );
	}

	m_rStaticInfo.SetWindowText( szMsg );
}

void CSceneToImageDlg::OnSelchangeComboscene() 
{
	UpdateData( TRUE );
	int32	i32Num = m_rComboScene.GetItemData( m_i32FileNum );
	FileHandleC*	pHandle = 0;
	if( i32Num != CB_ERR )
		pHandle = m_pFileList->get_file( i32Num );

	m_pHandle = pHandle;

	UpdateInfo();
}

void CSceneToImageDlg::OnCbnSelchangeCombobuffer()
{
	UpdateData( TRUE );
	int32	i32Num = m_rComboBuffer.GetItemData( m_i32BufferFileNum );
	FileHandleC*	pHandle = 0;
	if( i32Num != CB_ERR )
		pHandle = m_pFileList->get_file( i32Num );

	m_pBufferHandle = pHandle;

	UpdateInfo();
}
