#ifndef H_CORAL_CORE_UTIL_UELEMENT
#define H_CORAL_CORE_UTIL_UELEMENT
// This file is part of the Coral project.
// Please read the copyright notice in the LICENSE file.

/*
 * Helper functions for the Element class, separated
 * here because they don't need to muck with the inner workings
 * of Element.
 */

#include <coral/coral.h>
#include <coral/core/Element.h>
#include <coral/lib/ref_counted.h>
#include <coral/core/Collection.h>

NAMESPACE_BEGIN(coral);
NAMESPACE_BEGIN(util);

/*
 * Returns itself and the list of parents
 * beginning from itself traversing upwards.
 */
coral::autounref<coral::OrderedSet>
Element__getMyselfAndParents__(const Element* e, bool includemyself = true);


/*
 * Returns the list of parents and itself
 * beginning from the topmost traversing downwards.
 */
coral::autounref<coral::OrderedSet>
Element__getParentsAndMyself__(const Element* e, bool includemyself = true);


/*
 * Maps x,y in XMI-DI GraphElement coordinates (origin at top-left of
 * the GraphElement) to global coordinates (origin at top-left of world)
 */
std::pair<double, double> XMIDI_LocalToGlobalPosition(const Element* e,
						      double x,
						      double y);

/*
 * Maps x,y in global coordinates (origin at top-left of world) to 
 * XMI-DI GraphElement coordinates (origin at top-left of the GraphElement) 
 */
std::pair<double, double> XMIDI_GlobalToLocalPosition(const Element* e,
						      double x,
						      double y);

/* Returns true if DiagramElement de's
 * semanticBridge is referential. This means that next container of
 * de references a semantic element that is not the parent of de's
 * referenced semantic element.
 *
 * i.e. in this case:
 * 
 *  parent  <-------- container
 *    |                  |
 *  child   <-------- contained (de)
 * 
 * Other situations return false.
 */

bool XMIDI_HasReferentialRole(const Element* de);

coral::Element*
XMIDI_find_property_upwards(coral::Element* e,
			    const std::string& propname);

coral::Element*
XMIDI_find_either_property_upwards(coral::Element* e,
				   const std::string& propname1,
				   const std::string& propname2);

#ifndef SWIG
/**
 * Returns name of element if it exists and is suitable
 */
const ElementString* Element__getName(const Element* e);
#endif

NAMESPACE_END();
NAMESPACE_END();

#endif
