class RubyXL::Writer::StylesWriter

def hash_equal(h1,h2)

def hash_equal(h1,h2)
  if h1.nil?
    if h2.nil?
      return true
    else
      return false
    end
  elsif h2.nil?
    return false
  end
  if h1.size != h2.size
    return false
  end
  h1.each do |k,v|
    if (h1[k].is_a?String) || (h2[k].is_a?String)
      if (h1.is_a?Hash) && (h2.is_a?Hash)
        unless hash_equal(h1[k].to_s,h2[k].to_s)
          return false
        end
      else
        unless h1[k].to_s == h2[k].to_s
          return false
        end
      end
    else
      unless h1[k] == h2[k]
        return false
      end
    end
  end
  true
end

def initialize(dirpath, wb)

def initialize(dirpath, wb)
  @dirpath = dirpath
  @workbook = wb
  @filepath = @dirpath + '/xl/styles.xml'
end

def write()

def write()
  font_id_corrector = {}
  fill_id_corrector = {}
  border_id_corrector = {}
  style_id_corrector = {}
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.styleSheet('xmlns'=>"http://schemas.openxmlformats.org/spreadsheetml/2006/main") {
      unless @workbook.num_fmts.nil? || @workbook.num_fmts[:attributes].nil?
        xml.numFmts('count'=>@workbook.num_fmts[:attributes][:count].to_s) {
          @workbook.num_fmts[:numFmt].each do |fmt|
            attributes = fmt[:attributes]
            xml.numFmt('numFmtId'=>attributes[:numFmtId].to_s,
              'formatCode'=>attributes[:formatCode].to_s)
          end
        }
      end
      offset = 0
      #default font should stay the same
      font_id_corrector['0']=0
      1.upto(@workbook.fonts.size-1) do |i|
        font_id_corrector[i.to_s] = i-offset
        if @workbook.fonts[i.to_s][:count] == 0
          @workbook.fonts[i.to_s] = nil
          font_id_corrector[i.to_s] = nil
          offset += 1
        end
      end
      offset = 0
      #STARTS AT 2 because excel is stupid
      #and it seems to hard code access the first
      #2 styles.............
      fill_id_corrector['0']=0
      fill_id_corrector['1']=1
      2.upto(@workbook.fills.size-1) do |i|
        fill_id_corrector[i.to_s] = i-offset
        if @workbook.fills[i.to_s][:count] == 0
          @workbook.fills[i.to_s] = nil
          fill_id_corrector[i.to_s] = nil
          offset += 1
        end
      end
      #sets index to itself as init correction
      #if items deleted, indexes adjusted
      #that id 'corrects' to nil
      offset = 0
      #default border should stay the same
      border_id_corrector['0'] = 0
      1.upto(@workbook.borders.size-1) do |i|
        border_id_corrector[i.to_s] = i-offset
        if @workbook.borders[i.to_s][:count] == 0
          @workbook.borders[i.to_s] = nil
          border_id_corrector[i.to_s] = nil
          offset += 1
        end
      end
      if !@workbook.cell_xfs[:xf].is_a?(Array)
        @workbook.cell_xfs[:xf] = [@workbook.cell_xfs[:xf]]
      end
      
      
      style_id_corrector['0']=0
      delete_list = []
      i = 1
      while(i < @workbook.cell_xfs[:xf].size) do
        if style_id_corrector[i.to_s].nil?
          style_id_corrector[i.to_s]= i
        end
        # style correction commented out until bug is fixed
        j = i+1
        while(j < @workbook.cell_xfs[:xf].size) do
          if hash_equal(@workbook.cell_xfs[:xf][i],@workbook.cell_xfs[:xf][j]) #check if this is working
            style_id_corrector[j.to_s] = i
            delete_list << j
          end
          j += 1
        end
        i += 1
      end
      
      #go through delete list, if before delete_list index 0, offset 0, if before delete_list index 1, offset 1, etc.
      delete_list.sort!
      i = 1
      offset = 0
      offset_corrector = 0
      delete_list << @workbook.cell_xfs[:xf].size
      while offset < delete_list.size do
        delete_index = delete_list[offset] - offset
        while i <= delete_list[offset] do #if <= instead of <, fixes odd border but adds random cells with fill              
          if style_id_corrector[i.to_s] == i
            style_id_corrector[i.to_s] -= offset# unless style_id_corrector[i.to_s].nil? #173 should equal 53, not 52?
          end
          i += 1
        end
        @workbook.cell_xfs[:xf].delete_at(delete_index)
        offset += 1
      end
      
      @workbook.style_corrector = style_id_corrector
      xml.fonts('count'=>@workbook.fonts.size) {
        0.upto(@workbook.fonts.size-1) do |i|
          font = @workbook.fonts[i.to_s]
          unless font.nil?
            font = font[:font]
            xml.font {
              xml.sz('val'=>font[:sz][:attributes][:val].to_s)
              unless font[:b].nil?
                xml.b
              end
              unless font[:i].nil?
                xml.i
              end
              unless font[:u].nil?
                xml.u
              end
              unless font[:strike].nil?
                xml.strike
              end
              unless font[:color].nil?
                unless font[:color][:attributes][:indexed].nil?
                  xml.color('indexed'=>font[:color][:attributes][:indexed])
                else
                  unless font[:color][:attributes][:rgb].nil?
                    xml.color('rgb'=>font[:color][:attributes][:rgb])
                  else
                    unless font[:color][:attributes][:theme].nil?
                      xml.color('theme'=>font[:color][:attributes][:theme])
                    end
                  end
                end
              end
              unless font[:family].nil?
                xml.family('val'=>font[:family][:attributes][:val].to_s)
              end
              unless font[:scheme].nil?
                xml.scheme('val'=>font[:scheme][:attributes][:val].to_s)
              end
              xml.name('val'=>font[:name][:attributes][:val].to_s)
            }
          end
        end
      }
      xml.fills('count'=>@workbook.fills.size) {
        0.upto(@workbook.fills.size-1) do |i|
          fill = @workbook.fills[i.to_s]
          unless fill.nil?
            fill = fill[:fill]
            xml.fill {
              xml.patternFill('patternType'=>fill[:patternFill][:attributes][:patternType].to_s) {
                unless fill[:patternFill][:fgColor].nil?
                  fgColor = fill[:patternFill][:fgColor][:attributes]
                  unless fgColor[:indexed].nil?
                    xml.fgColor('indexed'=>fgColor[:indexed].to_s)
                  else
                    unless fgColor[:rgb].nil?
                      xml.fgColor('rgb'=>fgColor[:rgb])
                    end
                  end
                end
                unless fill[:patternFill][:bgColor].nil?
                  bgColor = fill[:patternFill][:bgColor][:attributes]
                  unless bgColor[:indexed].nil?
                    xml.bgColor('indexed'=>bgColor[:indexed].to_s)
                  else
                    unless bgColor[:rgb].nil?
                      xml.bgColor('rgb'=>bgColor[:rgb])
                    end
                  end
                end
              }
            }
          end
        end
      }
      xml.borders('count'=>@workbook.borders.size) {
        0.upto(@workbook.borders.size-1) do |i|
          border = @workbook.borders[i.to_s]
          unless border.nil?
            border = border[:border]
            xml.border {
              if border[:left][:attributes].nil?
                xml.left
              else
                xml.left('style'=>border[:left][:attributes][:style]) {
                  unless border[:left][:color].nil?
                    color = border[:left][:color][:attributes]
                    unless color[:indexed].nil?
                      xml.color('indexed'=>color[:indexed])
                    else
                      unless color[:rgb].nil?
                        xml.color('rgb'=>color[:rgb])
                      end
                    end
                  end
                }
              end
              if border[:right][:attributes].nil?
                xml.right
              else
                xml.right('style'=>border[:right][:attributes][:style]) {
                  unless border[:right][:color].nil?
                    color = border[:right][:color][:attributes]
                    unless color[:indexed].nil?
                      xml.color('indexed'=>color[:indexed])
                    else
                      unless color[:rgb].nil?
                        xml.color('rgb'=>color[:rgb])
                      end
                    end
                  end
                }
              end
              if border[:top][:attributes].nil?
                xml.top
              else
                xml.top('style'=>border[:top][:attributes][:style]) {
                  unless border[:top][:color].nil?
                    color = border[:top][:color][:attributes]
                    unless color[:indexed].nil?
                      xml.color('indexed'=>color[:indexed])
                    else
                      unless color[:rgb].nil?
                        xml.color('rgb'=>color[:rgb])
                      end
                    end
                  end
                }
              end
              if border[:bottom][:attributes].nil?
                xml.bottom
              else
                xml.bottom('style'=>border[:bottom][:attributes][:style]) {
                  unless border[:bottom][:color].nil?
                    color = border[:bottom][:color][:attributes]
                    unless color[:indexed].nil?
                      xml.color('indexed'=>color[:indexed])
                    else
                      unless color[:rgb].nil?
                        xml.color('rgb'=>color[:rgb])
                      end
                    end
                  end
                }
              end
              if border[:diagonal][:attributes].nil?
                xml.diagonal
              else
                xml.diagonal('style'=>border[:diagonal][:attributes][:style]) {
                  unless border[:diagonal][:color].nil?
                    color = border[:diagonal][:color][:attributes]
                    unless color[:indexed].nil?
                      xml.color('indexed'=>color[:indexed])
                    else
                      unless color[:rgb].nil?
                        xml.color('rgb'=>color[:rgb])
                      end
                    end
                  end
                }
              end
            }
          end #unless border.nil?
        end #0.upto(size)
      }
      xml.cellStyleXfs('count'=>@workbook.cell_style_xfs[:attributes][:count].to_s) {
        @workbook.cell_style_xfs[:xf].each do |style|
          style = @workbook.get_style_attributes(style)
          xml.xf('numFmtId'=>style[:numFmtId].to_s,
          'fontId'=>font_id_corrector[style[:fontId].to_s].to_s,
          'fillId'=>fill_id_corrector[style[:fillId].to_s].to_s,
          'borderId'=>border_id_corrector[style[:borderId].to_s].to_s)
        end
      }
      xml.cellXfs('count'=>@workbook.cell_xfs[:xf].size) {
        @workbook.cell_xfs[:xf].each do |xf_obj|
          xf = @workbook.get_style_attributes(xf_obj)
          xml.xf('numFmtId'=>xf[:numFmtId].to_s,
          'fontId'=>font_id_corrector[xf[:fontId].to_s].to_s,
          'fillId'=>fill_id_corrector[xf[:fillId].to_s].to_s,
          'borderId'=>border_id_corrector[xf[:borderId].to_s].to_s,
          'xfId'=>xf[:xfId].to_s,
          'applyFont'=>xf[:applyFont].to_i.to_s, #0 if nil
          'applyFill'=>xf[:applyFill].to_i.to_s,
          'applyAlignment'=>xf[:applyAlignment].to_i.to_s,
          'applyNumberFormat'=>xf[:applyNumberFormat].to_i.to_s) {
            unless xf_obj.is_a?Array
              unless xf_obj[:alignment].nil?
                xml.alignment('horizontal'=>xf_obj[:alignment][:attributes][:horizontal].to_s,
                              'vertical'=>xf_obj[:alignment][:attributes][:vertical].to_s,
                              'wrapText'=>xf_obj[:alignment][:attributes][:wrapText].to_s)
              end
            end
          }
        end
      }
      xml.cellStyles('count'=>@workbook.cell_styles[:attributes][:count].to_s) {
        @workbook.cell_styles[:cellStyle].each do |style|
          style = @workbook.get_style_attributes(style)
          xml.cellStyle('name'=>style[:name].to_s,
          'xfId'=>style[:xfId].to_s,
          'builtinId'=>style[:builtinId].to_s)
        end
      }
      xml.dxfs('count'=>'0')
      xml.tableStyles('count'=>'0', 'defaultTableStyle'=>'TableStyleMedium9')
      unless @colors.nil?
        xml.colors {
          unless @colors[:indexedColors].nil?
            xml.indexedColors {
              @colors[:indexedColors].each do |rgb_color|
                xml.rgbColor rgb_color[:attributes][:rgb]
              end
            }
          end
          unless @colors[:mruColors].nil?
            xml.mruColors {
              @colors[:mruColors].each do |color|
                xml.color color[:attributes][:rgb]
              end
            }
          end
        }
      end
    }
  end
  contents = builder.to_xml
  contents = contents.gsub(/\n/,'')
  contents = contents.gsub(/>(\s)+</,'><')
  contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
  contents
end