// demopajaView.h : interface of the CDemopajaView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_DEMOPAJAVIEW_H__B4C5B4F0_2A90_11D4_A80C_0000E8D926FD__INCLUDED_)
#define AFX_DEMOPAJAVIEW_H__B4C5B4F0_2A90_11D4_A80C_0000E8D926FD__INCLUDED_

#include "DemopajaDoc.h"
#include "PajaTypes.h"
#include "Vector2C.h"
#include "BBox2C.h"
#include "UndoC.h"
#include "TimeLineBar.h"
#include <vector>
#include <gl/gl.h>
#include <gl/glu.h>

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000



#define	DONT_SWAP_BUFFERS	true
#define	RENDER_TIMER_ID		100


class CDemopajaView : public CView
{
protected: // create from serialization only
	CDemopajaView();
	DECLARE_DYNCREATE(CDemopajaView)

	// Attributes
public:
	CDemopajaDoc* GetDocument();

	void				StartRenderTimer( PajaTypes::int32 i32Time, PajaTypes::int32 i32MaxTime );
	void				StopRenderTimer();
	void				SetTimePos( PajaTypes::int32 i32Time );
	bool				IsPlaying();

	void				UpdateNotify( PajaTypes::uint32 ui32Notify );

	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CDemopajaView)
	public:
	virtual void OnDraw(CDC* pDC);  // overridden to draw this view
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	virtual void OnInitialUpdate();
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CDemopajaView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif


protected:

	PajaTypes::int32	m_i32RenderTime;
	PajaTypes::int32	m_i32RenderStartTime;
	PajaTypes::int32	m_i32MaxRenderTime;
	PajaTypes::float64	m_f64RenderTimeScale;
	UINT				m_ui32TimerID;

	PajaTypes::int32	m_i32TempRenderTime;

	// view specific
	void				Redraw();
	PajaTypes::int32	HitTestEffects( PajaTypes::Vector2C rPoint, Composition::EffectI** pEffect, Composition::ParamI** pHitParam, PajaTypes::Vector2C* pOriginPt, PajaTypes::Vector2C* pHitPt, PajaTypes::int32* pTime, bool bSelectNext );
	void				NudgeEffects( const PajaTypes::Vector2C& rDelta );
	void				BoxSelect( const PajaTypes::BBox2C& rSelBox, bool bToggle );
	CTimeLineBar*		GetTimeline();
	void				ResetView();

	enum TrackActionE {
		TRACKING_NONE = 0,
		TRACKING_PAN,
		TRACKING_ZOOM,
		TRACKING_MOVE_EFFECT,
		TRACKING_ROTATE_EFFECT,
		TRACKING_SCALE_EFFECT,
		TRACKING_SCALE_SELECTED,
		TRACKING_MOVE_PIVOT,
		TRACKING_MOVE_POS_PARAM,
		TRACKING_BOX_SELECT,
	};

	TrackActionE		m_eTrackingAction;
	bool				m_bSpacePressed;
	bool				m_bCtrlPressed;
	HCURSOR				m_hCursor;
	PajaTypes::BBox2C	m_rOldViewport;
	PajaTypes::Vector2C	m_rMousePos;
	PajaTypes::Vector2C	m_rOldMousePos;
	CPoint				m_rStartMousePos;
	CPoint				m_rEndMousePos;
	PajaTypes::float64	m_f64LayoutAspectX;
	PajaTypes::float64	m_f64LayoutAspectY;
	PajaTypes::float64	m_f64ClientAspectX;
	PajaTypes::float64	m_f64ClientAspectY;
	Edit::UndoC*		m_pCurrentUndo;
	PajaTypes::Vector2C	m_rEffectOrigin;
	PajaTypes::Vector2C	m_rEffectHit;
	PajaTypes::float32	m_f32OrigValues[Composition::KEY_MAXCHANNELS];
	PajaTypes::BBox2C	m_rSelBBox;
	PajaTypes::BBox2C	m_rOrigSelBBox;
	bool				m_bStoreOrigSelBBox;
	PajaTypes::uint32	m_ui32CurTool;

	PajaTypes::Vector2C	m_rOrigScaleSize;
	PajaTypes::Vector2C	m_rOrigScaleCenter;
	PajaTypes::Vector2C	m_rOrigScaleCenterSize;

	PajaTypes::int32	m_i32LastHit;

	bool				m_bViewResetRequest;

	enum HitTestEffectE {
		HIT_SCALE_LEFT		= 0x0001,
		HIT_SCALE_RIGHT		= 0x0002,
		HIT_SCALE_TOP		= 0x0004,
		HIT_SCALE_BOTTOM	= 0x0008,
		HIT_SCALE			= 0x000f,
		HIT_MOVE			= 0x0010,
		HIT_PIVOT			= 0x0020,
		HIT_ROTATE			= 0x0040,
		HIT_SELECTED		= 0x0080,
		HIT_POS_PARAM		= 0x0100,
		HIT_SEL_BBOX		= 0x0200,
		HIT_POS_PARAM_KEY	= 0x0400,
	};

	struct SelRecordS {
		Composition::EffectI*	m_pEffect;
		Composition::ParamI*	m_pHitParam;
		PajaTypes::Vector2C		m_rOrigin;
		PajaTypes::Vector2C		m_rHit;
		PajaTypes::int32		m_i32Hit;
		PajaTypes::int32		m_i32Time;
	};

	struct SelEffectS {
		Composition::EffectI*	m_pEffect;
		PajaTypes::Matrix2C		m_rInvTM;
		PajaTypes::Vector2C		m_rOrigin;
		PajaTypes::int32		m_i32Time;
		PajaTypes::float32		m_f32Values[Composition::KEY_MAXCHANNELS];
		PajaTypes::float32		m_f32Values2[Composition::KEY_MAXCHANNELS];
		Composition::ParamI*	m_pParam;
	};

	std::vector<SelEffectS>	m_rOrigEffects;

	std::vector<Composition::EffectI*>	m_rEffectStack;
	std::vector<PajaTypes::int32>				m_rEffectTimeStack;


	// Generated message map functions
	//{{AFX_MSG(CDemopajaView)
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnEditCopy();
	afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
	afx_msg void OnEditCut();
	afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
	afx_msg void OnEditPaste();
	afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
	afx_msg void OnViewZoom100();
	afx_msg void OnUpdateViewZoom100(CCmdUI* pCmdUI);
	afx_msg void OnViewZoom200();
	afx_msg void OnUpdateViewZoom200(CCmdUI* pCmdUI);
	afx_msg void OnViewZoom300();
	afx_msg void OnUpdateViewZoom300(CCmdUI* pCmdUI);
	afx_msg void OnViewZoom400();
	afx_msg void OnUpdateViewZoom400(CCmdUI* pCmdUI);
	afx_msg void OnViewZoom50();
	afx_msg void OnUpdateViewZoom50(CCmdUI* pCmdUI);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnTimer(UINT nIDEvent);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};


#ifndef _DEBUG 

// debug version in demopajaView.cpp
inline
CDemopajaDoc*
CDemopajaView::GetDocument()
{
	return (CDemopajaDoc*)m_pDocument;
}

inline bool CheckGLError()
{
	GLenum errCode;
	if((errCode = glGetError()) != GL_NO_ERROR)
	{
		AfxMessageBox((char*)gluErrorString(errCode));
		ASSERT(0);
		return false;
	}
	return true;
}

#else
	inline bool CheckGLError()
	{
		return glGetError() == GL_NO_ERROR;
	}
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DEMOPAJAVIEW_H__B4C5B4F0_2A90_11D4_A80C_0000E8D926FD__INCLUDED_)
