text: import EJSC from '../EJSC.es6';
  import Formatter from './Formatter.es6';
  
  /**
   * Use this formatter when you want to display date values in your charts.
   *
   * @example
   * ```
   * // Create a basic DateFormatter
   * new EJSC.DateFormatter();
   * ```
   *
   * @class EJSC.DateFormatter
   * @extends EJSC.Formatter
   * @constructor
   * @param {String} formatString The format string
   * @param {Object} [options={}] The config options to apply
   * @since 1.0.0
   */
  export default EJSC.DateFormatter = class DateFormatter extends Formatter {
    /* eslint-disable no-irregular-whitespace */
    /**
     * Defines the format to convert the date into.
     *
     * The <b>formatString</b> property follows very closely to the PHP implementation of DateTime::format.
     *
     * <table class="border table table-sm">
     * <thead>
     * <tr><th>Char</th><th>Description</th><th>Example(s)</th></tr>
     * </thead>
     * <tbody>
     * <tr><th colspan="3">Day</th></tr>
     * <tr><td>d</td><td>Day of the month, 2 digits with leading zeros</td><td>01 to 31</td></tr>
     * <tr><td>D</td><td>A textual representation of a day, three letters</td><td>Mon through Sun</td></tr>
     * <tr><td>j</td><td>Day of the month without leading zeros</td><td>1 to 31</td></tr>
     * <tr><td>l</td><td>A full textual representation of the day of the week</td><td>Sunday through Saturday</td></tr>
     * <tr><th colspan="3">Month</th></tr>
     * <tr><td>F</td><td>A full textual representation of a month, such as January or March</td><td>January through December</td></tr>
     * <tr><td>m</td><td>Numeric representation of a month, with leading zeros</td><td>01 through 12</td></tr>
     * <tr><td>M</td><td>A short textual representation of a month, three letters</td><td>Jan through Dec</td></tr>
     * <tr><td>n</td><td>Numeric representation of a month, without leading zeros</td><td>1 through 12</td></tr>
     * <tr><th colspan="3">Year</th></tr>
     * <tr><td>Y</td><td>A full numeric representation of a year, 4 digits</td><td>Examples: 1999 or 2003</td></tr>
     * <tr><td>y</td><td>A two digit representation of a year</td><td>Examples: 99 or 03</td></tr>
     * <tr><th colspan="3">Time</th></tr>
     * <tr><td>a</td><td>Lowercase Ante meridiem and Post meridiem</td><td>am or pm</td></tr>
     * <tr><td>A</td><td>Uppercase Ante meridiem and Post meridiem</td><td>AM or PM</td></tr>
     * <tr><td>g</td><td>12-hour format of an hour without leading zeros</td><td>1 through 12</td></tr>
     * <tr><td>G</td><td>24-hour format of an hour without leading zeros</td><td>0 through 23</td></tr>
     * <tr><td>h</td><td>12-hour format of an hour with leading zeros</td><td>01 through 12</td></tr>
     * <tr><td>H</td><td>24-hour format of an hour with leading zeros</td><td>00 through 23</td></tr>
     * <tr><td>i</td><td>Minutes with leading zeros</td><td>00 to 59</td></tr>
     * <tr><td>s</td><td>Seconds with leading zeros</td><td>00 through 59</td></tr>
     * <tr><td>v</td><td>Milliseconds</td><td>Example: 654</td></tr>
     * </tbody>
     * </table>
     *
     * @example
     * ```
     * // Create a DateFormatter which will format the date like "2020-08-13"
     * new EJSC.DateFormatter({
     *   formatString: 'Y-m-d'
     * });
     * ```
     *
     * @required
     * @attribute {String} formatString
     * @since 3.0.0
     */
     /* eslint-enable no-irregular-whitespace */
  
    // getter
    getFormatString() {
      // Return the current format string
      return this.formatString;
    }
  
    // setter
    setFormatString(formatString) {
      // Update the current format string
      this.formatString = formatString;
  
      // Redraw the chart if needed
      if (this.listening) {
        this.update();
      }
    }
  
    /**
     * Set this property to false to use the workstation local time to calculate dates.
     * This may be useful when passing in dates generated by JavaScript on the client machine to indicate current time.
     *
     * @example
     * ```
     * // Create a DateFormatter which will use local time instead of UTC
     * new EJSC.DateFormatter({
     *   useUTC: false
     * });
     * ```
     *
     * @attribute {Boolean} useUTC
     * @default true
     * @since 3.0.0
     */
  
    // getter
    getUseUTC() {
      // Return the current use UTC
      return this.useUTC;
    }
  
    // setter
    setUseUTC(useUTC) {
      // Update the current use UTC
      this.useUTC = useUTC;
  
      // Redraw the chart if needed
      if (this.listening) {
        this.update();
      }
    }
  
    // constructor
    constructor(formatString, options) {
      // super
      super(options);
  
      // Store and prepare the data handler
      this.formatString = formatString;
    }
  
    /**
     * Initializes the variable properties of the class.
     *
     * @method init
     * @private
     * @since 3.0.0
     */
    init() {
      // super
      super.init();
  
      // Initialize some public properties
      this.useUTC = true;
    }
  
    /**
     * Formats the value for display.
     *
     * @example
     * ```
     * // TODO:
     * ```
     *
     * @method format
     * @param {*} value The value to format
     * @return {String} The formatted value
     * @since 1.0.0
     */
    format(value) {
      // Make sure the value is a number
      if (!_.isNumber(value)) {
        // TODO: error out
      }
  
      // Create some local variables
      let getPrefix = 'get' + (this.useUTC ? 'UTC' : '');
      let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
      let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
      let meridiems = ['AM', 'PM'];
  
      // Create the list of replacements
      let replacements = {
        'd': (date) => _.padStart(date[getPrefix + 'Date']().toString(), 2, '0'),
        'D': (date) => days[date[getPrefix + 'Day']()].substr(0, 3),
        'j': (date) => date[getPrefix + 'Date'](),
        'l': (date) => days[date[getPrefix + 'Day']()],
        'F': (date) => months[date[getPrefix + 'Month']()],
        'm': (date) => _.padStart((date[getPrefix + 'Month']() + 1).toString(), 2, '0'),
        'M': (date) => months[date[getPrefix + 'Month']()].substr(0, 3),
        'n': (date) => date[getPrefix + 'Month']() + 1,
        'Y': (date) => date[getPrefix + 'FullYear'](),
        'y': (date) => Math.round(((date[getPrefix + 'FullYear']() / 100) % 1) * 100),
        'a': (date) => meridiems[Math.floor(date[getPrefix + 'Hours']() / 12)].toLowerCase(),
        'A': (date) => meridiems[Math.floor(date[getPrefix + 'Hours']() / 12)],
        'g': (date) => ((date[getPrefix + 'Hours']() % 12) || 0),
        'G': (date) => date[getPrefix + 'Hours'](),
        'h': (date) => _.padStart(((date[getPrefix + 'Hours']() % 12) || 0).toString(), 2, '0'),
        'H': (date) => _.padStart(date[getPrefix + 'Hours']().toString(), 2, '0'),
        'i': (date) => _.padStart(date[getPrefix + 'Minutes']().toString(), 2, '0'),
        's': (date) => _.padStart(date[getPrefix + 'Seconds']().toString(), 2, '0'),
        'v': (date) => _.padStart(date[getPrefix + 'Milliseconds']().toString(), 3, '0')
      };
  
      // Return the formatted string
      return this.formatString.replace(new RegExp('(' + Object.keys(replacements).join('|') + ')', 'g'), (match) => replacements[match](new Date(value)));
    }
  };
  