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

// EvalSnapPointsTool.cpp: MGEvalSnapPointsTool クラスのインプリメンテーション

#include "stdafx.h"
#include "mgGL/SnapPositions.h"
#include "fugenView.h"
#include "EvalCmd/EvalSnapPointsTool.h"

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

// MGEvalSnapPointsTool

MGEvalSnapPointsTool::MGEvalSnapPointsTool(fugenDoc* pDoc)
:MGSelectState(pDoc,ID_EVAL_SNAP_DISPLAY_ON,MULTIPLE_SELECT,mgAll_Object){}

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

void MGEvalSnapPointsTool::draw_snaps(
		const MGPickObjects& objs
){
	size_t n=objs.size();
	for(size_t i=0; i<n; i++){
		const MGGel* gel=objs[i].top_object();
		erase_temporary(gel,false);
		draw_temporary(new MGEvalSnapPointsToolSysGL(gel,document()->getSnapAttr()),false,false);
	}
	InvalidateAllStdViews();
}

bool MGEvalSnapPointsTool::initiate_tool(){
	MGSelectState::initiate_tool();
	const MGPickObjects& cobjs=current_objects();
	if(is_breaking_command()){
		draw_snaps(cobjs);
		return true;
	}
	if(resetCurrentObjects(mgAll_Object))
		draw_snaps(cobjs);

	// Selection message.
	SetStatusMessage(IDS_PROMPT_OBJECT);
	return false;
}

bool MGEvalSnapPointsTool::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
){
	return MGSelectState::OnCommandEnd(1,false);//Curvature display stays displayed.
}

bool MGEvalSnapPointsTool::OnSelected(
	fugenView* window,//The fugenView pointer where point input event took place.
	MGPickObjects&	selected_objects,	//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).
){
	if(unselected_objects.size()){
		size_t n=unselected_objects.size();
		for(size_t i=0; i<n; i++){
			erase_temporary(unselected_objects[i].top_object());
		}
	}else{
		draw_snaps(selected_objects);
	}
	return false;
}

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

//Draw this Sysgl.
//This draw is used to draw the pictures for Undo(, Redo) operations.
void MGEvalSnapPointsToolSysGL::drawSysGL(){
	const MGGel& picked = *object_id();
	std::vector<MGPosition> snappoints;
	
	if(m_snap_attrib.getCenter()){
		MGSnapPositions centers(MGSnapPositions::centerpos);
		centers.extract(picked);
		centers.append_position_data(snappoints);
	}
	if(m_snap_attrib.getEnd()){
		MGSnapPositions ends(MGSnapPositions::endpos);
		ends.extract(picked);
		ends.append_position_data(snappoints);
	}
	if(m_snap_attrib.getKnot()){
		MGSnapPositions knts(MGSnapPositions::knotpos);
		knts.extract(picked);
		knts.append_position_data(snappoints);
	}
	if(m_snap_attrib.getVertex()){
		MGSnapPositions verteices(MGSnapPositions::vertexpos);
		verteices.extract(picked);
		verteices.append_position_data(snappoints);
	}

	if(snappoints.empty())
		return;

	MGColor::get_instance(MGColor::Magenta).exec(*this);
	std::vector<MGPosition>::iterator i=snappoints.begin(), ie=snappoints.end();
	for(; i!=ie; i++){
		drawPoint((*i)[0], (*i)[1], (*i)[2]);
	}
}
