/*
 * Copyright (C) 2009 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @unrestricted
 */
import {moduleSetting} from './Settings.js';

export class Color {
  /**
   * @param {!Array.<number>} rgba
   * @param {!Format} format
   * @param {string=} originalText
   */
  constructor(rgba, format, originalText) {
    this._hsla = undefined;
    this._rgba = rgba;
    this._originalText = originalText || null;
    this._originalTextIsValid = !!this._originalText;
    this._format = format;
    if (typeof this._rgba[3] === 'undefined') {
      this._rgba[3] = 1;
    }

    for (let i = 0; i < 4; ++i) {
      if (this._rgba[i] < 0) {
        this._rgba[i] = 0;
        this._originalTextIsValid = false;
      }
      if (this._rgba[i] > 1) {
        this._rgba[i] = 1;
        this._originalTextIsValid = false;
      }
    }
  }

  /**
   * @param {string} text
   * @return {?Color}
   */
  static parse(text) {
    // Simple - #hex, nickname
    const value = text.toLowerCase().replace(/\s+/g, '');
    const simple = /^(?:#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|(\w+))$/i;
    let match = value.match(simple);
    if (match) {
      if (match[1]) {  // hex
        let hex = match[1].toLowerCase();
        let format;
        if (hex.length === 3) {
          format = Format.ShortHEX;
          hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
        } else if (hex.length === 4) {
          format = Format.ShortHEXA;
          hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2) +
              hex.charAt(3) + hex.charAt(3);
        } else if (hex.length === 6) {
          format = Format.HEX;
        } else {
          format = Format.HEXA;
        }
        const r = parseInt(hex.substring(0, 2), 16);
        const g = parseInt(hex.substring(2, 4), 16);
        const b = parseInt(hex.substring(4, 6), 16);
        let a = 1;
        if (hex.length === 8) {
          a = parseInt(hex.substring(6, 8), 16) / 255;
        }
        return new Color([r / 255, g / 255, b / 255, a], format, text);
      }

      if (match[2]) {  // nickname
        const nickname = match[2].toLowerCase();
        if (nickname in Nicknames) {
          const rgba = Nicknames[nickname];
          const color = Color.fromRGBA(rgba);
          color._format = Format.Nickname;
          color._originalText = text;
          return color;
        }
        return null;
      }

      return null;
    }

    // rgb/rgba(), hsl/hsla()
    match = text.toLowerCase().match(/^\s*(?:(rgba?)|(hsla?))\((.*)\)\s*$/);

    if (match) {
      const components = match[3].trim();
      let values = components.split(/\s*,\s*/);
      if (values.length === 1) {
        values = components.split(/\s+/);
        if (values[3] === '/') {
          values.splice(3, 1);
          if (values.length !== 4) {
            return null;
          }
        } else if ((values.length > 2 && values[2].indexOf('/') !== -1) || (values.length > 3 && values[3].indexOf('/') !== -1)) {
          const alpha = values.slice(2, 4).join('');
          values = values.slice(0, 2).concat(alpha.split(/\//)).concat(values.slice(4));
        } else if (values.length >= 4) {
          return null;
        }
      }
      if (values.length !== 3 && values.length !== 4 || values.indexOf('') > -1) {
        return null;
      }
      const hasAlpha = (values[3] !== undefined);

      if (match[1]) {  // rgb/rgba
        const rgba = [
          Color._parseRgbNumeric(values[0]), Color._parseRgbNumeric(values[1]), Color._parseRgbNumeric(values[2]),
          hasAlpha ? Color._parseAlphaNumeric(values[3]) : 1
        ];
        if (rgba.indexOf(null) > -1) {
          return null;
        }
        return new Color(rgba, hasAlpha ? Format.RGBA : Format.RGB, text);
      }

      if (match[2]) {  // hsl/hsla
        const hsla = [
          Color._parseHueNumeric(values[0]), Color._parseSatLightNumeric(values[1]),
          Color._parseSatLightNumeric(values[2]), hasAlpha ? Color._parseAlphaNumeric(values[3]) : 1
        ];
        if (hsla.indexOf(null) > -1) {
          return null;
        }
        const rgba = [];
        Color.hsl2rgb(hsla, rgba);
        return new Color(rgba, hasAlpha ? Format.HSLA : Format.HSL, text);
      }
    }

    return null;
  }

  /**
   * @param {!Array.<number>} rgba
   * @return {!Color}
   */
  static fromRGBA(rgba) {
    return new Color([rgba[0] / 255, rgba[1] / 255, rgba[2] / 255, rgba[3]], Format.RGBA);
  }

  /**
   * @param {!Array.<number>} hsva
   * @return {!Color}
   */
  static fromHSVA(hsva) {
    const rgba = [];
    Color.hsva2rgba(hsva, rgba);
    return new Color(rgba, Format.HSLA);
  }

  /**
   * @param {string} value
   * return {number}
   */
  static _parsePercentOrNumber(value) {
    if (isNaN(value.replace('%', ''))) {
      return null;
    }
    const parsed = parseFloat(value);

    if (value.indexOf('%') !== -1) {
      if (value.indexOf('%') !== value.length - 1) {
        return null;
      }
      return parsed / 100;
    }
    return parsed;
  }

  /**
   * @param {string} value
   * return {number}
   */
  static _parseRgbNumeric(value) {
    const parsed = Color._parsePercentOrNumber(value);
    if (parsed === null) {
      return null;
    }

    if (value.indexOf('%') !== -1) {
      return parsed;
    }
    return parsed / 255;
  }

  /**
   * @param {string} value
   * return {number}
   */
  static _parseHueNumeric(value) {
    const angle = value.replace(/(deg|g?rad|turn)$/, '');
    if (isNaN(angle) || value.match(/\s+(deg|g?rad|turn)/)) {
      return null;
    }
    const number = parseFloat(angle);

    if (value.indexOf('turn') !== -1) {
      return number % 1;
    } else if (value.indexOf('grad') !== -1) {
      return (number / 400) % 1;
    } else if (value.indexOf('rad') !== -1) {
      return (number / (2 * Math.PI)) % 1;
    }
    return (number / 360) % 1;
  }

  /**
   * @param {string} value
   * return {number}
   */
  static _parseSatLightNumeric(value) {
    if (value.indexOf('%') !== value.length - 1 || isNaN(value.replace('%', ''))) {
      return null;
    }
    const parsed = parseFloat(value);
    return Math.min(1, parsed / 100);
  }

  /**
   * @param {string} value
   * return {number}
   */
  static _parseAlphaNumeric(value) {
    return Color._parsePercentOrNumber(value);
  }

  /**
   * @param {!Array.<number>} hsva
   * @param {!Array.<number>} out_hsla
   */
  static _hsva2hsla(hsva, out_hsla) {
    const h = hsva[0];
    let s = hsva[1];
    const v = hsva[2];

    const t = (2 - s) * v;
    if (v === 0 || s === 0) {
      s = 0;
    } else {
      s *= v / (t < 1 ? t : 2 - t);
    }

    out_hsla[0] = h;
    out_hsla[1] = s;
    out_hsla[2] = t / 2;
    out_hsla[3] = hsva[3];
  }

  /**
   * @param {!Array.<number>} hsl
   * @param {!Array.<number>} out_rgb
   */
  static hsl2rgb(hsl, out_rgb) {
    const h = hsl[0];
    let s = hsl[1];
    const l = hsl[2];

    function hue2rgb(p, q, h) {
      if (h < 0) {
        h += 1;
      } else if (h > 1) {
        h -= 1;
      }

      if ((h * 6) < 1) {
        return p + (q - p) * h * 6;
      } else if ((h * 2) < 1) {
        return q;
      } else if ((h * 3) < 2) {
        return p + (q - p) * ((2 / 3) - h) * 6;
      } else {
        return p;
      }
    }

    if (s < 0) {
      s = 0;
    }

    let q;
    if (l <= 0.5) {
      q = l * (1 + s);
    } else {
      q = l + s - (l * s);
    }

    const p = 2 * l - q;

    const tr = h + (1 / 3);
    const tg = h;
    const tb = h - (1 / 3);

    out_rgb[0] = hue2rgb(p, q, tr);
    out_rgb[1] = hue2rgb(p, q, tg);
    out_rgb[2] = hue2rgb(p, q, tb);
    out_rgb[3] = hsl[3];
  }

  /**
   * @param {!Array<number>} hsva
   * @param {!Array<number>} out_rgba
   */
  static hsva2rgba(hsva, out_rgba) {
    Color._hsva2hsla(hsva, Color.hsva2rgba._tmpHSLA);
    Color.hsl2rgb(Color.hsva2rgba._tmpHSLA, out_rgba);

    for (let i = 0; i < Color.hsva2rgba._tmpHSLA.length; i++) {
      Color.hsva2rgba._tmpHSLA[i] = 0;
    }
  }

  /**
   * Calculate the luminance of this color using the WCAG algorithm.
   * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
   * @param {!Array<number>} rgba
   * @return {number}
   */
  static luminance(rgba) {
    const rSRGB = rgba[0];
    const gSRGB = rgba[1];
    const bSRGB = rgba[2];

    const r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055) / 1.055), 2.4);
    const g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055) / 1.055), 2.4);
    const b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055) / 1.055), 2.4);

    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  }

  /**
   * Combine the two given color according to alpha blending.
   * @param {!Array<number>} fgRGBA
   * @param {!Array<number>} bgRGBA
   * @param {!Array<number>} out_blended
   */
  static blendColors(fgRGBA, bgRGBA, out_blended) {
    const alpha = fgRGBA[3];

    out_blended[0] = ((1 - alpha) * bgRGBA[0]) + (alpha * fgRGBA[0]);
    out_blended[1] = ((1 - alpha) * bgRGBA[1]) + (alpha * fgRGBA[1]);
    out_blended[2] = ((1 - alpha) * bgRGBA[2]) + (alpha * fgRGBA[2]);
    out_blended[3] = alpha + (bgRGBA[3] * (1 - alpha));
  }

  /**
   * Calculate the contrast ratio between a foreground and a background color.
   * Returns the ratio to 1, for example for two two colors with a contrast ratio of 21:1, this function will return 21.
   * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
   * @param {!Array<number>} fgRGBA
   * @param {!Array<number>} bgRGBA
   * @return {number}
   */
  static calculateContrastRatio(fgRGBA, bgRGBA) {
    Color.blendColors(fgRGBA, bgRGBA, Color.calculateContrastRatio._blendedFg);

    const fgLuminance = Color.luminance(Color.calculateContrastRatio._blendedFg);
    const bgLuminance = Color.luminance(bgRGBA);
    const contrastRatio = (Math.max(fgLuminance, bgLuminance) + 0.05) / (Math.min(fgLuminance, bgLuminance) + 0.05);

    for (let i = 0; i < Color.calculateContrastRatio._blendedFg.length; i++) {
      Color.calculateContrastRatio._blendedFg[i] = 0;
    }

    return contrastRatio;
  }

  /**
   * Compute a desired luminance given a given luminance and a desired contrast
   * ratio.
   * @param {number} luminance The given luminance.
   * @param {number} contrast The desired contrast ratio.
   * @param {boolean} lighter Whether the desired luminance is lighter or darker
   * than the given luminance. If no luminance can be found which meets this
   * requirement, a luminance which meets the inverse requirement will be
   * returned.
   * @return {number} The desired luminance.
   */
  static desiredLuminance(luminance, contrast, lighter) {
    function computeLuminance() {
      if (lighter) {
        return (luminance + 0.05) * contrast - 0.05;
      } else {
        return (luminance + 0.05) / contrast - 0.05;
      }
    }
    let desiredLuminance = computeLuminance();
    if (desiredLuminance < 0 || desiredLuminance > 1) {
      lighter = !lighter;
      desiredLuminance = computeLuminance();
    }
    return desiredLuminance;
  }

  /**
   * @param {!Color} color
   * @return {!Format}
   */
  static detectColorFormat(color) {
    const cf = Format;
    let format;
    const formatSetting = moduleSetting('colorFormat').get();
    if (formatSetting === cf.Original) {
      format = cf.Original;
    } else if (formatSetting === cf.RGB) {
      format = (color.hasAlpha() ? cf.RGBA : cf.RGB);
    } else if (formatSetting === cf.HSL) {
      format = (color.hasAlpha() ? cf.HSLA : cf.HSL);
    } else if (formatSetting === cf.HEX) {
      format = color.detectHEXFormat();
    } else {
      format = cf.RGBA;
    }

    return format;
  }

  /**
   * @return {!Format}
   */
  format() {
    return this._format;
  }

  /**
   * @return {!Array.<number>} HSLA with components within [0..1]
   */
  hsla() {
    if (this._hsla) {
      return this._hsla;
    }
    const r = this._rgba[0];
    const g = this._rgba[1];
    const b = this._rgba[2];
    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    const diff = max - min;
    const add = max + min;

    let h;
    if (min === max) {
      h = 0;
    } else if (r === max) {
      h = ((1 / 6 * (g - b) / diff) + 1) % 1;
    } else if (g === max) {
      h = (1 / 6 * (b - r) / diff) + 1 / 3;
    } else {
      h = (1 / 6 * (r - g) / diff) + 2 / 3;
    }

    const l = 0.5 * add;

    let s;
    if (l === 0) {
      s = 0;
    } else if (l === 1) {
      s = 0;
    } else if (l <= 0.5) {
      s = diff / add;
    } else {
      s = diff / (2 - add);
    }

    this._hsla = /** @type {!Array.<number>} */ ([h, s, l, this._rgba[3]]);
    return this._hsla;
  }

  /**
   * @return {!Array.<number>}
   */
  canonicalHSLA() {
    const hsla = this.hsla();
    return [Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100), hsla[3]];
  }

  /**
   * @return {!Array.<number>} HSVA with components within [0..1]
   */
  hsva() {
    const hsla = this.hsla();
    const h = hsla[0];
    let s = hsla[1];
    const l = hsla[2];

    s *= l < 0.5 ? l : 1 - l;
    return [h, s !== 0 ? 2 * s / (l + s) : 0, (l + s), hsla[3]];
  }

  /**
   * @return {boolean}
   */
  hasAlpha() {
    return this._rgba[3] !== 1;
  }

  /**
   * @return {!Format}
   */
  detectHEXFormat() {
    let canBeShort = true;
    for (let i = 0; i < 4; ++i) {
      const c = Math.round(this._rgba[i] * 255);
      if (c % 17) {
        canBeShort = false;
        break;
      }
    }

    const hasAlpha = this.hasAlpha();
    const cf = Format;
    if (canBeShort) {
      return hasAlpha ? cf.ShortHEXA : cf.ShortHEX;
    }
    return hasAlpha ? cf.HEXA : cf.HEX;
  }

  /**
   * @return {?string}
   */
  asString(format) {
    if (format === this._format && this._originalTextIsValid) {
      return this._originalText;
    }

    if (!format) {
      format = this._format;
    }

    /**
     * @param {number} value
     * @return {number}
     */
    function toRgbValue(value) {
      return Math.round(value * 255);
    }

    /**
     * @param {number} value
     * @return {string}
     */
    function toHexValue(value) {
      const hex = Math.round(value * 255).toString(16);
      return hex.length === 1 ? '0' + hex : hex;
    }

    /**
     * @param {number} value
     * @return {string}
     */
    function toShortHexValue(value) {
      return (Math.round(value * 255) / 17).toString(16);
    }

    switch (format) {
      case Format.Original:
        return this._originalText;
      case Format.RGB:
        if (this.hasAlpha()) {
          return null;
        }
        return String.sprintf(
            'rgb(%d, %d, %d)', toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]));
      case Format.RGBA:
        return String.sprintf(
            'rgba(%d, %d, %d, %f)', toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]),
            this._rgba[3]);
      case Format.HSL:
        if (this.hasAlpha()) {
          return null;
        }
        const hsl = this.hsla();
        return String.sprintf(
            'hsl(%d, %d%, %d%)', Math.round(hsl[0] * 360), Math.round(hsl[1] * 100), Math.round(hsl[2] * 100));
      case Format.HSLA:
        const hsla = this.hsla();
        return String.sprintf(
            'hsla(%d, %d%, %d%, %f)', Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100),
            hsla[3]);
      case Format.HEXA:
        return String
            .sprintf(
                '#%s%s%s%s', toHexValue(this._rgba[0]), toHexValue(this._rgba[1]), toHexValue(this._rgba[2]),
                toHexValue(this._rgba[3]))
            .toLowerCase();
      case Format.HEX:
        if (this.hasAlpha()) {
          return null;
        }
        return String
            .sprintf('#%s%s%s', toHexValue(this._rgba[0]), toHexValue(this._rgba[1]), toHexValue(this._rgba[2]))
            .toLowerCase();
      case Format.ShortHEXA:
        const hexFormat = this.detectHEXFormat();
        if (hexFormat !== Format.ShortHEXA && hexFormat !== Format.ShortHEX) {
          return null;
        }
        return String
            .sprintf(
                '#%s%s%s%s', toShortHexValue(this._rgba[0]), toShortHexValue(this._rgba[1]),
                toShortHexValue(this._rgba[2]), toShortHexValue(this._rgba[3]))
            .toLowerCase();
      case Format.ShortHEX:
        if (this.hasAlpha()) {
          return null;
        }
        if (this.detectHEXFormat() !== Format.ShortHEX) {
          return null;
        }
        return String
            .sprintf(
                '#%s%s%s', toShortHexValue(this._rgba[0]), toShortHexValue(this._rgba[1]),
                toShortHexValue(this._rgba[2]))
            .toLowerCase();
      case Format.Nickname:
        return this.nickname();
    }

    return this._originalText;
  }

  /**
   * @return {!Array<number>}
   */
  rgba() {
    return this._rgba.slice();
  }

  /**
   * @return {!Array.<number>}
   */
  canonicalRGBA() {
    const rgba = new Array(4);
    for (let i = 0; i < 3; ++i) {
      rgba[i] = Math.round(this._rgba[i] * 255);
    }
    rgba[3] = this._rgba[3];
    return rgba;
  }

  /**
   * @return {?string} nickname
   */
  nickname() {
    if (!Color._rgbaToNickname) {
      Color._rgbaToNickname = {};
      for (const nickname in Nicknames) {
        let rgba = Nicknames[nickname];
        if (rgba.length !== 4) {
          rgba = rgba.concat(1);
        }
        Color._rgbaToNickname[rgba] = nickname;
      }
    }

    return Color._rgbaToNickname[this.canonicalRGBA()] || null;
  }

  /**
   * @return {!{r: number, g: number, b: number, a: (number|undefined)}}
   */
  toProtocolRGBA() {
    const rgba = this.canonicalRGBA();
    const result = {r: rgba[0], g: rgba[1], b: rgba[2]};
    if (rgba[3] !== 1) {
      result.a = rgba[3];
    }
    return result;
  }

  /**
   * @return {!Color}
   */
  invert() {
    const rgba = [];
    rgba[0] = 1 - this._rgba[0];
    rgba[1] = 1 - this._rgba[1];
    rgba[2] = 1 - this._rgba[2];
    rgba[3] = this._rgba[3];
    return new Color(rgba, Format.RGBA);
  }

  /**
   * @param {number} alpha
   * @return {!Color}
   */
  setAlpha(alpha) {
    const rgba = this._rgba.slice();
    rgba[3] = alpha;
    return new Color(rgba, Format.RGBA);
  }

  /**
   * @param {!Color} fgColor
   * @return {!Color}
   */
  blendWith(fgColor) {
    const rgba = [];
    Color.blendColors(fgColor._rgba, this._rgba, rgba);
    return new Color(rgba, Format.RGBA);
  }
}

/** @type {!RegExp} */
export const Regex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{8}|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3,4}|\b[a-zA-Z]+\b(?!-))/g;

/**
 * @enum {string}
 */
export const Format = {
  Original: 'original',
  Nickname: 'nickname',
  HEX: 'hex',
  ShortHEX: 'shorthex',
  HEXA: 'hexa',
  ShortHEXA: 'shorthexa',
  RGB: 'rgb',
  RGBA: 'rgba',
  HSL: 'hsl',
  HSLA: 'hsla'
};

export const Nicknames = {
  'aliceblue': [240, 248, 255],
  'antiquewhite': [250, 235, 215],
  'aqua': [0, 255, 255],
  'aquamarine': [127, 255, 212],
  'azure': [240, 255, 255],
  'beige': [245, 245, 220],
  'bisque': [255, 228, 196],
  'black': [0, 0, 0],
  'blanchedalmond': [255, 235, 205],
  'blue': [0, 0, 255],
  'blueviolet': [138, 43, 226],
  'brown': [165, 42, 42],
  'burlywood': [222, 184, 135],
  'cadetblue': [95, 158, 160],
  'chartreuse': [127, 255, 0],
  'chocolate': [210, 105, 30],
  'coral': [255, 127, 80],
  'cornflowerblue': [100, 149, 237],
  'cornsilk': [255, 248, 220],
  'crimson': [237, 20, 61],
  'cyan': [0, 255, 255],
  'darkblue': [0, 0, 139],
  'darkcyan': [0, 139, 139],
  'darkgoldenrod': [184, 134, 11],
  'darkgray': [169, 169, 169],
  'darkgrey': [169, 169, 169],
  'darkgreen': [0, 100, 0],
  'darkkhaki': [189, 183, 107],
  'darkmagenta': [139, 0, 139],
  'darkolivegreen': [85, 107, 47],
  'darkorange': [255, 140, 0],
  'darkorchid': [153, 50, 204],
  'darkred': [139, 0, 0],
  'darksalmon': [233, 150, 122],
  'darkseagreen': [143, 188, 143],
  'darkslateblue': [72, 61, 139],
  'darkslategray': [47, 79, 79],
  'darkslategrey': [47, 79, 79],
  'darkturquoise': [0, 206, 209],
  'darkviolet': [148, 0, 211],
  'deeppink': [255, 20, 147],
  'deepskyblue': [0, 191, 255],
  'dimgray': [105, 105, 105],
  'dimgrey': [105, 105, 105],
  'dodgerblue': [30, 144, 255],
  'firebrick': [178, 34, 34],
  'floralwhite': [255, 250, 240],
  'forestgreen': [34, 139, 34],
  'fuchsia': [255, 0, 255],
  'gainsboro': [220, 220, 220],
  'ghostwhite': [248, 248, 255],
  'gold': [255, 215, 0],
  'goldenrod': [218, 165, 32],
  'gray': [128, 128, 128],
  'grey': [128, 128, 128],
  'green': [0, 128, 0],
  'greenyellow': [173, 255, 47],
  'honeydew': [240, 255, 240],
  'hotpink': [255, 105, 180],
  'indianred': [205, 92, 92],
  'indigo': [75, 0, 130],
  'ivory': [255, 255, 240],
  'khaki': [240, 230, 140],
  'lavender': [230, 230, 250],
  'lavenderblush': [255, 240, 245],
  'lawngreen': [124, 252, 0],
  'lemonchiffon': [255, 250, 205],
  'lightblue': [173, 216, 230],
  'lightcoral': [240, 128, 128],
  'lightcyan': [224, 255, 255],
  'lightgoldenrodyellow': [250, 250, 210],
  'lightgreen': [144, 238, 144],
  'lightgray': [211, 211, 211],
  'lightgrey': [211, 211, 211],
  'lightpink': [255, 182, 193],
  'lightsalmon': [255, 160, 122],
  'lightseagreen': [32, 178, 170],
  'lightskyblue': [135, 206, 250],
  'lightslategray': [119, 136, 153],
  'lightslategrey': [119, 136, 153],
  'lightsteelblue': [176, 196, 222],
  'lightyellow': [255, 255, 224],
  'lime': [0, 255, 0],
  'limegreen': [50, 205, 50],
  'linen': [250, 240, 230],
  'magenta': [255, 0, 255],
  'maroon': [128, 0, 0],
  'mediumaquamarine': [102, 205, 170],
  'mediumblue': [0, 0, 205],
  'mediumorchid': [186, 85, 211],
  'mediumpurple': [147, 112, 219],
  'mediumseagreen': [60, 179, 113],
  'mediumslateblue': [123, 104, 238],
  'mediumspringgreen': [0, 250, 154],
  'mediumturquoise': [72, 209, 204],
  'mediumvioletred': [199, 21, 133],
  'midnightblue': [25, 25, 112],
  'mintcream': [245, 255, 250],
  'mistyrose': [255, 228, 225],
  'moccasin': [255, 228, 181],
  'navajowhite': [255, 222, 173],
  'navy': [0, 0, 128],
  'oldlace': [253, 245, 230],
  'olive': [128, 128, 0],
  'olivedrab': [107, 142, 35],
  'orange': [255, 165, 0],
  'orangered': [255, 69, 0],
  'orchid': [218, 112, 214],
  'palegoldenrod': [238, 232, 170],
  'palegreen': [152, 251, 152],
  'paleturquoise': [175, 238, 238],
  'palevioletred': [219, 112, 147],
  'papayawhip': [255, 239, 213],
  'peachpuff': [255, 218, 185],
  'peru': [205, 133, 63],
  'pink': [255, 192, 203],
  'plum': [221, 160, 221],
  'powderblue': [176, 224, 230],
  'purple': [128, 0, 128],
  'rebeccapurple': [102, 51, 153],
  'red': [255, 0, 0],
  'rosybrown': [188, 143, 143],
  'royalblue': [65, 105, 225],
  'saddlebrown': [139, 69, 19],
  'salmon': [250, 128, 114],
  'sandybrown': [244, 164, 96],
  'seagreen': [46, 139, 87],
  'seashell': [255, 245, 238],
  'sienna': [160, 82, 45],
  'silver': [192, 192, 192],
  'skyblue': [135, 206, 235],
  'slateblue': [106, 90, 205],
  'slategray': [112, 128, 144],
  'slategrey': [112, 128, 144],
  'snow': [255, 250, 250],
  'springgreen': [0, 255, 127],
  'steelblue': [70, 130, 180],
  'tan': [210, 180, 140],
  'teal': [0, 128, 128],
  'thistle': [216, 191, 216],
  'tomato': [255, 99, 71],
  'turquoise': [64, 224, 208],
  'violet': [238, 130, 238],
  'wheat': [245, 222, 179],
  'white': [255, 255, 255],
  'whitesmoke': [245, 245, 245],
  'yellow': [255, 255, 0],
  'yellowgreen': [154, 205, 50],
  'transparent': [0, 0, 0, 0],
};

export const PageHighlight = {
  Content: Color.fromRGBA([111, 168, 220, .66]),
  ContentLight: Color.fromRGBA([111, 168, 220, .5]),
  ContentOutline: Color.fromRGBA([9, 83, 148]),
  Padding: Color.fromRGBA([147, 196, 125, .55]),
  PaddingLight: Color.fromRGBA([147, 196, 125, .4]),
  Border: Color.fromRGBA([255, 229, 153, .66]),
  BorderLight: Color.fromRGBA([255, 229, 153, .5]),
  Margin: Color.fromRGBA([246, 178, 107, .66]),
  MarginLight: Color.fromRGBA([246, 178, 107, .5]),
  EventTarget: Color.fromRGBA([255, 196, 196, .66]),
  Shape: Color.fromRGBA([96, 82, 177, 0.8]),
  ShapeMargin: Color.fromRGBA([96, 82, 127, .6]),
  CssGrid: Color.fromRGBA([0x4b, 0, 0x82, 1])
};

export class Generator {
  /**
   * @param {!{min: number, max: number}|number=} hueSpace
   * @param {!{min: number, max: number, count: (number|undefined)}|number=} satSpace
   * @param {!{min: number, max: number, count: (number|undefined)}|number=} lightnessSpace
   * @param {!{min: number, max: number, count: (number|undefined)}|number=} alphaSpace
   */
  constructor(hueSpace, satSpace, lightnessSpace, alphaSpace) {
    this._hueSpace = hueSpace || {min: 0, max: 360};
    this._satSpace = satSpace || 67;
    this._lightnessSpace = lightnessSpace || 80;
    this._alphaSpace = alphaSpace || 1;
    /** @type {!Map<string, string>} */
    this._colors = new Map();
  }

  /**
   * @param {string} id
   * @param {string} color
   */
  setColorForID(id, color) {
    this._colors.set(id, color);
  }

  /**
   * @param {string} id
   * @return {string}
   */
  colorForID(id) {
    let color = this._colors.get(id);
    if (!color) {
      color = this._generateColorForID(id);
      this._colors.set(id, color);
    }
    return color;
  }

  /**
   * @param {string} id
   * @return {string}
   */
  _generateColorForID(id) {
    const hash = String.hashCode(id);
    const h = this._indexToValueInSpace(hash, this._hueSpace);
    const s = this._indexToValueInSpace(hash >> 8, this._satSpace);
    const l = this._indexToValueInSpace(hash >> 16, this._lightnessSpace);
    const a = this._indexToValueInSpace(hash >> 24, this._alphaSpace);
    return `hsla(${h}, ${s}%, ${l}%, ${a})`;
  }

  /**
   * @param {number} index
   * @param {!{min: number, max: number, count: (number|undefined)}|number} space
   * @return {number}
   */
  _indexToValueInSpace(index, space) {
    if (typeof space === 'number') {
      return space;
    }
    const count = space.count || space.max - space.min;
    index %= count;
    return space.min + Math.floor(index / (count - 1) * (space.max - space.min));
  }
}

/** @type {!Array<number>} */
Color.hsva2rgba._tmpHSLA = [0, 0, 0, 0];

Color.calculateContrastRatio._blendedFg = [0, 0, 0, 0];
