/*
 * PrefixRankedPattern.h
 *
 *  Created on: Nov 23, 2013
 *      Author: Jan Travnicek
 */

#ifndef PREFIX_RANKED_PATTERN_H_
#define PREFIX_RANKED_PATTERN_H_

#include <set>
#include <vector>

#include "../../alphabet/RankedSymbol.h"
#include "../TreeBase.h"
#include "../common/RankedPatternAlphabet.h"

namespace tree {

class RankedPattern;

/**
 * Represents regular expression parsed from the XML. Regular expression is stored
 * as a tree of LinearStringElement.
 */
class PrefixRankedPattern : public TreeBase, public RankedPatternAlphabet {
	std::vector<alphabet::RankedSymbol> m_Data;

public:
	explicit PrefixRankedPattern(alphabet::RankedSymbol subtreeWildcard, std::set<alphabet::RankedSymbol> alphabet, std::vector<alphabet::RankedSymbol> data);
	explicit PrefixRankedPattern(alphabet::RankedSymbol subtreeWildcard, std::vector<alphabet::RankedSymbol> data);
	explicit PrefixRankedPattern(const RankedPattern& tree);

	virtual TreeBase* clone() const;
	virtual TreeBase* plunder() &&;

	virtual bool removeSymbolFromAlphabet(const alphabet::RankedSymbol & symbol);

	/**
	 * @return List of symbols forming tree (const version).
	 */
	const std::vector<alphabet::RankedSymbol>& getContent() const;

	void setContent(std::vector<alphabet::RankedSymbol> data);

	void arityChecksum(const std::vector<alphabet::RankedSymbol>& data);
	/**
	 * @return true if tree is an empty word (vector length is 0)
	 */
	bool isEmpty() const;

	virtual int compare(const ObjectBase& other) const {
		return ObjectBase::compare(*this, other);
	}

	virtual int compare(const PrefixRankedPattern& other) const;

	virtual void operator >>(std::ostream& out) const;

	virtual explicit operator std::string() const;

	virtual long long selfTypeId() const {
		return typeId(*this);
	}

	const static std::string XML_TAG_NAME;

	static PrefixRankedPattern parse(std::deque<sax::Token>::iterator& input);

	void compose(std::deque<sax::Token>& out) const;
};

} /* namespace tree */

namespace std {

template<>
struct compare<::tree::PrefixRankedPattern> {
	int operator()(const ::tree::PrefixRankedPattern& first, const ::tree::PrefixRankedPattern& second) const {
		return first.compare(second);
	}
};

} /* namespace std */

#endif /* PREFIX_RANKED_PATTERN_H_ */