// 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 '../parser.dart';

// 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 = 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 = 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 Rgba(r, g, b, a);
  }

  Hsla get hsla => 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 Color.hex("${newRgba.toHexArgbString()}");
  }

  Color lighter(num amount) {
    Rgba newRgba = Color._createNewTintShadeFromRgba(rgba, amount);
    return 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.isNotEmpty && 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 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 Hsla(args[0], args[1], args[2]).toHexArgbString();
        case _hslaCss:
          return Hsla(args[0], args[1], args[2], args[3]).toHexArgbString();
        default:
          // Type not defined UnsupportedOperationException should have thrown.
          assert(false);
          break;
      }
    }
    return null;
  }

  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 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) =>
      Color.css("#${Color._convertCssToArgb(hexValue)}").rgba;

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

  factory Rgba.fromArgbValue(num value) {
    return 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 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;
    return value;
  }

  Color get color => Color.createRgba(r, g, b, a);
  Hsla get hsla => 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 = 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 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 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 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() => Rgba.fromHsla(this).toHexArgbString();

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

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

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

  Hsla lighter(num amount) =>
      Hsla.fromRgba(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
    return null;
  }
}

// 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 = [
    FontFamily.arial,
    FontFamily.verdana,
    FontFamily.geneva,
    FontFamily.helvetica,
    FontGeneric.sansSerif
  ];

  /// Collection of most common serif fonts in order.
  static const List<String> serif = [
    FontFamily.georgia,
    FontFamily.timesNewRoman,
    FontFamily.times,
    FontGeneric.serif
  ];

  /// Collection of most common monospace fonts in order.
  static const List<String> monospace = [
    FontFamily.courierNew,
    FontFamily.courier,
    FontGeneric.monospace
  ];

  /// Collection of most common cursive fonts in order.
  static const List<String> cursive = [
    FontFamily.textile,
    FontFamily.appleChancery,
    FontFamily.zaphChancery,
    FontGeneric.fantasy
  ];

  /// Collection of most common fantasy fonts in order.
  static const List<String> fantasy = [
    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 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) => 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 ? 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 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);
}

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