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

/**
 * @file SurfCornersTool.cpp
 * @brief MGSurfCornersTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "mg/LBRep.h"
#include "mg/SBRep.h"
#include "Calc/mgcalc.h"
#include "fugenView.h"
#include "SurfCmd/SurfCornersTool.h"

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

// MGSurfCornersTool

MGSurfCornersTool::MGSurfCornersTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_SURFACE_CORNERS,NO_RUBBER,POINT_IPDRAW){
}

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

void MGSurfCornersTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	m_spPreview.reset(Compute(pView, cursor()));
	if(!m_spPreview.get()){
		return;
	}
	MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
	mgcalc::CreateDrawFunctor(sgl)(m_spPreview.get());
}

MGSurface* MGSurfCornersTool::Compute(fugenView*, const MGPosition& pos){
	const LInfoVec& linfos=locates();
	size_t n=linfos.size();
	if(n < 3){
		return 0;
	}

	const MGPosition& A = linfos[0]->point_world();
	const MGPosition& B = linfos[1]->point_world();
	const MGPosition& C = linfos[2]->point_world();
	const MGPosition& D = pos;

	std::unique_ptr<MGLBRep> perimeters[4];

	MGLBRep* lb;
	MGBPointSeq bp(2, 3);
	bp.store_at(0, A); bp.store_at(1, B);
	lb=new MGLBRep;lb->buildByInterpolation(bp, 2);
	perimeters[0].reset(lb);

	bp.store_at(0, B); bp.store_at(1, C);
	lb=new MGLBRep;lb->buildByInterpolation(bp, 2);
	perimeters[1].reset(lb);

	bp.store_at(0, D); bp.store_at(1, C);
	lb=new MGLBRep;lb->buildByInterpolation(bp, 2);
	perimeters[2].reset(lb);

	bp.store_at(0, A); bp.store_at(1, D);
	lb=new MGLBRep;lb->buildByInterpolation(bp, 2);
	perimeters[3].reset(lb);

	MGSBRep* srf = new MGSBRep;
	srf->buildGeneralizedRuledSurface(perimeters,false);
	return srf;
}

bool MGSurfCornersTool::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
){
	const LInfoVec& linfos=locates();
	size_t n=linfos.size();
	if(n<=3){
		return MGLocateState::OnCommandEnd(3);
	}

	MGSurface* surf = Compute(0, linfos[3]->point_world());
	add_object_to_current_group(surf);
	return MGLocateState::OnCommandEnd(1);
}

bool MGSurfCornersTool::OnLocated(const MGLocateInfo& info){
	if(locates().size() < 4){
		return false;
	}
	return OnCommandEnd(1);
}

void MGSurfCornersTool::prompt_message() const{
	SetStatusMessage(IDS_PROMPT_SURFACE_CORNER, locates().size()+1);
}
