//ROMTEAM WorldEditor
////////////////////////////////////////////////////////////////////////////////////////
// File        : DlgEditPoints.cpp: implementation file for the CDlgEditPoints class
// Author      : Viorel Preoteasa
// Date        : 97.11
// Description :
////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "dlgeditpoints.hpp"

#include "math.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDlgEditPoints

IMPLEMENT_DYNCREATE(CDlgEditPoints, CFormView)

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

CDlgEditPoints::~CDlgEditPoints()
{
}

void CDlgEditPoints::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgEditPoints)
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgEditPoints, CFormView)
	//{{AFX_MSG_MAP(CDlgEditPoints)
	ON_WM_HSCROLL()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgEditPoints diagnostics

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

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

/////////////////////////////////////////////////////////////////////////////
// CDlgEditPoints message handlers


void CDlgEditPoints::OnPaint() 
{
	CPaintDC dc1(this); // device context for painting
	
	// TODO: Add your message handler code here

	CWnd *wnd = GetDlgItem(IDC_STATIC_LINE);

	CPaintDC dc(wnd);

	RECT r;

	wnd->RedrawWindow();
	wnd->GetClientRect(&r);
	int dx = (r.right - r.left - 1);
	int dy = (r.bottom - r.top - 1);
	int i,j,ii;

	j = (int)(dy * Effect(1));
	MoveToEx(dc, 0, dy - j, NULL);
	for(i=-20; i<=20; i++)
	{
		//j = (int)((Effect((float)(i-10.f)*(i-10.f)/400)*dy));
		//LineTo(dc, i*dx/20, dy - j);
		ii = i>0 ? i : -i; 
		j = (int)(dy * Effect(((float)ii)/20));
		LineTo(dc, (20+i)*dx/40, dy - j);
	}
	// Do not call CFormView::OnPaint() for painting messages
}


#define MAXLIN 40

/*
float CDlgEditPoints::Effect(float dist)
{ 
	return (float)exp(-m_fLinearity*MAXLIN*dist);
	//return (float)exp(-0.5*MAXLIN*dist);
}
*/

/*
float CDlgEditPoints::Effect(float x)
{ 
	double t = 0.1 + m_fLinearity * 0.8;
	double t2 = t * t;
	double t3 = t2 * t;
	double t4 = t3 * t;
	double t5 = t4 * t;
	double b = (2*t4 + 5*t3 - 4*t2 - 3*t +2)/(t5 - 2*t4 + t3);
	double a = (-b*(t3-t2) + t2 + t - 1)/(t4 - t2);
	double c = -a - b - 1;

	float y = (float)(x*x*x*x*a + x*x*x*b + x*x*c + 1);
	return y;
}
*/

/*
float CDlgEditPoints::Effect(float x)
{ 
	double t = 0.05 + m_fLinearity * 0.90;

	float y = (float)(x<t ? (t-x+x*t)/t : (t-t*x)/(1-t));
	return y;
}
*/
/*
float Graphic[9][2] = {{0,30}, {1,17}, {2,10}, {3,6}, {4,4}, {6,3}, {10,2}, {17,1}, {30,0}};
float Graphic2[9][2] = {{0,30}, {13,29}, {20,28}, {24,27}, {26,26}, {27,24}, {28,20}, {29,13}, {30,0}};

float CDlgEditPoints::Effect(float x)
{ 
	int i;
	for(i=1; (i<9) && (x>Graphic[i][0]/30); i++);
	float y = Graphic[i-1][1]/30 + (Graphic[i][1]-Graphic[i-1][1])*(x-Graphic[i-1][0]/30)/(Graphic[i][0]-Graphic[i-1][0]);

	for(i=1; (i<9) && (x>Graphic2[i][0]/30); i++);
	float y2 = Graphic2[i-1][1]/30 + (Graphic2[i][1]-Graphic2[i-1][1])*(x-Graphic2[i-1][0]/30)/(Graphic2[i][0]-Graphic2[i-1][0]);
	y = (1-m_fLinearity) * y + m_fLinearity * y2;
	return y;
}
*/

float g0[10][2] = {{0,36}, {1,36}, {2,35}, {3,27}, {4,8}, {5,5}, {7,3}, {10,2}, {19,1}, {36,0}};
float g1[10][2] = {{0,36}, {1,36}, {3,36}, {12,36}, {31,35}, {33.5,33.5}, {35,31}, {36,28}, {36,18}, {36,0}};

float CDlgEditPoints::Effect(float x)
{ 
	int i;
	float a,x0,y0,x1,y1,y;
	x = x * 36;
	a = m_fLinearity;

	x0 = (1-a)*g0[0][0] + a*g1[0][0];
	y0 = (1-a)*g0[0][1] + a*g1[0][1];
	x1 = (1-a)*g0[1][0] + a*g1[1][0];
	y1 = (1-a)*g0[1][1] + a*g1[1][1];

	for(i=2; (i<10) && (x>x1); i++)
	{
		x0 = x1; y0 = y1;
		x1 = (1-a)*g0[i][0] + a*g1[i][0];
		y1 = (1-a)*g0[i][1] + a*g1[i][1];
	}
	y = y0+(y1-y0)*(x-x0)/(x1-x0);
	return y/36;
}

void CDlgEditPoints::Init() 
{
	CSliderCtrl *Slider = (CSliderCtrl*)GetDlgItem(IDC_SLIDER1);
	Slider->SetRange(0, 400, TRUE);
	m_fLinearity = ((float)Slider->GetPos()/400);
	
	CStaticLine *Static = (CStaticLine*)GetDlgItem(IDC_STATIC_LINE);
	//m_StaticLine.Init(&m_fLinearity);
	//Static->Init(&m_fLinearity);
	//Static->SendMessage(WM_PAINT);
	RedrawWindow();
}

void CDlgEditPoints::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	CFormView::OnHScroll(nSBCode, nPos, pScrollBar);

	CSliderCtrl *Slider = (CSliderCtrl*)GetDlgItem(IDC_SLIDER1);
	m_fLinearity = ((float)Slider->GetPos()/400);

//	RedrawWindow();
	RedrawWindow( NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); 

/*
	CStaticLine *Static = (CStaticLine*)GetDlgItem(IDC_STATIC_LINE);

	//CPaintDC dc(Static); // device context for painting
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	RECT r;
	Static->GetClientRect(&r);
	int dx = (r.right - r.left);
	int dy = (r.bottom - r.top);
	MoveToEx(dc, 0, 0, NULL);
	int i,j;
	for(i=0; i<=20; i++)
	{
		j = (int)((Static->Effect((float)(i-10.f)*(i-10.f)/400)*dy));
		LineTo(dc, i*dx/20, dy - j);
	}
	LineTo(dc, dx, dy);
*/
}
/////////////////////////////////////////////////////////////////////////////
// CStaticLine

CStaticLine::CStaticLine()
{
}

CStaticLine::~CStaticLine()
{
}


BEGIN_MESSAGE_MAP(CStaticLine, CStatic)
	//{{AFX_MSG_MAP(CStaticLine)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStaticLine message handlers

void CStaticLine::Init(float * Lin)
{
	m_pLin = Lin;
}

float CStaticLine::Effect(float dist)
{ 
	return (float)exp(-*m_pLin*MAXLIN*dist);
	//return (float)exp(-0.5*MAXLIN*dist);
}


void CStaticLine::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	RECT r;
	GetClientRect(&r);
	int dx = (r.right - r.left);
	int dy = (r.bottom - r.top);
	MoveToEx(dc, 0, 0, NULL);
	int i,j;
	for(i=0; i<=20; i++)
	{
		//j = (int)((Effect((float)(i-10.f)*(i-10.f)/400)*dy));
		j = (int)(dy * Effect(((float)i)/20));
		LineTo(dc, i*dx/20, j);
	}
	LineTo(dc, dx, dy);
	// Do not call CStatic::OnPaint() for painting messages
}

