#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  font_parser.py
#
#  Copyright (c) 2020 Dominic Davis-Foster <dominic@davis-foster.co.uk>
#
#  Function 'freezeargs' Copyright 2018 Cedar
#  https://stackoverflow.com/users/5810747/cedar
#  From https://stackoverflow.com/a/53394430
#  Licensed under CC-BY-SA 4.0
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
# generated by wxGlade 0.9.2 on Thu Jan 16 16:34:51 2020
#

# stdlib
import re
from functools import lru_cache, wraps

# 3rd party
from frozendict import frozendict


def freezeargs(func):
	"""
	Make mutable dictionary immutable for lru_cache

	From stackoverflow.com/a/53394430
	"""
	
	@wraps(func)
	def wrapped(*args, **kwargs):
		args = tuple(
				[frozendict(arg) if isinstance(arg, dict) else arg for arg in args])
		kwargs = {k: frozendict(v) if isinstance(v, dict) else v for k, v in kwargs.items()}
		return func(*args, **kwargs)
	
	return wrapped


@freezeargs
@lru_cache(5)
def parse_font(style_dict):
	"""
	Parse the font from the style_dict
	
	:param style_dict: Dictionary containing styling information for the font
	:type style_dict: dict
	
	:return: Tuple containing the colour of the font, and the font properties
	:rtype: (str, dict)
	
	The font properties dictionary returned will contain the following keys:
	
		family (wx.FontFamily) – The font family: a generic portable way of referring to fonts without specifying a facename. This parameter must be one of the wx.FontFamily enumeration values. If the faceName argument is provided, then it overrides the font family.
		
		style (wx.FontStyle) – One of wx.FONTSTYLE_NORMAL, wx.FONTSTYLE_SLANT and wx.FONTSTYLE_ITALIC.
		
		weight (wx.FontWeight) – Font weight, sometimes also referred to as font boldness. One of the wx.FontWeight enumeration values.
		
		underline (wx.bool) – The value can be True or False. At present this has an effect on Windows and Motif 2.x only.
		
		faceName (wx.string) – An optional string specifying the face name to be used. If it is an empty string, a default face name will be chosen based on the family.
		
		encoding (wx.FontEncoding) – An encoding which may be one of the enumeration values of wx.FontEncoding. If the specified encoding isn’t available, no font is created (see also Font Encodings).
	
	and one of:
	
		pointSize (int) – Size in points. See SetPointSize for more info. Notice that, for historical reasons, the value 70 here is interpreted at DEFAULT and results in creation of the font with the default size and not of a font with the size of 70pt. If you really need the latter, please use SetPointSize(70). Note that this constructor and the matching Create() method overload are the only places in wx.Font API handling DEFAULT specially: neither SetPointSize nor the constructor taking wx.FontInfo handle this value in this way.
		
		pixelSize (wx.Size) – Size in pixels. See SetPixelSize for more info.

	depending on the font size specified in 'style_dict'
	"""
	
	colour = style_dict["color"]
	
	font_data = {
			"family": style_dict["font-family"],
			"style": style_dict["font-style"],
			"weight": style_dict["font-weight"],
			"faceName": style_dict["font-face-name"]
			}
	
	if style_dict["text-decoration"].lower() == "underline":
		font_data["underline"] = True
	
	# if style_dict["font-size"] is None:
	# 	font_data["pointSize"] = None
	# else:
	font_size_value, pt_or_px = filter(None, re.split("(\d+|\D+)", style_dict["font-size"]))

	if pt_or_px.lower() == "pt":
		font_data["pointSize"] = int(font_size_value)
	elif pt_or_px.lower() == "px":
		font_data["pixelSize"] = int(font_size_value)

	return colour, font_data
