# frozen_string_literal: true

require_relative 'paragraph_properties/numbering_properties'
require_relative 'paragraph_properties/paragraph_borders'
require_relative 'paragraph_properties/paragraph_spacing'
require_relative 'paragraph_properties/paragraph_style_ref'
require_relative 'paragraph_properties/spacing'
require_relative 'paragraph_properties/tabs'
require_relative 'paragraph_properties/bullet_image'
module OoxmlParser
  # Class for data for ParagraphProperties
  class ParagraphProperties < OOXMLDocumentObject
    attr_accessor :align, :numbering, :level, :spacing, :spacing_before, :spacing_after, :indent, :margin_left, :margin_right
    # @return [FrameProperties] frame properties
    attr_reader :frame_properties
    # @return [Tabs] list of tabs
    attr_accessor :tabs
    # @return [RunProperties] properties of run
    attr_accessor :run_properties
    # @return [Borders] borders of paragraph
    attr_accessor :paragraph_borders
    # @return [ParagraphStyleRef] Referenced Paragraph Style
    attr_accessor :paragraph_style_ref
    # @return [True, False] Specifies that the paragraph
    # (or at least part of it) should be rendered on
    # the same page as the next paragraph when possible
    attr_accessor :keep_next
    # @return [PageProperties] properties of section
    attr_accessor :section_properties
    # @return [True, False] This element specifies that any space specified
    # before or after this paragraph, specified using the spacing element (17.3.1.33),
    # should not be applied when the preceding and following paragraphs are of
    # the same paragraph style, affecting the top and bottom spacing respectively
    attr_accessor :contextual_spacing
    # @return [Symbol] The alignment or justification to be applied to a paragraph
    attr_accessor :justification
    # @return [Shade] Shade property
    attr_accessor :shade

    def initialize(numbering = NumberingProperties.new, parent: nil)
      @numbering = numbering
      @spacing = Spacing.new(OoxmlSize.new(0),
                             OoxmlSize.new(0),
                             OoxmlSize.new(1, :centimeter),
                             :multiple)
      @keep_next = false
      @tabs = []
      super(parent: parent)
    end

    # Parse ParagraphProperties object
    # @param node [Nokogiri::XML:Element] node to parse
    # @return [ParagraphProperties] result of parsing
    def parse(node)
      @spacing.parse(node)
      node.attributes.each do |key, value|
        case key
        when 'algn'
          @align = value_to_symbol(value)
        when 'lvl'
          @level = value.value.to_i
        when 'indent'
          @indent = OoxmlSize.new(value.value.to_f, :emu)
        when 'marR'
          @margin_right = OoxmlSize.new(value.value.to_f, :emu)
        when 'marL'
          @margin_left = OoxmlSize.new(value.value.to_f, :emu)
        end
      end
      node.xpath('*').each do |node_child|
        case node_child.name
        when 'buSzPct'
          @numbering.size = node_child.attribute('val').value
        when 'buFont'
          @numbering.font = node_child.attribute('typeface').value
        when 'buChar'
          @numbering.symbol = node_child.attribute('char').value
        when 'buBlip'
          @numbering.image = BulletImage.new(parent: self).parse(node_child)
        when 'buAutoNum'
          @numbering.type = node_child.attribute('type').value.to_sym
          @numbering.start_at = node_child.attribute('startAt').value if node_child.attribute('startAt')
        when 'framePr'
          @frame_properties = FrameProperties.new(parent: self).parse(node_child)
        when 'tabs', 'tabLst'
          @tabs = Tabs.new(parent: self).parse(node_child)
        when 'ind'
          @indent = Indents.new(parent: self).parse(node_child)
        when 'rPr'
          @run_properties = RunProperties.new(parent: self).parse(node_child)
        when 'pBdr'
          @paragraph_borders = ParagraphBorders.new(parent: self).parse(node_child)
        when 'pStyle'
          @paragraph_style_ref = ParagraphStyleRef.new(parent: self).parse(node_child)
        when 'keepNext'
          @keep_next = true
        when 'sectPr'
          @section_properties = PageProperties.new(parent: self).parse(node_child, @parent, DocxParagraphRun.new)
        when 'shd'
          @shade = Shade.new(parent: self).parse(node_child)
        when 'spacing'
          @spacing = ParagraphSpacing.new(parent: self).parse(node_child)
        when 'jc'
          @justification_object = ValuedChild.new(:string, parent: self).parse(node_child)
          @justification = value_to_symbol(@justification_object)
        when 'contextualSpacing'
          contextual_spacing_object = ValuedChild.new(:boolean, parent: self).parse(node_child)
          @contextual_spacing = contextual_spacing_object.value
        end
      end
      self
    end
  end
end
