/********************************************************************/
/* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/

// GaussDlg.cpp: CGaussDlg クラスのインプリメンテーション

#include "stdafx.h"
#include "GaussDlg.h"
#include "EvalCmd/EvalSurfGauss.h"
#include "fugenDoc.h"

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

namespace{
	const int nSizeGcvt = 5;

	// CSrfCurvaDlg::DoDataExchange helper function.
	void SetCurvaMinMaxEdit(CDataExchange* pDX, int nIDC, double dVal)
	{
		TCHAR szBuffer[32];
		_stprintf_s(szBuffer, 32, _T("%.*g"), nSizeGcvt, dVal);
		AfxSetWindowText(pDX->PrepareEditCtrl(nIDC), szBuffer);
	}
}

CGaussDlg::CGaussDlg(MGEvalSurfGaussTool* tool)
 : mgModelessDialogue(tool){

	//{{AFX_DATA_INIT(CSrfCurvaDlg)
	m_dMin = -0.00001;
	m_dMax = 0.00001;
	m_strMean = _T("0");
	//}}AFX_DATA_INIT

	m_bModified = FALSE;
	Create(IDD_SRFCURVA_DLG);
}

BOOL CGaussDlg::OnInitDialog(){
	if(!mgModelessDialogue::OnInitDialog())
		return FALSE;

	CComboBox* pCb = (CComboBox*)GetDlgItem(IDC_SRFCURVA_COMBO);
	pCb->SetCurSel(0);

	double mean = (m_dMin + m_dMax)*.5;
	m_strMean.Format(_T("%f"), mean);
	UpdateData(FALSE);
	UpdateGradientArea();
	return TRUE;
}

void CGaussDlg::DoDataExchange(CDataExchange* pDX){
	CDialog::DoDataExchange(pDX);
	if(pDX->m_bSaveAndValidate){
		DDX_Text(pDX, IDC_SRFCURVA_MIN, m_dMin);
		DDX_Text(pDX, IDC_SRFCURVA_MAX, m_dMax);
	}
	else{
		SetCurvaMinMaxEdit(pDX, IDC_SRFCURVA_MIN, m_dMin);
		SetCurvaMinMaxEdit(pDX, IDC_SRFCURVA_MAX, m_dMax);	
	}
	DDX_Text(pDX, IDC_SRFCURVA_STA, m_strMean);
}

BEGIN_MESSAGE_MAP(CGaussDlg, mgModelessDialogue)
	//{{AFX_MSG_MAP(CGaussDlg)
	ON_BN_CLICKED(IDC_SRFCURVA_BTN_AUTO, ResetAutoRange)
	ON_BN_CLICKED(IDC_SRFCURVA_BTN_MAX, ResetMinMaxRange)
	ON_BN_CLICKED(IDC_SRFCURVA_BTN_REFRESH, UpdateView)
	ON_CBN_SELCHANGE(IDC_SRFCURVA_COMBO, ResetAutoRange)
	ON_EN_UPDATE(IDC_SRFCURVA_MAX, OnUpdateEditCtrl)
	ON_EN_UPDATE(IDC_SRFCURVA_MIN, OnUpdateEditCtrl)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

int CGaussDlg::GetCurvaKindfromDialog() const{
	CComboBox* pCb = (CComboBox*)GetDlgItem(IDC_SRFCURVA_COMBO);
	int nCur = pCb->GetCurSel();
	if(nCur == CB_ERR) nCur = 0; // gaussian
	return nCur;
}

MGEvalSurfGaussTool* CGaussDlg::getEvalSurfGaussTool(){
	return static_cast<MGEvalSurfGaussTool*>(getCmdTool());
}

MGCL::SURFACE_CURVATURE_KIND CGaussDlg::GetCurvaKind() const{	
	MGCL::SURFACE_CURVATURE_KIND kind;
	int cvkind=GetCurvaKindfromDialog();
	switch(cvkind){
	case 0:
		kind = MGCL::GAUSSIAN_CURVATURE;
		break;
	case 1:
		kind = MGCL::MEAN_CURVATURE;
		break;
	case 2:
		kind = MGCL::MINIMUM_CURVATURE;
		break;
	case 3:
		kind = MGCL::MAXIMUM_CURVATURE;
		break;
	default:
		ASSERT(FALSE);
	}
	return kind;
}

void CGaussDlg::OnOK(){
	UpdateView();
	mgModelessDialogue::OnOK();
}

void CGaussDlg::OnPaint(){
	CPaintDC dc(this);
	dc.GradientFill(m_vert, 5, m_gr, 4, GRADIENT_FILL_RECT_V);
	CDialog::OnPaint();
}

void CGaussDlg::UpdateView(){
	if(IsModified()){
		UpdateData();

		double mean = (m_dMin + m_dMax)*.5;
		m_strMean.Format(IDS_FORMAT_FLOAT, mean);

		MGEvalSurfGaussTool* tool=getEvalSurfGaussTool();
		if(tool)
			tool->draw_pictures(GetCurvaKind(), m_dMin, m_dMax);
		UpdateData(FALSE);
		SetModifiedFlag(FALSE);
	}
}

void CGaussDlg::UpdateGradientArea(){
	CRect rc;
	GetDlgItem(IDC_STATIC_GRADIENT)->GetWindowRect(rc);
	ScreenToClient(rc);

	const double dPitch = static_cast<double>(rc.Height()) / 4;
	TRIVERTEX vert[5] =
	{
		{rc.left, 0, 0xFF00, 0x0000, 0x0000, 0},
		{rc.right, 0, 0xFF00, 0xFF00, 0x0000, 0},
		{rc.left, 0, 0x0000, 0xFF00, 0x0000, 0},
		{rc.right, 0, 0x0000, 0xFF00, 0xFF00, 0},
		{rc.left, 0, 0x0000, 0x0000, 0xFF00, 0},
	};
	for(int i = 0; i < 5; ++i){
		vert[i].y = long(rc.top + dPitch * i);
	}
	GRADIENT_RECT gr[4] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}};

	std::copy(vert, vert + 5, m_vert);
	std::copy(gr, gr + 4, m_gr);
}

void CGaussDlg::ResetAutoRange(){
	MGEvalSurfGaussTool* tool=getEvalSurfGaussTool();
	if(!tool) return;

	MGCL::SURFACE_CURVATURE_KIND kind = GetCurvaKind();
	double dMin=tool->minimum_curvature(kind);
	double dMax=tool->maximum_curvature(kind);

	dMin = fabs(dMin);
	dMax = fabs(dMax);
	if(dMin < dMax){
		m_dMin = -dMax;
		m_dMax = dMax;
	}else{
		m_dMin = -dMin;
		m_dMax = dMin;
	}
	ASSERT(-m_dMin == m_dMax);
	UpdateData(FALSE);

	SetModifiedFlag(TRUE);
	UpdateView();
}

void CGaussDlg::ResetMinMaxRange(){
	MGEvalSurfGaussTool* tool=getEvalSurfGaussTool();
	if(!tool) return;

	MGCL::SURFACE_CURVATURE_KIND kind = GetCurvaKind();
	m_dMin=tool->minimum_curvature(kind);
	m_dMax=tool->maximum_curvature(kind);
	UpdateData(FALSE);
	SetModifiedFlag(TRUE);
	UpdateView();
}

void CGaussDlg::OnUpdateEditCtrl(){
	m_bModified = TRUE;
}

BOOL CGaussDlg::PreTranslateMessage(MSG* pMsg){
	switch(pMsg->message){
	case WM_MOUSEWHEEL:
		return -1;
	}
	return CDialog::PreTranslateMessage(pMsg);
}
