module RubyXL::OOXMLObjectInstanceMethods

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 dup

def dup
  new_copy = super
  new_copy.count = 0 if obtain_class_variable(:@@ooxml_countable, false)
  new_copy
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)
  instance_variable_set("@count", 0) if obtain_class_variable(:@@ooxml_countable, false)
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)

Creates a new Nokogiti::XML and
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
  attrs = obtain_class_variable(:@@ooxml_namespaces).dup
  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 :float then val.to_s.gsub(/\.0*$/, '') # 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