# coding: utf-8
#
# @package subtle
#
# @file Migrate config
# @copyright Copyright (c) 2011 Christoph Kappel <unexist@dorfelite.net>
# @version $Id$
#
# This program can be distributed under the terms of the GNU GPL.
# See the file COPYING.
#

require "pp"

def format_value(value)
  case value
    when String then "\"#{value}\""
    when Array  then value.join(", ")
    when Fixnum then value
    else value.to_s
  end
end

begin
  config  = nil
  styles  = {}
  skip    = []
  nline   = 0
  colline = nil
  ignore  = false
  lines   = nil

  # Init
  [ :title, :focus, :urgent, :occupied, :views,
    :sublets, :separator, :clients, :subtle
  ].each { |s| styles[s] = {} }

  # Check arguments
  if(0 == ARGV.size)
    # Get XDG path
    xdg_config_home = File.join((ENV["XDG_CONFIG_HOME"] ||
      File.join(ENV["HOME"], ".config")), "subtle")
    xdg_config_dir = File.join((ENV["XDG_CONFIG_DIRS"].split(":").first rescue
      File.join("/etc", "xdg")), "subtle")

    # Find config
    unless(File.exist?(config = File.join(xdg_config_home, "subtle.rb")))
      puts ">>> ERROR: Couldn't find config file"
      exit
    end
  elsif([ "--help", "-h", "help" ].include?(ARGV[0]))
    puts "Usage: %s [CONFIG]" % [ $0 ]
    puts "\nConvert color definitions to styles"
    puts "\nPlease report bugs at http://subforge.org/projects/subtle/issues"
    exit
  else
    config = ARGV[0]
  end

  puts ">>> Reading config `#{config}'"

  # Load config
  lines = IO.readlines(config)

  # Parse config
  lines.each do |line|
    case line
      # Block comments
      when /^=begin/ then ignore = true
      when /^=end/   then ignore = false

      # Options
      when /^\s*set\s*:border,\s*(\d+)/
        next if(ignore)
        value = $~[1].to_i
        styles[:clients][:active]   = value
        styles[:clients][:inactive] = value

        skip << nline
      when /^\s*set\s*:outline,\s*(\d+)/
        next if(ignore)
        value = $~[1].to_i
        styles[:title][:border]     = value
        styles[:focus][:border]     = value
        styles[:urgent][:border]    = value
        styles[:occupied][:border]  = value
        styles[:views][:border]     = value
        styles[:sublets][:border]   = value
        styles[:separator][:border] = value

        skip << nline
      when /^\s*set\s*:gap,\s*(\d+)/
        next if(ignore)
        styles[:clients][:margin] = $~[1].to_i

        skip << nline
      when /^\s*set\s*:padding,\s*\[((?:\s*(?:\d+)\s*,?)*)\]/
        next if(ignore)
        value = $~[1].split(",").map(&:to_i)

        styles[:title][:padding]     = value
        styles[:focus][:padding]     = value
        styles[:urgent][:padding]    = value
        styles[:occupied][:padding]  = value
        styles[:views][:padding]     = value
        styles[:sublets][:padding]   = value
        styles[:separator][:padding] = value

        skip << nline
      when /^\s*set\s*:strut,\s*\[((?:\s*(?:\d+)\s*,?)*)\]/
        next if(ignore)
        styles[:subtle][:padding] = $~[1].split(",").map(&:to_i)

        skip << nline

      # Colors
      when /^\s*color\s*:(\w+),\s*"(#[0-9a-fA-F]{6})/
        next if(ignore)
        name  = $~[1]
        sym   = name.split("_").first.to_sym
        color = $~[2]

        colline     ||= nline
        styles[sym] ||= {} if(styles.keys.include?(sym))

        case name
          when /^\w+_fg/     then styles[sym][:foreground]        = color
          when /^\w+_bg/     then styles[sym][:background]        = color
          when /^background/ then styles[:subtle][:background]    = color
          when /^stipple/    then styles[:subtle][:stipple]       = color
          when /^separator/  then styles[:separator][:foreground] = color
          when /^client_((?:in)?active)/
            sym = $~[1].to_sym

            # Set or append
            if(styles[:clients][sym].nil?)
              styles[:clients][sym] = color
            else
              styles[:clients][sym] = [
                format_value(color), styles[:clients][sym]
              ]
            end
          when /^panel/
            styles[:subtle][:panel]         = color
            styles[:separator][:background] = color
          when /^\w+_border/
            # Set or append
            if(styles[sym][:border].nil?)
              styles[sym][:border] = color
            else
              styles[sym][:border] = [
                format_value(color), styles[sym][:border]
              ]
            end
        end

        skip << nline
    end

    nline += 1
  end

  # Output
  filename = File.join(ENV["HOME"], "subtle.rb")
  File.open(filename, "w") do |f|
    nline = 0

    # Puts old config into new file
    lines.each do |line|
      # Replace colors by styles
      if(nline == colline)
        styles.each do |k, v|
          f.puts "style :#{k} do"

          # Arguments
          v.each do |k2, v2|
            value = format_value(v2)

            if(value.is_a?(String))
              f.puts "  %-10s  %s" % [ k2, value ]
            else
              f.puts "  %-10s  %d" % [ k2, value ]
            end
          end

          f.puts "end"
          f.puts
        end
      end

      # Puts line of not in skip list
      f.puts line unless(skip.include?(nline))

      nline += 1
    end
  end

  puts ">>> Created config `#{filename}'"

rescue => err
  puts ">>> ERROR: #{err}"
  puts err.backtrace
end
