// ==================================================
// Copyright 2014.
// Siemens Product Lifecycle Management Software Inc.
// All Rights Reserved.
// ==================================================

/**
    @file
    This file contains definition for convenient C++ class to manage a list of tag_t.
*/


#ifndef BASE_UTILS_TCTAGLIST_HXX
#define BASE_UTILS_TCTAGLIST_HXX


#include <string>

#include <unidefs.h>
#include <base_utils/TcBaseTypes.hxx>
#include <base_utils/libbase_utils_exports.h>


/**
    @brief A convenient C++ class to manage a list of tag_t.
    This convenient class is derived from TagList class which is only available for internal developers.
*/


namespace Teamcenter
{

class BASE_UTILS_API TcTagList
{
public:

    /**
        Default constructor
    */
    TcTagList();

    /**
        tag_t array based constructor
    */
    TcTagList( int  n,  const tag_t *  tags );

    /**
        Single tag_t constructor
    */
    TcTagList( tag_t  a_tag );

    /**
        std::set based constructor
    */
    TcTagList( const std::set<tag_t>& );

    /**
        std::vector based constructor
    */
    TcTagList( const std::vector<tag_t>& tags );

    /**
        TagVector based constructor
        As TagVector does not use sm_allocator now, rather uses std::allocator
        it is same as std::vector<tag_t>, so no need of separate overloaded constructor
    */
    TcTagList( const Teamcenter::TagVector&  tagVector );

    /**
        Default destructor.
    */
    ~TcTagList();

    /**
        Single tag_t setter function
    */
    void  set( tag_t  a_tag );

    /**
        tag_t array based setter function
    */
    void  set( int  n,  const tag_t *  tags );

    /**
        std::set based setter function
    */
    void  set( const std::set<tag_t>& tags );

    /**
        TagVector based setter function
    */
    void  set( const Teamcenter::TagVector&  tagVector );

    /**
        tag_t based '=' operator overload. It sets a_tag as the list.
    */
    TcTagList &  operator=( tag_t  a_tag );

    /**
        TagVector based '=' operator overload. It sets tagVector as the list.
    */
    TcTagList &  operator=( const Teamcenter::TagVector &  tagVector );

    /**
        TcTagList based add function
    */
    void  add( const TcTagList &  tags );

    /**
        tag_t based add function
    */
    void  add( tag_t  a_tag );

    /**
        tag_t array based add function
    */
    void  add( int  n,  const tag_t *  tags );

    /**
        std::set based add function
    */
    void  add( const std::set<tag_t> &  tags  );

    /**
        std::vector based add function
    */
    void  add( const std::vector<tag_t> &  tags  );

    /**
        TagVector based add function
    */
    void  add( const Teamcenter::TagVector&  tagVector );

    /**
        TcTagList based '+=' operator overload.  It adds tags to the list.
    */
    TcTagList &  operator+=( const TcTagList&  tags );

    /**
        tag_t based '+=' operator overload. It adds a_tag to the list.
    */
    TcTagList &  operator+=( tag_t  a_tag );

    /**
        TagVector based '+=' operator overload. It adds tagVector to the list.
    */
    TcTagList &  operator+=( const Teamcenter::TagVector &  tagVector );

    /**
        Remove the tag at a given index from the list
    */
    void  remove( int  index );

    /**
        Remove a_tag from the list
    */
    void  remove( tag_t a_tag );

    /**
        Remove tagsToRemove from the list
    */
    void  remove( const TcTagList &  tagsToRemove );

    /**
        Replace the tag at a given index from the list with newTag.  Return the replaced tag
    */
    tag_t   replace( int index, const tag_t & newTag );

    /**
        Reverse the order of tags in the list
    */
    void  reverse();

    /**
        Remove duplicate tags from the list.
    */
    void  removeDuplicates();

    /**
        Remove tags that are not in the other list.
    */
    TcTagList& intersect ( const TcTagList & otherTags );

    /**
        Return the size of the list.
    */
    int  size() const;

    /**
        Return the index of the given tag.  If the tag is not found, return -1.
    */
    int  index( tag_t a_tag ) const;

    /**
        Return the content of the list in tag_t array format. Caller must free the array by using MEM_free
    */
    void  list( int *  n,  tag_t **  tags ) const;

    /**
        Return the content of the list in std::vector format
    */
    void  list( std::vector<tag_t>& v ) const;

    /**
        Return the index of the given tag.  If the tag is not found, return -1.
    */
    tag_t  at( int  index ) const;

    /**
        '[]' operator overload
    */
    tag_t  operator[]( int  index ) const;

    /**
        Check if the given tag is in the list.  If the tag is not found, return -1.
    */
    bool  contains( tag_t  tag ) const;

    /**
        Clear the list
    */
    void  clear();

    /**
        Reserve the size of the list to avoid memory allocation
    */
    void reserve( int n );

    /**
        Copies the contents of the input vector to directly output a SM allocated dynamic array of tag_t ( without using Tag or TagList or TcTagList ).
        Caller must free the tag_t array by MEM_free after use.
    */
    static void smTagArray(
        const Teamcenter::TagVector&    iVecTag,        /**< (I) Input vector of tag_t(s). */
        int*                            oTagArraySize,  /**< (O) Size of the dynamic array of tag_t(s). */
        tag_t**                         oTagArray       /**< (OF) Dynamic array of tag_t(s). */
        );

    /**
        Copies the contents of the input vector to directly output a SM allocated dynamic array of tag_t ( without using Tag or TagList or TcTagList ).
        Caller must free the tag_t array by MEM_free after use.
    */
    static void smTagArray(
        const std::vector<tag_t>&       iVecTag,        /**< (I) Input vector of tag_t(s). */
        int*                            oTagArraySize,  /**< (O) Size of the dynamic array of tag_t(s). */
        tag_t**                         oTagArray       /**< (OF) Dynamic array of tag_t(s). */
        );

    /**
        Copies the contents of the input set to directly output a SM allocated dynamic array of tag_t ( without using Tag or TagList or TcTagList ).
        Caller must free the tag_t array by MEM_free after use.
    */
    static void smTagArray(
        const std::set<tag_t>&          iSetTag,        /**< (I) Input set of tag_t(s). */
        int*                            oTagArraySize,  /**< (O) Size of the dynamic array of tag_t(s). */
        tag_t**                         oTagArray       /**< (OF) Dynamic array of tag_t(s). */
        );



private:

    /**
        The list
    */
    typedef Teamcenter::StdSmVector<tag_t>::Vector  DataType;
    DataType    m_data;
};

}


#include <base_utils/libbase_utils_undef.h>
#endif
