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

/**
 * @file CPlaneToObj.h
 * @brief クラス MGCPlaneToObjTool の宣言
 */
#if !defined(AFX_CPLANETOOBJ_H__0A0E6F27_2978_44A8_80E8_00E395A0B02D__INCLUDED_)
#define AFX_CPLANETOOBJ_H__0A0E6F27_2978_44A8_80E8_00E395A0B02D__INCLUDED_

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

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

/// @class MGCPlaneToObjTool CPlaneToObj.h "ViewCmd/CPlaneToObj.h"
///
/// Changes the construction plane so that it orients to given object.
class MGCPlaneToObjTool : public MGCommandStateOwner{
	friend class MGCPlaneToObjSObj;
public:
	explicit MGCPlaneToObjTool(fugenDoc* pDoc);
	explicit MGCPlaneToObjTool(fugenView* pView);

	virtual bool can_break_into() const{ return true;}
	virtual MGCommandBase* initial_clone(fugenDoc* pDoc)const;
	virtual bool initiate_tool();

private:
	fugenView*  m_pView; // 対象となるビュー
	MGPickObject m_obj;   // CPlane をフィットさせるオブジェクト
};

// 状態クラス

class MGCPlaneToObjSObj : public MGSelectState{
public:
	MGCPlaneToObjSObj(MGCommandStateOwner* owner);
	MGCPlaneToObjTool* state_owner(){
		return static_cast<MGCPlaneToObjTool*>(get_owner_command());
	}

	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).
		);
};

//Class to identify on an FSurface to make cplane.
class MGCPlaneToSurfaceIPoint:public MGLocateOnObjects{
public:

MGCPlaneToSurfaceIPoint(
	MGCommandStateOwner* owner,
	fugenView* pView, // 対象となるビュー
	const MGFSurface* f // CPlane をフィットさせる曲線
);

MGCPlaneToObjTool* state_owner(){
	return static_cast<MGCPlaneToObjTool*>(get_owner_command());
}

const MGCPlaneToObjTool* state_owner() const{
	return static_cast<const MGCPlaneToObjTool*>(get_owner_command());
}

virtual bool OnKeyDown(
	fugenView* pView,///<The fugenView pointer where this event took place.
	UINT nChar,	UINT nRepCnt, UINT nFlags
		///<These parameters are of CWnd::OnKeyDown. See the document.
);

virtual bool OnLocated(const MGLocateInfo& info);
virtual void do_make_temporary_display(mgSysGL& sgl,fugenView* pView);

private:

void compute_plane(MGPosition& org,MGVector& X,MGVector& Y);
void display(mgSysGL& sgl,fugenView* pView);
void prompt_message() const;

fugenView* m_pView; // 対象となるビュー
bool m_OnlyMove;///<true means do not rotate, only origin move.
const MGFSurface* m_f; // CPlane をフィットさせる曲面
MGPosition m_param; // m_f の ピック位置パラメータ
const MGColor* m_zColor;//Color of CPlane's normal.

//(m_alongU,m_CplaneKind) indicates how new cplane's direction is defined
//from the 3 vectors of the surface m_f:(Tu,Tv,N) where
//Tu=m_f->eval(.,1,0), Tv=m_f->eval(.,0,1) and N=Tu*Tv.
//Suppose (Tu, Tv, N) is orthonormal system. Then
//m_CplaneKind =0:(X,Y)=(Tv,N), =1: =(N,Tu), =2: =(Tu, Tv).
//Actually (Tu, Tv, N) is not orthonormal.
//So, if m_alongU=true, Tv is set as N*Tu 
//    if m_aloneU=false, Tu is set as Tv*N.
bool m_alongU;
int m_CplaneKind;

};

class MGCPlaneCurveIPoint : public MGLocateOnObjects{
public:

MGCPlaneCurveIPoint(
	MGCommandStateOwner* owner,
	fugenView* pView, // 対象となるビュー
	const MGCurve* curve // CPlane をフィットさせる曲線
);

virtual bool OnKeyDown(
	fugenView* pView,///<The fugenView pointer where this event took place.
	UINT nChar,	UINT nRepCnt, UINT nFlags
		///<These parameters are of CWnd::OnKeyDown. See the document.
);

virtual bool OnLocated(const MGLocateInfo& info);
virtual void do_make_temporary_display(mgSysGL& sgl,fugenView* pView);

private:

void compute_plane(MGPosition& org,MGVector& X,MGVector& Y);
void display(mgSysGL& sgl,fugenView* pView);
void prompt_message() const;

fugenView* m_pView; // 対象となるビュー
bool m_OnlyMove;///<true means do not rotate, only origin move.
const MGCurve* m_curve; // CPlane をフィットさせる曲線
double         m_param; // m_curve の ピック位置パラメータ

// 曲線の (T,N,B)ベクタからどのようにCPlaneを生成するか
int m_CplaneKind;//=0:normal to T, =1:to N, =2:B.
	//Here (T,N,B) is a Frenet frame.

const MGColor* m_zColor;//Color of CPlane's normal.

};

#endif // !defined(AFX_CPLANETOOBJ_H__0A0E6F27_2978_44A8_80E8_00E395A0B02D__INCLUDED_)
