/*
**  ClanLib SDK
**  Copyright (c) 1997-2020 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):
**
**    Magnus Norddahl
*/

#include "UI/precomp.h"
#include "box_shadow.h"

namespace clan
{
	void force_link_style_parser_box_shadow()
	{
	}

	StylePropertyDefault style_default_box_shadow("box-shadow", StyleGetValue::from_keyword("none"), false);

	BoxShadowPropertyParser style_parser_box_shadow;

	void BoxShadowPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		StyleSetValue box_shadow;
		std::vector<StyleSetValue> box_shadow_styles;
		std::vector<StyleSetValue> box_shadow_colors;
		std::vector<StyleSetValue> box_shadow_horizontal_offsets;
		std::vector<StyleSetValue> box_shadow_vertical_offsets;
		std::vector<StyleSetValue> box_shadow_blur_radius;
		std::vector<StyleSetValue> box_shadow_spread_distances;

		size_t pos = 0;
		size_t last_pos = pos;
		StyleToken token = next_token(pos, tokens);

		if (token.type == StyleTokenType::ident && pos == tokens.size() && equals(token.value, "inherit"))
		{
			box_shadow = StyleSetValue::from_keyword("inherit");
		}
		else if (token.type == StyleTokenType::ident && pos == tokens.size() && equals(token.value, "none"))
		{
			box_shadow = StyleSetValue::from_keyword("none");
		}
		else
		{
			box_shadow = StyleSetValue::from_keyword("array");

			while (true)
			{
				StyleSetValue style;
				StyleSetValue color;
				StyleSetValue horizontal_offset;
				StyleSetValue vertical_offset;
				StyleSetValue blur_radius;
				StyleSetValue spread_distance;

				if (token.type == StyleTokenType::ident && equals(token.value, "inset"))
				{
					style = StyleSetValue::from_keyword("inset");
					last_pos = pos;
					token = next_token(pos, tokens);
				}
				else
				{
					style = StyleSetValue::from_keyword("outset");
				}

				int num_lengths;
				StyleSetValue lengths[4];
				for (num_lengths = 0; num_lengths < 4 && is_length(token); num_lengths++)
				{
					if (!parse_length(token, lengths[num_lengths]))
						return;
					last_pos = pos;
					token = next_token(pos, tokens);
				}
				if (num_lengths < 2)
					return;

				Colorf c = StandardColorf::black();
				if (parse_color(tokens, last_pos, c))
				{
					pos = last_pos;
					token = next_token(pos, tokens);
				}

				color = StyleSetValue::from_color(c);

				if (num_lengths == 2)
				{
					horizontal_offset = lengths[0];
					vertical_offset = lengths[1];
				}
				else if (num_lengths == 3)
				{
					horizontal_offset = lengths[0];
					vertical_offset = lengths[1];
					blur_radius = lengths[2];
				}
				else if (num_lengths == 4)
				{
					horizontal_offset = lengths[0];
					vertical_offset = lengths[1];
					blur_radius = lengths[2];
					spread_distance = lengths[3];
				}

				box_shadow_styles.push_back(style);
				box_shadow_colors.push_back(color);
				box_shadow_horizontal_offsets.push_back(horizontal_offset);
				box_shadow_vertical_offsets.push_back(vertical_offset);
				box_shadow_blur_radius.push_back(blur_radius);
				box_shadow_spread_distances.push_back(spread_distance);

				if (pos != tokens.size())
				{
					if (token.type != StyleTokenType::delim || token.value != ",")
						return;
					token = next_token(pos, tokens);
				}
				else
				{
					break;
				}
			}
		}

		setter->set_value(PropertyHash::hash_box_shadow, box_shadow);
		setter->set_value_array(PropertyHash::hash_box_shadow_style, box_shadow_styles);
		setter->set_value_array(PropertyHash::hash_box_shadow_color, box_shadow_colors);
		setter->set_value_array(PropertyHash::hash_box_shadow_horizontal_offset, box_shadow_horizontal_offsets);
		setter->set_value_array(PropertyHash::hash_box_shadow_vertical_offset, box_shadow_vertical_offsets);
		setter->set_value_array(PropertyHash::hash_box_shadow_blur_radius, box_shadow_blur_radius);
		setter->set_value_array("box-shadow-spread_distance", box_shadow_spread_distances);
	}
}
