module DocxGenerator
  class Document
    attr_reader :filename
  
    def initialize(filename)
      @filename = filename
      @content = []
    end
    
    def save
      content_types = generate_content_types
      rels = generate_rels
      document = generate_document
      
      Zip::Archive.open(@filename + ".docx", Zip::CREATE | Zip::TRUNC) do |docx|
        docx.add_dir('_rels')
        docx.add_dir('word')
        docx.add_buffer('[Content_Types].xml', content_types)
        docx.add_buffer('_rels/.rels', rels)
        docx.add_buffer('word/document.xml', document)
      end
    end
    
    # text_fragments : Word::Text or String
    # Later: Paragraph Object, with Text Object
    def add_paragraph(*text_fragments)
      content = []
      text_fragments.each do |text_fragment|
        content.push(text_fragment.respond_to?(:generate) ? text_fragment : text(text_fragment))
        content.push Word::Extensions.space
      end
      content.pop
      @content.push Word::Paragraph.new({}, content)
      self
    end
    
    def text(text_fragment, arguments = {})
      content = []
      if arguments.length != 0
        options = []
        arguments.each do |option, value|
          options.push parse_option(option, value)
        end
        content.push Word::RunProperties.new({}, options)
      end
      content.push Word::Text.new({}, [text_fragment])
      Word::Run.new({}, content)
    end
    
    private
    
      def generate_content_types
        <<EOF
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
  <Default Extension="xml" ContentType="application/xml"/>
  <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
</Types>
EOF
      end
      
      def generate_rels
        <<EOF
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
</Relationships>
EOF
      end
      
      def generate_document
        '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
        Word::Document.new({ "xmlns:w" => "http://schemas.openxmlformats.org/wordprocessingml/2006/main" },
          [ Word::Body.new({}, @content) ]).to_s
      end
      
      def parse_option(option, value)
        case option
          when :bold then Word::Bold.new(value)
          when :italics then Word::Italics.new(value)
        end
      end
  end
end