/********************************************************************/
/* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
#ifndef _MGLCisect_vector_HH_
#define _MGLCisect_vector_HH_
/** @file */
/** @addtogroup IsectContainer
 *  @{
 */

#include <vector>
#include "topo/LCisect.h"

//Forward class declaration.
class MGCurve;
class MGLoop;
class MGInterval;

/// MGLCisect_vector defines linked list of MGLCisect.

/// Used to represent Intersection points of a loop and a curve.
class MG_DLL_DECLR MGLCisect_vector{

public:

typedef std::vector<MGLCisect>::iterator LCiterator;
typedef std::vector<MGLCisect>::const_iterator const_LCiterator;
typedef std::vector<MGLCisect>::iterator iterator;
typedef std::vector<MGLCisect>::const_iterator const_iterator;

public:

///String stream Function
MG_DLL_DECLR friend std::ostream& operator<< (std::ostream&, const MGLCisect_vector& );

/// Constructor
MGLCisect_vector();
MGLCisect_vector(const MGLoop& loop);		///Loop

// Operator overload.

const MGLCisect& operator[](int i)const{return m_lcisects[i];};
MGLCisect& operator[](int i){return m_lcisects[i];};

/// Member Function.

iterator begin(){return m_lcisects.begin();};
const_iterator begin()const{return m_lcisects.begin();};
iterator end(){return m_lcisects.end();};
const_iterator end()const{return m_lcisects.end();};

/// Adds the MGLCisect to the end of the list.
void append(const MGLCisect& lcisect);

void append(
	const MGLEPoint& lp,		///<loop's parameter with edge id.
	double t,				///<Curve's parameter value.
	const MGPosition& uv	///<Face's parameter value(u,v) data.
);

/// Adds the MGLCisect_vector to the end of the list.
void append(const MGLCisect_vector& list);

/// Return the number of items that are in the list.
int entries() const{return (int)m_lcisects.size();};

/// Return  the first element in the list.
/// If list is empty, behavior is undefined.
const MGLCisect& first() const{return m_lcisects.front();};

///Insert MGLCisect at the position i.
void insertAt(LCiterator i, const MGLCisect& lcisect)
{m_lcisects.insert(i, lcisect);};

///Return true if there are no items in the list, false otherwise.
bool empty() const{return m_lcisects.empty();};

/// Return(but does not remove) last element in the list.
/// If list is empty, behavior is undefined.
const MGLCisect& last() const{return m_lcisects.back();};

///Return the pointer to loop.
const MGLoop* loop() const {return m_loop;};

///Update MGLEPoint in this LCisect_vector.
///This is to update MGLEPoints in this obtained before MGLoop::make_vertex
///and the loop is updated by MGLoop::make_vertex.
///Generally speaking, when make_vertex is invoked after MGLCisect_vector is obtaind,
///the MGLEPoints in the MGLCisect_vector do not contain correct values, since
///a new edge is inserted int the MGComplex's cell vector.
void update_lepoint(
	const MGLEPoint& lep
);

private:
	std::vector<MGLCisect> m_lcisects;///<Vector of MGLCisect.
	const MGLoop* m_loop;
	double m_error_square;		///<Error square allowed to compute isect and 
								///<end point coincidence.

};

/** @} */ // end of IsectContainer group
#endif
