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

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

// MGRect2VToolBase

MGRect2VToolBase::MGRect2VToolBase(fugenDoc* pDoc, int nCmdID)
: MGLocateState(pDoc,nCmdID,NO_RUBBER,POINT_IPDRAW){
}

bool MGRect2VToolBase::initiate_tool(){
	MGLocateState::initiate_tool();

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

//Build rectangle's 4 corner points in corners.
void buildRectPointsFromDiagonalPoints(
	const MGLocateInfo& linfP1,///<1st point
	const MGPosition& P2,///2nd diagonal point
	MGPosition corners[4]
){
	const MGPlane& pl=linfP1.window()->cplane().plane();
	const MGPosition& P1 = linfP1.point_world();

	const MGUnit_vector u = pl.u_deriv();
	const MGUnit_vector v = pl.v_deriv();

	MGVector diag(P2-P1);
	corners[0] = P1;
	corners[1] = P1+(diag%u)*u;
	corners[2] = P2;
	corners[3] = P1+(diag%v)*v;
}

void MGRect2VToolBase::do_make_temporary_display(mgSysGL& sgl,fugenView* pSView){
	const LInfoVec& linfos=locates();
	size_t n=linfos.size();
	if(n == 1){
		MGPosition corners[4];
		buildRectPointsFromDiagonalPoints(*linfos[0], cursor(),corners);

		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		sgl.drawPolyline(4,corners,true);
	}
}

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

	make_model();
	return OnCommandEnd(1); // コマンド終了
}

void MGRect2VToolBase::prompt_message()const{
	const LInfoVec& linfos=locates();
	UINT id=0;//This id=0 means SetStatusMessage does not put messages.
	switch(locates().size()){
	case 0:
		id=IDS_PROMPT_RECT_DIAG_START;
		break;
	case 1:
		id=IDS_PROMPT_RECT_DIAG_END;
		break;
	default:;
	}
	SetStatusMessage(id);
}

// MGRectFace2VTool

MGRectFace2VTool::MGRectFace2VTool(fugenDoc* pDoc)
:MGRect2VToolBase(pDoc, ID_SURFACE_RECT_CC){
}

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

void MGRectFace2VTool::make_model(){
	const LInfoVec& linfos=locates();
	const MGPosition& C = linfos[1]->point_world();
	MGPosition corners[4];
	buildRectPointsFromDiagonalPoints(*linfos[0], C,corners);
	std::unique_ptr<MGFace> f = mgcalc::rectangular_face(corners);
	add_object_to_current_group(f.release());
}

// MGPlaneVertexTool

MGPlaneVertexTool::MGPlaneVertexTool(fugenDoc* pDoc)
: MGRect2VToolBase(pDoc, ID_SURFACE_PLANE_VERTEX){
}

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

void MGPlaneVertexTool::make_model(){
	const LInfoVec& linfos=locates();
	const MGPosition& P1=linfos[1]->point_world();
	MGPosition corners[4];
	buildRectPointsFromDiagonalPoints(*linfos[0], P1,corners);

	const MGPosition& A=corners[0];
	const MGPosition& B=corners[1];
	const MGPosition& C=corners[2];
	
	MGUnit_vector U(B-A),V,W;
	U.orthonormal(C-B,V,W);
	add_object_to_current_group(new MGPlane(U,V,(A+C)*.5));
}
