/*! \brief Strings array class
 * \details This class is based on \a PIDeque<PIString> and
 * expand it functionality. */
/*
	PIP - Platform Independent Primitives
	Strings array class
	Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PISTRINGLIST_H
#define PISTRINGLIST_H

#include "pistring.h"


class PIP_EXPORT PIStringList: public PIDeque<PIString>
{
public:

	//! Contructs empty strings list
	PIStringList() {;}

	~PIStringList() {;}

	//! Contructs strings list with one string "str"
	PIStringList(const PIString & str) {push_back(str);}
	PIStringList(PIString && str) {push_back(std::move(str));}

	//! Contructs empty strings list with strings "s0" and "s1"
	PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);}
	PIStringList(PIString && s0, PIString && s1) {push_back(std::move(s0)); push_back(std::move(s1));}

	//! Contructs empty strings list with strings "s0", "s1" and "s2"
	PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);}
	PIStringList(PIString && s0, PIString && s1, PIString && s2) {push_back(std::move(s0)); push_back(std::move(s1)); push_back(std::move(s2));}

	//! Contructs empty strings list with strings "s0", "s1", "s2" and "s3"
	PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
	PIStringList(PIString && s0, PIString && s1, PIString && s2, PIString && s3) {push_back(std::move(s0)); push_back(std::move(s1)); push_back(std::move(s2)); push_back(std::move(s3));}

	PIStringList(const PIStringList & o): PIDeque<PIString>(o) {}
	PIStringList(PIStringList && o): PIDeque<PIString>(std::move(o)) {}
	PIStringList(const PIVector<PIString> & o): PIDeque<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}
	PIStringList(const PIDeque<PIString> & o): PIDeque<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}

	//! Contructs strings list with std::initializer_list
	PIStringList(std::initializer_list<PIString> init_list): PIDeque<PIString>(init_list) {}


	//! \brief Join all strings in one with delimiter "delim" and return it
	//! \details Example: \snippet pistring.cpp PIStringList::join
	PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;}

	//! \brief Remove all strings equal "value" and return this
	//! \details Example: \snippet pistring.cpp PIStringList::removeStrings
	PIStringList & removeStrings(const PIString & value) {for (uint i = 0; i < size(); ++i) {if (at(i) == value) {remove(i); --i;}} return *this;}

	PIStringList & remove(uint num) {PIDeque<PIString>::remove(num); return *this;}
	PIStringList & remove(uint num, uint count) {PIDeque<PIString>::remove(num, count); return *this;}

	//! \brief Remove duplicated strings and return this
	//! \details Example: \snippet pistring.cpp PIStringList::removeDuplicates
	PIStringList & removeDuplicates();

	//! \brief Trim all strings
	//! \details Example: \snippet pistring.cpp PIStringList::trim
	PIStringList & trim() {for (uint i = 0; i < size(); ++i) (*this)[i].trim(); return *this;}

	//! Return sum of lengths of all strings
	uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}

	//! Compare operator
	bool operator ==(const PIStringList & o) const {if (size() != o.size()) return false; for (size_t i = 0; i < size(); ++i) if (o[i] != (*this)[i]) return false; return true;}

	//! Compare operator
	bool operator !=(const PIStringList & o) const {return !(o == (*this));}

	PIStringList & operator =(const PIStringList & o) {PIDeque<PIString>::operator=(o); return *this;}

	PIStringList & operator <<(const PIString & str) {append(str); return *this;}
	PIStringList & operator <<(PIString && str) {append(std::move(str)); return *this;}
	PIStringList & operator <<(const PIStringList & sl) {append(sl); return *this;}

};


//! \relatesalso PIStringList \relatesalso PIByteArray \brief Output operator to PIByteArray
inline PIByteArray & operator <<(PIByteArray & s, const PIStringList & v) {s << int(v.size_s()); for (int i = 0; i < v.size_s(); ++i) s << v[i]; return s;}

//! \relatesalso PIStringList \relatesalso PIByteArray \brief Input operator from PIByteArray
inline PIByteArray & operator >>(PIByteArray & s, PIStringList & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}

//! \relatesalso PIStringList \relatesalso PICout \brief Output operator to PICout
inline PICout operator <<(PICout s, const PIStringList & v) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < v.size(); ++i) {s << "\"" << v[i] << "\""; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}

#endif // PISTRINGLIST_H
