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

/**
 * @file RectCVTool.cpp
 * @brief MGRectCVTool クラスのインプリメンテーション
 */
#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/RectCVTool.h"

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

// MGRectCVToolBase

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

//Build rectangle's 4 corner points in corners.
void buildRectPointsFromCenterCorner(
	const MGLocateInfo& linfP0,///< center data
	const MGPosition& P1,///< a corner data
	MGPosition corners[4]
){
	const MGPlane& pl=linfP0.window()->cplane().plane();
	const MGPosition& G = linfP0.point_world();

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

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

void MGRectCVToolBase::do_make_temporary_display(mgSysGL& sgl,fugenView*){
	const LInfoVec& linfos=locates();
	if(linfos.size()==1){
		MGLocateInfo& info=*linfos.front();
		MGPosition corners[4];
		buildRectPointsFromCenterCorner(info,cursor(),corners);
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		sgl.drawPolyline(4,corners,true);
	}
}

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

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

void MGRectCVToolBase::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_CENTER;
		break;
	case 1:
		id=IDS_PROMPT_RECT_VERTEX;
		break;
	default:;
	}
	SetStatusMessage(id);
}

// MGRectFaceCVTool
MGRectFaceCVTool::MGRectFaceCVTool(fugenDoc* pDoc)
: MGRectCVToolBase(pDoc, ID_SURFACE_RECT_CEN_C){
}

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

void MGRectFaceCVTool::make_model(){
	const LInfoVec& linfos=locates();
	size_t n=linfos.size();
	if(n<=1){
		// cancel
		return;
	}

	MGLocateInfo& info0=*linfos.front();
	const MGPosition& P1 = linfos[1]->point_world();
	MGPosition corners[4];
	buildRectPointsFromCenterCorner(info0,P1,corners);

	std::unique_ptr<MGFace> f = mgcalc::rectangular_face(corners);
	add_object_to_current_group(f.release());
}

// MGPlaneCenterTool

MGPlaneCenterTool::MGPlaneCenterTool(fugenDoc* pDoc)
: MGRectCVToolBase(pDoc, ID_SURFACE_PLANE_CENTER){
}

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

void MGPlaneCenterTool::make_model(){
	const LInfoVec& linfos=locates();
	MGLocateInfo& info0=*linfos.front();
	const MGPosition& P1 = linfos[1]->point_world();
	MGPosition corners[4];
	buildRectPointsFromCenterCorner(info0,P1,corners);

	MGUnit_vector U(corners[1]-corners[0]),V,W;
	U.orthonormal(corners[2]-corners[1],V,W);
	add_object_to_current_group(new MGPlane(U,V,info0.point_world()));
}
