/* -*- mia-c++  -*-
 *
 * This file is part of MIA - a toolbox for medical image analysis 
 * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
 *
 * MIA is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MIA; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef SegSection_h
#define SegSection_h

#include <vector>
#include <string>

#include <mia/2d/segpoint.hh>
#include <mia/2d/boundingbox.hh>
#include <mia/2d/polygon.hh>

NS_MIA_BEGIN

/**
   @ingroup perf 
   \brief Segmentation class to represent a section of the LV myocardium 

   Structure to save the segmentation of a section of the myocardium. 
   In theory this can be used for any king of segmentation that uses 
   a polynom to approximate a segmented 2D shape. 
*/


class  EXPORT_2D CSegSection {
public:
	/// convenicence typedef for the points defining the section 
	typedef std::vector<CSegPoint2D> Points;
	
	/// default constructor 
	CSegSection();

	/**
	   Constructor to create a segmentation shape and naming it 
	   @param id ID of the section (and color identifier) 
	   @param points the points that define a closed polynom representing the shape 
	   @param is_open describes if points should be interpreted as polygon 
	   (i.e. the last point connects to the first), or as poly-line only.
	 */
	CSegSection(const std::string& id, const Points& points, bool is_open);

	/**
	   Constructor to create a segmentation shape based on a XML sub tree 
	   @param node root of the XML sub tree 
	   \param version segmentation set version the node stems from. 
	*/
	CSegSection(const CXMLElement& node, int version);

	/**
	   Store the segmented section into a XML sub-tree 
	   @param node parent node to which the subtree should be added 
	   \param version segmentation set version the node stems from. 
	*/
	void write(CXMLElement& node, int version) const;

	/// \returns the ID of the section 
	const std::string& get_id() const;

	/// \returns the list of the points defining the section shape 
	const Points& get_points()const;

	/// \returns the orthogonal bounding box enclosing the shape 
	const C2DBoundingBox get_boundingbox() const;

	/**
	   translate the segmentation by a given shift 
	   @param delta 
	 */
	void shift(const C2DFVector& delta);

	/**
	   Evaluate the Hausdorff distance between this shape and another one 
	   @param other 
	   @returns the Hausdorff distance
	 */
	float get_hausdorff_distance(const CSegSection& other) const;

	/**
	   Append this shape to another shape, a very crude version of a logical or 
	   @param polygon to add the shape to 
	*/
	void append_to(C2DPolygon& polygon)const;

	/**
	   transform the shape by transforming its individual points 
	   @param t the transformation to be applied 
	 */
	void transform(const C2DTransformation& t); 

	/**
	   transform the shape by transforming its individual points 
	   @param t the inverse of the transformation to be applied 
	 */
	void inv_transform(const C2DTransformation& t); 

	/**
	   Draw the shape to a 2D image with a given color 
	   @param output image to draw to 
	   @param color color to use 
	 */
	void draw(C2DUBImage& output, unsigned char color)const; 

	/**
	   Draw the binary shape to a 2D image by xor-ing with what is already in there 
	   @param output image to draw to 
	*/
	void draw_xor(C2DUBImage& output)const; 

	/// \returns whether the curve is open (true) or closed (false). 
	bool is_open() const; 

private:
	std::string m_id;
	Points m_points;
	bool m_is_open; 
};

NS_MIA_END

#endif
