// 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(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 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;
    return value;
  }

  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
    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 = 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);
}

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