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

/**
 * @file SurfRibTool.cpp
 * @brief SurfRibTool.h の実装
 */
#include "stdafx.h"
#include "mg/Surface.h"
#include "Calc/curve.h"
#include "Calc/mgcalc.h"
#include "fugenDoc.h"
#include "SurfCmd/SurfRibTool.h"

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

// MGSurfRibTool

MGSurfRibTool::MGSurfRibTool(fugenDoc* pDoc)
: MGSelectState(pDoc,ID_SURFACE_RIB,SINGLE_SELECT,mgAll_Curve){
}

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

bool MGSurfRibTool::initiate_tool(){
	MGSelectState::initiate_tool();

	// 強制クリア
	clear_pick_object();
	set_add_mode();

	// 最初のメッセージ
	SetStatusMessage(IDS_PROMPT_CURVE_RIB);
	return false;
}

namespace{
	const bool DIRECTION_ADJUSTMENT = true;
}

bool MGSurfRibTool::calculate(){
	// 計算開始
	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor sandglass;

	MGPickObjects& curobj=current_objects();
	size_t n = curobj.size();
	std::vector<const MGCurve*> curves(n);
	for (size_t i = 0; i < n; i++)
		curves[i] = dynamic_cast<const MGCurve*>(curobj[i].top_object());
	
	std::unique_ptr<MGSurface> srf = MGCL::createSurfaceFromRibs(curves, DIRECTION_ADJUSTMENT);
	if(!srf.get()){
		// failed
		return false;
	}

	MGGelPosition gelp(curobj.front().bottom_group(),srf.release());
	add_object_to_document(gelp);
	return true;
}

bool MGSurfRibTool::OnCommandCanceled(UINT nIDS){
	clear_pick_object();
	return MGSelectState::OnCommandCanceled(nIDS);
}

bool MGSurfRibTool::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
){
	if(current_objects().size() < 2){
		// みなしキャンセル
		return OnCommandCanceled(1);
	}
	if(!calculate()){
		// failed
		return OnCommandCanceled(IDS_FAIL_GENERATE_SURF);
	}
	// コマンド終了
	return MGSelectState::OnCommandEnd(1);
}

bool MGSurfRibTool::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); // add-mode is on.
	
	// MGCompositeCurve must be excluded.
	objs.remove(mgAll_CompositeCurve);
	if(objs.empty()){
		return false;
	}

	// ここでは終了しない
	return false;
}
