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

/**
 * @file CircleT3Tool.cpp
 * @brief MGCircleT3Tool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "CurveCmd/CircleT3Tool.h"
#include "mg/Ellipse.h"

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

// MGCircleT3Tool
//Generate a circle that is tangent to 3 curves.

MGCircleT3Tool::MGCircleT3Tool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_CIRCLE_T3C,NO_RUBBER,POINT_IPDRAW){
	turn_on_near();
	turn_on_end();
}

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

bool MGCircleT3Tool::initiate_tool(){
	MGLocateState::initiate_tool();
	clear_pick_object();
	return false;
}

bool MGCircleT3Tool::OnCommandEnd(
		UINT nIDS,	//=0: erase the current message, and display no messages.
				//=1: display "xxxx" normally end.
				//otherwise: nIDS is a string id, and load the message from string table to display.
		bool erase_temporary_display
){
	const LInfoVec& linfos=locates();
	if(linfos.size()<3)
		return MGLocateState::OnCommandEnd(3);

	// 計算開始
	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor sandglass;

	const MGCurve& c1=*(dynamic_cast<const MGCurve*>(linfos[0]->object()));
	double t1=linfos[0]->curve_parameter();
	const MGCurve& c2=*(dynamic_cast<const MGCurve*>(linfos[1]->object()));
	double t2=linfos[1]->curve_parameter();
	const MGCurve& c3=*(dynamic_cast<const MGCurve*>(linfos[2]->object()));
	double t3=linfos[2]->curve_parameter();

	MGPosition p1=c1.eval(t1);
	MGPosition p2=c2.eval(t2);
	MGPosition p3=c3.eval(t3);
	MGUnit_vector normal = (p1-p2)*(p3-p2);

	int ret = 0;
	std::unique_ptr<MGEllipse> arc(new MGEllipse(c1,c2,c3,normal,t1,t2,t3,ret));

	if(ret){
		// failed
		return MGLocateState::OnCommandEnd(IDS_FAIL_GENERATE_CURVE);
	}
	arc->unlimit();
	add_object_to_current_group(arc.release());
	return MGLocateState::OnCommandEnd(nIDS);
}

bool MGCircleT3Tool::OnLocated(const MGLocateInfo& info){
	if(info.is_deleted()){
		return false;
	}

	const MGObject* obj=info.object();	
	const MGCurve* curve = dynamic_cast<const MGCurve*>(obj);
	if(!curve){
		// 曲線上の点以外のクリックは認めない
		cancel_last_locate();
		return false;
	}

	const LInfoVec& linfos=locates();
	size_t np=linfos.size();
	if(np==2){
		if(obj == linfos[0]->object()){
			cancel_last_locate();
			// 前回の曲線と同じではいけない(MGCL)?
		}
	}else if(np==3){
		if(obj == linfos[0]->object() || obj== linfos[1]->object()){
			cancel_last_locate();
			// 前回の曲線と同じではいけない(MGCL)?
		}
	}

	if(linfos.size()<3){
		return false;
	}

	// 計算開始
	return OnCommandEnd(1);
}

void MGCircleT3Tool::prompt_message()const{
	const LInfoVec& linfos=locates();
	size_t np1=linfos.size()+1;
	SetStatusMessage(IDS_PROMPT_CIRCLE_BASELINE, np1);
}
