// basisu_frontend.h
// Copyright (C) 2019-2021 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_enc.h"
#include "basisu_etc.h"
#include "basisu_gpu_texture.h"
#include "basisu_global_selector_palette_helpers.h"
#include "../transcoder/basisu_file_headers.h"
#include "../transcoder/basisu_transcoder.h"

namespace basisu
{
	struct vec2U
	{
		uint32_t m_comps[2];

		vec2U() { }
		vec2U(uint32_t a, uint32_t b) { set(a, b); }

		void set(uint32_t a, uint32_t b) { m_comps[0] = a; m_comps[1] = b; }

		uint32_t operator[] (uint32_t i) const { assert(i < 2); return m_comps[i]; }
		uint32_t &operator[] (uint32_t i) { assert(i < 2); return m_comps[i]; }
	};

	const uint32_t BASISU_DEFAULT_COMPRESSION_LEVEL = 2;
	const uint32_t BASISU_MAX_COMPRESSION_LEVEL = 6;

	class basisu_frontend
	{
		BASISU_NO_EQUALS_OR_COPY_CONSTRUCT(basisu_frontend);

	public:

		basisu_frontend() :
			m_total_blocks(0),
			m_total_pixels(0),
			m_endpoint_refinement(false),
			m_use_hierarchical_endpoint_codebooks(false),
			m_use_hierarchical_selector_codebooks(false),
			m_num_endpoint_codebook_iterations(0),
			m_num_selector_codebook_iterations(0)
		{
		}

		enum
		{
			cMaxEndpointClusters = 16128,
						
			cMaxSelectorClusters = 16128,
		};

		struct params
		{
			params() :
				m_num_source_blocks(0),
				m_pSource_blocks(NULL),
				m_max_endpoint_clusters(256),
				m_max_selector_clusters(256),
				m_compression_level(BASISU_DEFAULT_COMPRESSION_LEVEL),
				m_perceptual(true),
				m_debug_stats(false),
				m_debug_images(false),
																
				m_dump_endpoint_clusterization(true),
				m_validate(false),
				m_multithreaded(false),
				m_disable_hierarchical_endpoint_codebooks(false),
				m_pGlobal_sel_codebook(NULL),
				m_num_global_sel_codebook_pal_bits(0),
				m_num_global_sel_codebook_mod_bits(0),
				m_use_hybrid_selector_codebooks(false),
				m_hybrid_codebook_quality_thresh(0.0f),
				m_tex_type(basist::cBASISTexType2D),
				m_pGlobal_codebooks(nullptr),
				
				m_pJob_pool(nullptr)
			{
			}

			uint32_t m_num_source_blocks;
			pixel_block *m_pSource_blocks;

			uint32_t m_max_endpoint_clusters;
			uint32_t m_max_selector_clusters;

			uint32_t m_compression_level;

			bool m_perceptual;
			bool m_debug_stats;
			bool m_debug_images;
			bool m_dump_endpoint_clusterization;
			bool m_validate;
			bool m_multithreaded;
			bool m_disable_hierarchical_endpoint_codebooks;
			
			const basist::etc1_global_selector_codebook *m_pGlobal_sel_codebook;
			uint32_t m_num_global_sel_codebook_pal_bits;
			uint32_t m_num_global_sel_codebook_mod_bits;
			bool m_use_hybrid_selector_codebooks;
			float m_hybrid_codebook_quality_thresh;
			basist::basis_texture_type m_tex_type;
			const basist::basisu_lowlevel_etc1s_transcoder *m_pGlobal_codebooks;
			
			job_pool *m_pJob_pool;
		};

		bool init(const params &p);

		bool compress();

		const params &get_params() const { return m_params; }

		const pixel_block &get_source_pixel_block(uint32_t i) const { return m_source_blocks[i]; }

		// RDO output blocks
		uint32_t get_total_output_blocks() const { return static_cast<uint32_t>(m_encoded_blocks.size()); }

		const etc_block &get_output_block(uint32_t block_index) const { return m_encoded_blocks[block_index]; }
		const etc_block_vec &get_output_blocks() const { return m_encoded_blocks; }

		// "Best" ETC1S blocks
		const etc_block &get_etc1s_block(uint32_t block_index) const { return m_etc1_blocks_etc1s[block_index]; }

		// Per-block flags
		bool get_diff_flag(uint32_t block_index) const { return m_encoded_blocks[block_index].get_diff_bit(); }

		// Endpoint clusters
		uint32_t get_total_endpoint_clusters() const { return static_cast<uint32_t>(m_endpoint_clusters.size()); }
		uint32_t get_subblock_endpoint_cluster_index(uint32_t block_index, uint32_t subblock_index) const { return m_block_endpoint_clusters_indices[block_index][subblock_index]; }

		const color_rgba &get_endpoint_cluster_unscaled_color(uint32_t cluster_index, bool individual_mode) const { return m_endpoint_cluster_etc_params[cluster_index].m_color_unscaled[individual_mode]; }
		uint32_t get_endpoint_cluster_inten_table(uint32_t cluster_index, bool individual_mode) const { return m_endpoint_cluster_etc_params[cluster_index].m_inten_table[individual_mode]; }

		bool get_endpoint_cluster_color_is_used(uint32_t cluster_index, bool individual_mode) const { return m_endpoint_cluster_etc_params[cluster_index].m_color_used[individual_mode]; }

		// Selector clusters
		uint32_t get_total_selector_clusters() const { return static_cast<uint32_t>(m_selector_cluster_block_indices.size()); }
		uint32_t get_block_selector_cluster_index(uint32_t block_index) const { return m_block_selector_cluster_index[block_index]; }
		const etc_block &get_selector_cluster_selector_bits(uint32_t cluster_index) const { return m_optimized_cluster_selectors[cluster_index]; }

		const basist::etc1_global_selector_codebook_entry_id_vec &get_selector_cluster_global_selector_entry_ids() const { return m_optimized_cluster_selector_global_cb_ids; }
		const bool_vec &get_selector_cluster_uses_global_cb_vec() const { return m_selector_cluster_uses_global_cb; }

		// Returns block indices using each selector cluster
		const uint_vec &get_selector_cluster_block_indices(uint32_t selector_cluster_index) const { return m_selector_cluster_block_indices[selector_cluster_index]; }

		void dump_debug_image(const char *pFilename, uint32_t first_block, uint32_t num_blocks_x, uint32_t num_blocks_y, bool output_blocks);
		
		void reoptimize_remapped_endpoints(const uint_vec &new_block_endpoints, int_vec &old_to_new_endpoint_cluster_indices, bool optimize_final_codebook, uint_vec *pBlock_selector_indices = nullptr);

	private:
		params m_params;
		uint32_t m_total_blocks;
		uint32_t m_total_pixels;

		bool m_endpoint_refinement;
		bool m_use_hierarchical_endpoint_codebooks;
		bool m_use_hierarchical_selector_codebooks;

		uint32_t m_num_endpoint_codebook_iterations;
		uint32_t m_num_selector_codebook_iterations;

		// Source pixels for each blocks
		pixel_block_vec m_source_blocks;

		// The quantized ETC1S texture.
		etc_block_vec m_encoded_blocks;
		
		// Quantized blocks after endpoint quant, but before selector quant
		etc_block_vec m_orig_encoded_blocks; 
				
		// Full quality ETC1S texture
		etc_block_vec m_etc1_blocks_etc1s;
				
		typedef vec<6, float> vec6F;
		
		// Endpoint clusterizer
		typedef tree_vector_quant<vec6F> vec6F_quantizer;
		vec6F_quantizer m_endpoint_clusterizer;

		// For each endpoint cluster: An array of which subblock indices (block_index*2+subblock) are located in that cluster.
		// Array of block indices for each endpoint cluster
		basisu::vector<uint_vec> m_endpoint_clusters;

		// Array of block indices for each parent endpoint cluster
		basisu::vector<uint_vec> m_endpoint_parent_clusters;
		
		// Each block's parent cluster index
		uint8_vec m_block_parent_endpoint_cluster; 

		// Array of endpoint cluster indices for each parent endpoint cluster
		basisu::vector<uint_vec> m_endpoint_clusters_within_each_parent_cluster;
				
		struct endpoint_cluster_etc_params
		{
			endpoint_cluster_etc_params()
			{
				clear();
			}

			void clear()
			{
				clear_obj(m_color_unscaled);
				clear_obj(m_inten_table);
				clear_obj(m_color_error);
				m_subblocks.clear();

				clear_obj(m_color_used);
				m_valid = false;
			}

			// TODO: basisu doesn't use individual mode.
			color_rgba m_color_unscaled[2]; // [use_individual_mode]
			uint32_t m_inten_table[2];

			uint64_t m_color_error[2];

			uint_vec m_subblocks;

			bool m_color_used[2];

			bool m_valid;

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

				if (m_inten_table[0] != other.m_inten_table[0])
					return false;
				if (m_inten_table[1] != other.m_inten_table[1])
					return false;

				return true;
			}

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

				if (m_inten_table[0] < other.m_inten_table[0])
					return true;
				else if (m_inten_table[0] == other.m_inten_table[0])
				{
					if (m_inten_table[1] < other.m_inten_table[1])
						return true;
				}

				return false;
			}
		};

		typedef basisu::vector<endpoint_cluster_etc_params> cluster_subblock_etc_params_vec;
		
		// Each endpoint cluster's ETC1S parameters 
		cluster_subblock_etc_params_vec m_endpoint_cluster_etc_params;

		// The endpoint cluster index used by each ETC1 subblock.
		basisu::vector<vec2U> m_block_endpoint_clusters_indices;
				
		// The block(s) within each selector cluster
		// Note: If you add anything here that uses selector cluster indicies, be sure to update optimize_selector_codebook()!
		basisu::vector<uint_vec> m_selector_cluster_block_indices;

		// The selector bits for each selector cluster.
		basisu::vector<etc_block> m_optimized_cluster_selectors;

		// The block(s) within each parent selector cluster.
		basisu::vector<uint_vec> m_selector_parent_cluster_block_indices;
		
		// Each block's parent selector cluster
		uint8_vec m_block_parent_selector_cluster;

		// Array of selector cluster indices for each parent selector cluster
		basisu::vector<uint_vec> m_selector_clusters_within_each_parent_cluster;

		basist::etc1_global_selector_codebook_entry_id_vec m_optimized_cluster_selector_global_cb_ids;
		bool_vec m_selector_cluster_uses_global_cb;

		// Each block's selector cluster index
		basisu::vector<uint32_t> m_block_selector_cluster_index;

		struct subblock_endpoint_quant_err
		{
			uint64_t m_total_err;
			uint32_t m_cluster_index;
			uint32_t m_cluster_subblock_index;
			uint32_t m_block_index;
			uint32_t m_subblock_index;

			bool operator< (const subblock_endpoint_quant_err &rhs) const
			{
				if (m_total_err < rhs.m_total_err)
					return true;
				else if (m_total_err == rhs.m_total_err)
				{
					if (m_block_index < rhs.m_block_index)
						return true;
					else if (m_block_index == rhs.m_block_index)
						return m_subblock_index < rhs.m_subblock_index;
				}
				return false;
			}
		};

		// The sorted subblock endpoint quant error for each endpoint cluster
		basisu::vector<subblock_endpoint_quant_err> m_subblock_endpoint_quant_err_vec;

		std::mutex m_lock;

		//-----------------------------------------------------------------------------

		void init_etc1_images();
		bool init_global_codebooks();
		void init_endpoint_training_vectors();
		void dump_endpoint_clusterization_visualization(const char *pFilename, bool vis_endpoint_colors);
		void generate_endpoint_clusters();
		void compute_endpoint_subblock_error_vec();
		void introduce_new_endpoint_clusters();
		void generate_endpoint_codebook(uint32_t step);
		uint32_t refine_endpoint_clusterization();
		void eliminate_redundant_or_empty_endpoint_clusters();
		void generate_block_endpoint_clusters();
		void compute_endpoint_clusters_within_each_parent_cluster();
		void compute_selector_clusters_within_each_parent_cluster();
		void create_initial_packed_texture();
		void generate_selector_clusters();
		void create_optimized_selector_codebook(uint32_t iter);
		void find_optimal_selector_clusters_for_each_block();
		uint32_t refine_block_endpoints_given_selectors();
		void finalize();
		bool validate_output() const;
		void introduce_special_selector_clusters();
		void optimize_selector_codebook();
		bool check_etc1s_constraints() const;
	};

} // namespace basisu
