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

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

const MGInterval range(0., mgDBLPAI);

// MGElpsCenAxesTool

MGElpsCenAxesTool::MGElpsCenAxesTool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB, NO_RUBBER, POINT_IPDRAW){
}

std::unique_ptr<MGEllipse> MGElpsCenAxesTool::makeModle(
	const MGPosition& posLast
){
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	
	if(np<2){
		// キャンセル扱い
		return nullptr;
	}

	const MGPosition& center=linfos[0]->point_world();
	const MGPosition& P1=linfos[1]->point_world();

	// 計算開始
	const MGVector axis1 = P1-center;

	MGVector axis2 = posLast - center;
	axis2 -= axis2.project(axis1);
	return std::unique_ptr<MGEllipse>(new MGEllipse(center, axis1, axis2, range));
}

void MGElpsCenAxesTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pSView){
	std::unique_ptr<MGEllipse> elps=makeModle(cursor());
	if(elps.get()){
		MGPosition p = elps->eval(mgHALFPAI);
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		elps->drawWire(sgl);
		MGColor::get_instance(MGColor::White).exec(sgl);
		sgl.Begin(GL_LINES);
		sgl.Vertex3dv(elps->center().data());
		sgl.Vertex3dv(p.data());
		sgl.End();
		MGColor::get_instance(MGColor::Black).exec(sgl);
		sgl.drawPoint(p[0], p[1], p[2]);
	}
}

bool MGElpsCenAxesTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case 'a':
	case 'A':
		// Around Curve
		set_sibling_next_command(new MGElpsAroundCurveTool(get_owner_command()));
		break;
	case 'c':
	case 'C':
		// Corners
		set_sibling_next_command(new MGElpsCornerTool(get_owner_command()));
		break;
	case 'd':
	case 'D':
		// Diameter and Axes
		set_sibling_next_command(new MGElpsDiamAxesTool(get_owner_command()));
		break;
	case 'f':
	case 'F':
		// Foci
		set_sibling_next_command(new MGElpsFociTool(get_owner_command()));
		break;
	default:
		break;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGElpsCenAxesTool::OnLocated(const MGLocateInfo& info){
	const LInfoVec& linfos=locates();
	if(locates().size()<3){
		return false;
	}

	// 計算開始
	std::unique_ptr<MGEllipse> elps=makeModle(locates().back()->point_world());
	if(elps.get()){
		add_object_to_current_group(elps.release());
		return OnCommandEnd(1); // コマンド終了
	}
	// failed
	return OnCommandEnd(2);
}

void MGElpsCenAxesTool::prompt_message() const{
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	switch(np){
	case 0:
		SetStatusMessage(IDS_PROMPT_ELLIPSE_CENTER);
		break;
	case 1:
	case 2:
		SetStatusMessage(IDS_PROMPT_ELLIPSE_AXIS_NTH, np);
		break;
	}
}
