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

/**
 * @file CircleCRTool.cpp
 * @brief MGCircleCRTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "GLInputRealDlg.h"
#include "Common/CommandStateOwner.h"
#include "CurveCmd/CircleAroundCurve.h"
#include "CurveCmd/CircleDiamTool.h"
#include "CurveCmd/Circle3P.h"
#include "CurveCmd/CircleTTRTool.h"
#include "CurveCmd/CircleVertical.h"
#include "CurveCmd/CircleCRTool.h"

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

static double radius(5.);

// MGCircleCRTool

MGCircleCRTool::MGCircleCRTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_CIRCLE_CENTER_RADIUS,LINE_RUBBER,POINT_IPDRAW){
}

MGCircleCRTool::MGCircleCRTool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB, LINE_RUBBER, POINT_IPDRAW){
}

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

void MGCircleCRTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pSView){
	std::unique_ptr<MGCurve> circle=makeModel(cursor());
	if(circle.get()){
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		circle->drawWire(sgl);
	}
}

bool MGCircleCRTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	const LInfoVec& linfos=locates();
	if(linfos.size()==0){
		switch(nChar){
		case 'a':
		case 'A':
			// Around Curve
			set_sibling_next_command(new MGCircleAroundCurveTool(get_owner_command()));
			break;
		case 'v':
		case 'V':
			// Vertical
			set_sibling_next_command(new MGCircleVerticalTool(get_owner_command()));
			break;
		default:;
		}
	}else if(nChar=='r' || nChar=='R'){
		// 半径入力待ちの状態、数値入力ダイアログ出現
		CString title;title.LoadString(IDS_PROMPT_CIRCLE_RADIUS);
		CGLInputRealDlg dlg(title);
		dlg.SetValue(radius);
		if(dlg.DoModal()==IDOK){
			radius = dlg.GetValue();
			if(radius>MGTolerance::wc_zero()){
				const MGPosition& C=linfos[0]->point_world();
				const MGVector& normal=linfos[0]->window()->cplane().plane().normal();
				add_object_to_current_group(new MGEllipse(C,radius,normal));
				return OnCommandEnd(1); // コマンド終了
			}
		}
		pView->SetFocus();
	}		
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGCircleCRTool::OnLocated(const MGLocateInfo& info){
	const LInfoVec& linfos=locates();
	size_t n=linfos.size();
	if(n<=1){
		return false;
	}

	const MGPosition& P1=linfos[1]->point_world();
	add_object_to_current_group(makeModel(P1).release());	
	return OnCommandEnd(1); // コマンド終了
}

std::unique_ptr<MGCurve> MGCircleCRTool::makeModel(const MGPosition& P1){
	std::unique_ptr<MGCurve> circle;
	const LInfoVec& linfos=locates();
	if(!linfos.empty()){
		const MGPosition& C=linfos[0]->point_world();
		const MGVector& normal=linfos[0]->window()->cplane().plane().normal();
		circle.reset(new MGEllipse(C,P1,mgDBLPAI,normal));
	}
	return circle;
}

void MGCircleCRTool::prompt_message() const{
	const auto& linfos=locates();
	if(linfos.size()>=1){
		SetStatusMessage(IDS_PROMPT_ARC_TTR_2);
	}else
		SetStatusMessage(IDS_PROMPT_CIRCLE_CENTER);
}
