#include <afxdlgs.h>
#include <math.h>
//===    OpenGL
#include <gl/gl.h>
#include <gl/glu.h>
#include <vector>
using namespace std;



#pragma once

//==========  
class CPoint3D
{
public:
	//======  
	float x;
	float y;
	float z;

	//======  
	CPoint3D () 
	{
 	x = y = z = 0.f;
 }

	CPoint3D (float c1, float c2, float c3)
	{
		x = c1;
		z = c2;
		y = c3;
	}
	//======  
	CPoint3D& operator= (const CPoint3D& pt)
	{
		x = pt.x;	z = pt.z;	y = pt.y;
		return *this;
	}

	//======  
	CPoint3D (const CPoint3D& pt)
	{
		*this = pt;
	}
};

//===========   OpenGL
class COGView : public CView
{
protected:
	COGView();
	DECLARE_DYNCREATE(COGView)

public:
	virtual ~COGView();
	virtual void OnDraw(CDC* pDC);
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

	//=======   
	long		m_BkClr;			//   
	int			m_LightParam[11];//  
	HGLRC		m_hRC;				//  OpenGL
	HDC			m_hdc; 			//  Windows
	GLfloat	m_AngleX;			//     X
	GLfloat	m_AngleY;			//     Y
	GLfloat	m_AngleView;		//  
	GLfloat	m_fRangeX;		//    X
	GLfloat	m_fRangeY;		//    Y
	GLfloat	m_fRangeZ;		//    Z
	GLfloat	m_dx;				//    X
	GLfloat	m_dy;				//    Y
	GLfloat	m_xTrans;			// C  X
	GLfloat	m_yTrans;			// C  Y
	GLfloat	m_zTrans;			// C  Z
	GLenum		m_FillMode;		//   
	bool		m_bCaptured;		//   
	bool		m_bRightButton;	//    
	bool		m_bQuad;			//   GL_QUAD
	CPoint		m_pt;				//   
	UINT		m_xSize;			//     X
	UINT		m_zSize;			//     Y

	//======   
	vector <CPoint3D> m_cPoints;

	//======   
	//======  
	void DrawScene();
	//======    
	void DefaultGraphic();
	//======      
	void SetGraphPoints(BYTE* buff, DWORD nSize);
	//======   
	void SetLight();
	//======     
	void SetLightParam (short lp, int nPos);
	//======    
	void GetLightParams(int *pPos);
	//======    
	void ReadData();
	//======    
	bool DoRead(HANDLE hFile);
	//======      
	void SetBkColor();

	DECLARE_MESSAGE_MAP()
};



COGView::COGView()
{
	//======    
	m_hRC = 0;

	//======   
	m_AngleX = 35.f;
	m_AngleY = 20.f;

	//======     
	m_AngleView = 45.f;

	//======   
	m_BkClr = RGB(0, 0, 96);

	//      
	m_FillMode = GL_FILL;

	//======    
	DefaultGraphic();

	//======     
	//======      
	m_zTrans = -1.5f*m_fRangeX;
	m_xTrans = m_yTrans = 0.f;

	//==     ( )
	m_dx = m_dy = 0.f;

	//======   
	m_bCaptured = false;
	//======     
	m_bRightButton = false;
	//======  
	m_bQuad = true;

	//======    
	m_LightParam[0] = 50;	// X position
	m_LightParam[1] = 80;	// Y position
	m_LightParam[2] = 100;	// Z position
	m_LightParam[3] = 15;	// Ambient light
	m_LightParam[4] = 70;	// Diffuse light
	m_LightParam[5] = 100;	// Specular light
	m_LightParam[6] = 100;	// Ambient material
	m_LightParam[7] = 100;	// Diffuse material
	m_LightParam[8] = 40;	// Specular material
	m_LightParam[9] = 70;	// Shininess material
	m_LightParam[10] = 0;	// Emission material
}



BOOL COGView::PreCreateWindow(CREATESTRUCT& cs)
{
	//======   ,  OpenGL
	cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
	return CView::PreCreateWindow(cs);
}

BOOL COGView::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}



int COGView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	PIXELFORMATDESCRIPTOR pfd =	//  
	{
		sizeof(PIXELFORMATDESCRIPTOR),//  
		1,							//  
		PFD_DRAW_TO_WINDOW |	//  GDI
		PFD_SUPPORT_OPENGL |	//  OpenGL
		PFD_DOUBLEBUFFER,		//  
		PFD_TYPE_RGBA,			//  RGBA,  
		24, 						//  
		 							//    
		24,	0,						//   Red
		24,	0,						//   Green
		24,	0,						//   Blue
		24,	0,						//   Alpha
		0,							//  
									//  Accumulation
		0,			 				//     Red
		0,			 				//   Green
		0,							//   Blue
		0,							//   Alpha
		32, 						//  Z-
		0,							//   Stencil
		0,							//   Auxiliary
		0,				 			//  
		0,							//  
		0,							//  
		0,							//   
		0							//  
	};

	//======   
	m_hdc = ::GetDC(GetSafeHwnd());

	//======     
	int iD = ChoosePixelFormat(m_hdc, &pfd);
	if ( !iD )
	{
		MessageBox("ChoosePixelFormat::Error");
		return -1;
	}

	//======    
	if ( !SetPixelFormat (m_hdc, iD, &pfd) )
	{
		MessageBox("SetPixelFormat::Error");
		return -1;
	}

	//======     OpenGL
	if ( !(m_hRC = wglCreateContext (m_hdc)))
	{
		MessageBox("wglCreateContext::Error");
		return -1;
	}

	//======      
	if ( !wglMakeCurrent (m_hdc, m_hRC))
	{
		MessageBox("wglMakeCurrent::Error");
		return -1;
	}

	//======     OpenGL
	glEnable(GL_LIGHTING);			//  
	//======     
	glEnable(GL_LIGHT0);
	//======    ( Z)
	glEnable(GL_DEPTH_TEST);
	//======     
	glEnable(GL_COLOR_MATERIAL);

	//======   
	SetBkColor();

	//======      
	DrawScene();
	return 0;
}



void COGView::OnDestroy(void)
{
	//======   
	KillTimer(1);

	//======    
	wglMakeCurrent(0, 0);
	//======  
	if (m_hRC)
	{
		wglDeleteContext(m_hRC);
		m_hRC = 0;
	}

	CView::OnDestroy();
}


void COGView::OnSize(UINT nType, int cx, int cy)
{
	//======   
	CView::OnSize(nType, cx, cy);

	//======   
	double dAspect = cx<=cy ? double(cy)/cx 
								 : double(cx)/cy;

	glMatrixMode (GL_PROJECTION);
	glLoadIdentity();

	//======    
	gluPerspective (m_AngleView, dAspect, 0.01, 10000.);

	//======   
	glViewport(0, 0, cx, cy);
}



void COGView:: OnDraw(CDC* pDC)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//=======   
	SetLight();

	//======   
	glTranslatef(m_xTrans,m_yTrans,m_zTrans);
	glRotatef (m_AngleX, 1.0f, 0.0f, 0.0f );
	glRotatef (m_AngleY, 0.0f, 1.0f, 0.0f );

	//======     
	glCallList(1);

	//======  
	SwapBuffers(m_hdc);
}



void COGView::SetLight()
{
	//======    
	//======    
	//======    
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1);

	//======   
	//======    
	float fPos[] =
	{
		(m_LightParam[0]-50)*m_fRangeX/100,
		(m_LightParam[1]-50)*m_fRangeY/100,
		(m_LightParam[2]-50)*m_fRangeZ/100,
		1.f
	};
	glLightfv(GL_LIGHT0, GL_POSITION, fPos);

	//======   
	float f = m_LightParam[3]/100.f;
	float fAmbient[4] = { f, f, f, 0.f };
	glLightfv(GL_LIGHT0, GL_AMBIENT, fAmbient);

	//======   
	f = m_LightParam[4]/100.f;	
	float fDiffuse[4] = { f, f, f, 0.f };
	glLightfv(GL_LIGHT0, GL_DIFFUSE, fDiffuse);

	//======   
	f = m_LightParam[5]/100.f;
	float fSpecular[4] = { f, f, f, 0.f };
	glLightfv(GL_LIGHT0, GL_SPECULAR, fSpecular);

	//======   
	//======    
	f = m_LightParam[6]/100.f;
	float fAmbMat[4] = { f, f, f, 0.f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, fAmbMat);

	f = m_LightParam[7]/100.f;
	float fDifMat[4] = { f, f, f, 1.f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fDifMat);

	f = m_LightParam[8]/100.f;
	float fSpecMat[4] = { f, f, f, 0.f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fSpecMat);

	//======  
	float fShine = 128 * m_LightParam[9]/100.f;
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, fShine);

	//======   
	f = m_LightParam[10]/100.f;
	float fEmission[4] = { f, f, f, 0.f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, fEmission);
}



void COGView::SetBkColor()
{
	//======     
	GLclampf red	= GetRValue(m_BkClr)/255.f,
			 green	= GetGValue(m_BkClr)/255.f,
			 blue	= GetBValue(m_BkClr)/255.f;
	//======    () 
	glClearColor (red, green, blue, 0.f);

	//======  
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}



void COGView::DrawScene()
{
	//======    
	glNewList(1, GL_COMPILE);

	//======   
	//======   
	glPolygonMode(GL_FRONT_AND_BACK, m_FillMode);

	//======   
	UINT	nx = m_xSize-1,
			nz = m_zSize-1;

	//======    
	if (m_bQuad)
		glBegin (GL_QUADS);

	//======      ( Z)
	for (UINT z=0, i=0;  z<nz;  z++, i++)
	{
		//======   
		//======    
		if (!m_bQuad)
			glBegin(GL_QUAD_STRIP);

		//======     X
		for (UINT x=0;  x<nx;  x++, i++)
		{
			// i, j, k, n - 4    
			//      

			int	j = i + m_xSize,	//     Z
				k = j+1,			//    
				n = i+1; 			//   

			//===   4-   
			float
				xi = m_cPoints[i].x,
				yi = m_cPoints[i].y,
				zi = m_cPoints[i].z,

				xj = m_cPoints[j].x,
				yj = m_cPoints[j].y,
				zj = m_cPoints[j].z,

				xk = m_cPoints[k].x,
				yk = m_cPoints[k].y,
				zk = m_cPoints[k].z,

				xn = m_cPoints[n].x,
				yn = m_cPoints[n].y,
				zn = m_cPoints[n].z,

				//===    
				ax = xi-xn,
				ay = yi-yn,

				by = yj-yi,
				bz = zj-zi,

				//======   
				vx = ay*bz,
				vy = -bz*ax,
				vz = ax*by,

				//======  
				v  = float(sqrt(vx*vx + vy*vy + vz*vz));
			
			//======   
			vx /= v;
			vy /= v;
			vz /= v;

			//======   
			glNormal3f (vx,vy,vz);

			//    
			if (m_bQuad)
			{
				//======   
				//======     
				glColor3f (0.2f, 0.8f, 1.f);
				glVertex3f (xi, yi, zi);
				glColor3f (0.6f, 0.7f, 1.f);
				glVertex3f (xj, yj, zj);
				glColor3f (0.7f, 0.9f, 1.f);
				glVertex3f (xk, yk, zk);
				glColor3f (0.7f, 0.8f, 1.f);
				glVertex3f (xn, yn, zn);
			}
			else
			//======    
			{
				glColor3f (0.9f, 0.9f, 1.0f);
				glVertex3f (xn, yn, zn);
				glColor3f (0.5f, 0.8f, 1.0f);
				glVertex3f (xj, yj, zj);
			}
		}
		//======    GL_QUAD_STRIP
		if (!m_bQuad)
			glEnd();
	}
	//======    GL_QUADS
	if (m_bQuad)
		glEnd();

	//======    OpenGL
	glEndList();
}



void COGView::DefaultGraphic()
{
	//======   
	m_xSize = m_zSize = 33;

	//======       
	UINT	nz = m_zSize - 1,
			nx = m_xSize - 1;

	//        
	DWORD nSize = m_xSize * m_zSize * sizeof(float)
						+ 2*sizeof(UINT);

	//======     
	BYTE *buff = new BYTE[nSize+1];

	//======      
	UINT *p = (UINT*)buff;

	//======    
	*p++ = m_xSize;
	*p++ = m_zSize;

	//======   ,   
	//======    
	float *pf = (float*)p;

	//===    
	double	fi = atan(1.)*6,
			kx = fi/nx,
			kz = fi/nz;

	//======       
	//===        float
	for (UINT i=0;  i<m_zSize;  i++)
	{
		for (UINT j=0;  j<m_xSize;  j++)
		{
			*pf++ = float (sin(kz*(i-nz/2.))
							* sin(kx*(j-nx/2.)));
		}
	}

	//===   ,   
	//===      
	DWORD nBytes;

	//===      sin.dat
	HANDLE hFile = CreateFile(_T("sin.dat"), GENERIC_WRITE,
					0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

	//======     
	WriteFile(hFile,(LPCVOID)buff, nSize,&nBytes, 0);

	//======  
	CloseHandle(hFile);

	//======    m_cPoints
	SetGraphPoints (buff, nSize);

	//======   
	delete [] buff;
}



void COGView::SetGraphPoints(BYTE* buff, DWORD nSize)
{
	//======     
	//======      
	UINT *p = (UINT*)buff;

	//===    ,  
	m_xSize = *p;
	m_zSize = *++p;

	//======   
	if (m_xSize<2 || m_zSize<2 || 
			m_xSize*m_zSize*sizeof(float)
			+ 2 * sizeof(UINT) != nSize)
	{
		MessageBox(_T(" "));
		return;
	}

	//======   
	//======     
	m_cPoints.resize(m_xSize*m_zSize);

	if (m_cPoints.empty())
	{
		MessageBox(_T("   "));
		return;
	}

	//======      
	//======   
	float	x, z,
			//======   
			*pf   = (float*)++p,
			fMinY = *pf,
			fMaxY = *pf,
			right = (m_xSize-1)/2.f,
			left  = -right,
			rear  = (m_zSize-1)/2.f,
			front = -rear, 
			range = (right + rear)/2.f;

	UINT	i, j, n;

	//======    
	m_fRangeY = range;
	m_fRangeX = float(m_xSize);
	m_fRangeZ = float(m_zSize);

	//======     Z
	m_zTrans = -1.5f * m_fRangeZ;

	//======    (X-Z)
	//======     Y  
	for (z=front, i=0, n=0;  i<m_zSize;  i++, z+=1.f)
	{
		for (x=left, j=0;  j<m_xSize;  j++, x+=1.f, n++)
		{
			MinMax (*pf, fMinY, fMaxY);
			m_cPoints[n] = CPoint3D(x,z,*pf++);
		}
	}

	//======  
	float zoom = fMaxY > fMinY ? range/(fMaxY-fMinY)
									 : 1.f;

	for (n=0;  n<m_xSize*m_zSize;  n++)
	{
		m_cPoints[n].y = zoom * (m_cPoints[n].y - fMinY)
							- range/2.f;
	}
}



inline void MinMax (float d, float& Min, float& Max)
{
	//======     
	if (d > Max)
		Max = d;			//   
	else if (d < Min)
		Min = d;			//   
}



void COGView::ReadData()
{
	//=== ,      
	TCHAR szFile[MAX_PATH] = { 0 };

	//======    
	TCHAR *szFilter =TEXT("Graphics Data Files (*.dat)\0")
						TEXT("*.dat\0")
						TEXT("All Files\0")
						TEXT("*.*\0");

	//======   	
	TCHAR szCurDir[MAX_PATH];
	::GetCurrentDirectory(MAX_PATH-1,szCurDir);

	//===  ,   
	OPENFILENAME ofn;
	ZeroMemory(&ofn,sizeof(OPENFILENAME));

	//======    
	ofn.lStructSize	= sizeof(OPENFILENAME);
	//====== - 
	ofn.hwndOwner = GetSafeHwnd();
	ofn.lpstrFilter	= szFilter;
	//======    (  )
	ofn.nFilterIndex	= 1;
	ofn.lpstrFile		= szFile;
	ofn.nMaxFile		= sizeof(szFile);
	//======   
	ofn.lpstrTitle	= _T("   ");
	ofn.nMaxFileTitle = sizeof (ofn.lpstrTitle);
	//======    (  Win2K)
	ofn.Flags			= OFN_EXPLORER;

	//======    
	//===    GetOpenFileName  0
	if (GetOpenFileName(&ofn))
	{
		//   ,   
		HANDLE hFile = CreateFile(ofn.lpstrFile, GENERIC_READ,
				FILE_SHARE_READ, 0, OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL, 0);

		//===    CreateFile  -1
		if (hFile == (HANDLE)-1)
		{
			MessageBox(_T("   "));
			return;
		}

		//======      
		if (!DoRead(hFile))
			return;

		//======   
		DrawScene();

		//======   OpenGL
		Invalidate(FALSE);
	}
}



//======    
bool COGView::DoRead(HANDLE hFile)
{
	//======    
	DWORD nSize = GetFileSize (hFile, 0);

	//===     , GetFileSize
	//======  0xFFFFFFFF
	if (nSize == 0xFFFFFFFF)
	{
		GetLastError();
		MessageBox(_T("  "));
		CloseHandle(hFile);
		return false;
	}

	//===       
	BYTE *buff = new BYTE[nSize+1];

	//======    
	if (!buff)
	{
		MessageBox(_T("   "));
		CloseHandle(hFile);
		return false;
	}

	//======   
	DWORD nBytes;
	//======   
	ReadFile (hFile, buff, nSize, &nBytes, 0);
	CloseHandle(hFile);

	//======      
	if (nSize != nBytes)
	{
		MessageBox(_T("   "));
		return false;
	}

	//======   
	SetGraphPoints (buff, nSize);

	//======   
	delete [] buff;
	//======  
	return true;
}



void COGView::OnLButtonDown(UINT nFlags, CPoint point)
{
	//======  
	KillTimer(1);

	//======   
	m_dx = 0.f;
	m_dy = 0.f;

	//======   ,
	//======     
	SetCapture();
	//======   
	m_bCaptured = true;
	//======   
	m_pt = point;
}


void COGView::OnRButtonDown(UINT nFlags, CPoint point)
{
	//======     
	m_bRightButton = true;

	//======     
	OnLButtonDown(nFlags, point);
}


void COGView::OnLButtonUp(UINT nFlags, CPoint point)
{
	//======   ,
	if (m_bCaptured)
	{
		//===     
		//===    
		if (fabs(m_dx) > 0.5f || fabs(m_dy) > 0.5f)
			//===    
			SetTimer(1,33,0);
		else
			//===    
			KillTimer(1);

		//======    
		m_bCaptured = false;
		//======   
		ReleaseCapture();
	}
}


void COGView::OnRButtonUp(UINT nFlags, CPoint point)
{
	//======   
	m_bRightButton = false;
	//======    
	m_bCaptured = false;
	//======   
	ReleaseCapture();
}


void COGView::OnMouseMove(UINT nFlags, CPoint point)
{
	if (m_bCaptured)		//   ,
	{
		//     
		m_dy = float(point.y - m_pt.y)/40.f;
		m_dx = float(point.x - m_pt.x)/40.f;

		//======     Ctrl,
		if (nFlags & MK_CONTROL)
		{
			//===    
			m_xTrans += m_dx;
			m_yTrans -= m_dy;
		}
		else
		{
			//======     
			if (m_bRightButton)
				//======   
				m_zTrans += (m_dx + m_dy)/2.f;
			else
			{
				//====== ,   
				m_AngleX += m_dy;
				m_AngleY += m_dx;
			}
		}
		//===       
		m_pt = point;
		Invalidate(FALSE);
	}
}


void COGView::OnTimer(UINT nIDEvent)
{
	//======     
	if (nIDEvent==1)
	{
		//======   
		m_AngleX += m_dy;
		m_AngleY += m_dx;
		//======   
		if (m_AngleX > 360)
			m_AngleX -= 360;
		if (m_AngleX <-360)
			m_AngleX += 360;

		if (m_AngleY > 360)
			m_AngleY -= 360;
		if (m_AngleY <-360)
			m_AngleY += 360;

		//======   
		Invalidate(FALSE);
	}
	else
		//===     
		CView::OnTimer(nIDEvent);
}



void COGView::OnEditBackground(void)
{
	//======    
	CColorDialog dlg(m_BkClr);
	//======   
	dlg.m_cc.Flags |= CC_FULLOPEN;
	//======     
	if (dlg.DoModal()==IDOK)
	{
		m_BkClr = dlg.m_cc.rgbResult;
		//======   
		SetBkColor();
		Invalidate(FALSE);
	}
}



void COGView::OnViewQuad(void)
{
	//     
	m_bQuad = ! m_bQuad;

	//======   
	DrawScene();
	Invalidate(FALSE);
	UpdateWindow();
}


void COGView::OnUpdateViewQuad(CCmdUI* pCmdUI)
{
	//======     ()
	pCmdUI->SetCheck(m_bQuad==true);
}



void COGView::OnViewFill(void)
{
	//===    
	m_FillMode = m_FillMode==GL_FILL ? GL_LINE : GL_FILL;

	//======   
	DrawScene();
	Invalidate(FALSE);
	UpdateWindow();
}

void COGView::OnUpdateViewFill(CCmdUI *pCmdUI)
{
	//======     
	pCmdUI->SetCheck(m_FillMode==GL_FILL);
}



void COGView::GetLightParams(int *pPos)
{
	//======    
	for (int i=0; i<11; i++)
		//======    pPos
		pPos[i] = m_LightParam[i];
}

void COGView::SetLightParam (short lp, int nPos)
{
	//======   lp 
	//======     nPos
	m_LightParam[lp] = nPos;

	//======     
	Invalidate(FALSE);
}






IDD_PROP
 Ambient   Light
IDC_AMBIENT
 Diffuse   Light
IDC_DIFFUSE
 Specular   Light
IDC_SPECULAR
Static Text   Ambient   Light
IDC_AMB_TEXT
Static Text   Diffuse   Light
IDC_DIFFUSE_TEXT
Static Text   Specular   Light
IDC_SPECULAR_TEXT
 Ambient   Material
IDC_AMBMAT
 Diffuse   Material
IDC_DIFFMAT
 Specular   Material
IDC_SPECMAT
Static Text   Ambient   Material
IDC_AMBMAT_TEXT
Static Text   Diffuse   Material
IDC_DIFFMAT_TEXT
Static Text   Specular   Material
IDC_SPECMAT_TEXT
 Shininess
IDC_SHINE
 Emission
IDC_EMISSION
Static Text   Shininess
IDC_SHINE_TEXT
Static Text   Emission
IDC_EMISSION_TEXT
 X
IDC_XPOS
 Y
IDC_YPOS
 Z
IDC_ZPOS
Static Text   X
IDC_XPOS_TEXT
Static Text   Y
IDC_YPOS_TEXT
Static Text   Z
IDC_ZPOS_TEXT
 Data File
IDC_FILENAME



#pragma once

class COGView;				//  

class CPropDlg : public CDialog
{
	DECLARE_DYNAMIC(CPropDlg)

public:
	COGView *m_pView; 		//  
	int m_Pos[11]; 			//   

	CPropDlg(COGView* p);
	virtual ~CPropDlg();

	//      
	int GetSliderNum(HWND hwnd, UINT& nID);

	enum { IDD = IDD_PROP };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);

	DECLARE_MESSAGE_MAP()
};


CPropDlg::CPropDlg(COGView* p)
	: CDialog(CPropDlg::IDD, p)
{
	//======   
	m_pView = p;
}



BOOL CPropDlg::OnInitDialog(void)
{
	CDialog::OnInitDialog();

	//======     
	m_pView->GetLightParams(m_Pos);

	//======   
	UINT IDs[] = 
	{
		IDC_XPOS,		IDC_YPOS,		IDC_ZPOS,
		IDC_AMBIENT,
		IDC_DIFFUSE,
		IDC_SPECULAR,
		IDC_AMBMAT,
		IDC_DIFFMAT,
		IDC_SPECMAT,
		IDC_SHINE,
		IDC_EMISSION
	};

	//======     
	for (int i=0; i<sizeof(IDs)/sizeof(IDs[0]); i++)
	{
		//===  Windows-  
		HWND hwnd = GetDlgItem(IDs[i])->GetSafeHwnd();
		UINT nID;

		//======   
		int num = GetSliderNum(hwnd, nID);

		//      m_Pos[i]
		::SendMessage(hwnd, TBM_SETPOS, TRUE,
						(LPARAM)m_Pos[i]);
		char s[8];
		//======     
		sprintf (s,"%d",m_Pos[i]);
		//======       
		SetDlgItemText(nID, (LPCTSTR)s);
	}

	return TRUE;
}


int CPropDlg::GetSliderNum(HWND hwnd, UINT& nID)
{
	//====== GetDlgCtrlID   hwnd 
	//======     
	switch (::GetDlgCtrlID(hwnd))
	{
	//======    
	case IDC_XPOS:
		nID = IDC_XPOS_TEXT;
		return 0;
	case IDC_YPOS:
		nID = IDC_YPOS_TEXT;
		return 1;
	case IDC_ZPOS:
		nID = IDC_ZPOS_TEXT;
		return 2;
	case IDC_AMBIENT:
		nID = IDC_AMB_TEXT;
		return 3;
	case IDC_DIFFUSE:
		nID = IDC_DIFFUSE_TEXT;
		return 4;
	case IDC_SPECULAR:
		nID = IDC_SPECULAR_TEXT;
		return 5;
	case IDC_AMBMAT:
		nID = IDC_AMBMAT_TEXT;
		return 6;
	case IDC_DIFFMAT:
		nID = IDC_DIFFMAT_TEXT;
		return 7;
	case IDC_SPECMAT:
		nID = IDC_SPECMAT_TEXT;
		return 8;
	case IDC_SHINE:
		nID = IDC_SHINE_TEXT;
		return 9;
	case IDC_EMISSION:
		nID = IDC_EMISSION_TEXT;
		return 10;
	}
	return 0;
}



void CPropDlg::OnHScroll(UINT nSBCode, UINT nPos,
					CScrollBar* pScrollBar)
{
	//====== Windows-   
	HWND hwnd = pScrollBar->GetSafeHwnd();

	UINT nID;

	//===      
	int num = GetSliderNum(hwnd, nID);
	int delta, newPos;

	//======   
	switch (nSBCode)
	{
	case SB_THUMBTRACK:
	case SB_THUMBPOSITION:		//  
		m_Pos[num] = nPos;
		break;
	case SB_LEFT:					//  Home
		delta = -100;
		goto New_Pos;
	case SB_RIGHT:				//  End
		delta = +100;
		goto New_Pos;
	case SB_LINELEFT:			//  <-
		delta = -1;
		goto New_Pos;
	case SB_LINERIGHT:			//  ->
		delta = +1;
		goto New_Pos;
	case SB_PAGELEFT:			//  PgUp
		delta = -20;
		goto New_Pos;
	case SB_PAGERIGHT:			//  PgDn
		delta = +20;
		goto New_Pos;

	New_Pos:						//  
		//======    
		newPos = m_Pos[num] + delta;
		//====== 
		m_Pos[num] = newPos<0 ? 0 : newPos>100 ? 100 : newPos;
		break;
	case SB_ENDSCROLL:
	default:
		return;
	}

	//======    
	char s[8];
	sprintf (s,"%d",m_Pos[num]);
	SetDlgItemText(nID, (LPCTSTR)s);

	//======     
	m_pView->SetLightParam (num, m_Pos[num]);
}



void CPropDlg::OnClose(void)
{
	//===      
	m_pView->m_pDlg = 0;
	//======  
	CDialog::OnClose();
	//======  
	delete this;
}


void CPropDlg:: OnClickedFilename(void)
{
	//===      
	m_pView->ReadData();
}



void COGView::OnEditProperties (void)
{
	//======     
	if (!m_pDlg)
	{
		//===       
		m_pDlg = new CPropDlg(this);
		m_pDlg->Create(IDD_PROP);
	}
	else
		// ,      
		m_pDlg->SetActiveWindow();
}


void COGView::OnUpdateEditProperties(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck (m_pDlg != 0);
}


void COGView::OnEditProperties (void)
{
	m_pDlg = new CPropDlg(this);
	m_pDlg->Create(IDD_PROP);
}


void COGView::OnUpdateEditProperties(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_pDlg == 0);
}




