// ScaleDlg.cpp : implementation file
//

#include "stdafx.h"
#include "demopaja.h"
#include "ScaleDlg.h"
#include "demopajadoc.h"
#include "PajaTypes.h"
#include "Vector2C.h"
#include "BBox2C.h"
#include <math.h>
#include "SceneC.h"
#include "LayerC.h"
#include "EffectI.h"
#include "ParamI.h"
#include "UndoC.h"


using namespace Composition;
using namespace PajaTypes;
using namespace Edit;


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

/////////////////////////////////////////////////////////////////////////////
// CScaleDlg dialog


CScaleDlg::CScaleDlg( CWnd* pParent /*=NULL*/ ) :
	CDialog(CScaleDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CScaleDlg)
	m_f32X = 100.0f;
	m_f32Y = 100.0f;
	//}}AFX_DATA_INIT
}


void CScaleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CScaleDlg)
	DDX_Control(pDX, IDC_EDITX, m_rEditX);
	DDX_Control(pDX, IDC_EDITY, m_rEditY);
	DDX_Control(pDX, IDC_UNIFORM, m_rUniform);
	DDX_Text(pDX, IDC_EDITX, m_f32X);
	DDX_Text(pDX, IDC_EDITY, m_f32Y);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CScaleDlg, CDialog)
	//{{AFX_MSG_MAP(CScaleDlg)
	ON_BN_CLICKED(IDC_APPLY, OnApply)
	ON_BN_CLICKED(IDC_UNIFORM, OnUniform)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CScaleDlg message handlers

void CScaleDlg::OnApply() 
{
	// get latest data
	UpdateData( TRUE );

	CDemopajaDoc*			pDoc = GetDoc();
	ASSERT_VALID( pDoc );

	SceneC*		pScene = pDoc->GetCurrentScene();
	int32		i32Time = pDoc->GetTimecursor() * pDoc->GetFrameSizeInTicks();

	UndoC*	pUndo = new UndoC( "Transform Scale" );
	UndoC*	pOldUndo;

	int32	i32SelCount = 0;

	float32	f32ScaleX, f32ScaleY;

	f32ScaleX = m_f32X / 100.0f;
	if( m_rUniform.GetCheck() == 1 )
		f32ScaleY = f32ScaleX;
	else
		f32ScaleY = m_f32Y / 100.0f;

	for( uint32 i = 0; i < pScene->get_layer_count(); i++ ) {

		LayerC*	pLayer = pScene->get_layer( i );

		if( !pLayer || !(pLayer->get_flags() & ITEM_VISIBLE) || (pLayer->get_flags() & ITEM_LOCKED) ||
			!pLayer->get_timesegment()->is_visible( i32Time ) )
			continue;

		int32	i32TimeOffset = pLayer->get_timesegment()->get_segment_start();

		for( uint32 j = 0; j < pLayer->get_effect_count(); j++ ) {
			EffectI*	pEffect = pLayer->get_effect( j );

			if( !pEffect || !(pEffect->get_flags() & ITEM_VISIBLE) || (pEffect->get_flags() & ITEM_LOCKED) ||
				!pEffect->get_timesegment()->is_visible( i32Time - i32TimeOffset ) )
				continue;

			if( pEffect->get_flags() & ITEM_SELECTED ) {
				int32	i32ParamTime = i32Time - (i32TimeOffset + pEffect->get_timesegment()->get_segment_start());

				ParamVector2C*	pParamScale = (ParamVector2C*)pEffect->get_default_param( DEFAULT_PARAM_SCALE );

				if( pParamScale ) {
					Vector2C	rScale;
					pOldUndo = pParamScale->begin_editing( pUndo );
					pParamScale->get_val( i32ParamTime, rScale );
					rScale[0] *= f32ScaleX;
					rScale[1] *= f32ScaleY;
					pDoc->HandleParamNotify( pParamScale->set_val( i32ParamTime, rScale ) );	// create key at the timecursor time.
					pParamScale->end_editing( pOldUndo );
				}
				i32SelCount++;
			}
		}
	}
	
	if( i32SelCount ) {
		pDoc->GetUndoManager()->push( pUndo );
		pDoc->SetModifiedFlag();
	}
	else
		delete pUndo;

	pDoc->NotifyViews( NOTIFY_REDRAW_GRAPHICS );
}

BOOL CScaleDlg::Create( CWnd* pParentWnd ) 
{
	return CDialog::Create(IDD, pParentWnd);
}

BOOL CScaleDlg::PreTranslateMessage(MSG* pMsg) 
{
	if( pMsg->message == WM_KEYDOWN ) {
		if( (int)pMsg->wParam == VK_RETURN ) {
			OnApply();
			return TRUE; 
		}
		else if( (int)pMsg->wParam == VK_ESCAPE )
			return TRUE;
	}

	return CDialog::PreTranslateMessage(pMsg);
}

void CScaleDlg::OnUniform() 
{
	if( m_rUniform.GetCheck() == 1 ) {
		m_rEditY.SetWindowText( "0" );
		m_rEditY.EnableWindow( FALSE );
		m_rSpinnerY.EnableWindow( FALSE );
	}
	else {
		m_rEditY.EnableWindow( TRUE );
		m_rSpinnerY.EnableWindow( TRUE );

		UpdateData( TRUE );
		m_f32Y = m_f32X;
		UpdateData( FALSE );
	}
}

BOOL CScaleDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	if( !m_rSpinnerX.Create( WS_CHILD | WS_VISIBLE | SPNB_SETBUDDYFLOAT, CRect( 0, 0, 0, 0 ), this, IDC_SPINNER1 ) )
		return FALSE;
	m_rSpinnerX.SetScale( 1 );
	m_rSpinnerX.SetBuddy( &m_rEditX, SPNB_ATTACH_RIGHT );

	if( !m_rSpinnerY.Create( WS_CHILD | WS_VISIBLE | SPNB_SETBUDDYFLOAT, CRect( 0, 0, 0, 0 ), this, IDC_SPINNER2 ) )
		return FALSE;
	m_rSpinnerY.SetScale( 1 );
	m_rSpinnerY.SetBuddy( &m_rEditY, SPNB_ATTACH_RIGHT );

	
	return TRUE;
}
