/*! \file pistringlist.h
 * \ingroup Text
 * \~\brief
 * \~english Based on \a PIDeque<PIString> strings list
 * \~russian Основанный на \a PIDeque<PIString> массив строк
 */
/*
    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"


//! \~\ingroup Text
//! \~\brief
//! \~english Based on \a PIDeque<PIString> strings list.
//! \~russian Основанный на \a PIDeque<PIString> массив строк.
class PIP_EXPORT PIStringList: public PIDeque<PIString> {
public:
	//! \~english Contructs an empty strings list
	//! \~russian Создает пустой список строк
	PIStringList() { ; }

	//! \~english Contructs strings list with one string "str"
	//! \~russian Создает список строк с одной строкой "str"
	PIStringList(const PIString & str) { push_back(str); }
	PIStringList(PIString && str) { push_back(std::move(str)); }

	//! \~english Contructs strings list with strings "s0" and "s1"
	//! \~russian Создает список строк со строками "s0" и "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));
	}

	//! \~english Contructs strings list with strings "s0", "s1" and "s2"
	//! \~russian Создает список строк со строками "s0", "s1" и "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));
	}

	//! \~english Contructs strings list with strings "s0", "s1", "s2" and "s3"
	//! \~russian Создает список строк со строками "s0", "s1", "s2" и "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));
	}

	//! \~english Contructs strings list with strings "o"
	//! \~russian Создает список строк со строками "o"
	PIStringList(const PIStringList & o): PIDeque<PIString>(o) {}
	PIStringList(PIStringList && o): PIDeque<PIString>(std::move(o)) {}

	//! \~english Contructs strings list with strings "o"
	//! \~russian Создает список строк со строками "o"
	PIStringList(const PIVector<PIString> & o): PIDeque<PIString>() {
		resize(o.size());
		for (uint i = 0; i < size(); ++i)
			(*this)[i] = o[i];
	}

	//! \~english Contructs strings list with strings "o"
	//! \~russian Создает список строк со строками "o"
	PIStringList(const PIDeque<PIString> & o): PIDeque<PIString>() {
		resize(o.size());
		for (uint i = 0; i < size(); ++i)
			(*this)[i] = o[i];
	}

	//! \~english Contructs strings list with strings "init_list" in std::initializer_list format
	//! \~russian Создает список строк со строками "init_list" в формате std::initializer_list
	PIStringList(std::initializer_list<PIString> init_list): PIDeque<PIString>(init_list) {}


	//! \~english Join all strings in one with delimiter "delim" and returns it
	//! \~russian Соединяет все строки в одну через разделитель "delim" и возвращает её
	PIString join(const PIString & delim) const;

	//! \~english Remove all strings equal "value" and returns reference to this
	//! \~russian Удаляет все строки равные "value" и возвращает ссылку на этот список строк
	PIStringList & removeStrings(const PIString & value);

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

	//! \~english Remove duplicated strings and returns reference to this
	//! \~russian Удаляет все дублированные строки и возвращает ссылку на этот список строк
	PIStringList & removeDuplicates();

	//! \~english Trim all strings and returns reference to this
	//! \~russian Подчищает у всех строк пробельные символы в начале и в конце и возвращает ссылку на этот список строк
	PIStringList & trim();

	//! \~english Returns sum of lengths of all strings
	//! \~russian Возвращает сумму длин всех строк
	uint contentSize() {
		uint s = 0;
		for (uint i = 0; i < size(); ++i)
			s += at(i).size();
		return s;
	}

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	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;
	}

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator!=(const PIStringList & o) const { return !(o == (*this)); }

	//! \~english Assign operator
	//! \~russian Оператор присваивания
	PIStringList & operator=(const PIStringList & o) {
		PIDeque<PIString>::operator=(o);
		return *this;
	}

	//! \~english Append string "str"
	//! \~russian Добавляет строку "str"
	PIStringList & operator<<(const PIString & str) {
		append(str);
		return *this;
	}
	PIStringList & operator<<(PIString && str) {
		append(std::move(str));
		return *this;
	}

	//! \~english Append strings list "sl"
	//! \~russian Добавляет список строк "sl"
	PIStringList & operator<<(const PIStringList & sl) {
		append(sl);
		return *this;
	}
};


//! \relatesalso PIBinaryStream
//! \~english Store operator.
//! \~russian Оператор сохранения.
BINARY_STREAM_WRITE(PIStringList) {
	s << static_cast<const PIDeque<PIString> &>(v);
	return s;
}

//! \relatesalso PIBinaryStream
//! \~english Restore operator.
//! \~russian Оператор извлечения.
BINARY_STREAM_READ(PIStringList) {
	s >> static_cast<PIDeque<PIString> &>(v);
	return s;
}


//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator<<(PICout s, const PIStringList & v) {
	s.space();
	s.saveAndSetControls(0);
	s << "{";
	for (uint i = 0; i < v.size(); ++i) {
		s << "\"" << v[i] << "\"";
		if (i < v.size() - 1) s << ", ";
	}
	s << "}";
	s.restoreControls();
	return s;
}

#endif // PISTRINGLIST_H
