/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
// EvalDistanceTool.cpp: MGEvalDistanceTool クラスのインプリメンテーション

#include "stdafx.h"
#include "Calc/distance.h"
#include "fugenView.h"
#include "EvalCmd/EvalDistanceTool.h"

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

// MGEvalDistanceTool

MGEvalDistanceTool::MGEvalDistanceTool(fugenDoc* pDoc)
	 : MGSelectState(pDoc,ID_EVAL_DISTANCE,MGSelectState::SINGLE_SELECT)
{
}

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

bool MGEvalDistanceTool::initiate_tool(){
	MGSelectState::initiate_tool();

	const MGPickObjects& pobjs=current_objects();
	size_t npicked=pobjs.size();

	// 1 or 2
	if(npicked >= 2){
		const MGObject* obj1=pobjs[0].top_object();
		const MGObject* obj2=pobjs[1].top_object();
		MGEvalDistanceSysGL* sysgl=new MGEvalDistanceSysGL(obj1,obj2);
		draw_temporary(sysgl);
		return OnCommandEnd(1,false);
	}

	if(is_breaking_command())
		return true;

	set_add_mode();
	SetStatusMessage(IDS_PROMPT_OBJECT_NTH, npicked+1);
	return false;
}

bool MGEvalDistanceTool::OnSelected(
	fugenView* window,//The fugenView pointer where point input event took place.
	MGPickObjects&	objs,	//selected objects at this selection operation.
	MGPickObjects&	unselected_objects	//unselected objects at this selection operation.
		//unselected_objects.size()>=1 only when the already selected objects are selected
		//when add mode is set(or when operation is done with a crtl key pressed).
){
	const MGPickObjects& pobjs=current_objects();
	size_t npicked=pobjs.size();

	// 1 or 2
	if(npicked >= 2){
		const MGObject* obj1=pobjs[0].top_object();
		const MGObject* obj2=pobjs[1].top_object();
		MGEvalDistanceSysGL* sysgl=new MGEvalDistanceSysGL(obj1,obj2);
		draw_temporary(sysgl);
		return OnCommandEnd(1,false);
	}

	SetStatusMessage(IDS_PROMPT_OBJECT_NTH, npicked+1);
	return false;
}

MGEvalDistanceSysGL::MGEvalDistanceSysGL(
	const MGObject* obj1,
	const MGObject* obj2
):mgSys2GL(ID_EVAL_DISTANCE,obj1,obj2){;}

//Construct new object by copying to newed area.
//User must delete this copied object by "delete".
mgSysGL* MGEvalDistanceSysGL::clone()const{
	return new MGEvalDistanceSysGL(*this);
}

//Draw this Sysgl.
//This draw is used to draw the pictures for Undo(, Redo) operations.
void MGEvalDistanceSysGL::drawSysGL()
{
	MGPosition pos1, pos2;
	double d;
	if(!mgcalc::distance(*object1(), *object2(), d, pos1, pos2)){
		// failure
		return;
	}

	CString str;
	str.Format(IDS_FORMAT_DISTANCE, d);

	const MGPosition& posm = (pos1 + pos2) * .5;
	const MGColor& clr1 = MGColor::get_instance(MGColor::Magenta);
	const MGColor& clr2 = MGColor::get_instance(MGColor::Cyan);
	const MGColor& clrm = MGColor::get_instance(MGColor::White);

	clr1.exec(*this);
	drawPoint(pos1[0], pos1[1], pos1[2]);
	clr2.exec(*this);
	drawPoint(pos2[0], pos2[1], pos2[2]);

	Begin(GL_LINE_STRIP);
		Color(clr1);
		Vertex3dv(pos1.data());
		Color(clrm);
		Vertex3dv(posm.data());
		Color(clr2);
		Vertex3dv(pos2.data());
	End();

	drawString(str, posm);
}
