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

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

// MGCurvePullProjectTool

MGCurvePullProjectTool::MGCurvePullProjectTool(fugenDoc* pDoc)
: MGCommandStateOwner(pDoc, ID_CURVE_PULL_PROJECT),m_nIDS(1){
}

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

bool MGCurvePullProjectTool::initiate_tool(){
	MGCommandStateOwner::initiate_tool();

	// 選択オブジェクトをすべてチェック	
	m_point = select_from_current_objects(mgAll_Point);
	m_curve = select_from_current_objects(mgAll_Curve);
	m_surf  = select_from_current_objects(mgAll_FSurface);
	m_shell = select_from_current_objects(mgAll_Shell);
	
	if(!m_point.empty() || !m_curve.empty()){
		if(m_surf.empty() && m_shell.empty()){
			set_child_current_command(new MGCurvePullProjectSSurf(this));
			return false;
		}else{
			// 計算開始
			if(!calculate()){
				return OnCommandEnd(m_nIDS);
			}
			return OnCommandEnd(1);
		}
	}else{
		set_child_current_command(new MGCurvePullProjectSCurve(this));
	}
	return false;
}

bool MGCurvePullProjectTool::calculate(){
	if(m_point.empty() && m_curve.empty()){
		// みなしキャンセル
		return false;
	}
	if(m_surf.empty() && m_shell.empty()){
		// みなしキャンセル
		return false;
	}
	
	MGGelPositions gelps;

	// 1. point, curve を統合
	m_point.push_back(m_curve);
	m_curve.clear();
	
	// 2. surf, shell を統合
	m_surf.push_back(m_shell);
	m_shell.clear();

	// 3. 計算開始
	std::list<std::unique_ptr<MGGel>> res;
	MGPickObjects::iterator first = m_point.begin(), last = m_point.end();
	for(; first != last; ++first){
		MGPickObjects::iterator first2 = m_surf.begin(), last2 = m_surf.end();
		for(; first2 != last2; ++first2){
			mgcalc::MGProject tmp((*first2)->top_object(), (*first)->top_object());
			if(tmp.calculate()){
				res.splice(res.end(), std::move(tmp.result()));
			}
		}
	}
	if(res.empty()){
		// failed
		m_nIDS = IDS_FAIL_PROJECT;
		return false;
	}
	// ドキュメントを変更
	addListGelsToCurrentGroup(std::move(res));
	return true;
}

// MGCurvePullProjectSCurve

MGCurvePullProjectSCurve::MGCurvePullProjectSCurve(MGCommandStateOwner* owner)
	 : MGSelectState(owner, MGSelectState::MULTIPLE_SELECT, mgAll_Curve){
	// 見栄えが悪いがやむを得ない
	abstract_gels().push_back(mgAll_Point);
}

bool MGCurvePullProjectSCurve::initiate_tool(){
	MGSelectState::initiate_tool();
	set_add_mode();
	lock_so_far();
	SetStatusMessage(IDS_PROMPT_PROJECT_1);
	return false;
}

bool MGCurvePullProjectSCurve::OnKeyDown(
	fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags
){
	switch(nChar){
	case VK_RETURN:{
			MGCurvePullProjectTool* owner = state_owner();
			owner->m_point = select_from_current_objects(mgAll_Point);
			owner->m_curve = select_from_current_objects(mgAll_Curve);

			if(!owner->m_surf.empty() || !owner->m_shell.empty()){
				if(!owner->calculate()){
					owner->OnCommandEnd(owner->m_nIDS);
				}
				return owner->OnCommandEnd(1);
			}else{
				set_sibling_next_command(new MGCurvePullProjectSSurf(owner));
				return false;
			}
		}
	default:
		return MGSelectState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
	}
}

// MGCurvePullProjectSSurf

MGCurvePullProjectSSurf::MGCurvePullProjectSSurf(MGCommandStateOwner* owner)
: MGSelectState(owner, MGSelectState::MULTIPLE_SELECT, mgAll_2Manifold){
}

bool MGCurvePullProjectSSurf::initiate_tool(){
	MGSelectState::initiate_tool();
	set_add_mode();
	lock_so_far();
	SetStatusMessage(IDS_PROMPT_PROJECT_2);
	return false;
}

bool MGCurvePullProjectSSurf::OnKeyDown(
	fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags
){
	switch(nChar){
	case VK_RETURN:{
			MGCurvePullProjectTool* owner = state_owner();
			owner->m_surf  = select_from_current_objects(mgAll_FSurface);
			owner->m_shell = select_from_current_objects(mgAll_Shell);

			if(!owner->m_point.empty() || !owner->m_curve.empty()){
				if(!owner->calculate()){
					return owner->OnCommandEnd(owner->m_nIDS);
				}else{
					return owner->OnCommandEnd(1);
				}
			}else{
				set_sibling_next_command(new MGCurvePullProjectSCurve(owner));
				return false;
			}
		}
	default:
		return MGSelectState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
	}
}
