/*
* Copyright 2006 Sony Computer Entertainment Inc.
*
* Licensed under the MIT Open Source License, for details please see license.txt or the website
* http://www.opensource.org/licenses/mit-license.php
*
*/ 

#ifndef __DAE_IDREF_H__
#define __DAE_IDREF_H__

#include <string>
#include <dae/daeTypes.h>
#include <dae/daeElement.h>
class DAE;

/**
 * The @c daeIDRef is a simple class designed to aid in the parsing and resolution of
 * ID references inside of COLLADA elements.
 * A @c daeIDRef is created for every IDREF data type in the COLLADA schema.
 * It also has the capability to attempt to resolve this reference
 * into a @c daeElement.  If a @c daeIDRef is stored within a @c daeElement it fills
 * in its container field to point to the containing element.
 *
 * The main API is the @c daeIDRef::resolveElement() will use a @c daeIDRefResolver
 * to search for the @c daeElement inside of a @c daeDatabase.
 *
 */
class DLLSPEC daeIDRef
{
public:
	/**
	 * An enum describing the status of the ID resolution process.
	 */
	enum ResolveState{
		/** No ID specified */
		id_empty,
		/** ID specified but not resolved */
		id_loaded,
		/** ID resolution pending */
		id_pending,
		/** ID resolved correctly */
		id_success,
		/** Resolution failed because ID was not found */
		id_failed_id_not_found,
		/** Resolution failed because ID was invalid */
		id_failed_invalid_id,
		/** Resoltion failed due to invalid reference */
		id_failed_invalid_reference,
		/** Resolution failed due to an external error */
		id_failed_externalization,
		/** Resolution failed because we don't have a document in which to search for the element.
				This means you probably forgot to set a container element. */
		id_failed_no_document
	};
	
private:
	/** ID used to refer to another element */
	std::string id;

	/** Element that owns this ID (if any) */
	daeElement* container;

public:
	/**
	 * Simple Constructor
	 */
	daeIDRef();

	/**
	 * Constructs an id reference via a string, using @c setID(); loads the status.
	 * @param id ID to construct a reference for, passed to @c setID() automatically.
	 */
	daeIDRef(daeString id);
	
	/**
	 * Constructs a new id reference by copying an existing one. 
	 * @param constructFromIDRef @c daeIDRef to copy into this one.
	 */
	daeIDRef(const daeIDRef& constructFromIDRef);

	/**
	 * Constructs an id reference with a container element
	 * @param container The container element.
	 */
	daeIDRef(daeElement& container);

	/**
	 * Gets the ID string
	 * @return Returns the full ID string from <tt><i>id.</i></tt> 
	 */
	daeString getID() const;

	/**
	 * Copies <tt><i>ID</i></tt> into the  <tt><i>id	</i></tt> data member.
	 * After the call to @c setID(), the <tt><i>state</i></tt> is set to @c id_loaded
	 * @param ID String to use to configure this @c daeIDRef.
	 */
	void setID(daeString ID);

	/** 
	 * Gets the element that this URI resolves to in memory.
	 * @return Returns a ref to the element.
	 */
	daeElement* getElement() const;

	/**
	 * Gets a pointer to the @c daeElement that contains this URI.
	 * @return Returns the pointer to the containing daeElmement.
	 */
	daeElement* getContainer() const;

	/**
	 * Sets the pointer to the @c daeElement that contains this URI.
	 * @param cont Pointer to the containing @c daeElmement.
	 */
	void setContainer(daeElement* cont);

	/**
	 * Outputs all components of this @c daeIDRef to stderr.
	 */
	void print();

	/**
	 * Resets this @c daeIDRef; frees all string references
	 * and returns <tt><i>state</i></tt> to @c empty.
	 */
	void reset();

	/**
	 * Initializes the @c daeIDREf, setting <tt><i>id, element,</i></tt>  and <tt><i>container</i></tt> to NULL.
	 */
	void initialize();

	/**
	 * Comparison operator.
	 * @return Returns true if URI's are equal.
	 */
	bool operator==(const daeIDRef& other) const;

	/**
	 * Assignment operator.
	 * @return Returns a reference to this object.
	 */
	daeIDRef &operator=( const daeIDRef& other);

	// These methods are only provided for backwards compatibility. Use the listed alternatives.
	daeIDRef &get( daeUInt idx ); // Never should have existed. No alternative.
	size_t getCount() const; // Never should have existed. No alternative.
	daeIDRef& operator[](size_t index); // Never should have existed. No alternative.
	void resolveElement( daeString typeNameHint = NULL ); // Call getElement. No separate "resolve" step needed.
	void resolveID(); // Never should have existed. No alternative.
	void validate(); // Never should have existed. No alternative.
	void copyFrom(const daeIDRef& from); // Use the assignment operator instead.
	ResolveState getState() const; // Never should have existed. No alternative.
};

/**
 * The @c daeIDRefResolver class is the plugin point for @c daeIDRef resolution.
 * This class is an abstract base class that defines an interface for
 * resolving @c daeIDRefs.
 */
class DLLSPEC daeIDRefResolver
{
public:
	/**
	 * Constructor
	 */
	daeIDRefResolver(DAE& dae);

	/**
	 * Destructor
	 */
	virtual ~daeIDRefResolver();
	
	/**
	 * Provides an abstract interface to convert a @c daeIDRef into a @c daeElement.
	 * @param id The ID of the element to find.
	 * @param doc The document containing the element.
	 * @return Returns a daeElement with matching ID, if one is found.
	 */
	virtual daeElement* resolveElement(const std::string& id, daeDocument* doc) = 0;
	                                   

	/**
	 * Gets the name of this resolver.
	 * @return Returns the string name.
	 */
	virtual daeString getName() = 0;

protected:
	DAE* dae;
};


/**
 * The @c daeDefaultIDRefResolver resolves a @c daeIDRef by checking with a database.
 * It is a concrete implementation for @c daeIDRefResolver.
 */
class DLLSPEC daeDefaultIDRefResolver : public daeIDRefResolver
{
public:
	daeDefaultIDRefResolver(DAE& dae);
	~daeDefaultIDRefResolver();
	virtual daeElement* resolveElement(const std::string& id, daeDocument* doc);
	virtual daeString getName();
};


// This is a container class for storing a modifiable list of daeIDRefResolver objects.
class DLLSPEC daeIDRefResolverList {
public:
	daeIDRefResolverList();
	~daeIDRefResolverList();

	void addResolver(daeIDRefResolver* resolver);
	void removeResolver(daeIDRefResolver* resolver);

	daeElement* resolveElement(const std::string& id, daeDocument* doc);

private:
	// Disabled copy constructor/assignment operator
	daeIDRefResolverList(const daeIDRefResolverList& resolverList) { };
	daeIDRefResolverList& operator=(const daeIDRefResolverList& resolverList) { return *this; };

	daeTArray<daeIDRefResolver*> resolvers;
};


#endif //__DAE_IDREF_H__
