/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file PointFromCurveLength.cpp
 * @brief MGPointFromCurveLengthTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "CurveCmd/PointFromCurveLength.h"
#include "GLInputRealDlg.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 double dLength = 1.0;
}

// MGPointFromCurveLengthTool

MGPointFromCurveLengthTool::MGPointFromCurveLengthTool(fugenDoc* pDoc)
	 : MGSelectState(
		 pDoc,
		 ID_CURVE_DIVIDE_BY_LENGTH,
		 MGSelectState::MULTIPLE_SELECT, // multiple selection
		 mgAll_Curve
		 ),
	   m_dLength(dLength)
{
}

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

bool MGPointFromCurveLengthTool::initiate_tool(){
	MGSelectState::initiate_tool();
	const UserPreference& pref = UserPreference::getInstance();
	m_dLength = pref.GetDoubleValue(upv_Point_FromCurveLength_Span);

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

bool MGPointFromCurveLengthTool::terminate_tool(bool cancel)
{
	UserPreference& pref = UserPreference::getInstance();
	pref.SetDoubleValue(upv_Point_FromCurveLength_Span, m_dLength);

	return MGSelectState::terminate_tool(cancel);
}

bool MGPointFromCurveLengthTool::input_param(){
	
	CGLInputRealDlg dlg;
	dlg.SetValue(m_dLength);

	bool bOK = (IDOK == dlg.DoModal());
	if(!bOK)
		return false;

	double tmp = dlg.GetValue();
	if(tmp <= 0.){
			bOK = false;
	}else{
		m_dLength = tmp;
	}
	return bOK;
}

bool MGPointFromCurveLengthTool::calculate(){
	if(m_dLength <= 0.){
		// キャンセル扱いでよい
		return false;
	}

	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor wc;

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

	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 MGPointFromCurveLengthTool::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 MGPointFromCurveLengthTool::prompt_message() const{
	SetStatusMessage(IDS_PROMPT_POINT_FROM_LENGTH, m_dLength);
}
