module RubyXL::OOXMLObjectInstanceMethods

def self.included(klass)

def self.included(klass)
  klass.extend RubyXL::OOXMLObjectClassMethods
end

def ==(other)

def ==(other)
  other.is_a?(self.class) &&
    obtain_class_variable(:@@ooxml_attributes).all? { |k, v| self.send(v[:accessor]) == other.send(v[:accessor]) } &&
    obtain_class_variable(:@@ooxml_child_nodes).all? { |k, v| self.send(v[:accessor]) == other.send(v[:accessor]) }
end

def before_write_xml

the collection's root node if the collection is empty).
along with option to terminate the actual write if +false+ is returned (for example, to avoid writing
Subclass provided filter to perform last-minute operations (cleanup, count, etc.) immediately prior to write,
def before_write_xml
  #TODO# This will go away once containers are fully implemented.
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
  child_nodes.each_pair { |child_node_name, child_node_params|
    self.count = self.send(child_node_params[:accessor]).size if child_node_params[:is_array] == :with_count
  }
  true
end

def get_node_object(child_node_params)

def get_node_object(child_node_params)
  self.send(child_node_params[:accessor])
end

def index_in_collection

to the end of the collection.
is expected to reside in the collection. If +nil+ is returned, then object is simply added
Prototype method. For sparse collections (+Rows+, +Cells+, etc.) must return index at which this object
def index_in_collection
  nil
end

def init_child_nodes(params)

def init_child_nodes(params)
  obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
    initial_value =
      if params.has_key?(v[:accessor]) then params[v[:accessor]]
      elsif v[:is_array] then []
      else nil
      end
    instance_variable_set("@#{v[:accessor]}", initial_value)
  }
end

def initialize(params = {})

def initialize(params = {})
  obtain_class_variable(:@@ooxml_attributes).each_value { |v|
    instance_variable_set("@#{v[:accessor]}", params[v[:accessor]]) unless v[:computed]
  }
  init_child_nodes(params)
end

def obtain_class_variable(var_name, default = {})

def obtain_class_variable(var_name, default = {})
  self.class.obtain_class_variable(var_name, default)
end

def write_xml(xml = nil, node_name_override = nil)

Same as above, but uses the passed-in +node_name_override+ as the new element name, instead of its default name set by +define_element_name+.
obj.write_xml(seed_xml, 'overriden_element_name')
Using the passed-in +Nokogiri+ +xml+ object, creates a new element corresponding to +obj+ according to its definition, along with all its properties and children, and returns the newly created element.
obj.write_xml(seed_xml)
Creates a new empty +Nokogiri::XML+, populates it with the OOXML structure as described in the respective definition, and returns the resulting +Nokogiri::XML+ object.
obj.write_xml()
==== Examples
* +node_name_override+ - if present, is used instead of the default element name for this object provided by +define_element_name+
* +xml+ - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.
=== Parameters
can be used without additional +nil+ checking)
returns +false+, an empty string is returned (rather than +nil+, so Nokogiri::XML's << operator
generation, +before_write_xml()+ is called to perform last-minute cleanup and validation operations; if it
Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual
def write_xml(xml = nil, node_name_override = nil)
  if xml.nil? then
    seed_xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
    seed_xml.encoding = 'UTF-8'
    result = self.write_xml(seed_xml)
    return result if result == ''
    seed_xml << result
    return seed_xml.to_xml({ :indent => 0, :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML })
  end
  return '' unless before_write_xml
  # Populate namespaces, if any
  attrs = {}
  obtain_class_variable(:@@ooxml_namespaces).each_pair { |k, v| attrs[v.empty? ? 'xmlns' : "xmlns:#{v}"] = k }
  obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|
    val = self.send(v[:accessor])
    if val.nil? then
      next unless v[:required]
      val = v[:default]
    end
    val = val &&
            case v[:attr_type]
            when :bool   then val ? '1' : '0'
            when :double then val.to_s.gsub(/\.0*\Z/, '') # Trim trailing zeroes
            else val
            end
    attrs[k] = val
  }
  element_text = attrs.delete('_')
  elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
  child_nodes.each_pair { |child_node_name, child_node_params|
    node_obj = get_node_object(child_node_params)
    next if node_obj.nil?
    if node_obj.respond_to?(:write_xml) && !node_obj.equal?(self) then
      # If child node is either +OOXMLObject+, or +OOXMLContainerObject+ on its first (envelope) pass,
      # serialize that object.
      elem << node_obj.write_xml(xml, child_node_name)
    else
      # If child node is either vanilla +Array+, or +OOXMLContainerObject+ on its seconds (content) pass,
      # serialize write its members.
      node_obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
    end
  }
  elem
end