/*
**  ClanLib SDK
**  Copyright (c) 1997-2015 The ClanLib Team
**
**  This software is provided 'as-is', without any express or implied
**  warranty.  In no event will the authors be held liable for any damages
**  arising from the use of this software.
**
**  Permission is granted to anyone to use this software for any purpose,
**  including commercial applications, and to alter it and redistribute it
**  freely, subject to the following restrictions:
**
**  1. The origin of this software must not be misrepresented; you must not
**     claim that you wrote the original software. If you use this software
**     in a product, an acknowledgment in the product documentation would be
**     appreciated but is not required.
**  2. Altered source versions must be plainly marked as such, and must not be
**     misrepresented as being the original software.
**  3. This notice may not be removed or altered from any source distribution.
**
**  Note: Some of the libraries ClanLib may link to may have additional
**  requirements or restrictions.
**
**  File Author(s):
**
**    Harry Storbacka
*/


#pragma once

#include "../Image/pixel_buffer.h"
#include "../../Core/IOData/file_system.h"

namespace clan
{
/// \addtogroup clanDisplay_Image_Providers clanDisplay Image Providers
/// \{

class FileSystem;
class PNGOutputDescription_Impl;
class DateTime;

enum PNGColorType
{
	png_color_type_gray,
	png_color_type_gray_alpha,
	png_color_type_palette,
	png_color_type_rgb,
	png_color_type_rgb_alpha,
	png_color_mask_palette,
	png_color_mask_color,
	png_color_mask_alpha
};

enum PNGInterlaceType
{
	png_interlace_none,
	png_interlace_adam7
};

enum PNGFilterMethod
{
	png_filter_type_default,
	png_intrapixel_differencing
};

enum PNGsRGBIntent
{
	png_srgb_intent_saturation,
	png_srgb_intent_perceptual,
	png_srgb_intent_absolute,
	png_srgb_intent_relative
};

enum PNGUnknownChunkLocation
{
	png_before_plte,
	png_before_idat,
	png_after_idat
};

enum PNGOffsetUnitType
{
	png_offset_pixel,
	png_offset_micrometer
};

enum PNGResolutionUnitType
{
	png_resolution_unknown,
	png_resolution_meter
};


class PNGOutputDescriptionPalette
{
public:
	PNGOutputDescriptionPalette();

public:
	void set_colors(const std::vector<Color> &palette_colors);
	void set_key_color(const Color &color);
	void set_tranparent_color_indexes(const std::vector<int> &alpha_indexes);

private:
	std::vector<Color> colors;
	bool use_keycolor;
};


/// \brief Set PNG output options. Used with PNGProvider::save().
class PNGOutputDescription
{

/// \name Construction
/// \{

public:
	/// \brief Create output description.
	///
	/// \param bit_depth Number of bits per pixel. valid values are 1, 2, 4, 8, 16 - depending on color_type.
	/// \param color_type Color mode of output image.
	PNGOutputDescription(int bit_depth=8, PNGColorType color_type = png_color_type_rgb_alpha);

/// \}
/// \name Attributes
/// \{

public:

/// \}
/// \name Operations
/// \{

public:
	void add_palette(const PNGOutputDescriptionPalette &palette);

	void add_comment(
		const std::string &comment,
		std::string &keyword, // max 79 characters.
		const std::string &lang,
		const std::string &translated_keyword);

	void add_unknown_chunk(const std::string &name, const DataBuffer &chunk_data, PNGUnknownChunkLocation location);

	void set_background_color(const Color &background_color);

	void set_chromacities(const Vec2f &white, const Vec2f &red, const Vec2f &green, const Vec2f &blue);
	void set_chromacities_XYZ(const Vec3f &red, const Vec3f &green, const Vec3f &blue);

	void set_key_color(const Color &color);

	void set_filter_method(PNGFilterMethod filter);

	void set_gamma(float gamma);

	void set_icc_profile(const std::string &profile_name, const DataBuffer &profile_data);

	void set_interlace_type(PNGInterlaceType type);

	void set_modification_time(const DateTime &datetime);

	void set_offset_from_screen_topleft(const Vec2i &offset, PNGOffsetUnitType offset_unit_type);

	void set_physical_resolution(const Vec2i &resolution, PNGResolutionUnitType resolution_type);

	void set_physical_scale(int scale_units, const Sized &pixel_size_in_scale_units);

	void set_srgb_intent(PNGsRGBIntent intent);

	void set_significant_bits(int num_bits);

/// \}
/// \name Implementation
/// \{

private:

	std::shared_ptr<PNGOutputDescription_Impl> impl;

/// \}
};

}

/// \}
