/*
 * Copyright 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: jmarantz@google.com (Joshua Marantz)
 * Author: sligocki@google.com (Shawn Ligocki)
 */

// TODO(sligocki): Move to third_party/pagespeed/opt/responsive?

goog.provide('pagespeed.Responsive');
goog.provide('pagespeed.ResponsiveImage');
goog.provide('pagespeed.ResponsiveImageCandidate');
goog.provide('pagespeed.responsiveInstance');

goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events.EventType');
goog.require('goog.string');



/**
 * A single candidate image URL and target resolution (2x, 4x, etc.) from
 * a responsive image srcset.
 * @struct
 * @constructor
 * @param {number} resolution
 * @param {string} url
 */
pagespeed.ResponsiveImageCandidate = function(resolution, url) {
  /**
   * What devicePixelRatio is this image intended for?
   * @type {number}
   */
  this.resolution = resolution;

  /**
   * URL of image meant for this resolution.
   * @type {string}
   */
  this.url = url;
};



/**
 * Information about each responsive image.
 * @constructor
 * @param {!Element} img
 */
pagespeed.ResponsiveImage = function(img) {
  /**
   * @type {!Element}
   */
  this.img = img;

  /**
   * Current resolution level used as src.
   * @type {number}
   */
  this.currentResolution = 0;

  /**
   * List of possible resolution levels (with corresponding URLs).
   * It must be sorted from lowest to highest resolution level.
   * @type {!Array<!pagespeed.ResponsiveImageCandidate>}
   */
  this.availableResolutions = [];
};



/**
 * @constructor
 */
pagespeed.Responsive = function() {
  /**
   * List of all responsive images on page and the resolutions available for
   * each one. These are all updated on zoom.
   * @private {!Array<!pagespeed.ResponsiveImage>}
   */
  this.allImages_ = [];
};


/**
 * Pre-load hi-res image in background, updating this image src once it's
 * in cache.
 * @param {!Element} img
 * @param {string} url
 * @private
 */
pagespeed.Responsive.updateImgSrc_ = function(img, url) {
  var tempImg = new Image();
  tempImg.onload = function() {
    img.src = url;
  };
  tempImg.src = url;
};


/**
 * Load this image at the appropriate resolution setting. Current algorithm is
 * to load the smallest resolution >= devicePixelRatio.
 *
 * TODO(sligocki): Should we just load the highest resolution as soon as
 * they zoom?
 * TODO(sligocki): Is this the algorithm that browsers would use or do they
 * do something more complicated to compensate for moires, etc.?
 *
 * @param {number} devicePixelRatio
 */
pagespeed.ResponsiveImage.prototype.responsiveResize = function(
    devicePixelRatio) {
  if (devicePixelRatio > this.currentResolution) {
    var numResolutions = this.availableResolutions.length;
    for (var i = 0; i < numResolutions; ++i) {
      if (devicePixelRatio <= this.availableResolutions[i].resolution) {
        this.currentResolution = this.availableResolutions[i].resolution;
        pagespeed.Responsive.updateImgSrc_(this.img,
                                           this.availableResolutions[i].url);
        break;
      }
    }
  }
};


/**
 * Return the actual number of device pixels per CSS pixel including zoom.
 * Note that C-+ resizing on desktops seems to affect window.devicePixelRatio,
 * but pinch zoom on mobile does not seem to affect this value.
 *
 * @return {number}
 */
pagespeed.Responsive.prototype.computeDevicePixelRatioWithZoom = function() {
  var zoomRatio = document.documentElement.clientWidth / window.innerWidth;
  return goog.dom.getPixelRatio() * zoomRatio;
};


/**
 * Resize all images in response to a resize event.
 */
pagespeed.Responsive.prototype.responsiveResize = function() {
  var devicePixelRatio = this.computeDevicePixelRatioWithZoom();
  var numImages = this.allImages_.length;
  for (var i = 0; i < numImages; ++i) {
    this.allImages_[i].responsiveResize(devicePixelRatio);
  }
};


/**
 * Find the index for the first char to match regular expression re in str.
 * If no chars match re, returns str.length.
 *
 * @param {string} str String to search within.
 * @param {!RegExp} re RegExp to search for.
 * @return {number} Smallest index matching re (or str.length if none does).
 * @private
 */
pagespeed.Responsive.search_ = function(str, re) {
  var offset = str.search(re);
  if (offset == -1) {
    return str.length;
  } else {
    return offset;
  }
};


/**
 * From https://html.spec.whatwg.org/#space-character
 * The space characters, for the purposes of this specification, are
 * U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF),
 * U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
 * @private @const {!RegExp}
 */
var WHITESPACE = /[ \t\n\f\r]/;


/** @private @const {!RegExp} */
var NOT_WHITESPACE = /[^ \t\n\f\r]/;


/** @private @const {!RegExp} */
var WHITESPACE_OR_COMMA = /[ \t\n\f\r,]/;


/** @private @const {!RegExp} */
var NOT_WHITESPACE_OR_COMMA = /[^ \t\n\f\r,]/;


/**
 * Parse srcset attribute string into a ResponsiveImage object.
 * @param {!Element} img
 * @param {string} src
 * @param {string} srcset
 * @return {?pagespeed.ResponsiveImage}
 */
pagespeed.Responsive.prototype.parseSrcset = function(img, src, srcset) {
  var respImage = new pagespeed.ResponsiveImage(img);
  var has_1x = false;
  var rest = srcset;

  // Decompose srcset into each resolution
  // Mostly follows:
  // https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute
  // with the main exception that we fail early for most situations where the
  // srcset contains w descriptors (or other descriptors we don't understand).

  // Skip whitespace before first candidate URL. Ignore spurious preceding
  // commas too. Although preceding commas are considered parse errors, the
  // spec says to skip them and continue parsing the rest of the srcset.
  var pos = pagespeed.Responsive.search_(rest, NOT_WHITESPACE_OR_COMMA);
  rest = rest.slice(pos);
  while (rest.length > 0) {
    // URL is terminated by either a white space or a comma followed by a space.
    // Note: urlEnd is actually the index after the end of the URL.
    pos = pagespeed.Responsive.search_(rest, WHITESPACE);
    // Note rest[0] was not whitespace nor comma nor EOF, so url >0 length.
    var url = rest.slice(0, pos);
    rest = rest.slice(pos);

    if (url[url.length - 1] == ',') {
      // We cannot deal with srcset with no descriptors.
      // Abort the whole thing.
      return null;
    }

    // Skip whitespace
    pos = pagespeed.Responsive.search_(rest, NOT_WHITESPACE);
    rest = rest.slice(pos);
    // Descriptor is terminated by either a comma or whitespace.
    // Note: According to the spec, descriptor lexing rules are actually more
    // complicated and involve skipping over paren sections, however any such
    // strings (with parentheses) will fail to parse as a number and we will
    // fail the entire parse.
    // Note: descriptorEnd is the index after the end of the descriptor.
    pos = pagespeed.Responsive.search_(rest, WHITESPACE_OR_COMMA);
    var descriptor = rest.slice(0, pos);
    rest = rest.slice(pos);
    if ((descriptor.length > 1) &&
        (descriptor[descriptor.length - 1] == 'x')) {
      var resolution = goog.string.toNumber(descriptor.slice(0, -1));
      if (isNaN(resolution)) {
        return null;
      }
      respImage.availableResolutions.push(
          new pagespeed.ResponsiveImageCandidate(resolution, url));
      if (resolution == 1) {
        has_1x = true;
      }
    } else {
      // We cannot deal with srcset with w (or no) descriptors.
      // Abort the whole thing.
      // TODO(sligocki): Do we want to support srcset w descriptors? Or empty
      // descriptors, spec seems to say empty descriptor -> 1x.
      return null;
    }

    // Skip over whitespace before comma.
    pos = pagespeed.Responsive.search_(rest, NOT_WHITESPACE);
    rest = rest.slice(pos);
    if (rest.length > 0 && rest[0] != ',') {
      // Invalid srcset, should only have one descriptor field before comma or
      // end of string.
      return null;
    } else {
      // Skip over comma.
      rest = rest.slice(1);
    }
    // Skip whitespace after comma (before next candidate).
    pos = pagespeed.Responsive.search_(rest, NOT_WHITESPACE_OR_COMMA);
    rest = rest.slice(pos);
  }

  if (!has_1x && src) {
    // Use src for 1x version if no 1x in srcset.
    respImage.availableResolutions.push(
        new pagespeed.ResponsiveImageCandidate(1, src));
  }

  respImage.availableResolutions.sort(function(a, b) {
    return a.resolution - b.resolution;
  });

  return respImage;
};


/**
 * Collect all responsive images on site, add attributes and event listeners
 * and actually evaluate responsive srcset (as a polyfil).
 */
pagespeed.Responsive.prototype.init = function() {
  // Initialize responsive images.
  var images = document.getElementsByTagName(goog.dom.TagName.IMG);
  for (var i = 0, img; img = images[i]; ++i) {
    var src = img.getAttribute('src');
    var srcset = img.getAttribute('srcset');
    if (srcset) {
      var respImage = this.parseSrcset(img, src, srcset);
      if (respImage != null) {
        this.allImages_.push(respImage);
      }
    }
  }

  // Set event listeners to resize all images if any zoom event happens.

  // Resize event is fired on desktop C-+/C--, but not mobile pinch zoom.
  window.addEventListener(goog.events.EventType.RESIZE,
                          goog.bind(this.responsiveResize, this));
  // Heuristic for detecting pinch zoom.
  // Detect touchmove with more than one touch.
  // TODO(sligocki): Will touchmove event give us most zoomed view? Or do we
  // need to attach to a touchend event for that?
  // TODO(sligocki): Jud says this will fire continuously, test to see if this
  // will cause too much load on a site with many images and rate limit if it
  // does.
  window.addEventListener(goog.events.EventType.TOUCHMOVE,
                          goog.bind(function(event) {
                            // Multiple fingers.
                            if (event.touches.length > 1) {
                              this.responsiveResize();
                            }
                          }, this));

  // Polyfill (Apply responsive images for any browser which doesn't support
  // srcset natively).
  this.responsiveResize();
};


/**
 * Singleton instance used for keeping track of all responsive image rewrites.
 * @type {pagespeed.Responsive}
 */
pagespeed.responsiveInstance = new pagespeed.Responsive();
pagespeed.responsiveInstance.init();
