/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file CurveSmoothingState.h
 * @brief MGCurveSmoothingTool クラスのインターフェイス
 */
#if !defined(AFX_CurveSmoothingState_H__C3E90891_2410_47F2_865E_1AE95B1AC9FC__INCLUDED_)
#define AFX_CurveSmoothingState_H__C3E90891_2410_47F2_865E_1AE95B1AC9FC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "mg/LBRep.h"
#include "Common/CommandStateOwner.h"
#include "Common/LocateOnObjects.h"
#include "Common/SelectState.h"

class CSmoothingDlg;

/// @class MGCurveSmoothingState CurveSmoothingState.h CurveCmd/CurveSmoothingState.h
///
/// Smooths a curve.
class MGCurveSmoothingState : public MGCommandStateOwner{
	friend class CSmoothingDlg;
	friend class MGCurveSmoothingIPoint;

public:
	explicit MGCurveSmoothingState(
		fugenDoc* pDoc	//the document
	);

	virtual MGCommandBase* initial_clone(fugenDoc* pDoc)const;
	virtual bool initiate_tool();
	virtual void do_make_temporary_display(mgSysGL& sgl,fugenView*);

	//set smoothing weight for parameter t 
	void set_weight(
		bool add,	//true if add weight, false if subtract weight.
		double t	//curve's parameter value.
	);

	//set weights for all the input parameter values.
	void set_weights();

	//set fix weight 
	void set_fix_weight(
		bool start	//true if start point is set to be fixed.
	);

// EVENT

	//Invoked when command is to terminate as a nomal end.
	virtual bool 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=true
	);

private:

	//set the smoothing curve data into the member variables.
	void set_member_data(MGPickObjects& pobjs);

private:
	MGCurve* m_original ;///< Original curve to smooth.
	std::unique_ptr<MGLBRep> m_tmp; // Current smoothed data.
	MGNDDArray m_tau; ///< data points abcissa of m_tmp.
	MGBPointSeq m_bp; ///< data points ordinates of m_tmp.
	std::vector<double> m_weight;  ///< m_weight[i] is the weight fro m_bp[i].
	std::vector<bool> m_adds; ///< m_adds[i] is add for the i-th input locate.

	friend class MGCurveSmoothingScurve;
	friend class MGCurveSmoothingIPoint;
};

//Smoothing curve selection class.
class MGCurveSmoothingScurve : public MGSelectState{
public:
	MGCurveSmoothingState* state_owner(){
		return static_cast<MGCurveSmoothingState*>(get_owner_command());
	}
	MGCurveSmoothingScurve(MGCommandStateOwner* owner);
	virtual bool initiate_tool();
	virtual bool 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).
	);
};

//Weight data for the smoothing input class.
class MGCurveSmoothingIPoint : public MGLocateOnObjects{
public:
	MGCurveSmoothingState* state_owner(){
		return static_cast<MGCurveSmoothingState*>(get_owner_command());
	}
	MGCurveSmoothingIPoint(MGCommandStateOwner* owner);
	virtual bool initiate_tool();

	//OnLocated will be invoked when a point is input.
	virtual bool OnLocated(const MGLocateInfo& linfo);

	/////////*********method for draw_temporary()*********//////////
	virtual void do_make_temporary_display(mgSysGL& sgl,fugenView*);

};

#endif // !defined(AFX_CurveSmoothingState_H__C3E90891_2410_47F2_865E_1AE95B1AC9FC__INCLUDED_)
