/*
 * Copyright (C) 2014-2021 CZ.NIC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#pragma once

#include <QDate>
#include <QDateTime>
#include <QList>
#include <QPair>
#include <QScopedPointer>
#include <QString>

#include "src/datovka_shared/isds/types.h"

/*
 * Structures originating from pril_3/WS_ISDS_Sprava_datovych_schranek.pdf.
 */

namespace Isds {

	class BirthInfo; /* Forward declaration. */

	class AddressExt2Private;
	/*!
	 * @brief Exists as address element group gAddressExt2 (dbTypes.xsd).
	 *     // DbOwnerInfoExt2, DbUserInfoExt2
	 */
	class AddressExt2 {
		Q_DECLARE_PRIVATE(AddressExt2)

	public:
		AddressExt2(void);
		AddressExt2(const AddressExt2 &other);
#ifdef Q_COMPILER_RVALUE_REFS
		AddressExt2(AddressExt2 &&other) Q_DECL_NOEXCEPT;
#endif /* Q_COMPILER_RVALUE_REFS */
		~AddressExt2(void);

		AddressExt2 &operator=(const AddressExt2 &other) Q_DECL_NOTHROW;
#ifdef Q_COMPILER_RVALUE_REFS
		AddressExt2 &operator=(AddressExt2 &&other) Q_DECL_NOTHROW;
#endif /* Q_COMPILER_RVALUE_REFS */

		bool operator==(const AddressExt2 &other) const;
		bool operator!=(const AddressExt2 &other) const;

		friend void swap(AddressExt2 &first, AddressExt2 &second) Q_DECL_NOTHROW;

		bool isNull(void) const;

		/* adCode -- RUIAN address code */
		const QString &code(void) const;
		void setCode(const QString &co);
#ifdef Q_COMPILER_RVALUE_REFS
		void setCode(QString &&co);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adCity */
		const QString &city(void) const;
		void setCity(const QString &c);
#ifdef Q_COMPILER_RVALUE_REFS
		void setCity(QString &&c);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adDistrict */
		const QString &district(void) const;
		void setDistrict(const QString &di);
#ifdef Q_COMPILER_RVALUE_REFS
		void setDistrict(QString &&di);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adStreet */
		const QString &street(void) const;
		void setStreet(const QString &s);
#ifdef Q_COMPILER_RVALUE_REFS
		void setStreet(QString &&s);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adNumberInStreet */
		const QString &numberInStreet(void) const;
		void setNumberInStreet(const QString &nis);
#ifdef Q_COMPILER_RVALUE_REFS
		void setNumberInStreet(QString &&nis);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adNumberInMunicipality */
		const QString &numberInMunicipality(void) const;
		void setNumberInMunicipality(const QString &nim);
#ifdef Q_COMPILER_RVALUE_REFS
		void setNumberInMunicipality(QString &&nim);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adZipCode */
		const QString &zipCode(void) const;
		void setZipCode(const QString &zc);
#ifdef Q_COMPILER_RVALUE_REFS
		void setZipCode(QString &&zc);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adState */
		const QString &state(void) const;
		void setState(const QString &s);
#ifdef Q_COMPILER_RVALUE_REFS
		void setState(QString &&s);
#endif /* Q_COMPILER_RVALUE_REFS */

	private:
		QScopedPointer<AddressExt2Private> d_ptr; // ::std::unique_ptr ?
	};

	void swap(AddressExt2 &first, AddressExt2 &second) Q_DECL_NOTHROW;

	class PersonName2Private;
	/*!
	 * @brief Exists as name element group gPersonName2 (dbTypes.xsd).
	 *     // DbOwnerInfoExt2, DbUserInfoExt2
	 *
	 * pril_3/WS_ISDS_Sprava_datovych_schranek.pdf (section 1.6)
	 */
	class PersonName2 {
		Q_DECLARE_PRIVATE(PersonName2)

	public:
		PersonName2(void);
		PersonName2(const PersonName2 &other);
#ifdef Q_COMPILER_RVALUE_REFS
		PersonName2(PersonName2 &&other) Q_DECL_NOEXCEPT;
#endif /* Q_COMPILER_RVALUE_REFS */
		~PersonName2(void);

		PersonName2 &operator=(const PersonName2 &other) Q_DECL_NOTHROW;
#ifdef Q_COMPILER_RVALUE_REFS
		PersonName2 &operator=(PersonName2 &&other) Q_DECL_NOTHROW;
#endif /* Q_COMPILER_RVALUE_REFS */

		bool operator==(const PersonName2 &other) const;
		bool operator!=(const PersonName2 &other) const;

		friend void swap(PersonName2 &first, PersonName2 &second) Q_DECL_NOTHROW;

		bool isNull(void) const;

		/* pnGivenNames */
		const QString &givenNames(void) const;
		void setGivenNames(const QString &gn);
#ifdef Q_COMPILER_RVALUE_REFS
		void setGivenNames(QString &&gn);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* pnLastName */
		const QString &lastName(void) const;
		void setLastName(const QString &ln);
#ifdef Q_COMPILER_RVALUE_REFS
		void setLastName(QString &&ln);
#endif /* Q_COMPILER_RVALUE_REFS */

	private:
		QScopedPointer<PersonName2Private> d_ptr; // ::std::unique_ptr ?
	};

	void swap(PersonName2 &first, PersonName2 &second) Q_DECL_NOTHROW;

	class DbOwnerInfoExt2Private;
	/*!
	 * @brief Exists as type tDbOwnerInfoExt2 (dbTypes.xsd).
	 *
	 * pril_3/WS_ISDS_Sprava_datovych_schranek.pdf (section 1.6.1)
	 */
	class DbOwnerInfoExt2 {
		Q_DECLARE_PRIVATE(DbOwnerInfoExt2)

	public:
		DbOwnerInfoExt2(void);
		DbOwnerInfoExt2(const DbOwnerInfoExt2 &other);
#ifdef Q_COMPILER_RVALUE_REFS
		DbOwnerInfoExt2(DbOwnerInfoExt2 &&other) Q_DECL_NOEXCEPT;
#endif /* Q_COMPILER_RVALUE_REFS */
		~DbOwnerInfoExt2(void);

		DbOwnerInfoExt2 &operator=(const DbOwnerInfoExt2 &other) Q_DECL_NOTHROW;
#ifdef Q_COMPILER_RVALUE_REFS
		DbOwnerInfoExt2 &operator=(DbOwnerInfoExt2 &&other) Q_DECL_NOTHROW;
#endif /* Q_COMPILER_RVALUE_REFS */

		bool operator==(const DbOwnerInfoExt2 &other) const;
		bool operator!=(const DbOwnerInfoExt2 &other) const;

		friend void swap(DbOwnerInfoExt2 &first, DbOwnerInfoExt2 &second) Q_DECL_NOTHROW;

		bool isNull(void) const;

		/* dbID */
		const QString &dbID(void) const;
		void setDbID(const QString &bi);
#ifdef Q_COMPILER_RVALUE_REFS
		void setDbID(QString &&bi);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* aifoIsds */
		enum Type::NilBool aifoIsds(void) const;
		void setAifoIsds(enum Type::NilBool ai);
		/* dbType */
		enum Type::DbType dbType(void) const;
		void setDbType(enum Type::DbType bt);
		/* ic */
		const QString &ic(void) const;
		void setIc(const QString &ic);
#ifdef Q_COMPILER_RVALUE_REFS
		void setIc(QString &&ic);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* pnGivenNames, pnLastName */
		const PersonName2 &personName(void) const;
		void setPersonName(const PersonName2 &pn);
#ifdef Q_COMPILER_RVALUE_REFS
		void setPersonName(PersonName2 &&pn);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* firmName */
		const QString &firmName(void) const;
		void setFirmName(const QString &fn);
#ifdef Q_COMPILER_RVALUE_REFS
		void setFirmName(QString &&fn);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* biDate, biCity, biCounty, biState */
		const BirthInfo &birthInfo(void) const;
		void setBirthInfo(const BirthInfo &bi);
#ifdef Q_COMPILER_RVALUE_REFS
		void setBirthInfo(BirthInfo &&bi);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adCode, adCity, adDistrict, adStreet, adNumberInStreet, adNumberInMunicipality, adZipCode, adState */
		const AddressExt2 &address(void) const;
		void setAddress(const AddressExt2 &a);
#ifdef Q_COMPILER_RVALUE_REFS
		void setAddress(AddressExt2 &&a);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* Nationality */
		const QString &nationality(void) const;
		void setNationality(const QString &n);
#ifdef Q_COMPILER_RVALUE_REFS
		void setNationality(QString &&n);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* dbIdOVM */
		const QString &dbIdOVM(void) const;
		void setDbIdOVM(const QString &io);
#ifdef Q_COMPILER_RVALUE_REFS
		void setDbIdOVM(QString &&io);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* dbState */
		enum Type::DbState dbState(void) const;
		void setDbState(enum Type::DbState bs);
		/* dbOpenAddressing */
		enum Type::NilBool dbOpenAddressing(void) const;
		void setDbOpenAddressing(enum Type::NilBool oa);
		/* dbUpperID */
		const QString &dbUpperID(void) const;
		void setDbUpperID(const QString &ui);
#ifdef Q_COMPILER_RVALUE_REFS
		void setDbUpperID(QString &&ui);
#endif /* Q_COMPILER_RVALUE_REFS */

	private:
		QScopedPointer<DbOwnerInfoExt2Private> d_ptr; // ::std::unique_ptr ?
	};

	void swap(DbOwnerInfoExt2 &first, DbOwnerInfoExt2 &second) Q_DECL_NOTHROW;

	class DbUserInfoExt2Private;
	/*!
	 * @brief Exists as type tDbUserInfoExt2 (dbTypes.xsd).
	 *
	 * pril_3/WS_ISDS_Sprava_datovych_schranek.pdf (section 1.6.2)
	 */
	class DbUserInfoExt2 {
		Q_DECLARE_PRIVATE(DbUserInfoExt2)

	public:
		DbUserInfoExt2(void);
		DbUserInfoExt2(const DbUserInfoExt2 &other);
#ifdef Q_COMPILER_RVALUE_REFS
		DbUserInfoExt2(DbUserInfoExt2 &&other) Q_DECL_NOEXCEPT;
#endif /* Q_COMPILER_RVALUE_REFS */
		~DbUserInfoExt2(void);

		DbUserInfoExt2 &operator=(const DbUserInfoExt2 &other) Q_DECL_NOTHROW;
#ifdef Q_COMPILER_RVALUE_REFS
		DbUserInfoExt2 &operator=(DbUserInfoExt2 &&other) Q_DECL_NOTHROW;
#endif /* Q_COMPILER_RVALUE_REFS */

		bool operator==(const DbUserInfoExt2 &other) const;
		bool operator!=(const DbUserInfoExt2 &other) const;

		friend void swap(DbUserInfoExt2 &first, DbUserInfoExt2 &second) Q_DECL_NOTHROW;

		bool isNull(void) const;

		/* aifoIsds */
		enum Type::NilBool aifoIsds(void) const;
		void setAifoIsds(enum Type::NilBool ai);
		/* pnGivenNames, pnLastName */
		const PersonName2 &personName(void) const;
		void setPersonName(const PersonName2 &pn);
#ifdef Q_COMPILER_RVALUE_REFS
		void setPersonName(PersonName2 &&pn);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* adCity, adDistrict, adStreet, adNumberInStreet, adNumberInMunicipality, adZipCode, adState */
		const AddressExt2 &address(void) const;
		void setAddress(const AddressExt2 &a);
#ifdef Q_COMPILER_RVALUE_REFS
		void setAddress(AddressExt2 &&a);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* biDate */
		const QDate &biDate(void) const;
		void setBiDate(const QDate &bd);
#ifdef Q_COMPILER_RVALUE_REFS
		void setBiDate(QDate &&bd);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* isdsID */
		const QString &isdsID(void) const;
		void setIsdsID(const QString &id);
#ifdef Q_COMPILER_RVALUE_REFS
		void setIsdsID(QString &&id);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* userType */
		enum Type::UserType userType(void) const;
		void setUserType(enum Type::UserType ut);
		/* userPrivils */
		Type::Privileges userPrivils(void) const;
		void setUserPrivils(Type::Privileges p);
		/* ic */
		const QString &ic(void) const;
		void setIc(const QString &ic);
#ifdef Q_COMPILER_RVALUE_REFS
		void setIc(QString &&ic);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* firmName */
		const QString &firmName(void) const;
		void setFirmName(const QString &fn);
#ifdef Q_COMPILER_RVALUE_REFS
		void setFirmName(QString &&fn);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* caStreet */
		const QString &caStreet(void) const;
		void setCaStreet(const QString &cs);
#ifdef Q_COMPILER_RVALUE_REFS
		void setCaStreet(QString &&cs);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* caCity */
		const QString &caCity(void) const;
		void setCaCity(const QString &cc);
#ifdef Q_COMPILER_RVALUE_REFS
		void setCaCity(QString &&cc);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* caZipCode */
		const QString &caZipCode(void) const;
		void setCaZipCode(const QString &cz);
#ifdef Q_COMPILER_RVALUE_REFS
		void setCaZipCode(QString &&cz);
#endif /* Q_COMPILER_RVALUE_REFS */
		/* caState */
		const QString &caState(void) const;
		void setCaState(const QString &cs);
#ifdef Q_COMPILER_RVALUE_REFS
		void setCaState(QString &&cs);
#endif /* Q_COMPILER_RVALUE_REFS */

	private:
		QScopedPointer<DbUserInfoExt2Private> d_ptr; // ::std::unique_ptr ?
	};

	void swap(DbUserInfoExt2 &first, DbUserInfoExt2 &second) Q_DECL_NOTHROW;

}
