/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file PointFromCurveDivide.cpp
 * @brief MGPointFromCurveDivideTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "CurveCmd/PointFromCurveDivide.h"
#include "GLInputNumberDlg.h"
#include "Calc/mgfunctor.h"
#include "Calc/mgcalc.h"
#include "Misc/UserPreference.h"

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

namespace{
	const int nDivide = 5;
}

// MGPointFromCurveDivideTool

MGPointFromCurveDivideTool::MGPointFromCurveDivideTool(fugenDoc* pDoc)
	 : MGSelectState(
		 pDoc,
		 ID_CURVE_DIVIDE_BY_NUM,
		 MGSelectState::MULTIPLE_SELECT, // multiple-selection
		 mgAll_Curve
		 ),
	   m_nDivide(nDivide)
{
}

MGCommandBase* MGPointFromCurveDivideTool::initial_clone(fugenDoc* pDoc) const
{
	return new MGPointFromCurveDivideTool(pDoc);
}

bool MGPointFromCurveDivideTool::initiate_tool(){
	MGSelectState::initiate_tool();
	const UserPreference& pref = UserPreference::getInstance();
	m_nDivide = pref.GetIntValue(upv_Point_FromCurveDivide_Num);

	// 選択モデルから曲線を選別
	current_object_is_valid(mgAll_Curve,m_curve);
	set_current_object(m_curve);
	set_add_mode();
	prompt_message();
	return false;
}

bool MGPointFromCurveDivideTool::terminate_tool(bool cancel)
{
	UserPreference& pref = UserPreference::getInstance();
	pref.SetIntValue(upv_Point_FromCurveDivide_Num, m_nDivide);

	return MGSelectState::terminate_tool(cancel);
}

bool MGPointFromCurveDivideTool::input_param()
{
	CString strCaption;
	VERIFY(strCaption.LoadString(IDS_CAPTION_DIV_NUM));

	CGLInputNumberDlg dlg(CString(), strCaption);
	dlg.SetValue(m_nDivide);

	bool bOK = (IDOK == dlg.DoModal());
	if(bOK){
		int tmp = dlg.GetValue();
		if(tmp < 2){
			bOK = false;
		}else{
			m_nDivide = tmp;
		}
	}
	return bOK;
}

bool MGPointFromCurveDivideTool::calculate(){
	if(m_nDivide < 2){
		// cancel
		return false;
	}

	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor wc;

	// オブジェクト作成
	typedef std::deque<MGPoint*> Holder;
	Holder tmp;
	MGGelPositions gelps;
	mgcalc::MGPointFromCurveDivide<Holder> calc(tmp, m_nDivide);

	MGPickObjects::iterator cur = m_curve.begin(), last = m_curve.end();
	for(; cur != last; ++cur){
		MGGroup* grp=(*cur)->bottom_group();
		const MGCurve* c = dynamic_cast<const MGCurve*>((*cur)->top_object());
		calc(c);
		for (auto i = tmp.begin(), ie = tmp.end(); i != ie; i++) 
			gelps.push_back(MGGelPosition(grp, *i));
		tmp.clear();
	}

	// ドキュメント変更
	if(!gelps.empty()){
		add_object_to_document(gelps);
	}

	return true;
}


bool MGPointFromCurveDivideTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case 'd':
	case 'D':
		// 間隔を入力
		input_param();
		prompt_message();
		return false;
	case VK_RETURN:
		m_curve = current_objects();
		if(m_curve.empty()){
			return false;
		}
		
		if(!calculate()){
			return OnCommandEnd(2);
		}
		return OnCommandEnd(1);
	default:
		return MGSelectState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
	}
}


void MGPointFromCurveDivideTool::prompt_message() const{
	SetStatusMessage(IDS_PROMPT_POINT_DIV_NUM, m_nDivide);
}
