/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file Curve3DComposite.cpp
 * @brief MGCurve3DCompositeTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "mg/Straight.h"
#include "mg/LBRep.h"
#include "Calc/curve.h"
#include "Calc/mgcalc.h"
#include "fugenView.h"
#include "CurveCmd/Curve3DComposite.h"

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

// MGCurve3DCompositeTool

MGCurve3DCompositeTool::MGCurve3DCompositeTool(fugenDoc* pDoc)
: MGSelectState(pDoc,ID_CURVE_3D,
	 MGSelectState::SINGLE_SELECT, // single pick
	 mgAll_Curve){
}

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

bool MGCurve3DCompositeTool::initiate_tool()
{
	MGSelectState::initiate_tool();
	set_add_mode();

	resetCurrentObjects(mgAll_Curve);
	const MGPickObjects& curobj = current_objects();
	size_t n = curobj.size();
	if(n == 0 || n > 2){
		clear_pick_object();
		prompt_message();
		return false;
	}else{
		// 確実にとれる
		const MGCurve* crv = dynamic_cast<const MGCurve*>(curobj[0].top_object());
		m_curves.first = crv;
		if(n == 1){
			prompt_message();
			lock_so_far();
			return false;
		}
		ASSERT(n == 2);
		// 計算に入れる
		const MGCurve* crv2 = dynamic_cast<const MGCurve*>(curobj[1].top_object());
		m_curves.second = crv2;
		UINT inds=1;
		if(!calculate()){
			// failed
			inds=IDS_FAIL_GENERATE_CURVE;
		}
		return OnCommandEnd(inds);
	}
}

bool MGCurve3DCompositeTool::calculate(){
	if(!m_curves.first || !m_curves.second){
		// cancel
		return false;
	}

	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor sandglass;

	MGSSisects ls = mgcalc::compose_3D(*m_curves.first, *m_curves.second);
	if(ls.empty()){
		// failed
		return false;
	}

	MGGelPositions gelps;
	MGSSisects::const_iterator cur = ls.begin(), last = ls.end();
	for(; cur != last; ++cur){
		auto& ssi = isectCast<MGSSisect>(cur);
		gelps.push_back(MGGelPosition(current_group(),ssi.line().clone()));
	}

	add_object_to_document(gelps);
	return true;
}

bool MGCurve3DCompositeTool::OnSelected(
	fugenView* window,//The fugenView pointer where point input event took place.
	MGPickObjects&	objs,	//selected objects at this selection operation.
	MGPickObjects&	unselected_objects	//unselected objects at this selection operation.
		//unselected_objects.size()>=1 only when the already selected objects are selected
		//when add mode is set(or when operation is done with a crtl key pressed).
){
	ASSERT(objs.size() == 1);
	MGCurve* curve = dynamic_cast<MGCurve*>(objs.front().top_object()); assert(curve);
	if(!m_curves.first){
		// OK.
		m_curves.first = curve;
		prompt_message();
		lock_so_far();
		return false;
	}

	m_curves.second = curve;
	// 計算開始

	UINT inds=1;
	if(!calculate()){
		// failed
		inds=IDS_FAIL_GENERATE_CURVE;
	}
	return OnCommandEnd(inds);
}

void MGCurve3DCompositeTool::prompt_message() const{
	if(!m_curves.first){
		SetStatusMessage(IDS_PROMPT_CURVE_NTH, 1);
	}else if(!m_curves.second){
		SetStatusMessage(IDS_PROMPT_CURVE_NTH, 2);
	}
}
