/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file SurfRuledTool.cpp
 * @brief MGSurfRuledToolTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "SurfCmd/SurfRuledTool.h"
#include "Calc/surface.h"

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

// MGSurfRuledTool

MGSurfRuledTool::MGSurfRuledTool(fugenDoc* pDoc)
	 : MGSelectState(
		 pDoc,
		 ID_SURFACE_RULED,
		 MGSelectState::SINGLE_SELECT,  // single
		 mgAll_Curve)
{
}

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

bool MGSurfRuledTool::initiate_tool(){
	MGSelectState::initiate_tool();
	set_add_mode();
	if(resetCurrentObjects(mgAll_Curve)){
		const MGPickObjects& objs = current_objects();
		ASSERT(!objs.empty());

		switch(objs.size()){
		case 1:
			m_curve1 = objs.front();
			break;
		case 2:
			// 即計算、コマンド終了
			m_curve1 = objs[0];
			m_curve2 = objs[1];
			return OnCommandEnd(1);
		default:
			// 強制クリア
			clear_pick_object();
			break;
		}
	}
	// 最初のメッセージ
	prompt_message();
	return false;
}

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

bool MGSurfRuledTool::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(m_curve1.is_null() || m_curve2.is_null()){
		// みなしキャンセル
		return OnCommandCanceled(1);
	}

	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor sandglass;

	const MGCurve* c1 = dynamic_cast<const MGCurve*>(m_curve1.top_object());
	ASSERT(c1);
	const MGCurve* c2 = dynamic_cast<const MGCurve*>(m_curve2.top_object());
	ASSERT(c2);

	std::unique_ptr<MGSurface> ruled(MGCL::create_ruled_surface(*c1, *c2));
	if(!ruled.get()){
		return OnCommandCanceled(1);
	}

	MGGelPosition gelp(m_curve1.bottom_group(),ruled.release());
	add_object_to_document(gelp);
	return MGSelectState::OnCommandEnd(1);
}

bool MGSurfRuledTool::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
	ASSERT(dynamic_cast<const MGCurve*>(objs.front().top_object()));
	if(m_curve1.is_null()){
		// 1本目セット
		m_curve1 = objs.front();
		prompt_message();
		return false;
	}
	else{
		// 2本目セット
		MGPickObject& other = objs.back();
		auto c1 = dynamic_cast<const MGCurve*>(m_curve1.top_object());
		auto c2 = dynamic_cast<const MGCurve*>(other.top_object());
		if(c1==c2){
			return false;
		}
		m_curve2 = other;
	}

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

void MGSurfRuledTool::prompt_message() const{
	if(m_curve1.is_null()){
		SetStatusMessage(IDS_PROMPT_SURFACE_RULED_1);
		return;
	}
	if(m_curve2.is_null()){
		SetStatusMessage(IDS_PROMPT_SURFACE_RULED_2);
		return;
	}
}
