/*
* 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_URI_H__
#define __DAE_URI_H__

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

/**
 * The @c daeURI is a simple class designed to aid in the parsing and resolution
 * of URI references inside COLLADA elements.
 * A @c daeURI is created for every @c anyURL and @c IDREF in the COLLADA schema.
 * For example, the <instance> element has the url= attribute of type @c anyURL, and the 
 * <controller> element has the target= attribute of type @c IDREF.
 * The @c daeURI class contains a URI string; the @c set() method breaks the string into
 * its components including scheme, authority, path (directory), and fragment.
 * It also has the capability to attempt to resolve this reference
 * into a @c daeElement, through the method @c resolveElement().  
 * If a @c daeURI is stored within a @c daeElement, it fills
 * its container field to point to the containing element.
 *
 * The main API on the @c daeURI, @c resolveElement(), uses a @c daeURIResolver
 * to search for the @c daeElement inside a @c daeDatabase.
 *
 * URIs are resolved hierarchically, where each URI is resolved based on
 * the following criteria via itself and its element's base URI, which represents the
 * URI of the document that contains the element, retrieved by 
 * <tt>daeElement::getBaseURI().</tt>
 * If no base URI is provided, then the application URI
 * is used as a base.
 *
 * The URI resolution order for the COLLADA DOM is as follows:
 * - Absolute URI is specified (see definition below):
 *   The URI ignores its parent/base URI when validating. 
 * - Relative URI is specified:
 *   The URI uses the base URI to provide the scheme, authority, and base path.
 *    This URI's path is appended to the path given the the base URI.
 *    This URI's file and ID are used.
 * - Each level of URI is resolved in this way against the base URI of the
 *    containing file until the top level is reached.  Then the application URI
 *    is used as the default.
 *
 * <b>Definition of Absolute URI:</b>  
 * For the purposes of the COLLADA DOM, a URI is considered absolute
 * if it starts by specifying a scheme.
 * For example, 
 * - file:///c:/data/foo.dae#myScene is an absolute URI.
 * - foo.dae#myScene is relative.
 * - foo.dae is a top-level file reference and is relative.
 * If the URI does not include a pound sign (#), the <tt><i>fragment</i></tt> is empty.
 */
class DLLSPEC daeURI
{
private:
	daeElement* internalResolveElement() const;
	
public:
	/**
	 * An enum describing the status of the URI resolution process.
	 * This is pretty much entirely useless now. Just use the various accessors
	 * to query the state of the uri.
	 */
	enum ResolveState{
		/** No URI specified */
		uri_empty,
		/** URI specified but unresolved */
		uri_loaded,
		/** Resolution pending */
		uri_pending,
		/** Resolution successful */
		uri_success,
		/** Failure due to unsupported URI scheme */
		uri_failed_unsupported_protocol,
		/** Failure because the file was not found */
		uri_failed_file_not_found,
		/** Failure because the fragment was not found */
		uri_failed_id_not_found,
		/** Failure due to an invalid fragment */
		uri_failed_invalid_id,
		/** A flag specifying that the URI should be resolved locally to its own document */
		uri_resolve_local,
		/** A flag specifying that the URI should be resolved using this relative URI */
		uri_resolve_relative,
		/** A flag specifying that the URI should be resolved using this absolute URI */
		uri_resolve_absolute,
		/** Failure due to an invalid reference */
		uri_failed_invalid_reference,
		/** Failure due to an external error */
		uri_failed_externalization,
		/** Failure due to missing document */
		uri_failed_missing_container,
		/** Failure because automatic loading of a document is turned off */
		uri_failed_external_document
	};
	
private:
	// All daeURIs have a pointer to a master DAE that they use to access global information.
	mutable DAE* dae;
	
	/** Resolved version of the URI */
	std::string uriString;

	/** Original URI before resolution */
	std::string originalURIString;
	
	/** scheme component */
	std::string _scheme;
	/** authority component */
	std::string _authority;
	/** path component */
	std::string _path;
	/** query component */
	std::string _query;
	/** fragment component */
	std::string _fragment;
	/** Pointer to the element that owns this URI */
	daeElement* container;
	
public:
	/**
	 * Constructs a daeURI object that contains no URI reference.
	 * @param dae The DAE associated with this daeURI.
	 * current working directory.
	 */
	daeURI(DAE& dae);
	/**
	 * Destructor
	 */
	~daeURI();

	/**
	 * Constructs a daeURI object from a URI passed in as a string.
	 * @param dae The DAE associated with this daeURI.
	 * @param URIString Passed to set() automatically.
	 * @param nofrag If true, the fragment part of the URI is stripped off before construction.
	 */
	daeURI(DAE& dae, const std::string& URIString, daeBool nofrag = false);
	
	/**
	 * Constructs a daeURI object using a <tt><i>baseURI</i></tt> and a <tt><i>uriString.</i></tt> 
	 * Calls set(URIString), and @c validate(baseURI).
	 * @param baseURI Base URI to resolve against.
	 * @param URIString String designating this URI.
	 */
	daeURI(const daeURI& baseURI, const std::string& URIString);

	/**
	 * Constructs a daeURI object based on a simple copy from an existing @c daeURI. 
	 * @param constructFromURI  URI to copy into this one.
	 */
	daeURI(const daeURI& constructFromURI);

	/**
	 * Constructs a daeURI given a container element and a URI string.
	 * @param container The container element.
	 * @param uriString the URI string.
	 */
	daeURI(daeElement& container, const std::string& uriString = "");

	// This constructor is for internal DOM purposes only. For client code, use the constructor
	// that takes only a daeElement instead of this one.
	daeURI(DAE& dae, daeElement& container, const std::string& uriString = "");

	/**
	 * Gets the DAE objects associated with this daeURI.
	 * @return Returns a pointer to the associated DAE. This will never return null.
	 */
	DAE* getDAE() const;

	// Returns the fully resolved URI as a string
	const std::string& str() const;
	// Returns the URI as originally set (i.e. not resolved against the base URI)
	const std::string& originalStr() const;

	// Old C string versions of the previous functions
	daeString getURI() const; // Alias for str()
	daeString getOriginalURI() const; // Alias for originalStr();

	// Setter function for setting the full uri.
	void set(const std::string& uriStr, const daeURI* baseURI = NULL);
	// Setter function for setting the individual uri components.
	void set(const std::string& scheme,
	         const std::string& authority,
	         const std::string& path,
	         const std::string& query,
	         const std::string& fragment,
	         const daeURI* baseURI = NULL);

	// Old C string function. Alias for set().
	void setURI(daeString uriStr, const daeURI* baseURI = NULL);

	// std::string based component accessors.
	const std::string& scheme() const;
	const std::string& authority() const;
	const std::string& path() const;
	const std::string& query() const;
	const std::string& fragment() const;
	const std::string& id() const; // Alias for fragment()

	// Component setter functions. If you're going to be calling multiple setters, as in
	//   uri.path(path);
	//   uri.fragment(frag);
	// it'd be more efficient to call uri.set once instead.
	void scheme(const std::string& scheme);
	void authority(const std::string& authority);
	void path(const std::string& path);
	void query(const std::string& query);
	void fragment(const std::string& fragment);
	void id(const std::string& id); // Alias for uri.fragment(frag)
	
	// Retrieves the individual path components. For example, in a uri of the form
	// file:/folder/file.dae, dir = /folder/, baseName = file, ext = .dae
	void pathComponents(std::string& dir, std::string& baseName, std::string& ext) const;

	// Individual path component accessors. If you need access to multiple path
	// components, calling pathComponents() will be faster.
	std::string pathDir() const;      // daeURI("/folder/file.dae").pathDir() == "/folder/"
	std::string pathFileBase() const; // daeURI("/folder/file.dae").pathFileBase() == "file"
	std::string pathExt() const;      // daeURI("/folder/file.dae").pathExt() == ".dae"
	std::string pathFile() const;     // daeURI("/folder/file.dae").pathFile() == "file.dae"

	// Path component setter.
	void path(const std::string& dir, const std::string& baseName, const std::string& ext);

	// Individual path component setters. If you're going to be calling multiple setters,
	// it'd be more efficient to call set() instead.
	void pathDir(const std::string& dir);
	void pathFileBase(const std::string& baseName);
	void pathExt(const std::string& ext);
	void pathFile(const std::string& file);
	
	// The older C string accessors. Aliases for the std::string based component accessors.
	daeString getScheme() const;
	daeString getProtocol() const; // Alias for getScheme()
	daeString getAuthority() const;
	daeString getPath() const;
	daeString getQuery() const;
	daeString getFragment() const;
	daeString getID() const; // Alias for getFragment()
	// Same as getPath(), but puts the result in the destination buffer. This is only here
	// for backward compatibility. Use getPath() instead.
	daeBool getPath(daeChar* dest, daeInt size) const;

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

	// Returns the document that this URI references, or null if the document
	// hasn't been loaded yet.
	daeDocument* getReferencedDocument() const;
	
	/**
	 * Gets a pointer to the @c daeElement that contains this URI.
	 * @return Returns the pointer to the containing daeElmement.
	 */
	inline daeElement* getContainer() const {return(container);};

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

	/**
	 * Gets if this URI resolves to an element that is not contained in the same document as the URI.
	 * @return Returns true if the URI references an external element. False otherwise.
	 */
	daeBool isExternalReference() const;
	 
	/**
	 * Copies the URI specified in <tt><i>from</i></tt> into @c this.
	 * Performs a simple copy without validating the URI.
	 * @param from URI to copy from.
	 */
	void copyFrom(const daeURI& from);

	/**
	 * Outputs all components of this URI to stderr.
	 * Useful for debugging URIs, this outputs each part of the URI separately.
	 */
	void print();
	
	/**
	 * Makes the "originalURI" in this URI relative to some other uri
	 * @param uri the URI to make "this" relative to.
	 * @note this is experimental and not fully tested, please don't use in critical code yet.
	 */
	int makeRelativeTo(const daeURI* uri);

	/**
	 * Comparison operator.
	 * @return Returns true if URI's are equal.
	 */
	inline bool operator==(const daeURI& other) const {
		return uriString == other.uriString;
	}

	daeURI& operator=(const daeURI& other);
	daeURI& operator=(const std::string& uri);

	// These methods are deprecated.
	void resolveElement(); // Call getElement directly.
	void validate(const daeURI* baseURI = NULL); // Shouldn't ever need to call this.
	ResolveState getState() const; 	// Call getElement to see if resolving succeeded.
	void setState(ResolveState newState); // Don't call this.

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

	/**
	 * Provides a shared initialization for all constructors
	 */
	void initialize();
public:
	/**
	 * Performs RFC2396 path normalization.
	 * @param path Path to be normalized.
	 */
	static void normalizeURIPath(char* path);
};

class daeURIResolver;
typedef daeTArray<daeURIResolver*> daeURIResolverPtrArray;

/**
 * The @c daeURIResolver class is the plugin point for URI resolution.
 * This class is an abstract base class that defines an interface for
 * resolving URIs.
 * Every URI is passed through this list of @c daeURIResolvers for resolution.
 * The list is ordered on a first come, first serve basis, and resolution
 * terminates after any resolver instance resolves the URI.
 */
class DLLSPEC daeURIResolver
{
public:
	/**
	 * Constructor
	 * @param dae The associated dae object.
	 */
	daeURIResolver(DAE& dae);

	/**
	 * Destructor
	 */
	virtual ~daeURIResolver();
	
	/**
	 * Sets a flag that tells the URI resolver whether or not to load a separate document if a URI
	 * being resolved points to one.
	 * @param load Set to true if you want the URI Resolver to automatically load other documents to
	 * resolve URIs.
	 */
	static void setAutoLoadExternalDocuments( daeBool load );

	/**
	 * Gets a flag that tells if the URI resolver is set to load an external document if a URI
	 * being resolved points to one.
	 * @return Returns true if the resolver will automatically load documents to resolve a URI. 
	 * False otherwise.
	 */
	static daeBool getAutoLoadExternalDocuments();

	/**
	 * Provides an abstract interface for converting a @c daeURI into a @c daeElement
	 * @param uri @c daeURI to resolve.
	 * @return Returns the resolved element, or null if resolving failed.
	 * returns false otherwise.
	 */
	virtual daeElement* resolveElement(const daeURI& uri) = 0;

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

protected:
	static daeBool _loadExternalDocuments;
	DAE* dae;
};


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

	daeTArray<daeURIResolver*>& list();
	daeElement* resolveElement(const daeURI& uri);

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

	daeTArray<daeURIResolver*> resolvers;
};


// Helper functions for file path <--> URI conversion
namespace cdom {
	// Takes a uri reference and parses it into its components.
	DLLSPEC bool parseUriRef(const std::string& uriRef,
	                         std::string& scheme,
	                         std::string& authority,
	                         std::string& path,
	                         std::string& query,
	                         std::string& fragment);

	// Takes the uri components of a uri ref and combines them.
	//
	// The 'forceLibxmlCompatible' param is meant to work around bugs in the file
	// scheme uri handling of libxml. It causes the function to output a uri
	// that's fully compatible with libxml. It only modifies file scheme uris,
	// since uris with other schemes seem to work fine.
	//
	// The known libxml uri bugs are as follows:
	//   1) libxml won't write files when given file scheme URIs with an empty
	//      authority, as in "file:/home".
	//   2) libxml won't read or write Windows UNC paths represented with the
	//      machine name in the authority, as in "file://otherMachine/folder/file.dae"
	//   3) On Windows, libxml won't read or write paths that don't have a drive
	//      letter, as in "/folder/file.dae".
	DLLSPEC std::string assembleUri(const std::string& scheme,
	                                const std::string& authority,
	                                const std::string& path,
	                                const std::string& query,
	                                const std::string& fragment,
	                                bool forceLibxmlCompatible = false);

	// A wrapper function for calling assembleUri to create a URI that's compatible
	// with libxml.
	DLLSPEC std::string fixUriForLibxml(const std::string& uriRef);

	// This function takes a file path in the OS's native format and converts it to
	// a URI reference. If a relative path is given, a relative URI reference is
	// returned. If an absolute path is given, a relative URI reference containing 
	// a fully specified path is returned. Spaces are encoded as %20. The 'type'
	// parameter indicates the format of the nativePath.
	//
	// Examples - Windows
	//   nativePathToUri("C:\myFolder\myFile.dae") --> "/C:/myFolder/myFile.dae"
	//   nativePathToUri("\myFolder\myFile.dae") --> "/myFolder/myFile.dae"
	//   nativePathToUri("..\myFolder\myFile.dae") --> "../myFolder/myFile.dae"
	//   nativePathToUri("\\otherComputer\myFile.dae") --> "//otherComputer/myFile.dae"
	//
	// Examples - Linux/Mac
	//   nativePathToUri("/myFolder/myFile.dae") --> "/myFolder/myFile.dae"
	//   nativePathToUri("../myFolder/myFile.dae") --> "../myFolder/myFile.dae"
	//   nativePathToUri("/my folder/my file.dae") --> "/my%20folder/my%20file.dae"
	DLLSPEC std::string nativePathToUri(const std::string& nativePath,
	                                    systemType type = getSystemType());

	// This function takes a URI reference and converts it to an OS file path. Conversion
	// can fail if the URI reference is ill-formed, or if the URI contains a scheme other
	// than "file", in which case an empty string is returned. The 'type' parameter
	// indicates the format of the returned native path.
	//
	// Examples - Windows
	//   uriToNativePath("../folder/file.dae") --> "..\folder\file.dae"
	//   uriToNativePath("/folder/file.dae") --> "\folder\file.dae"
	//   uriToNativePath("file:/C:/folder/file.dae") --> "C:\folder\file.dae"
	//   uriToNativePath("file://otherComputer/file.dae") --> "\\otherComputer\file.dae"
	//   uriToNativePath("http://www.slashdot.org") --> "" (it's not a file scheme URI!)
	//
	// Examples - Linux/Mac
	//   uriToNativePath("../folder/file.dae") --> "../folder/file.dae"
	//   uriToNativePath("file:/folder/file.dae") --> "/folder/file.dae"
	//   uriToNativePath("http://www.slashdot.org") --> "" (it's not a file scheme URI!)
	DLLSPEC std::string uriToNativePath(const std::string& uriRef,
	                                    systemType type = getSystemType());

	DLLSPEC std::string filePathToUri(const std::string& filePath); // Alias for nativePathToUri
	DLLSPEC std::string uriToFilePath(const std::string& uriRef); // Alias for uriToNativePath
}

#endif //__DAE_URI_H__
