// Copyright (C) 1996 DIMACS Center, Rutgers, The State University of New Jersey
// Author(s): Jonathan Berry

// This software is copyrighted by the DIMACS Center at Rutgers, The State
// University of New Jersey.  IT IS PROVIDED AS IS, AND THE AUTHORS, DIMACS, AND
// RUTGERS, THE STATE UNIVERSITY OF NEW JERSEY  DISCLAIM
// ALL LIABILITY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
// DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
// IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
// NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
// MODIFICATIONS.

// The authors hereby grant permission to use, copy, modify, distribute,
// and license this software and its documentation for any purpose, provided
// that existing copyright notices are retained in all copies and that this
// notice is included verbatim in any distributions. No written agreement,
// license, or royalty fee is required for any of the authorized uses.
// Modifications to this software may be copyrighted by their authors
// and need not follow the licensing terms described here, provided that
// the new terms are clearly indicated on the first page of each file where
// they apply.

// Last File Update: 31-Jul-1996
// 

#ifndef Sequence_h
#define Sequence_h

#include <LINK/basic/List.h>
#include <LINK/basic/Set.h>

template <class Item, class Impl=DEFAULT_SEQ_IMPL<Item> > 
class Sequence : public MSet<Item, Impl> {
public:
    Sequence();
    Sequence(const Sequence<Item, Impl>& s);
    Sequence(const Collection<Item>& c);
    Sequence(const Container<Item>& c);

    Sequence<Item,Impl>&	operator=(const Sequence<Item,Impl>& c);  
    //Sequence<Item,Impl>& 	copy(const Sequence<Item,Impl>& c) 
    //					{*this = c; return *this; 	}
    Sequence<Item,Impl>&	operator=(const Collection<Item>&c);
    DataType		type() const    { return SEQCOL;  		}

    void		insert(const Item e) 
				{ newSequence(this); store->insert(e);  }
    void		prepend(const Item e)
				{ newSequence(this); store->prepend(e); }
    void		append(const Item e) 
				{ newSequence(this); store->append(e);  }
    void		insertAfter(const Item e, const Item after_item);
    void		insertBefore(const Item e, const Item before_item);


    ostream&		display(ostream& os) const;
    
    //void		reverse();
    //void		swap(Item e1, Item e2);
    //Sequence	positions(Item e);  // return type seq<int>

    Item                      element (int i);
    Sequence<Item,Impl>   subsequence(int i, int j);
    int                       search(Sequence<Item,Impl>* str);
    Bool                      SBmemberQ(Sequence<Item,Impl>* str) 
                                { return (search(str)==-1 ? FALSE : TRUE); }
    Collection<Item>*   newEmpty() const 
				{return new Sequence<Item,Impl>; }

    //Sequence<Item,Impl>& insert(Item char, int pos)
    //Sequence<Item,Impl>& insert(Sequence<Item> str, int pos)

    //Sequence<Item,Impl>& replace(Item char, int pos)
    //Sequence<Item,Impl>& replace(Sequence<Item> str, int pos)

    //Sequence<Item,Impl>& remove(int i);
    //Sequence<Item,Impl>& remove(int i, int j);

    //Sequence<Item,Impl>& operator+(Sequence<Item,Impl>& str) 
    //                        { return union(str); }
    //Sequence<Item,Impl>& union(Sequence<Item,Impl>& str);


protected:
    void		newSequence(Sequence<Item,Impl>* s);
    void		newStore();
    //friend class CollectionWrapper<Item>;
};

//#ifdef DEFINE_Sequence_TEMPLATE
#include <LINK/basic/Sequence.cpp>
//#endif


#endif
