#pragma once

constexpr auto TABWIDTH_MIN = 2;
constexpr auto TABWIDTH_DEFAULT = 8;
constexpr auto TABWIDTH_MAX = 16;

constexpr auto CHR_SPACE = 32;
constexpr auto CHR_TAB = 9;
constexpr auto CHR_N = 10;
constexpr auto CHR_R = 13;
constexpr auto CHR_127 = 127;
constexpr auto CHR_USCQR = 0x25a0;

constexpr auto ARR_LOWROW_SIZE = CHR_SPACE;
constexpr auto ARR_KOI8_SIZE = 128;


class CBaseFile
{
	protected:
		FILE           *m_f{ nullptr };
		fs::path        m_pathFileName;
		size_t          m_nFileLength{ 0 };
		int             m_nTabWidth{ TABWIDTH_DEFAULT }; // ширина табулятора по умолчанию для заданного типа файла.
		uint32_t        BKToUNICODE_Byte(uint8_t b) const;
		uint8_t         UNICODEtoBK_Byte(uint32_t tch) const;

		FILE           *BKOpen(const fs::path &filepath, const std::_tstring &mode);

	public:
		static const std::array<uint8_t, ARR_LOWROW_SIZE> m_LowRow;
		static const std::array<wchar_t, ARR_KOI8_SIZE> m_koi8tbl;

		CBaseFile(const fs::path &strName);
		virtual ~CBaseFile();

		virtual const fs::path &getFileName() const
		{
			return m_pathFileName;
		}

		virtual int     getTabWidth() const
		{
			return m_nTabWidth;
		}

		virtual void    setTabWidth(int n)
		{
			if (TABWIDTH_MIN <= n && n <= TABWIDTH_MAX)
			{
				m_nTabWidth = n;
			}
		}

		virtual bool    Open(bool bWrite = false); // открытие файла, имя которого задано в конструкторе
		virtual void    Close();
		virtual uint32_t ReadChar();
		virtual uint8_t ReadByte() const;
		virtual uint16_t ReadWord() const;
		virtual bool    WriteChar(uint32_t ch);
		virtual bool    WriteByte(uint8_t b) const;
		virtual bool    WriteWord(uint16_t w) const;
		virtual long    GetPos() const;
		virtual int     SetPos(long pos, long mode = SEEK_SET) const;
		virtual bool    isEOF() const;
		virtual bool    CheckOutFile();
};

