// ModifyView.cpp : implementation file
//

#include "stdafx.h"
#include "animscript.h"
#include "ModifyView.h"
#include "AnimScriptDoc.h"

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

/////////////////////////////////////////////////////////////////////////////
// CModifyView

IMPLEMENT_DYNCREATE(CModifyView, CFormView)

CModifyView::CModifyView()
	: CFormView(CModifyView::IDD)
{
	//{{AFX_DATA_INIT(CModifyView)
	//}}AFX_DATA_INIT
}

CModifyView::~CModifyView()
{
}

void CModifyView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CModifyView)
	DDX_Control(pDX, IDC_SLIDER_OVERRIDE, m_ctrlOverride);
	DDX_Control(pDX, IDC_SLIDER_TRANSSTART, m_ctrlTransStart);
	DDX_Control(pDX, IDC_SLIDER_STARTNEW, m_ctrlStartNew);
	DDX_Control(pDX, IDC_SLIDER_PLAYOLDTILL, m_ctrlPlayTill);
	DDX_Control(pDX, IDC_SLIDER_START, m_ctrlStart);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CModifyView, CFormView)
	//{{AFX_MSG_MAP(CModifyView)
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_START, OnCustomdrawSliderStart)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_START, OnReleasedcaptureSliderStart)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_TRANSSTART, OnReleasedcaptureSliderTransstart)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_STARTNEW, OnReleasedcaptureSliderStartnew)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_PLAYOLDTILL, OnReleasedcaptureSliderPlayoldtill)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_PLAYOLDTILL, OnCustomdrawSliderPlayoldtill)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_STARTNEW, OnCustomdrawSliderStartnew)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_TRANSSTART, OnCustomdrawSliderTransstart)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_OVERRIDE, OnCustomdrawSliderOverride)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_OVERRIDE, OnReleasedcaptureSliderOverride)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CModifyView diagnostics

#ifdef _DEBUG
void CModifyView::AssertValid() const
{
	CFormView::AssertValid();
}

void CModifyView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CModifyView message handlers

void CModifyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	CAnimNode *pNode = pDoc?pDoc->m_pSelectedNode:NULL;	

	if (pNode)
	{
		bool hascurves = false;
		CCurveTypeNode *pStartOverlapCurve = NULL;
		CCurveTypeNode *pEndOverlapCurve = NULL;
		float 
			start = 0.0f,
			transitionstart = 0.0f,
			playoldstatetill = 0.0f,
			startnewstate = 0.0f,
			overridenewstateposition = 0.0f;

		CPathNode *pPath = NULL,*pNewPath = NULL;
		CTransStateNode *pTrans = NULL;
		if (pNode->IsTransition())
			pTrans = (CTransStateNode *)pNode;

		POSITION pos = pNode->m_mapParams.GetStartPosition();
		while (pos)
		{

			CObject *pObj;
			WORD iKey;
			pNode->m_mapParams.GetNextAssoc(pos,iKey,pObj);
			CParamNode *pParam = (CParamNode *)pObj;
			switch (iKey)
			{
			case PARAM_START:
				{
					start = ((CFloatNode *)pParam)->m_fValue;
					break;
				}
			case PARAM_TRANSITIONSTART:
				{
					transitionstart = ((CFloatNode *)pParam)->m_fValue;
					break;
				}
			case PARAM_PLAYOLDSTATETILL:
				{
					playoldstatetill = ((CFloatNode *)pParam)->m_fValue;
					break;
				}
			case PARAM_STARTNEWSTATE:
				{
					startnewstate = ((CFloatNode *)pParam)->m_fValue;
					break;
				}
			case PARAM_OVERRIDENEWSTATEPOSITION:
				{
					overridenewstateposition = ((CFloatNode *)pParam)->m_fValue;
					break;
				}
			case PARAM_STARTOVERLAPCURVE:
				{
					pStartOverlapCurve = (CCurveTypeNode *)pParam;
					break;
				}
			case PARAM_ENDOVERLAPCURVE:
				{
					pEndOverlapCurve = (CCurveTypeNode *)pParam;
					CObject *pNObj;
					for (int x=PARAM_SLOWUPANIM;x<PARAM_COUNT;x++)
					{
						if (pTrans->m_pEndNode->m_mapParams.Lookup(x,pNObj))
						{
							pNewPath = (CPathNode *)pNObj;
							break;
						}
					}
					hascurves = true;
					break;
				}
			case PARAM_ANIM:
			case PARAM_FASTANIM:
			case PARAM_SLOWANIM:
			case PARAM_SLOWUPANIM:
			case PARAM_SLOWEVENANIM:
			case PARAM_SLOWDOWNANIM:
			case PARAM_FASTUPANIM:
			case PARAM_FASTEVENANIM:
			case PARAM_FASTDOWNANIM:
			case PARAM_UPANIM:
			case PARAM_EVENANIM:
			case PARAM_DOWNANIM:
			case PARAM_LEFTANIM:
			case PARAM_RIGHTANIM:
			case PARAM_SLOWLEFTANIM:
			case PARAM_SLOWRIGHTANIM:
			case PARAM_FASTLEFTANIM:
			case PARAM_FASTRIGHTANIM:
				{
					pPath = (CPathNode *)pParam;

					break;
				}
			default:
				{
				}
			}
		}
		if (hascurves&&pNewPath)
		{
			m_ctrlStart.SetPos(start*100.0f);
			m_ctrlPlayTill.SetPos(playoldstatetill * 100.0f);
			m_ctrlStartNew.SetPos(startnewstate * 100.0f);
			m_ctrlTransStart.SetPos(transitionstart * 100.0f);
			m_ctrlOverride.SetPos(overridenewstateposition* 100.0f);




			float totaltime = (transitionstart+playoldstatetill)-start;
			totaltime += startnewstate - playoldstatetill;
			totaltime += pNewPath->m_pAnimData->animHeaderBlock->endTime - overridenewstateposition;

		/*	{
				// Draw a tick every 0.5 seconds
				float yMult = ((float)sz.cy)/2.0f;
				float y = 1.4f;
				for (float x=0.0f;x<totaltime;x+=0.5f)
				{
					float xpos = ((float)sz.cx)*(x/totaltime);
					pDC->SetPixel(xpos,sz.cy-y*yMult,RGB(255,255,255));
				}
			}
			{
				// Draw the Old State
				float curvestart = 0.0f;
				float curveend = transitionstart+playoldstatetill;
				float range = curveend-curvestart;
				float xMult = (((float)sz.cx)*(range/totaltime))/100.0f;
				float yMult = ((float)sz.cy)/2.0f;
				if (range>0.00001)
				{
					int xstart = sz.cx*(curvestart/totaltime);

					for (int x=0;x<100;x++)
					{
						double y = 1.1f;
						pDC->SetPixel(xstart+((float)x)*xMult,sz.cy-y*yMult,RGB(0,255,0));
					}
				}

			}
			{
				// Draw the Start overlap curve
				float curvestart = start+pStartOverlapCurve->timeStart;
				float curveend = (transitionstart+pStartOverlapCurve->timeEnd);
				float range = curveend-curvestart;
				float xMult = (((float)sz.cx)*(range/totaltime))/100.0f;
				float yMult = ((float)sz.cy)/2.0f;
				if (range>0.00001)
				{
					int xstart = sz.cx*(curvestart/totaltime);

					for (int x=pStartOverlapCurve->timeStart*100;x<(100*pStartOverlapCurve->timeEnd);x++)
					{
						double y = pStartOverlapCurve->Play(((double)x)/(double)100.0);
						if ((y>0.0)&&(y<sz.cy))
							pDC->SetPixel(xstart+((float)x)*xMult,sz.cy-y*yMult,RGB(255,255,0));
					}
				}
			}
			{
				// Draw the Transition State
				float curvestart = transitionstart+pPath->m_pAnimData->animHeaderBlock->startTime;
				float curveend = transitionstart+pPath->m_pAnimData->animHeaderBlock->endTime;
				float range = curveend-curvestart;
				float xMult = (((float)sz.cx)*(range/totaltime))/100.0f;
				float yMult = ((float)sz.cy)/2.0f;
				if (range>0.00001)
				{
					int xstart = sz.cx*(curvestart/totaltime);

					for (int x=0;x<100;x++)
					{
						double y = 1.2f;
						pDC->SetPixel(xstart+((float)x)*xMult,sz.cy-y*yMult,RGB(255,0,0));
					}
				}

			}
			if (pEndOverlapCurve->curveType>=0)
			{
				// Draw the End overlap curve
				float curvestart = transitionstart+startnewstate+pEndOverlapCurve->timeStart;
				float curveend = transitionstart+startnewstate+(pEndOverlapCurve->timeEnd-overridenewstateposition);
				float range = curveend-curvestart;
				float xMult = (((float)sz.cx)*(range/totaltime))/100.0f;
				float yMult = ((float)sz.cy)/2.0f;
				if (range>0.00001)
				{
					int xstart = sz.cx*(curvestart/totaltime);

					for (int x=pEndOverlapCurve->timeStart*100;x<(100*pEndOverlapCurve->timeEnd);x++)
					{
						double y = pEndOverlapCurve->Play(((double)x)/(double)100.0);
						if ((y>0.0)&&(y<sz.cy))
							pDC->SetPixel(xstart+((float)x)*xMult,sz.cy-y*yMult,RGB(255,255,0));
					}
				}
			}
			{
				// Draw the new state
				float curvestart = transitionstart+startnewstate;
				float curveend = curvestart+(pNewPath->m_pAnimData->animHeaderBlock->endTime - overridenewstateposition);
				float range = curveend-curvestart;
				float xMult = (((float)sz.cx)*(range/totaltime))/100.0f;
				float yMult = ((float)sz.cy)/2.0f;
				if (range>0.00001)
				{
					int xstart = sz.cx*(curvestart/totaltime);

					for (int x=0;x<100;x++)
					{
						double y = 1.3f;
						pDC->SetPixel(xstart+((float)x)*xMult,sz.cy-y*yMult,RGB(0,0,255));
					}
				}
			}*/
		}
	}
}

void CModifyView::OnInitialUpdate() 
{
	CFormView::OnInitialUpdate();
	m_ctrlStart.SetRange(0,100);
	m_ctrlStart.SetTicFreq(50);
	m_ctrlPlayTill.SetRange(0,100);
	m_ctrlPlayTill.SetTicFreq(50);
	m_ctrlStartNew.SetRange(0,100);
	m_ctrlStartNew.SetTicFreq(50);
	m_ctrlTransStart.SetRange(0,100);
	m_ctrlTransStart.SetTicFreq(50);
	m_ctrlOverride.SetRange(0,100);
	m_ctrlOverride.SetTicFreq(50);
}

int CModifyView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CFormView::OnCreate(lpCreateStruct) == -1)
		return -1;

	return 0;
}

BOOL CModifyView::OnCommand(WPARAM wParam, LPARAM lParam) 
{
	
	return CFormView::OnCommand(wParam, lParam);
}

LRESULT CModifyView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	switch (message)
	{
	case WM_LBUTTONDOWN:
		{
			int x=1;
			break;
		}
	case WM_NOTIFY:
		{
		}
	}
	return CFormView::WindowProc(message, wParam, lParam);
}

void CModifyView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CFormView::OnLButtonDown(nFlags, point);
}

void CModifyView::OnReleasedcaptureSliderStart(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	CAnimNode *pNode = pDoc?pDoc->m_pSelectedNode:NULL;	
	if (pNode)
	{
		CParamNode *pParam = pNode->GetParam(PARAM_START);
		if (pParam)
		{
			CString str;
			str.Format("%f",((float)this->m_ctrlStart.GetPos()) / 100.0f);
			pParam->SetValue(str);
			pDoc->UpdateAllViews(this);
		}
	}
	*pResult = 0;
}

void CModifyView::OnReleasedcaptureSliderTransstart(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	CAnimNode *pNode = pDoc?pDoc->m_pSelectedNode:NULL;	
	if (pNode)
	{
		CParamNode *pParam = pNode->GetParam(PARAM_TRANSITIONSTART);
		if (pParam)
		{
			CString str;
			str.Format("%f",((float)this->m_ctrlTransStart.GetPos()) / 100.0f);
			pParam->SetValue(str);
			pDoc->UpdateAllViews(this);
		}
	}
	*pResult = 0;
}

void CModifyView::OnReleasedcaptureSliderStartnew(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	CAnimNode *pNode = pDoc?pDoc->m_pSelectedNode:NULL;	
	if (pNode)
	{
		CParamNode *pParam = pNode->GetParam(PARAM_STARTNEWSTATE);
		if (pParam)
		{
			CString str;
			str.Format("%f",((float)this->m_ctrlStartNew.GetPos()) / 100.0f);
			pParam->SetValue(str);
			pDoc->UpdateAllViews(this);
		}
	}
	*pResult = 0;
}

void CModifyView::OnReleasedcaptureSliderPlayoldtill(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	CAnimNode *pNode = pDoc?pDoc->m_pSelectedNode:NULL;	
	if (pNode)
	{
		CParamNode *pParam = pNode->GetParam(PARAM_PLAYOLDSTATETILL);
		if (pParam)
		{
			CString str;
			str.Format("%f",((float)this->m_ctrlPlayTill.GetPos()) / 100.0f);
			pParam->SetValue(str);
			pDoc->UpdateAllViews(this);
		}
	}
	*pResult = 0;
}

void CModifyView::OnReleasedcaptureSliderOverride(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	CAnimNode *pNode = pDoc?pDoc->m_pSelectedNode:NULL;	
	if (pNode)
	{
		CParamNode *pParam = pNode->GetParam(PARAM_OVERRIDENEWSTATEPOSITION);
		if (pParam)
		{
			CString str;
			str.Format("%f",((float)this->m_ctrlOverride.GetPos()) / 100.0f);
			pParam->SetValue(str);
			pDoc->UpdateAllViews(this);
		}
	}
	*pResult = 0;
}
void CModifyView::OnCustomdrawSliderStart(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnReleasedcaptureSliderStart(pNMHDR,pResult);
}

void CModifyView::OnCustomdrawSliderPlayoldtill(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnReleasedcaptureSliderPlayoldtill(pNMHDR,pResult);
}

void CModifyView::OnCustomdrawSliderStartnew(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnReleasedcaptureSliderStartnew(pNMHDR,pResult);
}

void CModifyView::OnCustomdrawSliderTransstart(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnReleasedcaptureSliderTransstart(pNMHDR,pResult);
}

void CModifyView::OnCustomdrawSliderOverride(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnReleasedcaptureSliderOverride(pNMHDR,pResult);
}

