# encoding: utf-8

"""
Step implementations for section-related features
"""

from __future__ import absolute_import, print_function, unicode_literals

from behave import given, then, when

from docx import Document
from docx.enum.section import WD_ORIENT, WD_SECTION
from docx.section import Section
from docx.shared import Inches

from helpers import test_docx


# given ====================================================

@given("a Section object as section")
def given_a_Section_object_as_section(context):
    context.section = Document(test_docx("sct-section-props")).sections[-1]


@given("a Section object {with_or_without} a distinct first-page header as section")
def given_a_Section_object_with_or_without_first_page_header(context, with_or_without):
    section_idx = {"with": 1, "without": 0}[with_or_without]
    context.section = Document(test_docx("sct-first-page-hdrftr")).sections[section_idx]


@given('a section collection containing 3 sections')
def given_a_section_collection_containing_3_sections(context):
    document = Document(test_docx('doc-access-sections'))
    context.sections = document.sections


@given('a section having known page dimension')
def given_a_section_having_known_page_dimension(context):
    document = Document(test_docx('sct-section-props'))
    context.section = document.sections[-1]


@given('a section having known page margins')
def given_a_section_having_known_page_margins(context):
    document = Document(test_docx('sct-section-props'))
    context.section = document.sections[0]


@given('a section having start type {start_type}')
def given_a_section_having_start_type(context, start_type):
    section_idx = {
        'CONTINUOUS': 0,
        'NEW_PAGE':   1,
        'ODD_PAGE':   2,
        'EVEN_PAGE':  3,
        'NEW_COLUMN': 4,
    }[start_type]
    document = Document(test_docx('sct-section-props'))
    context.section = document.sections[section_idx]


@given('a section known to have {orientation} orientation')
def given_a_section_having_known_orientation(context, orientation):
    section_idx = {
        'landscape': 0,
        'portrait':  1
    }[orientation]
    document = Document(test_docx('sct-section-props'))
    context.section = document.sections[section_idx]


# when =====================================================

@when("I assign {bool_val} to section.different_first_page_header_footer")
def when_I_assign_value_to_section_different_first_page_hdrftr(context, bool_val):
    context.section.different_first_page_header_footer = eval(bool_val)


@when('I set the {margin_side} margin to {inches} inches')
def when_I_set_the_margin_side_length(context, margin_side, inches):
    prop_name = {
        'left':   'left_margin',
        'right':  'right_margin',
        'top':    'top_margin',
        'bottom': 'bottom_margin',
        'gutter': 'gutter',
        'header': 'header_distance',
        'footer': 'footer_distance',
    }[margin_side]
    new_value = Inches(float(inches))
    setattr(context.section, prop_name, new_value)


@when('I set the section orientation to {orientation}')
def when_I_set_the_section_orientation(context, orientation):
    new_orientation = {
        'WD_ORIENT.PORTRAIT':  WD_ORIENT.PORTRAIT,
        'WD_ORIENT.LANDSCAPE': WD_ORIENT.LANDSCAPE,
        'None':                None,
    }[orientation]
    context.section.orientation = new_orientation


@when('I set the section page height to {y} inches')
def when_I_set_the_section_page_height_to_y_inches(context, y):
    context.section.page_height = Inches(float(y))


@when('I set the section page width to {x} inches')
def when_I_set_the_section_page_width_to_x_inches(context, x):
    context.section.page_width = Inches(float(x))


@when('I set the section start type to {start_type}')
def when_I_set_the_section_start_type_to_start_type(context, start_type):
    new_start_type = {
        'None':       None,
        'CONTINUOUS': WD_SECTION.CONTINUOUS,
        'EVEN_PAGE':  WD_SECTION.EVEN_PAGE,
        'NEW_COLUMN': WD_SECTION.NEW_COLUMN,
        'NEW_PAGE':   WD_SECTION.NEW_PAGE,
        'ODD_PAGE':   WD_SECTION.ODD_PAGE,
    }[start_type]
    context.section.start_type = new_start_type


# then =====================================================

@then('I can access a section by index')
def then_I_can_access_a_section_by_index(context):
    sections = context.sections
    for idx in range(3):
        section = sections[idx]
        assert isinstance(section, Section)


@then('I can iterate over the sections')
def then_I_can_iterate_over_the_sections(context):
    sections = context.sections
    actual_count = 0
    for section in sections:
        actual_count += 1
        assert isinstance(section, Section)
    assert actual_count == 3


@then('len(sections) is 3')
def then_len_sections_is_3(context):
    sections = context.sections
    assert len(sections) == 3, (
        'expected len(sections) of 3, got %s' % len(sections)
    )


@then("section.different_first_page_header_footer is {bool_val}")
def then_section_different_first_page_header_footer_is(context, bool_val):
    actual = context.section.different_first_page_header_footer
    expected = eval(bool_val)
    assert actual == expected, (
        "section.different_first_page_header_footer is %s" % actual
    )


@then("section.even_page_footer is a _Footer object")
def then_section_even_page_footer_is_a_Footer_object(context):
    actual = type(context.section.even_page_footer).__name__
    expected = "_Footer"
    assert actual == expected, "section.even_page_footer is a %s object" % actual


@then("section.even_page_header is a _Header object")
def then_section_even_page_header_is_a_Header_object(context):
    actual = type(context.section.even_page_header).__name__
    expected = "_Header"
    assert actual == expected, "section.even_page_header is a %s object" % actual


@then("section.first_page_footer is a _Footer object")
def then_section_first_page_footer_is_a_Footer_object(context):
    actual = type(context.section.first_page_footer).__name__
    expected = "_Footer"
    assert actual == expected, "section.first_page_footer is a %s object" % actual


@then("section.first_page_header is a _Header object")
def then_section_first_page_header_is_a_Header_object(context):
    actual = type(context.section.first_page_header).__name__
    expected = "_Header"
    assert actual == expected, "section.first_page_header is a %s object" % actual


@then("section.footer is a _Footer object")
def then_section_footer_is_a_Footer_object(context):
    actual = type(context.section.footer).__name__
    expected = "_Footer"
    assert actual == expected, "section.footer is a %s object" % actual


@then("section.header is a _Header object")
def then_section_header_is_a_Header_object(context):
    actual = type(context.section.header).__name__
    expected = "_Header"
    assert actual == expected, "section.header is a %s object" % actual


@then("section.{propname}.is_linked_to_previous is True")
def then_section_hdrftr_prop_is_linked_to_previous_is_True(context, propname):
    actual = getattr(context.section, propname).is_linked_to_previous
    expected = True
    assert actual == expected, (
        "section.%s.is_linked_to_previous is %s" % (propname, actual)
    )


@then('the reported {margin_side} margin is {inches} inches')
def then_the_reported_margin_is_inches(context, margin_side, inches):
    prop_name = {
        'left':   'left_margin',
        'right':  'right_margin',
        'top':    'top_margin',
        'bottom': 'bottom_margin',
        'gutter': 'gutter',
        'header': 'header_distance',
        'footer': 'footer_distance',
    }[margin_side]
    expected_value = Inches(float(inches))
    actual_value = getattr(context.section, prop_name)
    assert actual_value == expected_value


@then('the reported page orientation is {orientation}')
def then_the_reported_page_orientation_is_orientation(context, orientation):
    expected_value = {
        'WD_ORIENT.LANDSCAPE': WD_ORIENT.LANDSCAPE,
        'WD_ORIENT.PORTRAIT':  WD_ORIENT.PORTRAIT,
    }[orientation]
    assert context.section.orientation == expected_value


@then('the reported page width is {x} inches')
def then_the_reported_page_width_is_width(context, x):
    assert context.section.page_width == Inches(float(x))


@then('the reported page height is {y} inches')
def then_the_reported_page_height_is_11_inches(context, y):
    assert context.section.page_height == Inches(float(y))


@then('the reported section start type is {start_type}')
def then_the_reported_section_start_type_is_type(context, start_type):
    expected_start_type = {
        'CONTINUOUS': WD_SECTION.CONTINUOUS,
        'EVEN_PAGE':  WD_SECTION.EVEN_PAGE,
        'NEW_COLUMN': WD_SECTION.NEW_COLUMN,
        'NEW_PAGE':   WD_SECTION.NEW_PAGE,
        'ODD_PAGE':   WD_SECTION.ODD_PAGE,
    }[start_type]
    assert context.section.start_type == expected_start_type

[((21, 1, 21, 37), 'behave.given', 'given', ({(21, 7, 21, 36): '"""a Section object as section"""'}, {}), "('a Section object as section')", False, 'from behave import given, then, when\n'), ((26, 1, 26, 84), 'behave.given', 'given', ({(26, 7, 26, 83): '"""a Section object {with_or_without} a distinct first-page header as section"""'}, {}), "(\n    'a Section object {with_or_without} a distinct first-page header as section'\n    )", False, 'from behave import given, then, when\n'), ((32, 1, 32, 52), 'behave.given', 'given', ({(32, 7, 32, 51): '"""a section collection containing 3 sections"""'}, {}), "('a section collection containing 3 sections')", False, 'from behave import given, then, when\n'), ((38, 1, 38, 47), 'behave.given', 'given', ({(38, 7, 38, 46): '"""a section having known page dimension"""'}, {}), "('a section having known page dimension')", False, 'from behave import given, then, when\n'), ((44, 1, 44, 45), 'behave.given', 'given', ({(44, 7, 44, 44): '"""a section having known page margins"""'}, {}), "('a section having known page margins')", False, 'from behave import given, then, when\n'), ((50, 1, 50, 50), 'behave.given', 'given', ({(50, 7, 50, 49): '"""a section having start type {start_type}"""'}, {}), "('a section having start type {start_type}')", False, 'from behave import given, then, when\n'), ((63, 1, 63, 59), 'behave.given', 'given', ({(63, 7, 63, 58): '"""a section known to have {orientation} orientation"""'}, {}), "('a section known to have {orientation} orientation')", False, 'from behave import given, then, when\n'), ((75, 1, 75, 74), 'behave.when', 'when', ({(75, 6, 75, 73): '"""I assign {bool_val} to section.different_first_page_header_footer"""'}, {}), "('I assign {bool_val} to section.different_first_page_header_footer')", False, 'from behave import given, then, when\n'), ((80, 1, 80, 58), 'behave.when', 'when', ({(80, 6, 80, 57): '"""I set the {margin_side} margin to {inches} inches"""'}, {}), "('I set the {margin_side} margin to {inches} inches')", False, 'from behave import given, then, when\n'), ((95, 1, 95, 55), 'behave.when', 'when', ({(95, 6, 95, 54): '"""I set the section orientation to {orientation}"""'}, {}), "('I set the section orientation to {orientation}')", False, 'from behave import given, then, when\n'), ((105, 1, 105, 52), 'behave.when', 'when', ({(105, 6, 105, 51): '"""I set the section page height to {y} inches"""'}, {}), "('I set the section page height to {y} inches')", False, 'from behave import given, then, when\n'), ((110, 1, 110, 51), 'behave.when', 'when', ({(110, 6, 110, 50): '"""I set the section page width to {x} inches"""'}, {}), "('I set the section page width to {x} inches')", False, 'from behave import given, then, when\n'), ((115, 1, 115, 53), 'behave.when', 'when', ({(115, 6, 115, 52): '"""I set the section start type to {start_type}"""'}, {}), "('I set the section start type to {start_type}')", False, 'from behave import given, then, when\n'), ((130, 1, 130, 40), 'behave.then', 'then', ({(130, 6, 130, 39): '"""I can access a section by index"""'}, {}), "('I can access a section by index')", False, 'from behave import given, then, when\n'), ((138, 1, 138, 40), 'behave.then', 'then', ({(138, 6, 138, 39): '"""I can iterate over the sections"""'}, {}), "('I can iterate over the sections')", False, 'from behave import given, then, when\n'), ((148, 1, 148, 27), 'behave.then', 'then', ({(148, 6, 148, 26): '"""len(sections) is 3"""'}, {}), "('len(sections) is 3')", False, 'from behave import given, then, when\n'), ((156, 1, 156, 65), 'behave.then', 'then', ({(156, 6, 156, 64): '"""section.different_first_page_header_footer is {bool_val}"""'}, {}), "('section.different_first_page_header_footer is {bool_val}')", False, 'from behave import given, then, when\n'), ((165, 1, 165, 53), 'behave.then', 'then', ({(165, 6, 165, 52): '"""section.even_page_footer is a _Footer object"""'}, {}), "('section.even_page_footer is a _Footer object')", False, 'from behave import given, then, when\n'), ((172, 1, 172, 53), 'behave.then', 'then', ({(172, 6, 172, 52): '"""section.even_page_header is a _Header object"""'}, {}), "('section.even_page_header is a _Header object')", False, 'from behave import given, then, when\n'), ((179, 1, 179, 54), 'behave.then', 'then', ({(179, 6, 179, 53): '"""section.first_page_footer is a _Footer object"""'}, {}), "('section.first_page_footer is a _Footer object')", False, 'from behave import given, then, when\n'), ((186, 1, 186, 54), 'behave.then', 'then', ({(186, 6, 186, 53): '"""section.first_page_header is a _Header object"""'}, {}), "('section.first_page_header is a _Header object')", False, 'from behave import given, then, when\n'), ((193, 1, 193, 43), 'behave.then', 'then', ({(193, 6, 193, 42): '"""section.footer is a _Footer object"""'}, {}), "('section.footer is a _Footer object')", False, 'from behave import given, then, when\n'), ((200, 1, 200, 43), 'behave.then', 'then', ({(200, 6, 200, 42): '"""section.header is a _Header object"""'}, {}), "('section.header is a _Header object')", False, 'from behave import given, then, when\n'), ((207, 1, 207, 57), 'behave.then', 'then', ({(207, 6, 207, 56): '"""section.{propname}.is_linked_to_previous is True"""'}, {}), "('section.{propname}.is_linked_to_previous is True')", False, 'from behave import given, then, when\n'), ((216, 1, 216, 61), 'behave.then', 'then', ({(216, 6, 216, 60): '"""the reported {margin_side} margin is {inches} inches"""'}, {}), "('the reported {margin_side} margin is {inches} inches')", False, 'from behave import given, then, when\n'), ((232, 1, 232, 55), 'behave.then', 'then', ({(232, 6, 232, 54): '"""the reported page orientation is {orientation}"""'}, {}), "('the reported page orientation is {orientation}')", False, 'from behave import given, then, when\n'), ((241, 1, 241, 46), 'behave.then', 'then', ({(241, 6, 241, 45): '"""the reported page width is {x} inches"""'}, {}), "('the reported page width is {x} inches')", False, 'from behave import given, then, when\n'), ((246, 1, 246, 47), 'behave.then', 'then', ({(246, 6, 246, 46): '"""the reported page height is {y} inches"""'}, {}), "('the reported page height is {y} inches')", False, 'from behave import given, then, when\n'), ((251, 1, 251, 56), 'behave.then', 'then', ({(251, 6, 251, 55): '"""the reported section start type is {start_type}"""'}, {}), "('the reported section start type is {start_type}')", False, 'from behave import given, then, when\n'), ((34, 24, 34, 56), 'helpers.test_docx', 'test_docx', ({(34, 34, 34, 55): '"""doc-access-sections"""'}, {}), "('doc-access-sections')", False, 'from helpers import test_docx\n'), ((40, 24, 40, 54), 'helpers.test_docx', 'test_docx', ({(40, 34, 40, 53): '"""sct-section-props"""'}, {}), "('sct-section-props')", False, 'from helpers import test_docx\n'), ((46, 24, 46, 54), 'helpers.test_docx', 'test_docx', ({(46, 34, 46, 53): '"""sct-section-props"""'}, {}), "('sct-section-props')", False, 'from helpers import test_docx\n'), ((59, 24, 59, 54), 'helpers.test_docx', 'test_docx', ({(59, 34, 59, 53): '"""sct-section-props"""'}, {}), "('sct-section-props')", False, 'from helpers import test_docx\n'), ((69, 24, 69, 54), 'helpers.test_docx', 'test_docx', ({(69, 34, 69, 53): '"""sct-section-props"""'}, {}), "('sct-section-props')", False, 'from helpers import test_docx\n'), ((23, 31, 23, 61), 'helpers.test_docx', 'test_docx', ({(23, 41, 23, 60): '"""sct-section-props"""'}, {}), "('sct-section-props')", False, 'from helpers import test_docx\n'), ((29, 31, 29, 65), 'helpers.test_docx', 'test_docx', ({(29, 41, 29, 64): '"""sct-first-page-hdrftr"""'}, {}), "('sct-first-page-hdrftr')", False, 'from helpers import test_docx\n')]