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

/**
 * @file ArcSER.cpp
 * @brief MGArcSERTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "Calc/mgcalc.h"
#include "fugenView.h"
#include "GLInputRealDlg.h"
#include "CurveCmd/ArcSER.h"

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

// MGArcSERTool

MGArcSERTool::MGArcSERTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_ARC_SER,LINE_RUBBER,POINTLINE_IPDRAW),
m_mode(RADIUS), m_radius(-1.){
}

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

bool MGArcSERTool::initiate_tool(){
	MGLocateState::initiate_tool();
	UserPreference& pref = UserPreference::getInstance();
	m_radius = pref.GetDoubleValue(upv_Curve_Arc_Radius);
	return false;
}

bool MGArcSERTool::terminate_tool(bool cancel){
	UserPreference& pref = UserPreference::getInstance();
	pref.SetDoubleValue(upv_Curve_Arc_Radius, m_radius);

	return MGLocateState::terminate_tool(cancel);
}

MGEllipse* MGArcSERTool::create_arc(
	const MGPosition& epos
)const{
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	if(np>=2){
		const MGPosition& P0=linfos[0]->point_world();
		const MGPosition& P1=linfos[1]->point_world();
		switch(m_mode){
		case RADIUS:
			return new MGEllipse(m_radius,P0,P1, epos);
			break;
		case DIRECTION:
			// 始点・終点・方向
			return new MGEllipse(P0, epos, P1-P0);
			break;
		case THROUGH:
			// 始点・通過点・終点
			return new MGEllipse(P0, P1, epos);
			break;
		default:
			return nullptr;
		}
	}
	return nullptr;
}

void MGArcSERTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	std::unique_ptr<MGCurve> arc(create_arc(cursor()));
	if(arc.get()){
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		arc->drawWire(sgl);

		// 中心
		MGColor::get_instance(MGColor::Black).exec(sgl);
		sgl.drawPoint(arc->center());
	}
}

bool MGArcSERTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();

	switch(nChar){
	case 'd':
	case 'D':
		if(np == 1)
			m_mode = DIRECTION;
		break;
	case 'r':
	case 'R':
		if(m_mode == RADIUS && np>=2){
			// 半径と向き入力待ちの状態、数値入力ダイアログ出現
			CString title;title.LoadString(IDS_PROMPT_CIRCLE_RADIUS);
			CGLInputRealDlg dlg(title);
			dlg.SetValue(m_radius);
			if(dlg.DoModal()==IDOK){
				double radius = dlg.GetValue();
				if(radius>=m_minimumRadius)
					m_radius = radius;
			}
			pView->SetFocus();
		}
		break;
	case 't':
	case 'T':
		if(np == 1)
			m_mode = THROUGH;
		break;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGArcSERTool::OnLocated(const MGLocateInfo& info){	
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	if(np==1)
		setDrawerRubber(LINE_RUBBER);
	else if(np>=2)
		setDrawerRubber(NO_RUBBER);

	switch(m_mode){
	case RADIUS:
		if(np==2){
			const MGPosition& P0=linfos[0]->point_world();
			const MGPosition& P1=linfos[1]->point_world();
			m_radius=m_minimumRadius=P0.distance(P1)/2.;
		}
		break;
	case DIRECTION:
		break;
	case THROUGH:
		// 特になし
		break;
	}

	if(np < 3){
		return false;
	}

	// 計算開始
	const MGPosition& refpos = linfos[2]->point_world();
	add_object_to_current_group(create_arc(refpos));
	return OnCommandEnd(1);
}

void MGArcSERTool::prompt_message() const{
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	UINT nIDS = IDS_PROMPT_ARC_SED_START; // np == 0 のときのデフォルトメッセージ

	switch(m_mode){
	case RADIUS:
		if(np==0)
			nIDS = IDS_PROMPT_ARC_SED_START;
		else if(np==1)
			nIDS = IDS_PROMPT_ARC_SED_END_OPTION;
		else if(np==2){
			SetStatusMessage(IDS_PROMPT_ARC_SET_RADIUS, m_radius);
			return;
		}
		break;
	case DIRECTION:
		switch(np){
		case 1:
			nIDS = IDS_PROMPT_ARC_SED_DIR;
			break;
		case 2:
			nIDS = IDS_PROMPT_ARC_SED_END;
			break;
		}
		break;
	case THROUGH:
		switch(np){
		case 1:
			nIDS = IDS_PROMPT_ARC_SED_THROUGH;
			break;
		case 2:
			nIDS = IDS_PROMPT_ARC_END;
			break;
		}
		break;
	}

	SetStatusMessage(nIDS);
}
