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

#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "EvalCmd/EvalPointCurvatureTool.h"

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

// MGEvalCurvatureTool

MGEvalPointCurvatureTool::MGEvalPointCurvatureTool(fugenDoc* pDoc)
:MGLocateState(pDoc,ID_EVAL_RADIUS,NO_RUBBER,NO_IPDRAW),
 m_curve(0){
	turn_on_near();
	turn_on_end();
}

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

bool MGEvalPointCurvatureTool::initiate_tool(){
	MGLocateState::initiate_tool();
	clear_pick_object();

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

bool MGEvalPointCurvatureTool::OnCommandEnd(
	UINT nIDS,	//=0: erase the current message, and display no messages.
				//=1: display "xxxx" normally end.
				//otherwise: nIDS is a string id, and load the message from string table to display.
	bool erase_temporary_display
){
	if(!m_curve){
		// キャンセル
		return MGLocateState::OnCommandEnd(3);
	}

	draw_temporary(new MGEvalPointCurvatureToolSysGL(m_curve,m_param),false);
	// 描画したら終了
	return MGLocateState::OnCommandEnd(1,false);
}

bool MGEvalPointCurvatureTool::OnLocated(const MGLocateInfo& info){
	m_curve = dynamic_cast<const MGCurve*>(info.object());
	if(!m_curve){
		return false;
	}

	m_param = info.curve_parameter();
	return OnCommandEnd(1,false);
}

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

//Draw this Sysgl.
//This draw is used to draw the pictures for Undo(, Redo) operations.
void MGEvalPointCurvatureToolSysGL::drawSysGL(){
	const MGCurve* curve=dynamic_cast<const MGCurve*>(object_id());
	MGVector T, N, B;
	double curva, torsion;
	MGPosition val = curve->eval(m_param);
	double deriLen = curve->eval(m_param, 1).len();
	double axisLen = curve->param_e()-curve->param_s();
	axisLen *= deriLen*.3;//About 1/3 of curve length.
	curve->Frenet_frame(m_param, T, N, B, curva, torsion);
	T *= axisLen;
	N *= axisLen;
	B *= axisLen;

	MGColor::get_instance(MGColor::Cyan).exec(*this);
	drawPoint(val);

	MGColor::get_instance(MGColor::Red).exec(*this);
	drawStraight(val, val+T);
	MGColor::get_instance(MGColor::Green).exec(*this);
	drawStraight(val,val+N);
	MGColor::get_instance(MGColor::White).exec(*this);
	drawStraight(val, val+B);

	CString str;
	if(curva != 0.){
		str.Format(IDS_FORMAT_CURVATURE, curva, 1./curva, torsion);
	}else{
		str.Format(IDS_FORMAT_CURVATURE_INF, curva, torsion);
	}
	drawString(str, val, &MGColor::get_instance(MGColor::White));
}
