#ifndef	ANTLR3COLLECTIONS_HPP
#define	ANTLR3COLLECTIONS_HPP

// [The "BSD licence"]
// Copyright (c) 2005-2009 Gokulakannan Somasundaram, ElectronDB

//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include    "antlr3defs.hpp"

ANTLR_BEGIN_NAMESPACE()

/* -------------- TRIE Interfaces ---------------- */

/** Structure that holds the payload entry in an ANTLR3_INT_TRIE or ANTLR3_STRING_TRIE
 */
template< class ImplTraits, class DataType >
class TrieEntry : public ImplTraits::AllocPolicyType
{
public:
	typedef typename ImplTraits::AllocPolicyType AllocPolicy;

private:
	DataType			m_data;
	TrieEntry*			m_next;	    /* Allows duplicate entries for same key in insertion order	*/

public:
	TrieEntry(const DataType& data, TrieEntry* next);
	DataType& get_data();
	const DataType& get_data() const;
	TrieEntry* get_next() const;
	void set_next( TrieEntry* next );
};

/** Structure that defines an element/node in an ANTLR_INT_TRIE
 */
template< class ImplTraits, class DataType >
class IntTrieNode : public ImplTraits::AllocPolicyType
{
public:
	typedef TrieEntry<ImplTraits, DataType> TrieEntryType;
	typedef TrieEntryType BucketsType;
	
private:
    ANTLR_UINT32	m_bitNum;	/**< This is the left/right bit index for traversal along the nodes				*/
    ANTLR_INTKEY	m_key;		/**< This is the actual key that the entry represents if it is a terminal node  */
    BucketsType*	m_buckets;	/**< This is the data bucket(s) that the key indexes, which may be NULL			*/
    IntTrieNode*	m_leftN;	/**< Pointer to the left node from here when sKey & bitNum = 0					*/
    IntTrieNode*	m_rightN;	/**< Pointer to the right node from here when sKey & bitNum, = 1				*/

public:
	IntTrieNode();
	~IntTrieNode();

	ANTLR_UINT32 get_bitNum() const;
	ANTLR_INTKEY get_key() const;
	BucketsType* get_buckets() const;
	IntTrieNode* get_leftN() const;
	IntTrieNode* get_rightN() const;
	void  set_bitNum( ANTLR_UINT32 bitNum );
	void  set_key( ANTLR_INTKEY key );
	void  set_buckets( BucketsType* buckets );
	void  set_leftN( IntTrieNode* leftN );
	void  set_rightN( IntTrieNode* rightN );
};
  
/** Structure that defines an ANTLR3_INT_TRIE. For this particular implementation,
 *  as you might expect, the key is turned into a "string" by looking at bit(key, depth)
 *  of the integer key. Using 64 bit keys gives us a depth limit of 64 (or bit 0..63)
 *  and potentially a huge trie. This is the algorithm for a Patricia Trie.
 *  Note also that this trie [can] accept multiple entries for the same key and is
 *  therefore a kind of elastic bucket patricia trie.
 *
 *  If you find this code useful, please feel free to 'steal' it for any purpose
 *  as covered by the BSD license under which ANTLR is issued. You can cut the code
 *  but as the ANTLR library is only about 50K (Windows Vista), you might find it 
 *  easier to just link the library. Please keep all comments and licenses and so on
 *  in any version of this you create of course.
 *
 *  Jim Idle.
 *  
 */
class IntTrieBase
{
public:
	static const ANTLR_UINT8* get_bitIndex();
	static const ANTLR_UINT64* get_bitMask();
};
 
template< class ImplTraits, class DataType >
class IntTrie : public ImplTraits::AllocPolicyType, public IntTrieBase
{
public:
	typedef TrieEntry<ImplTraits, DataType> TrieEntryType;
	typedef IntTrieNode<ImplTraits, DataType> IntTrieNodeType;
	
private:
    IntTrieNodeType*	m_root;			/* Root node of this integer trie					*/
    IntTrieNodeType*	m_current;		/* Used to traverse the TRIE with the next() method	*/
    ANTLR_UINT32	m_count;			/* Current entry count								*/
    bool			m_allowDups;		/* Whether this trie accepts duplicate keys			*/

public:
	/* INT TRIE Implementation of depth 64 bits, being the number of bits
	 * in a 64 bit integer. 
	 */
    IntTrie( ANTLR_UINT32 depth );

	/** Search the int Trie and return a pointer to the first bucket indexed
	 *  by the key if it is contained in the trie, otherwise NULL.
	 */
    TrieEntryType*	get( ANTLR_INTKEY key);
    bool		del( ANTLR_INTKEY key);

	/** Add an entry into the INT trie.
	 *  Basically we descend the trie as we do when searching it, which will
	 *  locate the only node in the trie that can be reached by the bit pattern of the
	 *  key. If the key is actually at that node, then if the trie accepts duplicates
	 *  we add the supplied data in a new chained bucket to that data node. If it does
	 *  not accept duplicates then we merely return FALSE in case the caller wants to know
	 *  whether the key was already in the trie.
	 *  If the node we locate is not the key we are looking to add, then we insert a new node
	 *  into the trie with a bit index of the leftmost differing bit and the left or right 
	 *  node pointing to itself or the data node we are inserting 'before'. 
	 */
    bool		add( ANTLR_INTKEY key, const DataType& data );
    ~IntTrie();
};

/**
 * A topological sort system that given a set of dependencies of a node m on node n,
 * can sort them in dependency order. This is a generally useful utility object
 * that does not care what the things are it is sorting. Generally the set
 * to be sorted will be numeric indexes into some other structure such as an ANTLR3_VECTOR.
 * I have provided a sort method that given ANTLR3_VECTOR as an input will sort
 * the vector entries in place, as well as a sort method that just returns an
 * array of the sorted noded indexes, in case you are not sorting ANTLR3_VECTORS but
 * some set of your own device.
 *
 * Of the two main algorithms that could be used, I chose to use the depth first
 * search for unvisited nodes as a) This runs in linear time, and b) it is what
 * we used in the ANTLR Tool to perform a topological sort of the input grammar files
 * based on their dependencies.
 */
template<class ImplTraits>
class Topo : public ImplTraits::AllocPolicyType
{
public:
	typedef typename ImplTraits::BitsetType BitsetType;
	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;

private:
    /**
     * A vector of vectors of edges, built by calling the addEdge method()
     * to indicate that node number n depends on node number m. Each entry in the vector
     * contains a bitset, which has a bit index set for each node upon which the
     * entry node depends.
     */
    BitsetType**	m_edges;

    /**
     * A vector used to build up the sorted output order. Note that
     * as the vector contains UINT32 then the maximum node index is
     * 'limited' to 2^32, as nodes should be zero based.
     */
    ANTLR_UINT32*				m_sorted;

    /**
     * A vector used to detect cycles in the edge dependecies. It is used
     * as a stack and each time we descend a node to one of its edges we
     * add the node into this stack. If we find a node that we have already
     * visited in the stack, then it means there wasa cycle such as 9->8->1->9
     * as the only way a node can be on the stack is if we are currently
     * descnding from it as we remove it from the stack as we exit from
     * descending its dependencies
     */
    ANTLR_UINT32*		m_cycle;

    /**
     * A flag that indicates the algorithm found a cycle in the edges
     * such as 9->8->1->9
     * If this flag is set after you have called one of the sort routines
     * then the detected cycle will be contained in the cycle array and
     * cycleLimit will point to the one after the last entry in the cycle.
     */
    bool				m_hasCycle;

    /**
     * A watermark used to accumulate potential cycles in the cycle array.
     * This should be zero when we are done. Check hasCycle after calling one
     * of the sort methods and if it is true then you can find the cycle
     * in cycle[0]...cycle[cycleMark-1]
     */
    ANTLR_UINT32		m_cycleMark;
    
    /**
     * One more than the largest node index that is contained in edges/sorted.
     */
    ANTLR_UINT32		m_limit;

    /**
     * The set of visited nodes as determined by a set entry in
     * the bitmap.
     */
    BitsetType*			m_visited;

public:
	Topo();
    /**
     * A method that adds an edge from one node to another. An edge
     * of n -> m indicates that node n is dependent on node m. Note that
     * while building these edges, it is perfectly OK to add nodes out of
     * sequence. So, if you have edges:
     *
     * 3 -> 0
     * 2 -> 1
     * 1 -> 3
     *
     * The you can add them in that order and so add node 3 before nodes 2 and 1
     *
     */
    void  addEdge(ANTLR_UINT32 edge, ANTLR_UINT32 dependency);


    /**
     * A method that returns a pointer to an array of sorted node indexes.
     * The array is sorted in topological sorted order. Note that the array
     * is only as large as the largest node index you created an edge for. This means
     * that if you had an input of 32 nodes, but that largest node with an edge
     * was 16, then the returned array will be the sorted order of the first 16
     * nodes and the last 16 nodes of your array are basically fine as they are
     * as they had no dependencies and do not need any particular sort order.
     *
     * NB: If the structure that contains the array is freed, then the sorted
     * array will be freed too so you should use the value of limit to
     * make a long term copy of this array if you do not want to keep the topo
     * structure around as well.
     */
    ANTLR_UINT32*  sortToArray();

    /** 
     * A method that sorts the supplied ANTLR3_VECTOR in place based
     * on the previously supplied edge data.
     */
	template<typename DataType>
    void   sortVector( typename ImplTraits::template VectorType<DataType>& v);

	void   DFS(ANTLR_UINT32 node);

    /**
     *  A method to free this structure and any associated memory.
     */
	~Topo();
};

ANTLR_END_NAMESPACE()

#include "antlr3collections.inl"
    
#endif


