# coding: utf8

#  WeasyPrint converts web documents (HTML, CSS, ...) to PDF.
#  Copyright (C) 2011  Simon Sapin
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""
Functions resolving percentages.

"""

from ..formatting_structure import boxes
from ..css.values import get_percentage_value


def resolve_one_percentage(box, property_name, refer_to,
                           allowed_keywords=None):
    """Set a used length value from a computed length value.

    ``refer_to`` is the length for 100%. If ``refer_to`` is not a number, it
    just replaces percentages.

    """
    # box.style has computed values
    values = box.style[property_name]
    if isinstance(values, (int, float)):
        # Absolute length (was converted to pixels in "computed values")
        result = values
    else:
        percentage = get_percentage_value(values)
        if percentage is not None:
            if isinstance(refer_to, (int, float)):
                # A percentage
                result = percentage * refer_to / 100.
            else:
                # Replace percentages when we have no refer_to that
                # makes sense.
                result = refer_to
        else:
            # Some other values such as 'auto' may be allowed
            result = values
            assert allowed_keywords and result in allowed_keywords
    # box attributes are used values
    setattr(box, property_name, result)


def resolve_percentages(box, containing_block):
    """Set used values as attributes of the box object."""
    # cb = containing block
    cb_width = containing_block.width
    cb_height = containing_block.height
    if isinstance(box, boxes.PageBox):
        maybe_height = cb_height
    else:
        maybe_height = cb_width
    resolve_one_percentage(box, 'margin_left', cb_width, ['auto'])
    resolve_one_percentage(box, 'margin_right', cb_width, ['auto'])
    resolve_one_percentage(box, 'margin_top', maybe_height, ['auto'])
    resolve_one_percentage(box, 'margin_bottom', maybe_height, ['auto'])
    resolve_one_percentage(box, 'padding_left', cb_width)
    resolve_one_percentage(box, 'padding_right', cb_width)
    resolve_one_percentage(box, 'padding_top', maybe_height)
    resolve_one_percentage(box, 'padding_bottom', maybe_height)
    resolve_one_percentage(box, 'text_indent', cb_width)
    resolve_one_percentage(box, 'min_width', cb_width)
    resolve_one_percentage(box, 'max_width', cb_width, ['none'])
    resolve_one_percentage(box, 'width', cb_width, ['auto'])

    # TODO: background-position?
    # XXX later: top, bottom, left and right on positioned elements

    if cb_height == 'auto':
        # Special handling when the height of the containing block
        # depends on its content.
        resolve_one_percentage(box, 'min_height', 0)
        resolve_one_percentage(box, 'max_height', None, ['none'])
        resolve_one_percentage(box, 'height', 'auto', ['auto'])
    else:
        resolve_one_percentage(box, 'min_height', cb_height)
        resolve_one_percentage(box, 'max_height', cb_height, ['none'])
        resolve_one_percentage(box, 'height', cb_height, ['auto'])

    # Used value == computed value
    for side in ['top', 'right', 'bottom', 'left']:
        prop = 'border_{}_width'.format(side)
        values = getattr(box.style, prop)
        pixels = values
        setattr(box, prop, pixels)

@@ -2922,246 +2922,183 @@
 x, '
-text_indent', cb_width)%0A    resolve_one_percentage(box, 'min_width', cb_width)%0A    resolve_one_percentage(box, 'max_width', cb_width, %5B'none'%5D)%0A    resolve_one_percentage(box, 'width', cb_width, %5B'auto'%5D)%0A%0A    # TODO: background-position?
+width', cb_width, %5B'auto'%5D)%0A    # Not supported yet:%0A#    resolve_one_percentage(box, 'min_width', cb_width)%0A#    resolve_one_percentage(box, 'max_width', cb_width, %5B'none'%5D)%0A
 %0A   
@@ -3321,36 +3321,32 @@
 ercentage(box, '
-min_
 height', 0)%0A    
@@ -3342,11 +3342,56 @@
 t', 
-0)%0A
+'auto', %5B'auto'%5D)%0A        # Not supported yet:%0A#
     
@@ -3416,34 +3416,34 @@
 rcentage(box, 'm
-ax
+in
 _height', None, 
@@ -3440,24 +3440,12 @@
 t', 
-None, %5B'none'%5D
+0
 )%0A
+#
     
@@ -3469,32 +3469,36 @@
 ercentage(box, '
+max_
 height', 'auto',
@@ -3486,38 +3486,36 @@
 ax_height', 
-'auto', %5B'auto
+None, %5B'none
 '%5D)%0A    else
@@ -3545,36 +3545,32 @@
 ercentage(box, '
-min_
 height', cb_heig
@@ -3567,26 +3567,66 @@
 ', cb_height
-)%0A
+, %5B'auto'%5D)%0A        # Not supported yet:%0A#
         reso
@@ -3643,34 +3643,34 @@
 rcentage(box, 'm
-ax
+in
 _height', cb_hei
@@ -3672,28 +3672,19 @@
 b_height
-, %5B'none'%5D
 )%0A
+#
         
@@ -3704,32 +3704,36 @@
 ercentage(box, '
+max_
 height', cb_heig
@@ -3734,28 +3734,28 @@
 b_height, %5B'
-auto
+none
 '%5D)%0A%0A    # U
@@ -3892,97 +3892,40 @@
     
-values = getattr(box.style, prop)%0A        pixels = values%0A        setattr(box, prop, pixels
+setattr(box, prop, box.style%5Bprop%5D
 )%0A

Remove or comment unused percentage stuff.