// Copyright (c) 2012, 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.

/** Representations of CSS styles. */

part of csslib.parser;

// TODO(terry): Prune down this file we do need some of the code in this file
//              for darker, lighter, how to represent a Font, etc but alot of
//              the complexity can be removed.
//              See https://github.com/dart-lang/csslib/issues/7

/**
 * Base for all style properties (e.g., Color, Font, Border, Margin, etc.)
 */
abstract class _StyleProperty {
  /**
   * Returns the expression part of a CSS declaration.  Declaration is:
   *
   *     property:expression;
   *
   * E.g., if property is color then expression could be rgba(255,255,0) the
   *       CSS declaration would be 'color:rgba(255,255,0);'.
   *
   * then _cssExpression would return 'rgba(255,255,0)'.  See
   * <http://www.w3.org/TR/CSS21/grammar.html>
   */
  String get cssExpression;
}


/**
 * Base interface for Color, HSL and RGB.
 */
abstract class ColorBase {
  /**
   * Canonical form for color #rrggbb with alpha blending (0.0 == full
   * transparency and 1.0 == fully opaque). If _argb length is 6 it's an
   * rrggbb otherwise it's aarrggbb.
   */
  String toHexArgbString();

  /**
   * Return argb as a value (int).
   */
  int get argbValue;
}


/**
 * General purpse Color class.  Represent a color as an ARGB value that can be
 * converted to and from num, hex string, hsl, hsla, rgb, rgba and SVG pre-
 * defined color constant.
 */
class Color implements _StyleProperty, ColorBase {
  // If _argb length is 6 it's an rrggbb otherwise it's aarrggbb.
  final String _argb;

  // TODO(terry): Look at reducing Rgba and Hsla classes as factories for
  //              converting from Color to an Rgba or Hsla for reading only.
  //              Usefulness of creating an Rgba or Hsla is limited.

  /**
   * Create a color with an integer representing the rgb value of red, green,
   * and blue.  The value 0xffffff is the color white #ffffff (CSS style).
   * The [rgb] value of 0xffd700 would map to #ffd700 or the constant
   * Color.gold, where ff is red intensity, d7 is green intensity, and 00 is
   * blue intensity.
   */
  Color(int rgb, [num alpha]) :
    this._argb = Color._rgbToArgbString(rgb, alpha);

  /**
   * RGB takes three values. The [red], [green], and [blue] parameters are
   * the intensity of those components where '0' is the least and '256' is the
   * greatest.
   *
   * If [alpha] is provided, it is the level of translucency which ranges from
   * '0' (completely transparent) to '1.0' (completely opaque).  It will
   * internally be mapped to an int between '0' and '255' like the other color
   * components.
   */
  Color.createRgba(int red, int green, int blue, [num alpha]) :
      this._argb = Color.convertToHexString(Color._clamp(red, 0, 255),
          Color._clamp(green, 0, 255),
          Color._clamp(blue, 0, 255),
          alpha != null ? Color._clamp(alpha, 0, 1) : alpha);

  /**
   * Creates a new color from a CSS color string. For more information, see
   * <https://developer.mozilla.org/en/CSS/color>.
   */
  Color.css(String color) :
      this._argb = Color._convertCssToArgb(color);

  // TODO(jmesserly): I found the use of percents a bit suprising.
  /**
   * HSL takes three values.  The [hueDegree] degree on the color wheel; '0' is
   * the least and '100' is the greatest.  The value '0' or '360' is red, '120'
   * is green, '240' is blue. Numbers in between reflect different shades.
   * The [saturationPercent] percentage; where'0' is the least and '100' is the
   * greatest (100 represents full color).  The [lightnessPercent] percentage;
   * where'0' is the least and '100' is the greatest.  The value 0 is dark or
   * black, 100 is light or white and 50 is a medium lightness.
   *
   * If [alpha] is provided, it is the level of translucency which ranges from
   * '0' (completely transparent foreground) to '1.0' (completely opaque
   * foreground).
   */
  Color.createHsla(num hueDegree, num saturationPercent, num lightnessPercent,
      [num alpha]) :
          this._argb = new Hsla(Color._clamp(hueDegree, 0, 360) / 360,
          Color._clamp(saturationPercent, 0, 100) / 100,
          Color._clamp(lightnessPercent, 0, 100) / 100,
          alpha != null ? Color._clamp(alpha, 0, 1) : alpha).toHexArgbString();

  /**
   * The hslaRaw takes three values.  The [hue] degree on the color wheel; '0'
   * is the least and '1' is the greatest.  The value '0' or '1' is red, the
   * ratio of 120/360 is green, and the ratio of 240/360 is blue.  Numbers in
   * between reflect different shades.  The [saturation] is a percentage; '0'
   * is the least and '1' is the greatest.  The value of '1' is equivalent to
   * 100% (full colour).  The [lightness] is a percentage; '0' is the least and
   * '1' is the greatest.  The value of '0' is dark (black), the value of '1'
   * is light (white), and the value of '.50' is a medium lightness.
   *
   * The fourth optional parameter is:
   *   [alpha]      level of translucency range of values is 0..1, zero is a
   *                completely transparent foreground and 1 is a completely
   *                opaque foreground.
   */
  Color.hslaRaw(num hue, num saturation, num lightness, [num alpha]) :
    this._argb = new Hsla(Color._clamp(hue, 0, 1),
          Color._clamp(saturation, 0, 1),
          Color._clamp(lightness, 0, 1),
          alpha != null ? Color._clamp(alpha, 0, 1) : alpha).toHexArgbString();

  /**
   * Generate a real constant for pre-defined colors (no leading #).
   */
  const Color.hex(this._argb);

  // TODO(jmesserly): this is needed by the example so leave it exposed for now.
  String toString() => cssExpression;

  // TODO(terry): Regardless of how color is set (rgb, num, css or hsl) we'll
  //              always return a rgb or rgba loses fidelity when debugging in
  //              CSS if user uses hsl and would like to edit as hsl, etc.  If
  //              this is an issue we should keep the original value and not re-
  //              create the CSS from the normalized value.
  String get cssExpression {
    if (_argb.length == 6) {
      return "#$_argb";         // RGB only, no alpha blending.
    } else {
      num alpha = Color.hexToInt(_argb.substring(0, 2));
      String a = (alpha / 255).toStringAsPrecision(2);
      int r = Color.hexToInt(_argb.substring(2, 4));
      int g = Color.hexToInt(_argb.substring(4, 6));
      int b = Color.hexToInt(_argb.substring(6, 8));
      return "rgba($r,$g,$b,$a)";
    }
  }

  Rgba get rgba {
    int nextIndex = 0;
    num a;
    if (_argb.length == 8) {
      // Get alpha blending value 0..255
      int alpha = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
      // Convert to value from 0..1
      a = double.parse((alpha / 255).toStringAsPrecision(2));
      nextIndex += 2;
    }
    int r = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
    nextIndex += 2;
    int g = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
    nextIndex += 2;
    int b = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
    return new Rgba(r, g, b, a);
  }

  Hsla get hsla => new Hsla.fromRgba(rgba);

  int get argbValue => Color.hexToInt(_argb);

  bool operator ==(other) => Color.equal(this, other);

  String toHexArgbString() => _argb;

  Color darker(num amount) {
    Rgba newRgba = Color._createNewTintShadeFromRgba(rgba, -amount);
    return new Color.hex("${newRgba.toHexArgbString()}");
  }

  Color lighter(num amount) {
    Rgba newRgba = Color._createNewTintShadeFromRgba(rgba, amount);
    return new Color.hex("${newRgba.toHexArgbString()}");
  }

  static bool equal(ColorBase curr, other) {
    if (other is Color) {
      Color o = other;
      return o.toHexArgbString() == curr.toHexArgbString();
    } else if (other is Rgba) {
      Rgba rgb = other;
      return rgb.toHexArgbString() == curr.toHexArgbString();
    } else if (other is Hsla) {
      Hsla hsla = other;
      return hsla.toHexArgbString() == curr.toHexArgbString();
    } else {
      return false;
    }
  }

  int get hashCode => _argb.hashCode;

  // Conversion routines:

  static String _rgbToArgbString(int rgba, num alpha) {
    int a;
    // If alpha is defined then adjust from 0..1 to 0..255 value, if not set
    // then a is left as undefined and passed to convertToHexString.
    if (alpha != null) {
      a = (Color._clamp(alpha, 0, 1) * 255).round();
    }

    int r = (rgba & 0xff0000) >> 0x10;
    int g = (rgba & 0xff00) >> 8;
    int b = rgba & 0xff;

    return Color.convertToHexString(r, g, b, a);
  }

  static const int _rgbCss = 1;
  static const int _rgbaCss = 2;
  static const int _hslCss = 3;
  static const int _hslaCss = 4;
  /**
   * Parse CSS expressions of the from #rgb, rgb(r,g,b), rgba(r,g,b,a),
   * hsl(h,s,l), hsla(h,s,l,a) and SVG colors (e.g., darkSlateblue, etc.) and
   * convert to argb.
   */
  static String _convertCssToArgb(String value) {
    // TODO(terry): Better parser/regex for converting CSS properties.
    String color = value.trim().replaceAll("\\s", "");
    if (color[0] == '#') {
      String v = color.substring(1);
      Color.hexToInt(v);              // Valid hexadecimal, throws if not.
      return v;
    } else if (color.length > 0 && color[color.length - 1] == ')') {
      int type;
      if (color.indexOf("rgb(") == 0 || color.indexOf("RGB(") == 0) {
        color = color.substring(4);
        type = _rgbCss;
      } else if (color.indexOf("rgba(") == 0 || color.indexOf("RGBA(") == 0) {
        type = _rgbaCss;
        color = color.substring(5);
      } else if (color.indexOf("hsl(") == 0 || color.indexOf("HSL(") == 0) {
        type = _hslCss;
        color = color.substring(4);
      } else if (color.indexOf("hsla(") == 0 || color.indexOf("HSLA(") == 0) {
        type = _hslaCss;
        color = color.substring(5);
      } else {
        throw new UnsupportedError('CSS property not implemented');
      }

      color = color.substring(0, color.length - 1);     // Strip close paren.

      var args = <num>[];
      List<String> params = color.split(",");
      for (String param in params) {
        args.add(double.parse(param));
      }
      switch (type) {
        case _rgbCss:
          return Color.convertToHexString(args[0], args[1], args[2]);
        case _rgbaCss:
          return Color.convertToHexString(args[0], args[1], args[2], args[3]);
        case _hslCss:
          return new Hsla(args[0], args[1], args[2]).toHexArgbString();
        case _hslaCss:
          return new Hsla(args[0], args[1], args[2],
              args[3]).toHexArgbString();
        default:
          // Type not defined UnsupportedOperationException should have thrown.
          assert(true);
          break;
      }
    }
  }

  static int hexToInt(String hex) => int.parse(hex, radix: 16);

  static String convertToHexString(int r, int g, int b, [num a]) {
    String rHex = Color._numAs2DigitHex(Color._clamp(r, 0, 255));
    String gHex = Color._numAs2DigitHex(Color._clamp(g, 0, 255));
    String bHex = Color._numAs2DigitHex(Color._clamp(b, 0, 255));
    String aHex = (a != null) ?
        Color._numAs2DigitHex((Color._clamp(a, 0, 1) * 255).round()) : "";

    // TODO(terry) 15.toRadixString(16) return 'F' on Dartium not f as in JS.
    //             bug: <http://code.google.com/p/dart/issues/detail?id=2670>
    return "$aHex$rHex$gHex$bHex".toLowerCase();
  }

  static String _numAs2DigitHex(num v) {
    // TODO(terry): v.toInt().toRadixString instead of v.toRadixString
    //              Bug <http://code.google.com/p/dart/issues/detail?id=2671>.
    String hex = v.toInt().toRadixString(16);
    if (hex.length == 1) {
      hex = "0${hex}";
    }
    return hex;
  }

  static num _clamp(num value, num min, num max) =>
      math.max(math.min(max, value), min);

  /**
   * Change the tint (make color lighter) or shade (make color darker) of all
   * parts of [rgba] (r, g and b).  The [amount] is percentage darker between
   * -1 to 0 for darker and 0 to 1 for lighter; '0' is no change.  The [amount]
   * will darken or lighten the rgb values; it will not change the alpha value.
   * If [amount] is outside of the value -1 to +1 then [amount] is changed to
   * either the min or max direction -1 or 1.
   *
   * Darker will approach the color #000000 (black) and lighter will approach
   * the color #ffffff (white).
   */
  static Rgba _createNewTintShadeFromRgba(Rgba rgba, num amount) {
    int r, g, b;
    num tintShade = Color._clamp(amount, -1, 1);
    if (amount < 0 && rgba.r == 255 && rgba.g == 255 && rgba.b == 255) {
      // TODO(terry): See TODO in _changeTintShadeColor; eliminate this test
      //              by converting to HSL and adjust lightness although this
      //              is fastest lighter/darker algorithm.
      // Darkening white special handling.
      r = Color._clamp((255 + (255 * tintShade)).round().toInt(), 0, 255);
      g = Color._clamp((255 + (255 * tintShade)).round().toInt(), 0, 255);
      b = Color._clamp((255 + (255 * tintShade)).round().toInt(), 0, 255);
    } else {
      // All other colors then darkening white go here.
      r = Color._changeTintShadeColor(rgba.r, tintShade).round().toInt();
      g = Color._changeTintShadeColor(rgba.g, tintShade).round().toInt();
      b = Color._changeTintShadeColor(rgba.b, tintShade).round().toInt();
    }
    return new Rgba(r, g, b, rgba.a);
  }

  // TODO(terry): This does an okay lighter/darker; better would be convert to
  //              HSL then change the lightness.
  /**
   * The parameter [v] is the color to change (r, g, or b) in the range '0' to
   * '255'. The parameter [delta] is a number between '-1' and '1'.  A value
   * between '-1' and '0' is darker and a value between '0' and '1' is lighter
   * ('0' imples no change).
   */
  static num _changeTintShadeColor(num v, num delta) =>
      Color._clamp(((1 - delta) * v + (delta * 255)).round(), 0, 255);

  // Predefined CSS colors see <http://www.w3.org/TR/css3-color/>
  static final Color transparent = const Color.hex("00ffffff");  // Alpha 0.0
  static final Color aliceBlue = const Color.hex("0f08ff");
  static final Color antiqueWhite = const Color.hex("0faebd7");
  static final Color aqua = const Color.hex("00ffff");
  static final Color aquaMarine = const Color.hex("7fffd4");
  static final Color azure = const Color.hex("f0ffff");
  static final Color beige = const Color.hex("f5f5dc");
  static final Color bisque = const Color.hex("ffe4c4");
  static final Color black = const Color.hex("000000");
  static final Color blanchedAlmond = const Color.hex("ffebcd");
  static final Color blue = const Color.hex("0000ff");
  static final Color blueViolet = const Color.hex("8a2be2");
  static final Color brown = const Color.hex("a52a2a");
  static final Color burlyWood = const Color.hex("deb887");
  static final Color cadetBlue = const Color.hex("5f9ea0");
  static final Color chartreuse = const Color.hex("7fff00");
  static final Color chocolate = const Color.hex("d2691e");
  static final Color coral = const Color.hex("ff7f50");
  static final Color cornFlowerBlue = const Color.hex("6495ed");
  static final Color cornSilk = const Color.hex("fff8dc");
  static final Color crimson = const Color.hex("dc143c");
  static final Color cyan = const Color.hex("00ffff");
  static final Color darkBlue = const Color.hex("00008b");
  static final Color darkCyan = const Color.hex("008b8b");
  static final Color darkGoldenRod = const Color.hex("b8860b");
  static final Color darkGray = const Color.hex("a9a9a9");
  static final Color darkGreen = const Color.hex("006400");
  static final Color darkGrey = const Color.hex("a9a9a9");
  static final Color darkKhaki = const Color.hex("bdb76b");
  static final Color darkMagenta = const Color.hex("8b008b");
  static final Color darkOliveGreen = const Color.hex("556b2f");
  static final Color darkOrange = const Color.hex("ff8c00");
  static final Color darkOrchid = const Color.hex("9932cc");
  static final Color darkRed = const Color.hex("8b0000");
  static final Color darkSalmon = const Color.hex("e9967a");
  static final Color darkSeaGreen = const Color.hex("8fbc8f");
  static final Color darkSlateBlue = const Color.hex("483d8b");
  static final Color darkSlateGray = const Color.hex("2f4f4f");
  static final Color darkSlateGrey = const Color.hex("2f4f4f");
  static final Color darkTurquoise = const Color.hex("00ced1");
  static final Color darkViolet = const Color.hex("9400d3");
  static final Color deepPink = const Color.hex("ff1493");
  static final Color deepSkyBlue = const Color.hex("00bfff");
  static final Color dimGray = const Color.hex("696969");
  static final Color dimGrey = const Color.hex("696969");
  static final Color dodgerBlue = const Color.hex("1e90ff");
  static final Color fireBrick = const Color.hex("b22222");
  static final Color floralWhite = const Color.hex("fffaf0");
  static final Color forestGreen = const Color.hex("228b22");
  static final Color fuchsia = const Color.hex("ff00ff");
  static final Color gainsboro = const Color.hex("dcdcdc");
  static final Color ghostWhite = const Color.hex("f8f8ff");
  static final Color gold = const Color.hex("ffd700");
  static final Color goldenRod = const Color.hex("daa520");
  static final Color gray = const Color.hex("808080");
  static final Color green = const Color.hex("008000");
  static final Color greenYellow = const Color.hex("adff2f");
  static final Color grey = const Color.hex("808080");
  static final Color honeydew = const Color.hex("f0fff0");
  static final Color hotPink = const Color.hex("ff69b4");
  static final Color indianRed = const Color.hex("cd5c5c");
  static final Color indigo = const Color.hex("4b0082");
  static final Color ivory = const Color.hex("fffff0");
  static final Color khaki = const Color.hex("f0e68c");
  static final Color lavender = const Color.hex("e6e6fa");
  static final Color lavenderBlush = const Color.hex("fff0f5");
  static final Color lawnGreen = const Color.hex("7cfc00");
  static final Color lemonChiffon = const Color.hex("fffacd");
  static final Color lightBlue = const Color.hex("add8e6");
  static final Color lightCoral = const Color.hex("f08080");
  static final Color lightCyan = const Color.hex("e0ffff");
  static final Color lightGoldenRodYellow = const Color.hex("fafad2");
  static final Color lightGray = const Color.hex("d3d3d3");
  static final Color lightGreen = const Color.hex("90ee90");
  static final Color lightGrey = const Color.hex("d3d3d3");
  static final Color lightPink = const Color.hex("ffb6c1");
  static final Color lightSalmon = const Color.hex("ffa07a");
  static final Color lightSeaGreen = const Color.hex("20b2aa");
  static final Color lightSkyBlue = const Color.hex("87cefa");
  static final Color lightSlateGray = const Color.hex("778899");
  static final Color lightSlateGrey = const Color.hex("778899");
  static final Color lightSteelBlue = const Color.hex("b0c4de");
  static final Color lightYellow = const Color.hex("ffffe0");
  static final Color lime = const Color.hex("00ff00");
  static final Color limeGreen = const Color.hex("32cd32");
  static final Color linen = const Color.hex("faf0e6");
  static final Color magenta = const Color.hex("ff00ff");
  static final Color maroon = const Color.hex("800000");
  static final Color mediumAquaMarine = const Color.hex("66cdaa");
  static final Color mediumBlue = const Color.hex("0000cd");
  static final Color mediumOrchid = const Color.hex("ba55d3");
  static final Color mediumPurple = const Color.hex("9370db");
  static final Color mediumSeaGreen = const Color.hex("3cb371");
  static final Color mediumSlateBlue = const Color.hex("7b68ee");
  static final Color mediumSpringGreen = const Color.hex("00fa9a");
  static final Color mediumTurquoise = const Color.hex("48d1cc");
  static final Color mediumVioletRed = const Color.hex("c71585");
  static final Color midnightBlue = const Color.hex("191970");
  static final Color mintCream = const Color.hex("f5fffa");
  static final Color mistyRose = const Color.hex("ffe4e1");
  static final Color moccasin = const Color.hex("ffe4b5");
  static final Color navajoWhite = const Color.hex("ffdead");
  static final Color navy = const Color.hex("000080");
  static final Color oldLace = const Color.hex("fdf5e6");
  static final Color olive = const Color.hex("808000");
  static final Color oliveDrab = const Color.hex("6b8e23");
  static final Color orange = const Color.hex("ffa500");
  static final Color orangeRed = const Color.hex("ff4500");
  static final Color orchid = const Color.hex("da70d6");
  static final Color paleGoldenRod = const Color.hex("eee8aa");
  static final Color paleGreen = const Color.hex("98fb98");
  static final Color paleTurquoise = const Color.hex("afeeee");
  static final Color paleVioletRed = const Color.hex("db7093");
  static final Color papayaWhip = const Color.hex("ffefd5");
  static final Color peachPuff = const Color.hex("ffdab9");
  static final Color peru = const Color.hex("cd85ef");
  static final Color pink = const Color.hex("ffc0cb");
  static final Color plum = const Color.hex("dda0dd");
  static final Color powderBlue = const Color.hex("b0e0e6");
  static final Color purple = const Color.hex("800080");
  static final Color red = const Color.hex("ff0000");
  static final Color rosyBrown = const Color.hex("bc8f8f");
  static final Color royalBlue = const Color.hex("4169e1");
  static final Color saddleBrown = const Color.hex("8b4513");
  static final Color salmon = const Color.hex("fa8072");
  static final Color sandyBrown = const Color.hex("f4a460");
  static final Color seaGreen = const Color.hex("2e8b57");
  static final Color seashell = const Color.hex("fff5ee");
  static final Color sienna = const Color.hex("a0522d");
  static final Color silver = const Color.hex("c0c0c0");
  static final Color skyBlue = const Color.hex("87ceeb");
  static final Color slateBlue = const Color.hex("6a5acd");
  static final Color slateGray = const Color.hex("708090");
  static final Color slateGrey = const Color.hex("708090");
  static final Color snow = const Color.hex("fffafa");
  static final Color springGreen = const Color.hex("00ff7f");
  static final Color steelBlue = const Color.hex("4682b4");
  static final Color tan = const Color.hex("d2b48c");
  static final Color teal = const Color.hex("008080");
  static final Color thistle = const Color.hex("d8bfd8");
  static final Color tomato = const Color.hex("ff6347");
  static final Color turquoise = const Color.hex("40e0d0");
  static final Color violet = const Color.hex("ee82ee");
  static final Color wheat = const Color.hex("f5deb3");
  static final Color white = const Color.hex("ffffff");
  static final Color whiteSmoke = const Color.hex("f5f5f5");
  static final Color yellow = const Color.hex("ffff00");
  static final Color yellowGreen = const Color.hex("9acd32");
}


/**
 * Rgba class for users that want to interact with a color as a RGBA value.
 */
class Rgba implements _StyleProperty, ColorBase {
  // TODO(terry): Consider consolidating rgba to a single 32-bit int, make sure
  //              it works under JS and Dart VM.
  final int r;
  final int g;
  final int b;
  final num a;

  Rgba(int red, int green, int blue, [num alpha]) :
    this.r = Color._clamp(red, 0, 255),
    this.g = Color._clamp(green, 0, 255),
    this.b = Color._clamp(blue, 0, 255),
    this.a = (alpha != null) ? Color._clamp(alpha, 0, 1) : alpha;

  factory Rgba.fromString(String hexValue) =>
    new Color.css("#${Color._convertCssToArgb(hexValue)}").rgba;

  factory Rgba.fromColor(Color color) => color.rgba;

  factory Rgba.fromArgbValue(num value) {
    return new Rgba(((value.toInt() & 0xff000000) >> 0x18),  /* a */
      ((value.toInt() & 0xff0000) >> 0x10),                  /* r */
      ((value.toInt() & 0xff00) >> 8),                       /* g */
      ((value.toInt() & 0xff)));                             /* b */
  }

  factory Rgba.fromHsla(Hsla hsla) {
    // Convert to Rgba.
    // See site <http://easyrgb.com/index.php?X=MATH> for good documentation
    // and color conversion routines.

    num h = hsla.hue;
    num s = hsla.saturation;
    num l = hsla.lightness;
    num a = hsla.alpha;

    int r;
    int g;
    int b;

    if (s == 0) {
      r = (l * 255).round().toInt();
      g = r;
      b = r;
    } else {
      num var2;

      if (l < 0.5) {
        var2 = l * (1 + s);
      } else {
        var2 = (l + s) - (s * l);
      }
      num var1 = 2 * l - var2;

      r = (255 * Rgba._hueToRGB(var1, var2, h + (1/3))).round().toInt();
      g = (255 * Rgba._hueToRGB(var1, var2, h)).round().toInt();
      b = (255 * Rgba._hueToRGB(var1, var2, h - (1/3))).round().toInt();
    }

    return new Rgba(r, g, b, a);
  }

  static num _hueToRGB(num v1, num v2, num vH) {
    if (vH < 0) {
      vH += 1;
    }

    if (vH > 1) {
      vH -= 1;
    }

    if ((6 * vH) < 1) {
      return (v1 + (v2 - v1) * 6 * vH);
    }

    if ((2 * vH) < 1) {
      return v2;
    }

    if ((3 * vH) < 2) {
      return (v1 + (v2 - v1) * ((2 / 3 - vH) * 6));
    }

    return v1;
  }

  bool operator ==(other) => Color.equal(this, other);

  String get cssExpression {
    if (a == null) {
      return "#${Color.convertToHexString(r, g, b)}";
    } else {
      return "rgba($r,$g,$b,$a)";
    }
  }

  String toHexArgbString() => Color.convertToHexString(r, g, b, a);

  int get argbValue {
    int value = 0;
    if (a != null) {
      value = (a.toInt() << 0x18);
    }
    value += (r << 0x10);
    value += (g << 0x08);
    value += b;
  }

  Color get color => new Color.createRgba(r, g, b, a);
  Hsla get hsla => new Hsla.fromRgba(this);

  Rgba darker(num amount) => Color._createNewTintShadeFromRgba(this, -amount);
  Rgba lighter(num amount) => Color._createNewTintShadeFromRgba(this, amount);

  int get hashCode => toHexArgbString().hashCode;
}


/**
 * Hsl class support to interact with a color as a hsl with hue, saturation, and
 * lightness with optional alpha blending.  The hue is a ratio of 360 degrees
 * 360° = 1 or 0, (1° == (1/360)), saturation and lightness is a 0..1 fraction
 * (1 == 100%) and alpha is a 0..1 fraction.
 */
class Hsla implements _StyleProperty, ColorBase {
  final num _h;             // Value from 0..1
  final num _s;             // Value from 0..1
  final num _l;             // Value from 0..1
  final num _a;             // Value from 0..1

  /**
   * [hue] is a 0..1 fraction of 360 degrees (360 == 0).
   * [saturation] is a 0..1 fraction (100% == 1).
   * [lightness] is a 0..1 fraction (100% == 1).
   * [alpha] is a 0..1 fraction, alpha blending between 0..1, 1 == 100% opaque.
   */
  Hsla(num hue, num saturation, num lightness, [num alpha]) :
    this._h = (hue == 1) ? 0 : Color._clamp(hue, 0, 1),
    this._s = Color._clamp(saturation, 0, 1),
    this._l = Color._clamp(lightness, 0, 1),
    this._a = (alpha != null) ? Color._clamp(alpha, 0, 1) : alpha;

  factory Hsla.fromString(String hexValue) {
    Rgba rgba = new Color.css("#${Color._convertCssToArgb(hexValue)}").rgba;
    return _createFromRgba(rgba.r, rgba.g, rgba.b, rgba.a);
  }

  factory Hsla.fromColor(Color color) {
    Rgba rgba = color.rgba;
    return _createFromRgba(rgba.r, rgba.g, rgba.b, rgba.a);
  }

  factory Hsla.fromArgbValue(num value) {
    num a = (value.toInt() & 0xff000000) >> 0x18;
    int r = (value.toInt() & 0xff0000) >> 0x10;
    int g = (value.toInt() & 0xff00) >> 8;
    int b = value.toInt() & 0xff;

    // Convert alpha to 0..1 from (0..255).
    if (a != null) {
      a = double.parse((a / 255).toStringAsPrecision(2));
    }

    return _createFromRgba(r, g, b, a);
  }

  factory Hsla.fromRgba(Rgba rgba) =>
    _createFromRgba(rgba.r, rgba.g, rgba.b, rgba.a);

  static Hsla _createFromRgba(num r, num g, num b, num a) {
    // Convert RGB to hsl.
    // See site <http://easyrgb.com/index.php?X=MATH> for good documentation
    // and color conversion routines.
    r /= 255;
    g /= 255;
    b /= 255;

    // Hue, saturation and lightness.
    num h;
    num s;
    num l;

    num minRgb = math.min(r, math.min(g, b));
    num maxRgb = math.max(r, math.max(g, b));
    l = (maxRgb + minRgb) / 2;
    if (l <= 0) {
      return new Hsla(0, 0, l);   // Black;
    }

    num vm = maxRgb - minRgb;
    s = vm;
    if (s > 0) {
      s /= (l < 0.5) ? (maxRgb + minRgb) : (2 - maxRgb - minRgb);
    } else {
      return new Hsla(0, 0, l);   // White
    }

    num r2, g2, b2;
    r2 = (maxRgb - r) / vm;
    g2 = (maxRgb - g) / vm;
    b2 = (maxRgb - b) / vm;
    if (r == maxRgb) {
      h = (g == minRgb) ? 5.0 + b2 : 1 - g2;
    } else if (g == maxRgb) {
      h = (b == minRgb) ? 1 + r2 : 3 - b2;
    } else {
      h = (r == minRgb) ? 3 + g2 : 5 - r2;
    }
    h /= 6;

    return new Hsla(h, s, l, a);
  }

  /**
   * Returns 0..1 fraction (ratio of 360°, e.g. 1° == 1/360).
   */
  num get hue => _h;

  /**
   * Returns 0..1 fraction (1 == 100%)
   */
  num get saturation => _s;

  /**
   * Returns 0..1 fraction (1 == 100%).
   */
  num get lightness => _l;

  /**
   * Returns number as degrees 0..360.
   */
  num get hueDegrees => (_h * 360).round();

  /**
   * Returns number as percentage 0..100
   */
  num get saturationPercentage => (_s * 100).round();

  /**
   * Returns number as percentage 0..100.
   */
  num get lightnessPercentage => (_l * 100).round();

  /**
   * Returns number as 0..1
   */
  num get alpha => _a;

  bool operator ==(other) => Color.equal(this, other);

  String get cssExpression => (_a == null) ?
      "hsl($hueDegrees,$saturationPercentage,$lightnessPercentage)" :
      "hsla($hueDegrees,$saturationPercentage,$lightnessPercentage,$_a)";

  String toHexArgbString() => new Rgba.fromHsla(this).toHexArgbString();

  int get argbValue => Color.hexToInt(this.toHexArgbString());

  Color get color => new Color.createHsla(_h, _s, _l, _a);
  Rgba get rgba => new Rgba.fromHsla(this);

  Hsla darker(num amount) =>
      new Hsla.fromRgba(new Rgba.fromHsla(this).darker(amount));

  Hsla lighter(num amount) =>
      new Hsla.fromRgba(new Rgba.fromHsla(this).lighter(amount));

  int get hashCode => toHexArgbString().hashCode;
}


/** X,Y position. */
class PointXY implements _StyleProperty {
  final num x, y;
  const PointXY(this.x, this.y);

  String get cssExpression {
    // TODO(terry): TBD
  }
}


// TODO(terry): Implement style and color.
/**
 * Supports border for measuring with layout.
 */
class Border implements _StyleProperty {
  final int top, left, bottom, right;

  // TODO(terry): Just like CSS, 1-arg -> set all properties, 2-args -> top and
  //               bottom are first arg, left and right are second, 3-args, and
  //               4-args -> tlbr or trbl.
  const Border([this.top, this.left, this.bottom, this.right]);

  // TODO(terry): Consider using Size or width and height.
  Border.uniform(num amount) :
      top = amount, left = amount, bottom = amount, right = amount;

  int get width => left + right;
  int get height => top + bottom;

  String get cssExpression {
    return (top == left && bottom == right && top == right) ? "${left}px" :
      "${top != null ? '$top' : '0'}px ${
      right != null ? '$right' : '0'}px ${
      bottom != null ? '$bottom' : '0'}px ${
      left != null ? '$left' : '0'}px";
  }
}


/** Font style constants. */
class FontStyle {
  /** Font style [normal] default. */
  static const String normal = "normal";
  /**
   * Font style [italic] use explicity crafted italic font otherwise inclined
   * on the fly like oblique.
   */
  static const String italic = "italic";
  /**
   * Font style [oblique] is rarely used. The normal style of a font is inclined
   * on the fly to the right by 8-12 degrees.
   */
  static const String oblique = "oblique";
}


/** Font variant constants. */
class FontVariant {
  /** Font style [normal] default. */
  static const String normal = "normal";
  /** Font variant [smallCaps]. */
  static const String smallCaps = "small-caps";
}


/** Font weight constants values 100, 200, 300, 400, 500, 600, 700, 800, 900. */
class FontWeight {
  /** Font weight normal [default] */
  static const int normal = 400;
  /** Font weight bold */
  static const int bold = 700;

  static const int wt100 = 100;
  static const int wt200 = 200;
  static const int wt300 = 300;
  static const int wt400 = 400;
  static const int wt500 = 500;
  static const int wt600 = 600;
  static const int wt700 = 700;
  static const int wt800 = 800;
  static const int wt900 = 900;
}


/** Generic font family names. */
class FontGeneric {
  /** Generic family sans-serif font (w/o serifs). */
  static const String sansSerif = "sans-serif";
  /** Generic family serif font. */
  static const String serif = "serif";
  /** Generic family fixed-width font. */
  static const monospace = "monospace";
  /** Generic family emulate handwriting font. */
  static const String cursive = "cursive";
  /** Generic family decorative font. */
  static const String fantasy = "fantasy";
}


/**
 * List of most common font families across different platforms.  Use the
 * collection names in the Font class (e.g., Font.SANS_SERIF, Font.FONT_SERIF,
 * Font.MONOSPACE, Font.CURSIVE or Font.FANTASY).  These work best on all
 * platforms using the fonts that best match availability on each platform.
 * See <http://www.angelfire.com/al4/rcollins/style/fonts.html> for a good
 * description of fonts available between platforms and browsers.
 */
class FontFamily {
  /** Sans-Serif font for Windows similar to Helvetica on Mac bold/italic. */
  static const String arial = "arial";
  /** Sans-Serif font for Windows less common already bolded. */
  static const String arialBlack = "arial black";
  /** Sans-Serif font for Mac since 1984, similar to Arial/Helvetica. */
  static const String geneva = "geneva";
  /** Sans-Serif font for Windows most readable sans-serif font for displays. */
  static const String verdana = "verdana";
  /** Sans-Serif font for Mac since 1984 is identical to Arial. */
  static const String helvetica = "helvetica";

  /** Serif font for Windows traditional font with “old-style” numerals. */
  static const String georgia = "georgia";
  /**
   * Serif font for Mac. PCs may have the non-scalable Times use Times New
   * Roman instead.  Times is more compact than Times New Roman.
   */
  static const String times = "times";
  /**
   * Serif font for Windows most common serif font and default serif font for
   * most browsers.
   */
  static const String timesNewRoman = "times new roman";

  /**
   * Monospace font for Mac/Windows most common. Scalable on Mac not scalable
   * on Windows.
   */
  static const String courier = "courier";
  /** Monospace font for Mac/Windows scalable on both platforms. */
  static const String courierNew = "courier new";

  /** Cursive font for Windows and default cursive font for IE. */
  static const String comicSansMs = "comic sans ms";
  /** Cursive font for Mac on Macs 2000 and newer. */
  static const String textile = "textile";
  /** Cursive font for older Macs. */
  static const String appleChancery = "apple chancery";
  /** Cursive font for some PCs. */
  static const String zaphChancery = "zaph chancery";

  /** Fantasy font on most Mac/Windows/Linux platforms. */
  static const String impact = "impact";
  /** Fantasy font for Windows. */
  static const String webdings = "webdings";
}

class LineHeight {
  final num height;
  final bool inPixels;
  const LineHeight(this.height, {this.inPixels : true});
}

// TODO(terry): Support @font-face fule.
/**
 * Font style support for size, family, weight, style, variant, and lineheight.
 */
class Font implements _StyleProperty {
  /** Collection of most common sans-serif fonts in order. */
  static const List<String> sansSerif = const [FontFamily.arial,
                                               FontFamily.verdana,
                                               FontFamily.geneva,
                                               FontFamily.helvetica,
                                               FontGeneric.sansSerif];

  /** Collection of most common serif fonts in order. */
  static const List<String> serif = const [FontFamily.georgia,
                                           FontFamily.timesNewRoman,
                                           FontFamily.times,
                                           FontGeneric.serif];
  /** Collection of most common monospace fonts in order. */
  static const List<String> monospace = const [FontFamily.courierNew,
                                               FontFamily.courier,
                                               FontGeneric.monospace];
  /** Collection of most common cursive fonts in order. */
  static const List<String> cursive = const [FontFamily.textile,
                                             FontFamily.appleChancery,
                                             FontFamily.zaphChancery,
                                             FontGeneric.fantasy];
  /** Collection of most common fantasy fonts in order. */
  static const List<String> fantasy = const [FontFamily.comicSansMs,
                                             FontFamily.impact,
                                             FontFamily.webdings,
                                             FontGeneric.fantasy];

  // TODO(terry): Should support the values xx-small, small, large, xx-large,
  //              etc. (mapped to a pixel sized font)?
  /** Font size in pixels. */
  final num size;

  // TODO(terry): _family should be an immutable list, wrapper class to do this
  //              should exist in Dart.
  /**
   * Family specifies a list of fonts, the browser will sequentially select the
   * the first known/supported font.  There are two types of font families the
   * family-name (e.g., arial, times, courier, etc) or the generic-family (e.g.,
   * serif, sans-seric, etc.)
   */
  final List<String> family;

  /** Font weight from 100, 200, 300, 400, 500, 600, 700, 800, 900 */
  final int weight;

  /** Style of a font normal, italic, oblique. */
  final String style;

  /**
   * Font variant NORMAL (default) or SMALL_CAPS.  Different set of font glyph
   * lower case letters designed to have to fit within the font-height and
   * weight of the corresponding lowercase letters.
   */
  final String variant;

  final LineHeight lineHeight;

  // TODO(terry): Size and computedLineHeight are in pixels.  Need to figure out
  //              how to handle in other units (specified in other units) like
  //              points, inches, etc.  Do we have helpers like Units.Points(12)
  //              where 12 is in points and that's converted to pixels?
  // TODO(terry): lineHeight is computed as 1.2 although CSS_RESET is 1.0 we
  //              need to be consistent some browsers use 1 others 1.2.
  // TODO(terry): There is a school of thought "Golden Ratio Typography".
  // Where width to display the text is also important in computing the line
  // height.  Classic typography suggest the ratio be 1.5.  See
  // <http://www.pearsonified.com/2011/12/golden-ratio-typography.php> and
  // <http://meyerweb.com/eric/thoughts/2008/05/06/line-height-abnormal/>.
  /**
   * Create a font using [size] of font in pixels, [family] name of font(s)
   * using [FontFamily], [style] of the font using [FontStyle], [variant] using
   * [FontVariant], and [lineHeight] extra space (leading) around the font in
   * pixels, if not specified it's 1.2 the font size.
   */
  const Font({this.size, this.family, this.weight, this.style, this.variant,
              this.lineHeight});

  /**
   * Merge the two fonts and return the result. See [Style.merge] for
   * more information.
   */
  factory Font.merge(Font a, Font b) {
    if (a == null) return b;
    if (b == null) return a;
    return new Font._merge(a, b);
  }

  Font._merge(Font a, Font b)
    : size = _mergeVal(a.size, b.size),
      family = _mergeVal(a.family, b.family),
      weight = _mergeVal(a.weight, b.weight),
      style = _mergeVal(a.style, b.style),
      variant = _mergeVal(a.variant, b.variant),
      lineHeight = _mergeVal(a.lineHeight, b.lineHeight);

  /**
   * Shorthand CSS format for font is:
   *
   *    font-style font-variant font-weight font-size/line-height font-family
   *
   * The font-size and font-family values are required. If any of the other
   * values are missing the default value is used.
   */
  String get cssExpression {
    // TODO(jimhug): include variant, style, other options
    if (weight != null) {
      // TODO(jacobr): is this really correct for lineHeight?
      if (lineHeight != null) {
        return "$weight ${size}px/$lineHeightInPixels $_fontsAsString";
      }
      return '$weight ${size}px $_fontsAsString';
    }

    return '${size}px $_fontsAsString';
  }

  Font scale(num ratio) =>
      new Font(size: size * ratio, family: family, weight: weight, style: style,
          variant: variant);

  /**
   * The lineHeight, provides an indirect means to specify the leading. The
   * leading is the difference between the font-size height and the (used)
   * value of line height in pixels.  If lineHeight is not specified it's
   * automatically computed as 1.2 of the font size.  Firefox is 1.2, Safari is
   * ~1.2, and CSS suggest a ration from 1 to 1.2 of the font-size when
   * computing line-height. The Font class constructor has the computation for
   * _lineHeight.
   */
  num get lineHeightInPixels {
    if (lineHeight != null) {
      if (lineHeight.inPixels) {
        return lineHeight.height;
      } else {
        return (size != null) ? lineHeight.height * size : null;
      }
    } else {
      return (size != null) ? size * 1.2 : null;
    }
  }

  int get hashCode {
    // TODO(jimhug): Lot's of potential collisions here. List of fonts, etc.
    return size.toInt() % family[0].hashCode;
  }

  bool operator ==(other) {
    if (other is! Font) return false;
    Font o = other;
    return o.size == size && o.family == family && o.weight == weight &&
        o.lineHeight == lineHeight && o.style == style && o.variant == variant;
  }

  // TODO(terry): This is fragile should probably just iterate through the list
  //              of fonts construction the font-family string.
  /** Return fonts as a comma seperated list sans the square brackets. */
  String get _fontsAsString {
    String fonts = family.toString();
    return fonts.length > 2 ? fonts.substring(1, fonts.length - 1) : "";
  }
}

/**
 * This class stores the sizes of the box edges in the CSS [box model][]. Each
 * edge area is placed around the sides of the content box. The innermost area
 * is the [Style.padding] area which has a background and surrounds the content.
 * The content and padding area is surrounded by the [Style.border], which
 * itself is surrounded by the transparent [Style.margin]. This box represents
 * the eges of padding, border, or margin depending on which accessor was used
 * to retrieve it.
 *
 * [box model]: https://developer.mozilla.org/en/CSS/box_model
 */
class BoxEdge {
  /** The size of the left edge, or null if the style has no edge. */
  final num left;

  /** The size of the top edge, or null if the style has no edge. */
  final num top;

  /** The size of the right edge, or null if the style has no edge. */
  final num right;

  /** The size of the bottom edge, or null if the style has no edge. */
  final num bottom;

  /**
   * Creates a box edge with the specified [left], [top], [right], and
   * [bottom] width.
   */
  const BoxEdge([this.left, this.top, this.right, this.bottom]);

  /**
   * Creates a box edge with the specified [top], [right], [bottom], and
   * [left] width. This matches the typical CSS order:
   * <https://developer.mozilla.org/en/CSS/margin>
   * <https://developer.mozilla.org/en/CSS/border-width>
   * <https://developer.mozilla.org/en/CSS/padding>.
   */
   const BoxEdge.clockwiseFromTop(this.top, this.right, this.bottom, this.left);

  /**
   * This is a helper to creates a box edge with the same [left], [top]
   * [right], and [bottom] widths.
   */
  const BoxEdge.uniform(num size)
    : top = size, left = size, bottom = size, right = size;

  /**
   * Takes a possibly null box edge, with possibly null metrics, and fills
   * them in with 0 instead.
   */
  factory BoxEdge.nonNull(BoxEdge other) {
    if (other == null) return const BoxEdge(0, 0, 0, 0);
    num left = other.left;
    num top = other.top;
    num right = other.right;
    num bottom = other.bottom;
    bool make = false;
    if (left == null) {
      make = true;
      left = 0;
    }
    if (top == null) {
      make = true;
      top = 0;
    }
    if (right == null) {
      make = true;
      right = 0;
    }
    if (bottom == null) {
      make = true;
      bottom = 0;
    }
    return make ? new BoxEdge(left, top, right, bottom) : other;
  }

  /**
   * Merge the two box edge sizes and return the result. See [Style.merge] for
   * more information.
   */
  factory BoxEdge.merge(BoxEdge x, BoxEdge y) {
    if (x == null) return y;
    if (y == null) return x;
    return new BoxEdge._merge(x, y);
  }

  BoxEdge._merge(BoxEdge x, BoxEdge y)
    : left = _mergeVal(x.left, y.left),
      top = _mergeVal(x.top, y.top),
      right = _mergeVal(x.right, y.right),
      bottom = _mergeVal(x.bottom, y.bottom);

  /**
   * The total size of the horizontal edges. Equal to [left] + [right], where
   * null is interpreted as 0px.
   */
  num get width => (left != null ? left : 0) + (right != null ? right : 0);

  /**
   * The total size of the vertical edges. Equal to [top] + [bottom], where
   * null is interpreted as 0px.
   */
  num get height => (top != null ? top : 0) + (bottom != null ? bottom : 0);
}

_mergeVal(x, y) => y != null ? y : x;
