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

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

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

// MGCornerR_CPPTool

MGCornerR_CPPTool::MGCornerR_CPPTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_CORNER_R_CPP,NO_RUBBER,POINT_IPDRAW){
	turn_on_near();
	turn_on_end();
}

MGCornerR_CPPTool::MGCornerR_CPPTool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB, NO_RUBBER, POINT_IPDRAW){
	turn_on_near();
	turn_on_end();
}

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

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

void MGCornerR_CPPTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	LInfoVec& linfos=locates();
	if(linfos.size()>=1){
		std::unique_ptr<MGCurve> arc(Compute(cursor()));
		if(!arc.get()){
			return;
		}

		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		arc->drawWire(sgl);
	}
}

bool MGCornerR_CPPTool::OnLocated(const MGLocateInfo& info){
	LInfoVec& linfos=locates();
	size_t np=linfos.size();
	if(linfos.size()==1){
		const MGLocateInfo& info0=*linfos[0];
		const MGCurve* curve = dynamic_cast<const MGCurve*>(info0.object());
		if(!curve){
			// 曲線上の点以外のクリックは認めない
			cancel_last_locate();
		}else{
			m_pair=std::pair<const MGCurve*, double>(curve,info0.curve_parameter());
		}
	}
	if(linfos.size()<=1){
		return false;
	}


	// 計算開始
	std::unique_ptr<MGCurve> arc(Compute(linfos[1]->point_world()));
	if(!arc.get()){
		// failed
		return OnCommandEnd(IDS_FAIL_GENERATE_CURVE);
	}
	add_object_to_current_group(arc.release());
	return OnCommandEnd(1);
}

MGCurve* MGCornerR_CPPTool::Compute(const MGPosition& pos)const{
	if(!m_pair.first){
		return 0;
	}

	// 円の乗る平面の法線方向を自分で求める...
	const MGCurve* target = m_pair.first;
	const double dParam = m_pair.second;
	// XXX: 中点ピック時に不安定
	const bool bNearStart = target->is_startpoint_parameter(target->param_se(dParam));

	const MGPosition& pos1 = target->eval(dParam);
	const MGPosition& pos2 = pos;
	const MGVector& v1 = target->eval(dParam, 1);

	MGVector& normal = v1 * (pos2 - pos1);
	if(bNearStart){
		normal.negate();
	}

	// 円弧を作成する。
	// BUG: 180 度を超える円弧ができない。
	return new MGEllipse(*target, pos2, normal, dParam);
}

void MGCornerR_CPPTool::prompt_message() const{
	if(!m_pair.first){
		SetStatusMessage(IDS_PROMPT_CORNER_R_END);
	}else{
		SetStatusMessage(IDS_PROMPT_CORNER_R_POINT);
	}
}
