#!/usr/bin/ruby

require 'find'

def parse_css_color(value)
  value.strip!
  if /#([0-9A-F]{6})/i =~ value
    red = $1.slice(0, 2).to_i(16)
    green = $1.slice(2, 2).to_i(16)
    blue = $1.slice(4, 2).to_i(16)
  elsif /rgb\((\d+), (\d+), (\d+)\)/ =~ value
    red = $1.to_i
    green = $2.to_i
    blue = $3.to_i
  else
    raise "Unexpected color format: #{value}"
  end
  
  [red, green, blue]
end

def format_css_color(color)
  "rgb(#{color[0]}, #{color[1]}, #{color[2]})"
end

def mix_values(x, y, proportion)
  (x.to_f * proportion + y.to_f * (1 - proportion)).to_i
end

def mix_colors(a, b, proportion)
  red = mix_values(a[0], b[0], proportion)
  green = mix_values(a[1], b[1], proportion)
  blue = mix_values(a[2], b[2], proportion)
  return [red, green, blue]
end



OutDir = '../src/org/rstudio/studio/client/workbench/views/source/editors/text/themes'

Find.find('ace/lib/ace/theme/') do |file|
  next if FileTest.directory?(file)
  next unless file =~ /([^\\\/]+)\.css$/

  style_name = "ace-#{$1.gsub(/_/, '-')}"

  next if style_name == 'ace-github'
  style_name = 'ace-tm' if style_name == 'ace-textmate'

  puts style_name

  rules = File.read(file)

  raise "File #{file} needs explicit style name" unless rules =~ /\.#{style_name}\b/

  rules.gsub!(/\.#{style_name} ?/, '')
  
  raise "No keyword color found for #{style_name}" unless /\.ace_keyword\b.*?\s+(color:[^;\n]+)/m =~ rules
  rules += "\n.nocolor.ace_editor .ace_line span {#{$1} !important;}"
  
  raise "No bracket color found for #{style_name}" unless /\.ace_bracket\b.*?\s+border: 1px solid ([^;\n]+)/m =~ rules
  rules += "\n.ace_bracket {margin: 0 !important; border: 0 !important; background-color: #{$1};}"

  if /\.ace_scroller\b.*?\s+background-color: ([^;\n]+)/m =~ rules
    background = $1
  else
    background = '#FFFFFF'
  end
  raise "No text color found for #{style_name}" unless /\.ace_text-layer\b.*?\s+color: ([^;\n]+)/m =~ rules
  foreground = $1
  background = parse_css_color(background)
  foreground = parse_css_color(foreground)
  foreign_bg = format_css_color(mix_colors(background, foreground, 0.8))
  rules += "\n.ace_marker-layer .ace_foreign_line {position: absolute; z-index: -1; background-color: #{foreign_bg};}"

  find_bg = format_css_color(mix_colors(background, foreground, 0.5))
  rules += "\n.ace_marker-layer .ace_find_line {position: absolute; z-index: -1; background-color: #{find_bg};}"
  

  newfile = "#{OutDir}/#{File.basename(file).gsub(/\.js$/, '.css')}"
  File.open(newfile, 'w') {|f| f.write(rules)}
end