#!/usr/bin/python2.6
#
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""Generates Css.dart from css property definitions defined in WebKit."""

import tempfile, os

COMMENT_LINE_PREFIX = '   * '
SOURCE_PATH = 'Source/WebCore/css/CSSPropertyNames.in'
INPUT_URL = 'http://trac.webkit.org/export/latest/trunk/%s' % SOURCE_PATH
OUTPUT_FILE = '../Css.dart'

def main():
  _, css_names_file = tempfile.mkstemp('.CSSPropertyNames.in')
  try:
    if os.system('wget %s -O %s' % (INPUT_URL, css_names_file)):
      return 1
    generate_code(css_names_file)
    print 'Successfully generated ' + OUTPUT_FILE
  finally:
    os.remove(css_names_file)

def camelCaseName(name):
  """Convert a CSS property name to a lowerCamelCase name."""
  name = name.replace('-webkit-', '')
  words = []
  for word in name.split('-'):
    if words:
      words.append(word.title())
    else:
      words.append(word)
  return ''.join(words)

def generate_code(input_path):
  data = open(input_path).readlines()

  # filter CSSPropertyNames.in to only the properties
  data = [d[:-1] for d in data
          if len(d) > 1
          and not d.startswith('#')
          and not d.startswith('//')
          and not '=' in d]

  output_file = open(OUTPUT_FILE, 'w')

  output_file.write("""
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit.
// This file was generated by base/scripts/css_code_generator.py

// Source of CSS properties:
//   %s

// TODO(jacobr): add versions that take numeric values in px, miliseconds, etc.

/**
 * Browser neutral and typesafe class for setting CSS styles from Dart.
 * This class smoothes over browser differences.
 */
class Css {
  static String _cachedBrowserPrefix;

  final CSSStyleDeclaration raw;
  Css(CSSStyleDeclaration this.raw) { }

  static String get _browserPrefix() {
    if (_cachedBrowserPrefix === null) {
      if (Device.isFirefox) {
        _cachedBrowserPrefix = '-moz-';
      } else {
        _cachedBrowserPrefix = '-webkit-';
      }
      // TODO(jacobr): support IE 9.0 and Opera as well.
    }
    return _cachedBrowserPrefix;
  }
""".lstrip() % SOURCE_PATH);

  static_method_lines = [];
  property_lines = [];

  seen = set()
  for prop in sorted(data, key=lambda p: camelCaseName(p)):
    camel_case_name = camelCaseName(prop)
    upper_camel_case_name = camel_case_name[0].upper() + camel_case_name[1:];
    css_name = prop.replace('-webkit-', '${_browserPrefix}')
    base_css_name = prop.replace('-webkit-', '')

    if base_css_name in seen:
      continue
    seen.add(base_css_name)

    comment = '  /** %s the value of "' + base_css_name + '" */'

    static_method_lines.append('\n');
    static_method_lines.append(comment % 'Gets')
    static_method_lines.append("""
  static String get%s(CSSStyleDeclaration style) {
    return style.getPropertyValue('%s');
  }

""" % (upper_camel_case_name, css_name))

    static_method_lines.append(comment % 'Sets')
    static_method_lines.append("""
  static void set%s(CSSStyleDeclaration style, String value) {
    style.setProperty('%s', value, '');
  }
""" % (upper_camel_case_name, css_name))

    property_lines.append('\n')
    property_lines.append(comment % 'Gets')
    property_lines.append("""
  String get %s() {
    return get%s(raw);
  }

""" % (camel_case_name, upper_camel_case_name))

    property_lines.append(comment % 'Sets')
    property_lines.append("""
  void set %s(String value) {
    set%s(raw, value);
  }
""" % (camel_case_name, upper_camel_case_name))

  output_file.write(''.join(static_method_lines));
  output_file.write(''.join(property_lines));
  output_file.write('}\n')
  output_file.close()

if __name__ == '__main__':
  main()
