// MainFrm.cpp : implementation of the CMainFrame class
//

#pragma warning( disable : 4786 )		// long names generated by STL

#include "stdafx.h"
#include "demopaja.h"
#include "MainFrm.h"
#include "DLLInfoDlg.h"
#include "DynDialog.h"
#include "DemopajaView.h"
#include "PajaTypes.h"
#include "ChooseImporterDlg.h"
#include "GridSettingsDlg.h"
#include "HelpDlg.h"
#include "FactoryC.h"
#include "ClassDescC.h"
#include "GraphicsDeviceI.h"
#include "MergeFileDlg.h"
#include "CommonDirsDlg.h"

using namespace PajaTypes;
using namespace Edit;
using namespace Import;
using namespace PluginClass;
using namespace PajaSystem;


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

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
	ON_UPDATE_COMMAND_UI(ID_HELP_PLUGINS, OnUpdateHelpPlugins)
	ON_COMMAND(ID_HELP_PLUGINS, OnHelpPlugins)
	ON_COMMAND(ID_EDIT_PURGE_UNDOSTACK, OnEditPurgeUndostack)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PURGE_UNDOSTACK, OnUpdateEditPurgeUndostack)
	ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
	ON_COMMAND(ID_VIEW_FILEINSPECTOR, OnViewFileinspector)
	ON_UPDATE_COMMAND_UI(ID_VIEW_FILEINSPECTOR, OnUpdateViewFileinspector)
	ON_COMMAND(ID_VIEW_TIMELINE, OnViewTimeline)
	ON_UPDATE_COMMAND_UI(ID_VIEW_TIMELINE, OnUpdateViewTimeline)
	ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
	ON_UPDATE_COMMAND_UI(ID_FILE_IMPORT, OnUpdateFileImport)
	ON_COMMAND(ID_EDIT_DEMOPROPERTIES, OnEditDemoproperties)
	ON_UPDATE_COMMAND_UI(ID_EDIT_DEMOPROPERTIES, OnUpdateEditDemoproperties)
	ON_COMMAND(ID_VIEW_GRID, OnViewGrid)
	ON_UPDATE_COMMAND_UI(ID_VIEW_GRID, OnUpdateViewGrid)
	ON_COMMAND(ID_VIEW_SNAPTOGRID, OnViewSnaptogrid)
	ON_UPDATE_COMMAND_UI(ID_VIEW_SNAPTOGRID, OnUpdateViewSnaptogrid)
	ON_COMMAND(ID_VIEW_GRIDSETTINGS, OnViewGridsettings)
	ON_UPDATE_COMMAND_UI(ID_VIEW_GRIDSETTINGS, OnUpdateViewGridsettings)
	ON_COMMAND(ID_PLAY_PLAY, OnPlayPlay)
	ON_UPDATE_COMMAND_UI(ID_PLAY_PLAY, OnUpdatePlayPlay)
	ON_COMMAND(ID_PLAY_PLAYPREVIEW, OnPlayPlaypreview)
	ON_UPDATE_COMMAND_UI(ID_PLAY_PLAYPREVIEW, OnUpdatePlayPlaypreview)
	ON_COMMAND(ID_FILE_MERGE, OnFileMerge)
	ON_UPDATE_COMMAND_UI(ID_FILE_MERGE, OnUpdateFileMerge)
	ON_COMMAND(ID_VIEW_TOOLSTOOLBAR, OnViewToolstoolbar)
	ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLSTOOLBAR, OnUpdateViewToolstoolbar)
	ON_COMMAND(ID_TOOL_ARROW, OnToolArrow)
	ON_UPDATE_COMMAND_UI(ID_TOOL_ARROW, OnUpdateToolArrow)
	ON_COMMAND(ID_TOOL_KEYARROW, OnToolKeyarrow)
	ON_UPDATE_COMMAND_UI(ID_TOOL_KEYARROW, OnUpdateToolKeyarrow)
	ON_COMMAND(ID_TOOL_PAN, OnToolPan)
	ON_UPDATE_COMMAND_UI(ID_TOOL_PAN, OnUpdateToolPan)
	ON_COMMAND(ID_TOOL_ROTATE, OnToolRotate)
	ON_UPDATE_COMMAND_UI(ID_TOOL_ROTATE, OnUpdateToolRotate)
	ON_UPDATE_COMMAND_UI(ID_TOOL_SCALE, OnUpdateToolScale)
	ON_COMMAND(ID_TOOL_SCALE, OnToolScale)
	ON_COMMAND(ID_TOOL_ZOOM, OnToolZoom)
	ON_UPDATE_COMMAND_UI(ID_TOOL_ZOOM, OnUpdateToolZoom)
	ON_COMMAND(ID_VIEW_TRANSFORMDIALOG, OnViewTransformdialog)
	ON_UPDATE_COMMAND_UI(ID_VIEW_TRANSFORMDIALOG, OnUpdateViewTransformdialog)
	ON_COMMAND(ID_VIEW_ALIGNDIALOG, OnViewAligndialog)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ALIGNDIALOG, OnUpdateViewAligndialog)
	ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
	ON_UPDATE_COMMAND_UI(ID_FILE_EXPORT, OnUpdateFileExport)
	ON_COMMAND(ID_VIEW_HELPDIALOG, OnViewHelpdialog)
	ON_UPDATE_COMMAND_UI(ID_VIEW_HELPDIALOG, OnUpdateViewHelpdialog)
	ON_COMMAND(ID_VIEW_LAYOUTRULERS, OnViewLayoutrulers)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LAYOUTRULERS, OnUpdateViewLayoutrulers)
	ON_COMMAND(ID_VIEW_TOOLBAR, OnViewToolbar)
	ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateViewToolbar)
	ON_COMMAND(ID_VIEW_PLAYTOOLBAR, OnViewPlaytoolbar)
	ON_UPDATE_COMMAND_UI(ID_VIEW_PLAYTOOLBAR, OnUpdateViewPlaytoolbar)
	ON_COMMAND(ID_FILE_EXPORTAVI, OnFileExportavi)
	ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTAVI, OnUpdateFileExportavi)
	ON_COMMAND(ID_VIEW_PARAMETERS, OnViewParameters)
	ON_UPDATE_COMMAND_UI(ID_VIEW_PARAMETERS, OnUpdateViewParameters)
	//}}AFX_MSG_MAP
	ON_UPDATE_COMMAND_UI( ID_INDICATOR_GRAPHDEVICE, OnUpdateIndicatorGraphDevice )
	ON_UPDATE_COMMAND_UI( ID_INDICATOR_PROJECTPATH, OnUpdateIndicatorProjectPath )
	ON_COMMAND(ID_EDIT_PROJECTPATH, OnEditProjectpath)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PROJECTPATH, OnUpdateEditProjectpath)
	ON_COMMAND(ID_HELP_HELPINDEX, OnHelpHelpindex)
	ON_UPDATE_COMMAND_UI(ID_HELP_HELPINDEX, OnUpdateHelpHelpindex)
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_PROJECTPATH,
	ID_INDICATOR_GRAPHDEVICE,
//	ID_INDICATOR_CAPS,
//	ID_INDICATOR_NUM,
//	ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame() :
	m_pTransDlg( 0 ),
	m_pAlignDlg( 0 ),
	m_pHelpDlg( 0 )
{
	
}

CMainFrame::~CMainFrame()
{
	delete m_pAlignDlg;
	delete m_pTransDlg;
	delete m_pHelpDlg;
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndStandardBar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(0, 0, 0, 0), IDR_MAINFRAME ) ||
		!m_wndStandardBar.LoadToolBar( IDR_MAINFRAME ) )
	{
		TRACE0("Failed to create standard toolbar\n");
		return -1;      // fail to create
	}
	m_wndStandardBar.SetWindowText( "Standard" );

	if( !m_wndToolsBar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(0, 0, 0, 0), IDR_TOOLS ) ||
		!m_wndToolsBar.LoadToolBar( IDR_TOOLS ) )
	{
		TRACE0( "Failed to create tools toolbar\n" );
		return -1;      // fail to create
	}
	m_wndToolsBar.SetWindowText( "Tools" );

	if( !m_wndPlayBar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(0, 0, 0, 0), IDR_PLAYBAR ) ||
		!m_wndPlayBar.LoadToolBar( IDR_PLAYBAR ) )
	{
		TRACE0( "Failed to create tools toolbar\n" );
		return -1;      // fail to create
	}
	m_wndPlayBar.SetWindowText( "Play" );

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	if( !m_wndInspector.Create( _T("File Inspector"), this, CSize( 250, 350 ),
		TRUE, ID_INSPECTOR ) ) {
		TRACE0( "Failed to create Inspector bar.\n" );
		return -1;
	}
	m_wndInspector.SetBarStyle( m_wndInspector.GetBarStyle() |
		CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC );

	if( !m_wndTimeLine.Create( _T("Timeline"), this, CSize( 600, 300 ),
		TRUE, ID_TIMELINE ) ) {
		TRACE0( "Failed to create Timeline bar.\n" );
		return -1;
	}
	m_wndTimeLine.SetBarStyle( m_wndTimeLine.GetBarStyle() |
		CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC );

//	if( !m_wndParameter.Create( _T("Parameters"), this, CSize( 250, 350 ),
//		TRUE, ID_PARAMETERS ) ) {
//		TRACE0( "Failed to create Parameter bar.\n" );
//		return -1;
//	}
//	m_wndParameter.SetBarStyle( m_wndParameter.GetBarStyle() |
//		CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC );


	m_wndStandardBar.EnableDocking( CBRS_ALIGN_ANY );
	m_wndToolsBar.EnableDocking( CBRS_ALIGN_ANY );
	m_wndPlayBar.EnableDocking( CBRS_ALIGN_ANY );
	EnableDocking( CBRS_ALIGN_ANY );
	m_wndInspector.EnableDocking( CBRS_ALIGN_ANY );
	m_wndTimeLine.EnableDocking( CBRS_ALIGN_ANY );
//	m_wndParameter.EnableDocking( CBRS_ALIGN_ANY );

	DockControlBar( &m_wndStandardBar );
    DockControlBarLeftOf( &m_wndToolsBar, &m_wndStandardBar );
    DockControlBarLeftOf( &m_wndPlayBar, &m_wndToolsBar );
    DockControlBar( &m_wndInspector, AFX_IDW_DOCKBAR_LEFT );
//    DockControlBar( &m_wndParameter, AFX_IDW_DOCKBAR_RIGHT );
    DockControlBar( &m_wndTimeLine, AFX_IDW_DOCKBAR_BOTTOM );

	// Load bar states
	CString	sProfile( "BarStates" );
	if( VerifyBarState( sProfile ) ) {
		m_wndTimeLine.LoadState( sProfile );
		m_wndInspector.LoadState( sProfile );
		LoadBarState( sProfile );
	}

#ifdef _SCB_REPLACE_MINIFRAME
	m_pFloatingFrameClass = RUNTIME_CLASS( CSCBMiniDockFrameWnd );
#endif //_SCB_REPLACE_MINIFRAME

	return 0;
}


BOOL CMainFrame::DestroyWindow() 
{
	// Save bar states
	CString	sProfile( "BarStates" );
	m_wndTimeLine.SaveState( sProfile );
	m_wndInspector.SaveState( sProfile );
//	m_wndParameter.SaveState( sProfile );
    SaveBarState( sProfile );
	
	return CFrameWnd::DestroyWindow();
}

void CMainFrame::DockControlBarLeftOf( CControlBar* pBar, CControlBar* pPrev )
{
	CRect	rc;
    RecalcLayout( TRUE );
	pPrev->GetWindowRect( &rc );
	rc.OffsetRect( 32, 0 );
    DockControlBar( pBar, AFX_IDW_DOCKBAR_TOP, &rc );
}


void CMainFrame::DockControlBarTopOf( CControlBar* pBar, CControlBar* pPrev )
{
	CRect	rc;
    RecalcLayout( TRUE );
	pPrev->GetWindowRect( &rc );
	rc.OffsetRect( 0, 1 );
    DockControlBar( pBar, AFX_IDW_DOCKBAR_LEFT, &rc );
}


BOOL CMainFrame::VerifyBarState(LPCTSTR lpszProfileName)
{
    CDockState state;
    state.LoadState( lpszProfileName );
	
    for( int i = 0; i < state.m_arrBarInfo.GetSize(); i++ ) {
        CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
        ASSERT( pInfo != NULL );
        int nDockedCount = pInfo->m_arrBarID.GetSize();
        if( nDockedCount > 0 ) {
            // dockbar
            for( int j = 0; j < nDockedCount; j++ ) {
                UINT nID = (UINT) pInfo->m_arrBarID[j];
                if (nID == 0) continue; // row separator
                if (nID > 0xFFFF)
                    nID &= 0xFFFF; // placeholder - get the ID
                if( GetControlBar( nID ) == NULL )
                    return FALSE;
            }
        }
        
        if( !pInfo->m_bFloating ) // floating dockbars can be created later
            if( GetControlBar( pInfo->m_nBarID ) == NULL )
                return FALSE; // invalid bar ID
    }
	
    return TRUE;
}


BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers


void CMainFrame::OnEditUndo() 
{
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();
	UndoManagerC*	pUndo = pDoc->GetUndoManager();
	pUndo->undo();
	pDoc->UndoNotify();

	NotifyViews( NOTIFY_REDRAW_ALL );
}

void CMainFrame::OnUpdateEditUndo(CCmdUI* pCmdUI) 
{
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();
	UndoManagerC*	pUndo = pDoc->GetUndoManager();
	if( pUndo->can_undo() ) {
		CString	sStr( "Undo " );
		sStr += pUndo->get_undo_name();
		pCmdUI->Enable( TRUE );
		pCmdUI->SetText( sStr );
	}
	else {
		pCmdUI->Enable( FALSE );
		pCmdUI->SetText( "Undo" );
	}
}

void CMainFrame::OnEditRedo() 
{
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();
	UndoManagerC*	pUndo = pDoc->GetUndoManager();
	pUndo->redo();
	pDoc->UndoNotify();
	NotifyViews( NOTIFY_REDRAW_ALL );
}

void CMainFrame::OnUpdateEditRedo(CCmdUI* pCmdUI) 
{
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();
	UndoManagerC*	pUndo = pDoc->GetUndoManager();
	if( pUndo->can_redo() ) {
		CString	sStr( "Redo " );
		sStr += pUndo->get_redo_name();
		pCmdUI->Enable( TRUE );
		pCmdUI->SetText( sStr );
	}
	else {
		pCmdUI->Enable( FALSE );
		pCmdUI->SetText( "Redo" );
	}
}


void CMainFrame::OnUpdateHelpPlugins(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
}

void CMainFrame::OnHelpPlugins() 
{
	CDLLInfoDlg	rDlg;
	rDlg.DoModal();
}

void CMainFrame::OnEditPurgeUndostack() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	ASSERT( pDoc );
	if( MessageBox( "All modifications so far will be made non-undoable.\nThis command cannot be undone. Proceed?", "Warning", MB_OKCANCEL | MB_ICONQUESTION ) == IDOK )
		pDoc->GetUndoManager()->purge();
}

void CMainFrame::OnUpdateEditPurgeUndostack(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
}

void CMainFrame::OnViewFileinspector() 
{
	if( !m_wndInspector.IsVisible() )
		ShowControlBar( &m_wndInspector, TRUE, FALSE );
	else
		ShowControlBar( &m_wndInspector, FALSE, FALSE );
}

void CMainFrame::OnUpdateViewFileinspector(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
	if( m_wndInspector.IsVisible() )
		pCmdUI->SetCheck( 1 );
	else
		pCmdUI->SetCheck( 0 );
}

void CMainFrame::OnViewTimeline() 
{
	if( !m_wndTimeLine.IsVisible() )
		ShowControlBar( &m_wndTimeLine, TRUE, FALSE );
	else
		ShowControlBar( &m_wndTimeLine, FALSE, FALSE );
}

void CMainFrame::OnUpdateViewTimeline(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
	if( m_wndTimeLine.IsVisible() )
		pCmdUI->SetCheck( 1 );
	else
		pCmdUI->SetCheck( 0 );
}


void CMainFrame::OnViewParameters() 
{
//	if( !m_wndParameter.IsVisible() )
//		ShowControlBar( &m_wndParameter, TRUE, FALSE );
//	else
//		ShowControlBar( &m_wndParameter, FALSE, FALSE );
}

void CMainFrame::OnUpdateViewParameters(CCmdUI* pCmdUI) 
{
//	pCmdUI->Enable( TRUE );
//	if( m_wndParameter.IsVisible() )
//		pCmdUI->SetCheck( 1 );
//	else
//		pCmdUI->SetCheck( 0 );
}

void CMainFrame::OnViewToolstoolbar() 
{
	if( !m_wndToolsBar.IsVisible() )
		ShowControlBar( &m_wndToolsBar, TRUE, FALSE );
	else
		ShowControlBar( &m_wndToolsBar, FALSE, FALSE );
}

void CMainFrame::OnUpdateViewToolstoolbar(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
	if( m_wndToolsBar.IsVisible() )
		pCmdUI->SetCheck( 1 );
	else
		pCmdUI->SetCheck( 0 );
}

void CMainFrame::OnViewPlaytoolbar() 
{
	if( !m_wndPlayBar.IsVisible() )
		ShowControlBar( &m_wndPlayBar, TRUE, FALSE );
	else
		ShowControlBar( &m_wndPlayBar, FALSE, FALSE );
}

void CMainFrame::OnUpdateViewPlaytoolbar(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
	if( m_wndPlayBar.IsVisible() )
		pCmdUI->SetCheck( 1 );
	else
		pCmdUI->SetCheck( 0 );
}


void CMainFrame::OnViewToolbar() 
{
	if( !m_wndStandardBar.IsVisible() )
		ShowControlBar( &m_wndStandardBar, TRUE, FALSE );
	else
		ShowControlBar( &m_wndStandardBar, FALSE, FALSE );
}

void CMainFrame::OnUpdateViewToolbar(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
	if( m_wndStandardBar.IsVisible() )
		pCmdUI->SetCheck( 1 );
	else
		pCmdUI->SetCheck( 0 );
}

void CMainFrame::OnFileImport() 
{
	CDemopajaDoc*	pDoc = GetDoc();

	if( !pDoc )
		return;

	pDoc->ImportFile( m_wndInspector.GetCurrentFolderHandle() );	// import to current folder
}

void CMainFrame::OnUpdateFileImport(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
}


void CMainFrame::OnEditDemoproperties() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->AskDemoProperties();
	pDoc->SetModifiedFlag();
}

void CMainFrame::OnUpdateEditDemoproperties(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );
}

void CMainFrame::NotifyViews( uint32 ui32Notify )
{
	CDemopajaDoc*	pDoc = GetDoc();

	m_wndTimeLine.UpdateNotify( ui32Notify );
	m_wndInspector.UpdateNotify( ui32Notify );

	CDemopajaView*	pView = 0;
	// get the view
	POSITION rPos = pDoc->GetFirstViewPosition();
	if( rPos )
		pView = (CDemopajaView*)pDoc->GetNextView( rPos );

	if( pView )
		pView->UpdateNotify( ui32Notify );


/*
	// First see which window has the focus
	CWnd*	pFocusWindow = GetFocus();

	if( ui32Notify == REDRAW_GRAPHICS ) {
		// redraw timeline
		if( !(ui32Ignore & REDRAW_IGNORE_TIMELINE) ) {
			m_wndTimeLine.SetScrollRanges();
			m_wndTimeLine.Invalidate();
		}
		// update parameter window
//		if( !(ui32Ignore & REDRAW_IGNORE_PARAMWINDOW) ) {
//			m_wndParameter.UpdateFromEffect( pDoc->GetSelectedEffect() );
//			m_wndParameter.Invalidate();
//		}
		// update main window
		if( !(ui32Ignore & REDRAW_IGNORE_MAINVIEW) )
			pDoc->UpdateAllViews( NULL, REDRAW_VIEWS );
	}
	else if( ui32Notify == REDRAW_ALL ) {
		// redraw timeline
		if( !(ui32Ignore & REDRAW_IGNORE_TIMELINE) ) {
			m_wndTimeLine.SetScrollRanges();
			m_wndTimeLine.Invalidate();
		}
		// update filelist
		if( !(ui32Ignore & REDRAW_IGNORE_FILEINSPECTOR) ) {
			m_wndInspector.UpdateList();
			m_wndInspector.Invalidate();
		}
		// update parameter window
//		if( !(ui32Ignore & REDRAW_IGNORE_PARAMWINDOW) ) {
//			m_wndParameter.UpdateFromEffect( pDoc->GetSelectedEffect() );
//			m_wndParameter.Invalidate();
//		}
		// update main window
		if( !(ui32Ignore & REDRAW_IGNORE_MAINVIEW) )
			pDoc->UpdateAllViews( NULL, REDRAW_VIEWS );
	}
	else if( ui32Notify == REDRAW_ALL_RECALC ) {
		// redraw timeline
		if( !(ui32Ignore & REDRAW_IGNORE_TIMELINE) ) {
			m_wndTimeLine.SetScrollRanges();
			m_wndTimeLine.Invalidate();
		}
		// update filelist
		if( !(ui32Ignore & REDRAW_IGNORE_FILEINSPECTOR) ) {
			m_wndInspector.UpdateList();
			m_wndInspector.Invalidate();
		}
		// update parameter window
//		if( !(ui32Ignore & REDRAW_IGNORE_PARAMWINDOW) ) {
//			m_wndParameter.UpdateFromEffect( pDoc->GetSelectedEffect() );
//			m_wndParameter.Invalidate();
//		}
		// update main window
		if( !(ui32Ignore & REDRAW_IGNORE_MAINVIEW) )
			pDoc->UpdateAllViews( NULL, RECALC_VIEWS );
	}
	else if( ui32Notify == REDRAW_ALL_CHANGELIST ) {
		// redraw timeline
		if( !(ui32Ignore & REDRAW_IGNORE_TIMELINE) ) {
			m_wndTimeLine.UpdateSceneTab();
			m_wndTimeLine.SetScrollRanges();
		}
		// update filelist
		if( !(ui32Ignore & REDRAW_IGNORE_FILEINSPECTOR) ) {
			m_wndInspector.UpdateList();
		}
		// update parameter window
//		if( !(ui32Ignore & REDRAW_IGNORE_PARAMWINDOW) ) {
//			m_wndParameter.UpdateFromEffect( pDoc->GetSelectedEffect(), true );
//		}
	}

	if( pFocusWindow )
		pFocusWindow->SetFocus();
*/
}


CTimeLineBar* CMainFrame::GetTimelineBar()
{
	return &m_wndTimeLine;
}


void CMainFrame::OnViewLayoutrulers() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetDrawRulers( !pDoc->GetDrawRulers() );
	NotifyViews( NOTIFY_REDRAW_GRAPHICS );
}

void CMainFrame::OnUpdateViewLayoutrulers(CCmdUI* pCmdUI) 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->Enable( TRUE );	
	pCmdUI->SetCheck( pDoc->GetDrawRulers() );
}

void CMainFrame::OnViewGrid() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetDrawGrid( !pDoc->GetDrawGrid() );
	NotifyViews( NOTIFY_REDRAW_GRAPHICS );
}

void CMainFrame::OnUpdateViewGrid(CCmdUI* pCmdUI) 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->Enable( TRUE );	
	pCmdUI->SetCheck( pDoc->GetDrawGrid() );
}


void CMainFrame::OnViewSnaptogrid() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetSnapToGrid( !pDoc->GetSnapToGrid() );
	NotifyViews( NOTIFY_REDRAW_GRAPHICS );
}

void CMainFrame::OnUpdateViewSnaptogrid(CCmdUI* pCmdUI) 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->Enable( TRUE );	
	pCmdUI->SetCheck( pDoc->GetSnapToGrid() );
}

void CMainFrame::OnViewGridsettings() 
{
	CDemopajaDoc*		pDoc = GetDoc();
	CGridSettingsDlg	rDlg;

	rDlg.m_bGridEnabled = pDoc->GetSnapToGrid() ? TRUE : FALSE;
	rDlg.m_i32GridSize = pDoc->GetGridSize();

	if( rDlg.DoModal() == IDOK ) {
		pDoc->SetSnapToGrid( rDlg.m_bGridEnabled ? true : false );
		pDoc->SetGridSize( rDlg.m_i32GridSize );
	}

	NotifyViews( NOTIFY_REDRAW_GRAPHICS );
}

void CMainFrame::OnUpdateViewGridsettings(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );	
}


void CMainFrame::OnPlayPlay() 
{
	m_wndTimeLine.OnPlay();
}

void CMainFrame::OnUpdatePlayPlay(CCmdUI* pCmdUI) 
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();
/*	if( pApp->IsPlaying() )
		pCmdUI->SetText( "Stop\tEnter" );
	else*/
		pCmdUI->SetText( "Play\tEnter" );
	pCmdUI->Enable( TRUE );	
}

void CMainFrame::OnPlayPlaypreview() 
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();
	CDemopajaDoc*	pDoc = GetDoc();
	pApp->PlayPreview( pDoc->GetTimecursor(), pDoc->GetLastFrameTime() );
	SetFocus();
	NotifyViews( NOTIFY_RESET_VIEWS );
}

void CMainFrame::OnUpdatePlayPlaypreview(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );	
}


void CMainFrame::OnFileMerge() 
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();

	char	szFileType[] = "Demopaja (*.dmo)|*.dmo|All Files (*.*)|*.*||";
	CFileDialog	rDlg( TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER, szFileType );
	rDlg.m_ofn.lpstrTitle = "Merge";
	rDlg.m_ofn.lpstrInitialDir = pApp->GetCurrentDir( CURDIR_OPEN );

	if( rDlg.DoModal() == IDOK ) {
		CDemopajaDoc*	pDoc = GetDoc();

		if( MessageBox( "This operation cannot be undone.\nSaving the document before merging is recommended.\n\nProceed?", "Merge", MB_YESNO | MB_ICONWARNING ) != IDYES )
			return;

		bool	bMergeFiles = false;

//		if( MessageBox( "If a imported file with same name can already be found in the document,\ndo you want to use the file found in current document?", "Merge Files", MB_YESNO | MB_ICONQUESTION ) != IDYES )
//			bMergeFiles = true;

		CMergeFileDlg	rMergeDlg;
		rMergeDlg.m_bNewScene = FALSE;
		rMergeDlg.m_bUseFiles = TRUE;
		rMergeDlg.m_iDestFolder = 0;
		rMergeDlg.m_sFolder = "";

		if( rMergeDlg.DoModal() == IDOK ) {

			FileHandleC*	pFolder = 0;

			if( rMergeDlg.m_iDestFolder == 0 ) {
				pFolder = m_wndInspector.GetCurrentFolderHandle();
			}
			else {
				pFolder = pDoc->CreateFolder( rMergeDlg.m_sFolder, NULL, FILEHANDLE_FOLDERCOLOR_WHITE );
			}

			pDoc->OnMergeDocument( rDlg.GetPathName(), pFolder, rMergeDlg.m_bUseFiles ? true : false, rMergeDlg.m_bNewScene ? true : false );

			pApp->SetCurrentDir( CURDIR_OPEN, rDlg.GetPathName() );
		}
	}
}

void CMainFrame::OnUpdateFileMerge(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( TRUE );	
}

void CMainFrame::OnToolArrow() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetTool( TOOL_ARROW );
}

void CMainFrame::OnToolKeyarrow() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetTool( TOOL_KEYARROW );
}

void CMainFrame::OnToolPan() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetTool( TOOL_PAN );
}

void CMainFrame::OnToolRotate() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetTool( TOOL_ROTATE );
}

void CMainFrame::OnToolScale() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetTool( TOOL_SCALE );
}

void CMainFrame::OnToolZoom() 
{
	CDemopajaDoc*	pDoc = GetDoc();
	pDoc->SetTool( TOOL_ZOOM );
}

void CMainFrame::OnUpdateToolZoom(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->SetCheck( pDoc->GetTool() == TOOL_ZOOM ? 1 : 0 );
}

void CMainFrame::OnUpdateToolArrow(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->SetCheck( pDoc->GetTool() == TOOL_ARROW ? 1 : 0 );
}

void CMainFrame::OnUpdateToolRotate(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->SetCheck( pDoc->GetTool() == TOOL_ROTATE ? 1 : 0 );
}

void CMainFrame::OnUpdateToolScale(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->SetCheck( pDoc->GetTool() == TOOL_SCALE ? 1 : 0 );
}

void CMainFrame::OnUpdateToolPan(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->SetCheck( pDoc->GetTool() == TOOL_PAN ? 1 : 0 );
}

void CMainFrame::OnUpdateToolKeyarrow(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	CDemopajaDoc*	pDoc = GetDoc();
	pCmdUI->SetCheck( pDoc->GetTool() == TOOL_KEYARROW ? 1 : 0 );
}

void CMainFrame::OnViewTransformdialog() 
{
	if( !m_pTransDlg ) {
		m_pTransDlg = new CTransformDlg;
		if( !m_pTransDlg || !m_pTransDlg->Create() ) {
			delete m_pTransDlg;
			return;
		}
		m_pTransDlg->ShowWindow( SW_SHOW );
	}
	else {
		m_pTransDlg->ShowWindow( m_pTransDlg->IsWindowVisible() ? SW_HIDE : SW_SHOW );
	}
}

void CMainFrame::OnUpdateViewTransformdialog(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	pCmdUI->SetCheck( (m_pTransDlg && m_pTransDlg->IsWindowVisible()) ? 1 : 0 );
}

void CMainFrame::OnViewAligndialog() 
{
	if( !m_pAlignDlg ) {
		m_pAlignDlg = new CAlignDlg;
		if( !m_pAlignDlg || !m_pAlignDlg->Create() ) {
			delete m_pAlignDlg;
			return;
		}
		m_pAlignDlg->ShowWindow( SW_SHOW );
	}
	else {
		m_pAlignDlg->ShowWindow( m_pAlignDlg->IsWindowVisible() ? SW_HIDE : SW_SHOW );
	}
}

void CMainFrame::OnUpdateViewAligndialog(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
	pCmdUI->SetCheck( (m_pAlignDlg && m_pAlignDlg->IsWindowVisible()) ? 1 : 0 );
}

void CMainFrame::OnFileExport() 
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();

	char	szFileType[] = "Demopaja ASCII Export (*.dae)|*.dae|All Files (*.*)|*.*||";
	CFileDialog	rDlg( FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_EXPLORER | OFN_OVERWRITEPROMPT, szFileType );
	rDlg.m_ofn.lpstrTitle = "Export";
	rDlg.m_ofn.lpstrInitialDir = pApp->GetCurrentDir( CURDIR_EXPORT );

	if( rDlg.DoModal() == IDOK ) {
		CDemopajaDoc*	pDoc = GetDoc();


		char	szPathBuffer[_MAX_PATH];
		char	szDrive[_MAX_DRIVE];
		char	szDir[_MAX_DIR];
		char	szFName[_MAX_FNAME];
		char	szExt[_MAX_EXT];

		_splitpath( (const char*)rDlg.GetPathName(), szDrive, szDir, szFName, szExt );

		if( strlen( szExt ) < 1 ) {
			strcpy( szExt, ".dae" );
		}

		_makepath( szPathBuffer, szDrive, szDir, szFName, szExt );
   
		pDoc->ExportScript( szPathBuffer );

		pApp->SetCurrentDir( CURDIR_EXPORT, rDlg.GetPathName() );
	}
}

void CMainFrame::OnUpdateFileExport(CCmdUI* pCmdUI) 
{
	//pCmdUI->Enable();
}



void CMainFrame::OnFileExportavi() 
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();

	char	szFileType[] = "AVI video (*.avi)|*.avi|All Files (*.*)|*.*||";
	CFileDialog	rDlg( FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_EXPLORER | OFN_OVERWRITEPROMPT, szFileType );
	rDlg.m_ofn.lpstrTitle = "Export AVI";
	rDlg.m_ofn.lpstrInitialDir = pApp->GetCurrentDir( CURDIR_EXPORT );

	if( rDlg.DoModal() == IDOK ) {
		CDemopajaDoc*	pDoc = GetDoc();


		char	szPathBuffer[_MAX_PATH];
		char	szDrive[_MAX_DRIVE];
		char	szDir[_MAX_DIR];
		char	szFName[_MAX_FNAME];
		char	szExt[_MAX_EXT];

		_splitpath( (const char*)rDlg.GetPathName(), szDrive, szDir, szFName, szExt );

		if( strlen( szExt ) < 1 ) {
			strcpy( szExt, ".avi" );
		}

		_makepath( szPathBuffer, szDrive, szDir, szFName, szExt );
   
		pDoc->ExportAVI( szPathBuffer );

		pApp->SetCurrentDir( CURDIR_EXPORT, rDlg.GetPathName() );
	}
}

void CMainFrame::OnUpdateFileExportavi(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
}


void CMainFrame::OnViewHelpdialog() 
{
	if( !m_pHelpDlg ) {
		m_pHelpDlg = new CHelpDlg;
		if( !m_pHelpDlg || !m_pHelpDlg->Create() ) {
			delete m_pHelpDlg;
			return;
		}
		m_pHelpDlg->ShowWindow( SW_SHOW );
	}
	else {
		m_pHelpDlg->ShowWindow( m_pHelpDlg->IsWindowVisible() ? SW_HIDE : SW_SHOW );
	}
}

void CMainFrame::OnUpdateViewHelpdialog(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
}

void CMainFrame::BrowseHelp( const ClassIdC& rClassId )
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();
	FactoryC*		pFac = pApp->GetFactory();
	ClassDescC*		pDesc = 0;
	int32			i32Idx = -1;

	for( uint32 i = 0; i < pFac->get_classdesc_count(); i++ ) {
		if( pFac->get_classdesc( i )->get_class_id() == rClassId ) {
			pDesc = pFac->get_classdesc( i );
			i32Idx = i;
			break;
		}
	}

	if( pDesc && i32Idx != -1 ) {
		// Set the help URL
		CString	sHelpUrl;

		if( strncmp( "res://", pDesc->get_help_filename(), 6 ) == 0 ) {
			sHelpUrl = "res://";
			sHelpUrl += pApp->GetPluginDir();
			sHelpUrl += pFac->get_classdesc_dll_name( i32Idx );
			sHelpUrl += "/";
			sHelpUrl += (pDesc->get_help_filename() + 6);
		}
		else if( strncmp( "int://", pDesc->get_help_filename(), 6 ) == 0 ) {
			TCHAR	sModuleName[_MAX_PATH];
			::GetModuleFileName( AfxGetInstanceHandle(), sModuleName, _MAX_PATH );
			sHelpUrl = "res://";
			sHelpUrl += sModuleName;
			sHelpUrl += "/";
			sHelpUrl += (pDesc->get_help_filename() + 6);
		}
		else if( strncmp( "help://", pDesc->get_help_filename(), 7 ) == 0 ) {
			TCHAR	sModuleName[_MAX_PATH];
			::GetModuleFileName( AfxGetInstanceHandle(), sModuleName, _MAX_PATH );
			sHelpUrl = "file://";
			sHelpUrl += pApp->GetAppDir();
			sHelpUrl += "/users manual/";
			sHelpUrl += (pDesc->get_help_filename() + 7);
		}
		else {
			sHelpUrl = pApp->GetPluginDir();
			sHelpUrl += pDesc->get_help_filename();
		}

		if( !m_pHelpDlg || !m_pHelpDlg->IsWindowVisible() )
			OnViewHelpdialog();

		if( m_pHelpDlg )
			m_pHelpDlg->Browse( sHelpUrl );
	}
}

void CMainFrame::OnUpdateIndicatorGraphDevice(CCmdUI* pCmdUI)
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();
	DeviceContextC*		pContext = pDoc->GetDeviceContext();
	GraphicsDeviceI*	pGraphDevice = (GraphicsDeviceI*)pContext->query_interface( SUPERCLASS_GRAPHICSDEVICE );

	if( pGraphDevice )
		m_wndStatusBar.SetPaneText( m_wndStatusBar.CommandToIndex( ID_INDICATOR_GRAPHDEVICE ), pGraphDevice->get_class_name() );
	else
		m_wndStatusBar.SetPaneText( m_wndStatusBar.CommandToIndex( ID_INDICATOR_GRAPHDEVICE ), "---" );
}

void CMainFrame::OnUpdateIndicatorProjectPath(CCmdUI* pCmdUI)
{
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();

	CString		sPath = pDoc->GetProjectPath();
	if( pDoc->IsProjectPathTemporary() )
		sPath += " (temp)";

	m_wndStatusBar.SetPaneText( m_wndStatusBar.CommandToIndex( ID_INDICATOR_PROJECTPATH ), sPath );
}


void CMainFrame::OnEditProjectpath()
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();
	CDemopajaDoc*	pDoc = (CDemopajaDoc*)GetActiveDocument();
	CCommonDirsDlg	rDlg;

	// get project path
	rDlg.m_sProjectPath = pDoc->GetProjectPath();

	if( rDlg.DoModal() == IDOK ) {
		// set project path
		if( rDlg.m_bUpdateImportables ) {

			// Ask to proceed the operation, since it cannot be undone.
			if( ::MessageBox( m_hWnd, "This operation cannot be undone.\n\nAre you sure to proceed?", "Change Project Path", MB_YESNO | MB_ICONWARNING ) != IDYES )
				return;

			std::string	sOldPath = pDoc->GetProjectPath();
			std::string	sNewPath = (const char*)rDlg.m_sProjectPath;

			// Remove the ending slash.
			if( sNewPath[(int32)sNewPath.size() - 1] == '\\' || sNewPath[(int32)sNewPath.size() - 1] == '/' )
				sNewPath.resize( (int32)sNewPath.size() - 1 );

			// Find the part of the path that has changed
			FactoryC*	pFac = pApp->GetFactory();
			FileListC*	pFileList = pDoc->GetFileList();
			DemoInterfaceC*	pDemoInterface = pDoc->GetDemoInterface();

			for( int32 i = 0; i < pFileList->get_file_count(); i++ ) {
				FileHandleC*	pHandle = pFileList->get_file( i );
				// Skip directories
				if( pHandle->get_flags() & FILEHANDLE_FOLDER )
					continue;
				// get importable
				ImportableI*	pImp = pHandle->get_importable();
				// find class desc
				ClassDescC*		pDesc = pFac->get_classdesc( pImp->get_class_id() );
				// check if the importables name is file name

				if( pDesc->get_classtype() == CLASS_TYPE_FILEIMPORT ) {

					// Get the old absolute path
					std::string	sName = pDemoInterface->get_absolute_path( pImp->get_filename() );

					// make the path relative again (for the new path)
					if( sNewPath.size() > 2 && sName.size() > (sNewPath.size() + 1) && _strnicmp( sNewPath.c_str(), sName.c_str(), sNewPath.size() ) == 0 ) {
						sName = sName.substr( sNewPath.size() + 1, sName.size() - (sNewPath.size() + 1) );
					}

//					TRACE( "-- '%s'('%s') to '%s'\n", pImp->get_filename(), pDemoInterface->get_absolute_path( pImp->get_filename() ), sName.c_str() );
					
					pImp->set_filename( sName.c_str() );
				}
			}
		}
		pDoc->SetProjectPath( rDlg.m_sProjectPath, pDoc->IsProjectPathTemporary() );

		NotifyViews( NOTIFY_FILELIST_CHANGED );
	}
}

void CMainFrame::OnUpdateEditProjectpath(CCmdUI *pCmdUI)
{
	pCmdUI->Enable();
}

void CMainFrame::OnHelpHelpindex()
{
	CDemopajaApp*	pApp = (CDemopajaApp*)AfxGetApp();

	if( !m_pHelpDlg || !m_pHelpDlg->IsWindowVisible() )
		OnViewHelpdialog();

	CString	sPath;
	sPath = "file://";
	sPath += pApp->GetAppDir();
	sPath += "/users manual/index.html";

	TRACE( "path: %s\n", sPath );

	if( m_pHelpDlg )
		m_pHelpDlg->Browse( sPath );
}

void CMainFrame::OnUpdateHelpHelpindex(CCmdUI *pCmdUI)
{
	pCmdUI->Enable();
}
