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

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

const MGInterval range(0., mgDBLPAI);
std::unique_ptr<MGEllipse> makeEllipseModel(
	const LInfoVec& linfos,//locates 1st 2 points.
	const MGPosition& P2	//3rd point to locate.
){
	assert(linfos.size()>=2);	
	const MGPosition& P0=linfos[0]->point_world();
	const MGPosition& P1=linfos[1]->point_world();
	const MGPosition center = (P0+P1)*.5;
	const MGVector axis1 = P1-center;
	MGVector axis2 = P2-center;
	axis2 -= axis2.project(axis1);
	return std::unique_ptr<MGEllipse>(new MGEllipse(center, axis1, axis2, range));
}

// MGElpsDiamAxesTool

MGElpsDiamAxesTool::MGElpsDiamAxesTool(fugenDoc* pDoc)
: MGLocateState(pDoc, ID_CURVE_ELLIPSE_DIAMETER, NO_RUBBER, POINT_IPDRAW),
m_bVert(false){
}

MGElpsDiamAxesTool::MGElpsDiamAxesTool(MGCommandStateOwner* owner)
: MGLocateState(owner,UNLOCK_SNAP_ATTRIB,NO_RUBBER,POINT_IPDRAW), m_bVert(false){
}

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

void MGElpsDiamAxesTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pSView){
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	if(np<=1)
		return;

	std::unique_ptr<MGEllipse> elps=makeEllipseModel(linfos,cursor());
	const MGPosition apex = elps->eval(mgHALFPAI);
	MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
	elps->drawWire(sgl);

	const MGColor& white=MGColor::get_instance(MGColor::White);
	white.exec(sgl);
	sgl.Begin(GL_LINES);
		sgl.Vertex3dv(elps->center().data());
		sgl.Vertex3dv(apex.data());
	sgl.End();

	const MGColor& black=MGColor::get_instance(MGColor::Black);
	black.exec(sgl);
	sgl.drawPoint(apex[0], apex[1], apex[2]);
}

bool MGElpsDiamAxesTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case 'v':
	case 'V':
		// 最後のロケート時以外にチャンスを与える。
		if(locates().size()<2){
			m_bVert = !m_bVert;
		}
		break;
	default:;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGElpsDiamAxesTool::OnLocated(const MGLocateInfo& info){
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	if(np<=2){		// 制限解除
		if(np<=1){
			disable_AETPmode();
		}else if(np>=2){
			const MGPosition& P0=linfos[0]->point_world();
			const MGPosition& P1=linfos[1]->point_world();
			if(m_bVert){
				// マウスポインタ制限
				const MGVector& normal=linfos[0]->window()->cplane().plane().normal();
				MGPosition C=(P0+P1)*.5;
				setElevationRestrictionToProhibitUpdate(C,normal);
			}
		}
		return false;
	}

	// 計算開始
	std::unique_ptr<MGEllipse> ellipse=makeEllipseModel(linfos,linfos[2]->point_world());
	add_object_to_current_group(ellipse.release());
	disable_AETPmode();
	return OnCommandEnd(1); // コマンド終了
}

void MGElpsDiamAxesTool::prompt_message() const{
	CString strVertYesNo;
	strVertYesNo.LoadString(m_bVert ? IDS_YES : IDS_NO);
	switch(locates().size()){
	case 0:
		SetStatusMessage(IDS_PROMPT_ELLIPSE_DIAM_1S,strVertYesNo);
		break;
	case 1:
		SetStatusMessage(IDS_PROMPT_ELLIPSE_DIAM_1E,strVertYesNo);
		break;
	case 2:
		SetStatusMessage(IDS_PROMPT_ELLIPSE_DIAM_2E);
		break;
	}
}
