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

// SmoothingDlg.cpp : インプリメンテーション ファイル

#include "stdafx.h"
#include "fugen.h"
#include "fugenDoc.h"
#include "CurveCmd/CurveSmoothingState.h"
#include "SmoothingDlg.h"
#include "Misc/UserPreference.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSmoothingDlg ダイアログ

CSmoothingDlg::CSmoothingDlg(MGCurveSmoothingState* tool)
:mgModelessDialogue(tool){
	//{{AFX_DATA_INIT(CSmoothingDlg)
	//}}AFX_DATA_INIT
	LoadUserPref();
	Create(IDD_SMOOTHING_DLG);
}

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

	m_dScaleMin = 0.;
	SetIcon(::AfxGetApp()->LoadIcon(IDR_MGCLTYPE), FALSE);

	int nLower = 1;
	int nUpper = 320;

	CSpinButtonCtrl* pSpin = static_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_CURVA_SCALE_SPIN));
	pSpin->SetRange(nLower, nUpper);

	pSpin = static_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_CURVA_DENS_SPIN));
	nUpper = 32;
	pSpin->SetRange(nLower, nUpper);
	return TRUE;
}

void CSmoothingDlg::DoDataExchange(CDataExchange* pDX){
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSmoothingDlg)
	DDX_Text(pDX, IDC_EDIT_SMOOTHING_WEIGHT, m_dWeight);
	DDV_MinMaxDouble(pDX, m_dWeight, 0., 50.);

	DDX_Text(pDX, IDC_EDIT_SMOOTHING_MAXDEV, m_dMaxDev);
	DDV_MinMaxDouble(pDX, m_dMaxDev, 0., 1000.);

	DDX_Radio(pDX, IDC_CURVA_RADIO, m_iType);

	DDX_Control(pDX, IDC_CURVA_SCALE_SPIN, m_spnScale);
	DDX_Text(pDX, IDC_CURVA_SCALE, m_dScale);
	DDV_MinMaxDouble(pDX, m_dScale, m_dScaleMin, m_dScaleMax);

	DDX_Control(pDX, IDC_CURVA_DENS_SPIN, m_spnDens);
	DDX_Text(pDX, IDC_CURVA_DENSITY, m_nDensity);
	DDV_MinMaxInt(pDX, m_nDensity, m_nDensMin, m_nDensMax);

	DDX_Check(pDX, IDC_CURVA_SMOOTH_FIX_START, m_bFixStart);
	DDX_Check(pDX, IDC_CURVA_SMOOTH_FIX_END, m_bFixEnd);

	DDX_CBIndex(pDX, IDC_CURVA_SMOOTH_DEV_KIND, m_nDevKind);
	DDX_CBIndex(pDX, IDC_SMOOTHING_END_COND_TYPE, m_nEndKind);
	DDX_Check(pDX, IDC_CURVA_NEGATE, m_bNegate);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSmoothingDlg, CDialog)
	//{{AFX_MSG_MAP(CSmoothingDlg)
	ON_BN_CLICKED(IDC_CURVA_RADIO, UpdateView)
	ON_NOTIFY(UDN_DELTAPOS, IDC_CURVA_DENS_SPIN, OnDeltaposSpin)
	ON_NOTIFY(UDN_DELTAPOS, IDC_CURVA_SCALE_SPIN, OnDeltaposSpin)
	ON_BN_CLICKED(IDC_CURVA_RADIO2, UpdateView)
	ON_BN_CLICKED(IDC_PREVIEW, UpdateView)
	ON_BN_CLICKED(IDC_CURVA_SMOOTH_FIX_START, OnCurvaSmoothFixStart)
	ON_BN_CLICKED(IDC_CURVA_SMOOTH_FIX_END, OnCurvaSmoothFixEnd)
	ON_BN_CLICKED(IDC_CURVA_NEGATE, UpdateView)
	ON_CBN_SELENDOK(IDC_CURVA_SMOOTH_DEV_KIND, UpdateView)
	ON_CBN_SELENDOK(IDC_SMOOTHING_END_COND_TYPE, UpdateView)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

double CSmoothingDlg::GetScale() const{
	return m_bNegate ? -m_dScale : m_dScale;
}

void CSmoothingDlg::LoadUserPref(){
	const UserPreference& pref = UserPreference::getInstance();
	m_dWeight = pref.GetDoubleValue(upv_Curve_Smooth_Weight);
	m_nDevKind = pref.GetIntValue(upv_Curve_Smooth_DeviationType);
	m_dMaxDev = pref.GetDoubleValue(upv_Curve_Smooth_Deviation);
	m_nEndKind = pref.GetIntValue(upv_Curve_Smooth_EndCondition);
	m_bFixStart = pref.GetBoolValue(upv_Curve_Smooth_FixStart);
	m_bFixEnd = pref.GetBoolValue(upv_Curve_Smooth_FixEnd);
	pref.GetDoubleValue(upv_Eval_CurveCurvature_Scale, m_dScale, m_dScaleMin, m_dScaleMax);
	pref.GetIntValue(upv_Eval_CurveCurvature_Density, m_nDensity, m_nDensMin, m_nDensMax);
	m_iType = pref.GetIntValue(upv_Curve_Smooth_CurvatureType);
	m_bNegate = pref.GetBoolValue(upv_Curve_Smooth_Negate);
}

void CSmoothingDlg::SaveUserPref() const{
	UserPreference& pref = UserPreference::getInstance();
	pref.SetDoubleValue(upv_Curve_Smooth_Weight, m_dWeight);
	pref.SetIntValue(upv_Curve_Smooth_DeviationType, m_nDevKind);
	pref.SetDoubleValue(upv_Curve_Smooth_Deviation, m_dMaxDev);
	pref.SetIntValue(upv_Curve_Smooth_EndCondition, m_nEndKind);
	pref.SetBoolValue(upv_Curve_Smooth_FixStart, m_bFixStart==TRUE);
	pref.SetBoolValue(upv_Curve_Smooth_FixEnd, m_bFixEnd==TRUE);
	pref.SetDoubleValue(upv_Eval_CurveCurvature_Scale, m_dScale);
	pref.SetIntValue(upv_Eval_CurveCurvature_Density, m_nDensity);
	pref.SetIntValue(upv_Curve_Smooth_CurvatureType, m_iType);
	pref.SetBoolValue(upv_Curve_Smooth_Negate, m_bNegate==TRUE);
}

void CSmoothingDlg::UpdateView(){
	UpdateData();
	getCmdTool()->draw_temporary();
}

/////////////////////////////////////////////////////////////////////////////
// CSmoothingDlg メッセージ ハンドラ

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

#define DELTA .02
void CSmoothingDlg::OnDeltaposSpin(NMHDR* pNM, LRESULT* pResult){
	NM_UPDOWN* pUpDown = reinterpret_cast<NM_UPDOWN*>(pNM);
	UINT nIDC = (UINT)pUpDown->hdr.idFrom;
	switch(nIDC){
	case IDC_CURVA_SCALE_SPIN:// 自前でインクリメント
		m_dScale = m_dScale+pUpDown->iDelta*DELTA;
		m_dScale = (std::max)(m_dScale, m_dScaleMin);
		m_dScale = (std::min)(m_dScale, m_dScaleMax);
		UpdateData(FALSE);
		break;
	case IDC_CURVA_DENS_SPIN: break;
	default: *pResult = 1; break;
	}

	UpdateView();
}

// 始点固定ボタン
void CSmoothingDlg::OnCurvaSmoothFixStart(){
	MGCurveSmoothingState* tool=static_cast<MGCurveSmoothingState*>(getCmdTool());
	tool->set_weights();
	UpdateView();
}

// 終点固定ボタン
void CSmoothingDlg::OnCurvaSmoothFixEnd(){
	MGCurveSmoothingState* tool = static_cast<MGCurveSmoothingState*>(getCmdTool());
	tool->set_weights();
	UpdateView();
}

void CSmoothingDlg::OnOK(){
	UpdateView();
	SaveUserPref();
	MGCurveSmoothingState* tool = static_cast<MGCurveSmoothingState*>(getCmdTool());
	if(tool)
		tool->document()->normalEnd_command_tool(tool, 1);
}

void CSmoothingDlg::OnCancel(){
	MGCurveSmoothingState* tool = static_cast<MGCurveSmoothingState*>(getCmdTool());
	if(tool)	// コマンドをキャンセル終了とする。
		tool->document()->cancel_command_tool(tool, 1);
}
