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

#include "mg/Position.h"
#include "mgGL/SnapPositions.h"

class fugenView;
class MGLocateInfo;
class MGObject;

//
//Define MGLocateInfo Class.
//MGLocateInfo is a class to get point data(locate).
//

using UniqueLinfo = std::unique_ptr<MGLocateInfo>;
using LInfoVec = std::vector<UniqueLinfo>;

//Class Declaration
class MGLocateInfo{

///Extracts point_world() data from linfos.
friend void extract_points_world(
	const LInfoVec& linfos, 
	std::vector<MGPosition>& ipos ///Extracted date will be output.
);

public:

//////////Constructor//////////

MGLocateInfo():m_snap_kind(MGSnapPositions::nopos),m_object(0),m_window(0){;}

/// Standard constructor.
MGLocateInfo(
	const MGPosition& pointWC,	///<World coordinate point data.
	MGSnapPositions::snap_kind snap_kind,///<input point kind.
	MGObject* object,
		///<When snap_kind is not nopos(i.e. nearpos, end, knot, vertex,
		///< near, center, or ON_SURFACE), the object pointer
		///<and the point's parameter value of the object is set.
		///<object is curve when end, knot, or near.
		///<object is fsurface when vertex, or ON_SURFACE.
		///<object is curve or fsurface when center.
	double t,

	const CPoint& pointSC,///<Screen coordinate whose origin is (left, top).
	fugenView* window=0
		///<The fugenView pointer where the location event took place.
		///<When the data was not input from fugenView, m_window=0 is set.
):m_pointWC(pointWC),m_snap_kind(snap_kind),m_object(object),
m_parameter(1,&t),
m_pointSC(pointSC),m_window(window){;}

/// Standard constructor 2.
MGLocateInfo(
	const MGPosition& pointWC,	///<World coordinate point data.
	MGSnapPositions::snap_kind snap_kind,//input point kind.
	MGObject* object,
		///<When snap_kind is not nopos(i.e. nearpos, end, knot, vertex,
		///< near, center, or ON_SURFACE), the object pointer
		///<and the point's parameter value of the object is set.
		///<object is curve when end, knot, or near.
		///<object is fsurface when vertex, or ON_SURFACE.
		///<object is curve or fsurface when center.
	const MGPosition param,

	const CPoint& pointSC,///<Screen coordinate whose origin is (left, top).
	fugenView* window=0
		///<The fugenView pointer where the location event took place.
		///<When the data was not input from fugenView, m_window=0 is set.
):m_pointWC(pointWC),m_snap_kind(snap_kind),m_object(object),
m_parameter(param),
m_pointSC(pointSC),m_window(window){;}


//////////Destructor//////////////
~MGLocateInfo(){;};

//////////Member Function//////////

///Test if this MGLocateInfo is MGSnapPositions::DELETE_POINT.
///Return true if DELETE_POINT.
bool is_deleted()const{
	return snap_kind()==MGSnapPositions::DELETE_POINT;
}

const MGPosition& point_world()const{return m_pointWC;};
MGPosition& point_world(){return m_pointWC;};

const CPoint& point_screen()const{return m_pointSC;};
CPoint& point_screen(){return m_pointSC;};

MGSnapPositions::snap_kind snap_kind()const{return m_snap_kind;};

const MGObject* object()const{return m_object;};
MGObject* object(){return m_object;};

///Return the parameter value of the locate point.
const MGPosition& parameter()const{return m_parameter;};
MGPosition& parameter(){return m_parameter;};
double curve_parameter()const{return m_parameter[0];};

fugenView* window()const{return m_window;};

private:

	MGPosition m_pointWC;	//World coordinate point data.

	MGSnapPositions::snap_kind m_snap_kind;//Located point kind.
	MGObject* m_object;
		//m_snap_kind is nearpos, end, or knot, the object pointer
		//and the point's parameter value m_parameter of the object are set.
		//When sk=center, only MGObject pointer will be set(no parameter).

	MGPosition m_parameter;//parameter value of m_object.
		//m_parameter.sdim() = m_object->manifold_dimension(),
		//if m_parameter is valid.

	
	CPoint m_pointSC;//Screen coordinate whose origin is (left, top).
	fugenView* m_window;
		//The fugenView pointer where the location event took place.
		//When the data was not input from fugenView, m_window=0 is set.

};

#endif
