#!/usr/bin/python
#
# Copyright (c) 2014, 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 CSSStyleDeclaration template file from css property definitions
defined in WebKit."""

import tempfile, os, re

COMMENT_LINE_PREFIX = '   * '
# TODO(efortuna): Pull from DEPS so that we have latest css *in sync* with our
# Dartium. Then remove the checked in CSSPropertyNames.in.
SOURCE_PATH = 'CSSPropertyNames.in'
#SOURCE_PATH = 'Source/WebCore/css/CSSPropertyNames.in'
TEMPLATE_FILE = '../templates/html/impl/impl_CSSStyleDeclaration.darttemplate'

# These are the properties that are supported on all Dart project supported
# browsers as camelCased names on the CssStyleDeclaration.
BROWSER_PATHS = [
    'cssProperties.CSS21.txt',  # Remove when we have samples from all browsers.
    'cssProperties.ie9.txt',
    'cssProperties.ie10.txt',
    'cssProperties.ie11.txt',
    'cssProperties.ff36.txt',
    'cssProperties.chrome40.txt',
    'cssProperties.safari-7.1.3.txt',
    'cssProperties.mobileSafari-8.2.txt',
    'cssProperties.iPad4Air.onGoogleSites.txt',
    ]

# Supported annotations for any specific CSS properties.
annotated = {
  'transition': '''@SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)'''
}

class Error:
  def __init__(self, message):
    self.message = message
  def __repr__(self):
    return self.message

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 dashifyName(camelName):
  def fix(match):
    return '-' + match.group(0).lower()
  return re.sub(r'[A-Z]', fix, camelName)

def isCommentLine(line):
  return line.strip() == '' or line.startswith('#') or line.startswith('//')

def readCssProperties(filename):
  data = open(filename).readlines()
  data = sorted([d.strip() for d in set(data) if not isCommentLine(d)])
  return data

def GenerateCssTemplateFile():
  data = open(SOURCE_PATH).readlines()

  # filter CSSPropertyNames.in to only the properties
  # TODO(efortuna): do we also want CSSPropertyNames.in?
  data = [d.strip() for d in data
          if not isCommentLine(d)
          and not '=' in d]

  browser_props = [readCssProperties(file) for file in BROWSER_PATHS]
  universal_properties = reduce(
        lambda a, b: set(a).intersection(b), browser_props)
  universal_properties = universal_properties.difference(['cssText'])
  universal_properties = universal_properties.intersection(
        map(camelCaseName, data))

  class_file = open(TEMPLATE_FILE, 'w')

  class_file.write("""
// Copyright (c) 2014, 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 TEMPLATE FILE.
// The template file was generated by scripts/css_code_generator.py

// Source of CSS properties:
//   %s

part of $LIBRARYNAME;
""" % SOURCE_PATH)


  class_file.write("""
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME $EXTENDS with
    $(CLASSNAME)Base $IMPLEMENTS {
  factory $CLASSNAME() => new CssStyleDeclaration.css('');

  factory $CLASSNAME.css(String css) {
    final style = new Element.tag('div').style;
    style.cssText = css;
    return style;
  }

  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValueHelper(propertyName);
    return propValue != null ? propValue : '';
  }

  String _getPropertyValueHelper(String propertyName) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return _getPropertyValue(propertyName);
    } else {
      return _getPropertyValue(Device.cssPrefix + propertyName);
    }
  }

  /**
   * Returns true if the provided *CSS* property name is supported on this
   * element.
   *
   * Please note the property name camelCase, not-hyphens. This
   * method returns true if the property is accessible via an unprefixed _or_
   * prefixed property.
   */
  bool supportsProperty(String propertyName) {
    return _supportsProperty(propertyName) ||
        _supportsProperty(_camelCase(Device.cssPrefix + propertyName));
  }

  bool _supportsProperty(String propertyName) {
$if DART2JS
    return JS('bool', '# in #', propertyName, this);
$else
    // You can't just check the value of a property, because there is no way
    // to distinguish between property not being present in the browser and
    // not having a value at all. (Ultimately we'll want the native method to
    // return null if the property doesn't exist and empty string if it's
    // defined but just doesn't have a value.
    return _hasProperty(propertyName);
$endif
  }

$if DARTIUM
  bool _hasProperty(String propertyName) =>
  $if JSINTEROP
      _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(this, propertyName);
  $else
      _blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_1(this, propertyName);
  $endif
$endif

  @DomName('CSSStyleDeclaration.setProperty')
  void setProperty(String propertyName, String value, [String priority]) {
    return _setPropertyHelper(_browserPropertyName(propertyName),
      value, priority);
  }

  String _browserPropertyName(String propertyName) {
    String name = _readCache(propertyName);
    if (name is String) return name;
    if (_supportsProperty(_camelCase(propertyName))) {
      name = propertyName;
    } else {
      name = Device.cssPrefix + propertyName;
    }
    _writeCache(propertyName, name);
    return name;
  }

$if DART2JS
  static final _propertyCache = JS('', '{}');
  static String _readCache(String key) =>
    JS('String|Null', '#[#]', _propertyCache, key);
  static void _writeCache(String key, String value) {
    JS('void', '#[#] = #', _propertyCache, key, value);
  }
$else
  static String _readCache(String key) => null;
  static void _writeCache(String key, value) {}
$endif

  static String _camelCase(String hyphenated) {
$if DART2JS
    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);

    var fToUpper = const JS_CONST(
        r'function(_, letter) { return letter.toUpperCase(); }');
    return JS('String', r'#.replace(/-([\da-z])/ig, #)', replacedMs, fToUpper);
$else
    // The "ms" prefix is always lowercased.
    return hyphenated.replaceFirst(new RegExp('^-ms-'), 'ms-').replaceAllMapped(
        new RegExp('-([a-z]+)', caseSensitive: false),
        (match) => match[0][1].toUpperCase() + match[0].substring(2));
$endif
  }

$if DART2JS
  void _setPropertyHelper(String propertyName, String value, [String priority]) {
    if (value == null) value = '';
    if (priority == null) priority = '';
    JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    return document.body.style.supportsProperty('transition');
  }
$else
  void _setPropertyHelper(String propertyName, String value, [String priority]) {
    if (priority == null) {
      priority = '';
    }
    _setProperty(propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions => true;
$endif
$!MEMBERS
$if DART2JS
""")

  for camelName in sorted(universal_properties):
    property = dashifyName(camelName)
    class_file.write("""
  /** Gets the value of "%s" */
  String get %s => this._%s;

  /** Sets the value of "%s" */
  set %s(String value) {
    _%s = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('%s')
  String _%s;
    """ % (property, camelName, camelName,
           property, camelName, camelName,
           camelName, camelName))

  class_file.write("""
$endif
}

class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
  final Iterable<Element> _elementIterable;
  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;

  _CssStyleDeclarationSet(this._elementIterable) {
    _elementCssStyleDeclarationSetIterable = new List.from(
        _elementIterable).map((e) => e.style);
  }

  String getPropertyValue(String propertyName) =>
      _elementCssStyleDeclarationSetIterable.first.getPropertyValue(
          propertyName);

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable.forEach((e) =>
        e.setProperty(propertyName, value, priority));
  }

""")

  class_file.write("""
$if DART2JS
  void _setAll(String propertyName, String value) {
    value = value == null ? '' : value;
    for (Element element in _elementIterable) {
      JS('void', '#.style[#] = #', element, propertyName, value);
    }
  }
""")


  for camelName in sorted(universal_properties):
    property = dashifyName(camelName)
    class_file.write("""
  /** Sets the value of "%s" */
  set %s(String value) {
    _setAll('%s', value);
  }
    """ % (property, camelName, camelName))

  class_file.write("""
$endif

  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

$if DART2JS
abstract class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName);
  void setProperty(String propertyName, String value, [String priority]);
$else
  $if JSINTEROP
class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName) =>
    throw new StateError('getProperty not overridden in dart:html');
  void setProperty(String propertyName, String value, [String priority]) =>
    throw new StateError('setProperty not overridden in dart:html');
  $else
abstract class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName);
  void setProperty(String propertyName, String value, [String priority]);
  $endif
$endif
""")

  class_lines = [];

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

    if base_css_name in seen or base_css_name.startswith('-internal'):
      continue
    seen.add(base_css_name)

    comment = '  /** %s the value of "' + base_css_name + '" */'
    class_lines.append('\n');
    class_lines.append(comment % 'Gets')
    if base_css_name in annotated:
      class_lines.append(annotated[base_css_name])
    class_lines.append("""
  String get %s =>
    getPropertyValue('%s');

""" % (camel_case_name, css_name))

    class_lines.append(comment % 'Sets')
    if base_css_name in annotated:
      class_lines.append(annotated[base_css_name])
    class_lines.append("""
  set %s(String value) {
    setProperty('%s', value, '');
  }
""" % (camel_case_name, css_name))

  class_file.write(''.join(class_lines));
  class_file.write('}\n')
  class_file.close()
