// basisu_global_selector_palette.h
// Copyright (C) 2017-2019 Binomial LLC. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "basisu_transcoder_internal.h"
#include <algorithm>

namespace basist
{
	class etc1_global_palette_entry_modifier
	{
	public:
		enum { cTotalBits = 15, cTotalValues = 1 << cTotalBits };

		etc1_global_palette_entry_modifier(uint32_t index = 0)
		{
#ifdef _DEBUG
			static bool s_tested;
			if (!s_tested)
			{
				s_tested = true;
				for (uint32_t i = 0; i < cTotalValues; i++)
				{
					etc1_global_palette_entry_modifier m(i);
					etc1_global_palette_entry_modifier n = m;

					assert(n.get_index() == i);
				}
			}
#endif

			set_index(index);
		}

		void set_index(uint32_t index)
		{
			assert(index < cTotalValues);
			m_rot = index & 3;
			m_flip = (index >> 2) & 1;
			m_inv = (index >> 3) & 1;
			m_contrast = (index >> 4) & 3;
			m_shift = (index >> 6) & 1;
			m_median = (index >> 7) & 1;
			m_div = (index >> 8) & 1;
			m_rand = (index >> 9) & 1;
			m_dilate = (index >> 10) & 1;
			m_shift_x = (index >> 11) & 1;
			m_shift_y = (index >> 12) & 1;
			m_erode = (index >> 13) & 1;
			m_high_pass = (index >> 14) & 1;
		}

		uint32_t get_index() const
		{
			return m_rot | (m_flip << 2) | (m_inv << 3) | (m_contrast << 4) | (m_shift << 6) | (m_median << 7) | (m_div << 8) | (m_rand << 9) | (m_dilate << 10) | (m_shift_x << 11) | (m_shift_y << 12) | (m_erode << 13) | (m_high_pass << 14);
		}

		void clear()
		{
			basisu::clear_obj(*this);
		}

		uint8_t m_contrast;
		bool m_rand;
		bool m_median;
		bool m_div;
		bool m_shift;
		bool m_inv;
		bool m_flip;
		bool m_dilate;
		bool m_shift_x;
		bool m_shift_y;
		bool m_erode;
		bool m_high_pass;
		uint8_t m_rot;
	};

	enum modifier_types
	{
		cModifierContrast,
		cModifierRand,
		cModifierMedian,
		cModifierDiv,
		cModifierShift,
		cModifierInv,
		cModifierFlippedAndRotated,
		cModifierDilate,
		cModifierShiftX,
		cModifierShiftY,
		cModifierErode,
		cModifierHighPass,
		cTotalModifiers
	};

#define ETC1_GLOBAL_SELECTOR_CODEBOOK_MAX_MOD_BITS (etc1_global_palette_entry_modifier::cTotalBits)

	struct etc1_selector_palette_entry
	{
		etc1_selector_palette_entry()
		{
			clear();
		}

		void clear()
		{
			basisu::clear_obj(*this);
		}

		uint8_t operator[] (uint32_t i) const { assert(i < 16); return m_selectors[i]; }
		uint8_t&operator[] (uint32_t i) { assert(i < 16); return m_selectors[i]; }

		void set_uint32(uint32_t v)
		{
			for (uint32_t byte_index = 0; byte_index < 4; byte_index++)
			{
				uint32_t b = (v >> (byte_index * 8)) & 0xFF;

				m_selectors[byte_index * 4 + 0] = b & 3;
				m_selectors[byte_index * 4 + 1] = (b >> 2) & 3;
				m_selectors[byte_index * 4 + 2] = (b >> 4) & 3;
				m_selectors[byte_index * 4 + 3] = (b >> 6) & 3;
			}
		}

		uint32_t get_uint32() const
		{
			return get_byte(0) | (get_byte(1) << 8) | (get_byte(2) << 16) | (get_byte(3) << 24);
		}

		uint32_t get_byte(uint32_t byte_index) const
		{
			assert(byte_index < 4);

			return m_selectors[byte_index * 4 + 0] |
				(m_selectors[byte_index * 4 + 1] << 2) |
				(m_selectors[byte_index * 4 + 2] << 4) |
				(m_selectors[byte_index * 4 + 3] << 6);
		}

		uint8_t operator()(uint32_t x, uint32_t y) const { assert((x < 4) && (y < 4)); return m_selectors[x + y * 4]; }
		uint8_t&operator()(uint32_t x, uint32_t y) { assert((x < 4) && (y < 4)); return m_selectors[x + y * 4]; }

		uint32_t calc_distance(const etc1_selector_palette_entry &other) const
		{
			uint32_t dist = 0;
			for (uint32_t i = 0; i < 8; i++)
			{
				int delta = static_cast<int>(m_selectors[i]) - static_cast<int>(other.m_selectors[i]);
				dist += delta * delta;
			}
			return dist;
		}

#if 0
		uint32_t calc_hamming_dist(const etc1_selector_palette_entry &other) const
		{
			uint32_t dist = 0;
			for (uint32_t i = 0; i < 4; i++)
				dist += g_hamming_dist[get_byte(i) ^ other.get_byte(i)];
			return dist;
		}
#endif

		etc1_selector_palette_entry get_inverted() const
		{
			etc1_selector_palette_entry result;

			for (uint32_t i = 0; i < 16; i++)
				result.m_selectors[i] = 3 - m_selectors[i];

			return result;
		}

		etc1_selector_palette_entry get_divided() const
		{
			etc1_selector_palette_entry result;

			const uint8_t div_selector[4] = { 2, 0, 3, 1 };

			for (uint32_t i = 0; i < 16; i++)
				result.m_selectors[i] = div_selector[m_selectors[i]];

			return result;
		}

		etc1_selector_palette_entry get_shifted(int delta) const
		{
			etc1_selector_palette_entry result;

			for (uint32_t i = 0; i < 16; i++)
				result.m_selectors[i] = static_cast<uint8_t>(basisu::clamp<int>(m_selectors[i] + delta, 0, 3));

			return result;
		}

		etc1_selector_palette_entry get_randomized() const
		{
			uint32_t seed = get_uint32();

			etc1_selector_palette_entry result;

			for (uint32_t y = 0; y < 4; y++)
			{
				for (uint32_t x = 0; x < 4; x++)
				{
					int s = (*this)(x, y);

					// between 0 and 10
					uint32_t i = basisd_urand(seed, 6) + basisd_urand(seed, 6);
					if (i == 0)
						s -= 2;
					else if (i == 10)
						s += 2;
					else if (i < 3)
						s -= 1;
					else if (i > 7)
						s += 1;

					result(x, y) = static_cast<uint8_t>(basisu::clamp<int>(s, 0, 3));
				}
			}

			return result;
		}

		etc1_selector_palette_entry get_contrast(int table_index) const
		{
			assert(table_index < 4);

			etc1_selector_palette_entry result;

			static const uint8_t s_contrast_tables[4][4] =
			{
				{ 0, 1, 2, 3 }, // not used
				{ 0, 0, 3, 3 },
				{ 1, 1, 2, 2 },
				{ 1, 1, 3, 3 }
			};

			for (uint32_t i = 0; i < 16; i++)
			{
				result[i] = s_contrast_tables[table_index][(*this)[i]];
			}

			return result;
		}

		etc1_selector_palette_entry get_dilated() const
		{
			etc1_selector_palette_entry result;

			for (uint32_t y = 0; y < 4; y++)
			{
				for (uint32_t x = 0; x < 4; x++)
				{
					uint32_t max_selector = 0;

					for (int yd = -1; yd <= 1; yd++)
					{
						int fy = y + yd;
						if ((fy < 0) || (fy > 3))
							continue;

						for (int xd = -1; xd <= 1; xd++)
						{
							int fx = x + xd;
							if ((fx < 0) || (fx > 3))
								continue;

							max_selector = basisu::maximum<uint32_t>(max_selector, (*this)(fx, fy));
						}
					}

					result(x, y) = static_cast<uint8_t>(max_selector);
				}
			}

			return result;
		}

		etc1_selector_palette_entry get_eroded() const
		{
			etc1_selector_palette_entry result;

			for (uint32_t y = 0; y < 4; y++)
			{
				for (uint32_t x = 0; x < 4; x++)
				{
					uint32_t min_selector = 99;

					for (int yd = -1; yd <= 1; yd++)
					{
						int fy = y + yd;
						if ((fy < 0) || (fy > 3))
							continue;

						for (int xd = -1; xd <= 1; xd++)
						{
							int fx = x + xd;
							if ((fx < 0) || (fx > 3))
								continue;

							min_selector = basisu::minimum<uint32_t>(min_selector, (*this)(fx, fy));
						}
					}

					result(x, y) = static_cast<uint8_t>(min_selector);
				}
			}

			return result;
		}

		etc1_selector_palette_entry get_shift_x() const
		{
			etc1_selector_palette_entry result;

			for (uint32_t y = 0; y < 4; y++)
			{
				for (uint32_t x = 0; x < 4; x++)
				{
					int sx = x - 1;
					if (sx < 0)
						sx = 0;

					result(x, y) = (*this)(sx, y);
				}
			}

			return result;
		}

		etc1_selector_palette_entry get_shift_y() const
		{
			etc1_selector_palette_entry result;

			for (uint32_t y = 0; y < 4; y++)
			{
				int sy = y - 1;
				if (sy < 0)
					sy = 3;

				for (uint32_t x = 0; x < 4; x++)
					result(x, y) = (*this)(x, sy);
			}

			return result;
		}

		etc1_selector_palette_entry get_median() const
		{
			etc1_selector_palette_entry result;

			for (uint32_t y = 0; y < 4; y++)
			{
				for (uint32_t x = 0; x < 4; x++)
				{
					// ABC
					// D F
					// GHI

					uint8_t selectors[8];
					uint32_t n = 0;

					for (int yd = -1; yd <= 1; yd++)
					{
						int fy = y + yd;
						if ((fy < 0) || (fy > 3))
							continue;

						for (int xd = -1; xd <= 1; xd++)
						{
							if ((xd | yd) == 0)
								continue;

							int fx = x + xd;
							if ((fx < 0) || (fx > 3))
								continue;

							selectors[n++] = (*this)(fx, fy);
						}
					}

					std::sort(selectors, selectors + n);

					result(x, y) = selectors[n / 2];
				}
			}

			return result;
		}

		etc1_selector_palette_entry get_high_pass() const
		{
			etc1_selector_palette_entry result;

			static const int kernel[3][3] =
			{
				{ 0,  -1,  0 },
				{ -1,  8, -1 },
				{ 0,  -1,  0 }
			};

			for (uint32_t y = 0; y < 4; y++)
			{
				for (uint32_t x = 0; x < 4; x++)
				{
					// ABC
					// D F
					// GHI

					int sum = 0;

					for (int yd = -1; yd <= 1; yd++)
					{
						int fy = y + yd;
						fy = basisu::clamp<int>(fy, 0, 3);

						for (int xd = -1; xd <= 1; xd++)
						{
							int fx = x + xd;
							fx = basisu::clamp<int>(fx, 0, 3);

							int k = (*this)(fx, fy);
							sum += k * kernel[yd + 1][xd + 1];
						}
					}

					sum = sum / 4;

					result(x, y) = static_cast<uint8_t>(basisu::clamp<int>(sum, 0, 3));
				}
			}

			return result;
		}

		etc1_selector_palette_entry get_flipped_and_rotated(bool flip, uint32_t rotation_index) const
		{
			etc1_selector_palette_entry temp;

			if (flip)
			{
				for (uint32_t y = 0; y < 4; y++)
					for (uint32_t x = 0; x < 4; x++)
						temp(x, y) = (*this)(x, 3 - y);
			}
			else
			{
				temp = *this;
			}

			etc1_selector_palette_entry result;

			switch (rotation_index)
			{
			case 0:
				result = temp;
				break;
			case 1:
				for (uint32_t y = 0; y < 4; y++)
					for (uint32_t x = 0; x < 4; x++)
						result(x, y) = temp(y, 3 - x);
				break;
			case 2:
				for (uint32_t y = 0; y < 4; y++)
					for (uint32_t x = 0; x < 4; x++)
						result(x, y) = temp(3 - x, 3 - y);
				break;
			case 3:
				for (uint32_t y = 0; y < 4; y++)
					for (uint32_t x = 0; x < 4; x++)
						result(x, y) = temp(3 - y, x);
				break;
			default:
				assert(0);
				break;
			}

			return result;
		}

		etc1_selector_palette_entry get_modified(const etc1_global_palette_entry_modifier &modifier) const
		{
			etc1_selector_palette_entry r(*this);

			if (modifier.m_shift_x)
				r = r.get_shift_x();

			if (modifier.m_shift_y)
				r = r.get_shift_y();

			r = r.get_flipped_and_rotated(modifier.m_flip != 0, modifier.m_rot);

			if (modifier.m_dilate)
				r = r.get_dilated();

			if (modifier.m_erode)
				r = r.get_eroded();

			if (modifier.m_high_pass)
				r = r.get_high_pass();

			if (modifier.m_rand)
				r = r.get_randomized();

			if (modifier.m_div)
				r = r.get_divided();

			if (modifier.m_shift)
				r = r.get_shifted(1);

			if (modifier.m_contrast)
				r = r.get_contrast(modifier.m_contrast);

			if (modifier.m_inv)
				r = r.get_inverted();

			if (modifier.m_median)
				r = r.get_median();

			return r;
		}

		etc1_selector_palette_entry apply_modifier(modifier_types mod_type, const etc1_global_palette_entry_modifier &modifier) const
		{
			switch (mod_type)
			{
			case cModifierContrast:
				return get_contrast(modifier.m_contrast);
			case cModifierRand:
				return get_randomized();
			case cModifierMedian:
				return get_median();
			case cModifierDiv:
				return get_divided();
			case cModifierShift:
				return get_shifted(1);
			case cModifierInv:
				return get_inverted();
			case cModifierFlippedAndRotated:
				return get_flipped_and_rotated(modifier.m_flip != 0, modifier.m_rot);
			case cModifierDilate:
				return get_dilated();
			case cModifierShiftX:
				return get_shift_x();
			case cModifierShiftY:
				return get_shift_y();
			case cModifierErode:
				return get_eroded();
			case cModifierHighPass:
				return get_high_pass();
			default:
				assert(0);
				break;
			}

			return *this;
		}

		etc1_selector_palette_entry get_modified(const etc1_global_palette_entry_modifier &modifier, uint32_t num_order, const modifier_types *pOrder) const
		{
			etc1_selector_palette_entry r(*this);

			for (uint32_t i = 0; i < num_order; i++)
			{
				r = r.apply_modifier(pOrder[i], modifier);
			}

			return r;
		}

		bool operator< (const etc1_selector_palette_entry &other) const
		{
			for (uint32_t i = 0; i < 16; i++)
			{
				if (m_selectors[i] < other.m_selectors[i])
					return true;
				else if (m_selectors[i] != other.m_selectors[i])
					return false;
			}

			return false;
		}

		bool operator== (const etc1_selector_palette_entry &other) const
		{
			for (uint32_t i = 0; i < 16; i++)
			{
				if (m_selectors[i] != other.m_selectors[i])
					return false;
			}

			return true;
		}

	private:
		uint8_t m_selectors[16];
	};

	typedef std::vector<etc1_selector_palette_entry> etc1_selector_palette_entry_vec;

	extern const uint32_t g_global_selector_cb[];
	extern const uint32_t g_global_selector_cb_size;

#define ETC1_GLOBAL_SELECTOR_CODEBOOK_MAX_PAL_BITS (12)

	struct etc1_global_selector_codebook_entry_id
	{
		uint32_t m_palette_index;
		etc1_global_palette_entry_modifier m_modifier;

		etc1_global_selector_codebook_entry_id(uint32_t palette_index, const etc1_global_palette_entry_modifier &modifier) : m_palette_index(palette_index), m_modifier(modifier) { }

		etc1_global_selector_codebook_entry_id() { }

		void set(uint32_t palette_index, const etc1_global_palette_entry_modifier &modifier) { m_palette_index = palette_index; m_modifier = modifier; }
	};

	typedef std::vector<etc1_global_selector_codebook_entry_id> etc1_global_selector_codebook_entry_id_vec;

	class etc1_global_selector_codebook
	{
	public:
		etc1_global_selector_codebook() { }
		etc1_global_selector_codebook(uint32_t N, const uint32_t *pEntries) { init(N, pEntries); }

		void init(uint32_t N, const uint32_t* pEntries);

		void print_code(FILE *pFile);

		void clear()
		{
			m_palette.clear();
		}

		uint32_t size() const { return (uint32_t)m_palette.size(); }

		const etc1_selector_palette_entry_vec &get_palette() const
		{
			return m_palette;
		}

		etc1_selector_palette_entry get_entry(uint32_t palette_index) const
		{
			return m_palette[palette_index];
		}

		etc1_selector_palette_entry get_entry(uint32_t palette_index, const etc1_global_palette_entry_modifier &modifier) const
		{
			return m_palette[palette_index].get_modified(modifier);
		}

		etc1_selector_palette_entry get_entry(const etc1_global_selector_codebook_entry_id &id) const
		{
			return m_palette[id.m_palette_index].get_modified(id.m_modifier);
		}

		etc1_selector_palette_entry_vec m_palette;
	};

} // namespace basist
