// 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;
    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
  }
}

// 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;
