require 'anguilla'    
require 'spongiae/unit'

##
# TMX module for Spongiae
# Not a format because producer does not use same translate method as for unilingual formats

module Spongiae
   module TMX

      class TmxCallbacks
         include REXML::StreamListener 
         
         def initialize(sub)
            @sub = sub
            @lastId = 0
         end
                  
         def tag_start(element, attributes)
            if element == 'tu'
               if attributes['tuid'] != nil then
                  @tu = Spongiae::Unit::Multilingual.new(attributes['tuid'], {})
               else
                  @tu = Spongiae::Unit::Multilingual.new(@lastId, {})
                  @lastId = @lastId + 1
               end
               @lang = nil; @where = ''
            elsif element == 'tuv'
               @lang = attributes['xml:lang']
               if @lang == '' or @lang == nil then 
                  @lang = attributes['lang'] 
               end
               @langProps = {}
            elsif element == 'seg'
               @text = ''; @prop = nil
            elsif element == 'prop'
               @text = ''; @prop = attributes['type']
            end	
         end
            
         def text(text) 
            @text = @text + text if @text != nil
         end
         
         def tag_end(element)
            if element == 'tu'
               @sub.call(@tu)
            elsif element == 'tuv'
               @lang = nil
            elsif element == 'seg'
               @tu.variants[@lang] = Spongiae::Unit::Variant.new(@lang, @langProps, @text)
            elsif element == 'prop'
               if @lang != nil then @langProps[@prop] = @text elsif @tu != nil then @tu.props[@prop] = @text end
            end
         end
           
      end
      
      class TmxReader      
         def initialize(file, props = {})
            @file = file
         end
         
         def read_unit(&sub)			
            Anguilla::parse(@file,TmxCallbacks.new(sub))
         end
      end
      
      ##
      # Takes result from Spongiae::XLIFF::read_units from various languages and merges them to TMX units
      # Parameter xliff_map is a hash { target language => { segment_id => bilingual unit } }
      def self.merge(src_lang, xliff_map, &sub)
          firstLang, firstFile = xliff_map.first
          xliff_map.delete firstLang
                    
          firstFile.each do |unitId, blUnit|
              tu = Spongiae::Unit::Multilingual.new(unitId, {})
              tu.variants[src_lang] = Spongiae::Unit::Variant.new(src_lang, nil, blUnit.srcText)
              tu.variants[firstLang] = Spongiae::Unit::Variant.new(firstLang, nil, blUnit.traText)
              xliff_map.each do |lang, langMap|
                  tu.variants[lang] = Spongiae::Unit::Variant.new(lang, nil, langMap[unitId].traText) if langMap[unitId] != nil
              end
              yield tu
          end
      end
      
      class TmxWriter
          
          def initialize(target)
            @target = target
            target.puts <<'EOF'
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tmx SYSTEM "tmx14.dtd">
<tmx version="1.4">
      <header
         creationtool="Spongiae"
         creationtoolversion="1.0"
         o-tmf="Spongiae"
         segtype="sentence"
         datatype="PlainText"
         adminlang="EN-US"
         srclang="EN-GB" />
      <body>
EOF
         end
      
         def add(tuid,tu)
            @target.puts "          <tu id=\"#{tuid}\">\n"
            tu.props.each { |k,v| @target.puts "            <prop type=\"#{k}\">#{v.encode(:xml => :text)}</prop>" } unless tu.props == nil 
            tu.variants.each do |lang, var|
               tuvProps = ''
               var.props.each { |k,v| tuvProps = tuvProps + "\n                <prop type=\"#{k}\">#{v.encode(:xml => :text)}</prop>" } unless var.props == nil 
               @target.puts <<"EOF".gsub(/\n\n/,"\n").gsub(/ >/, '>')
            <tuv xml:lang="#{lang}">#{tuvProps}
               <seg>#{var.text.encode(:xml => :text)}</seg>
            </tuv>
EOF
            end
            @target.puts "          </tu>\n"
         end
         
         def comment(text) @target.puts "          <!-- #{text} -->\n" end
         
         def close
            @target.puts "      </body>\n"
            @target.puts "</tmx>\n"
         end
      
      end

    
    end
end

