/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

// TODO: Define a more convenient set of methods for iframe resizing in wave.

/**
 * @fileoverview This library augments gadgets.window with functionality
 * to change the width of a gadget dynamically. Derived from the
 * dynamic-height feature source code.
 * See:
 * http://svn.apache.org/repos/asf/shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js
 */

/**
 * @static
 * @class This namespace is used by the Gadgets API for the features it offers
 * in all containers, including Wave. Those are documented here:
 * http://code.google.com/apis/gadgets/docs/reference/
 * @name gadgets
 */

/**
 * @static
 * @class This namespace is defined by the Gadgets API, and documented here:
 * http://code.google.com/apis/gadgets/docs/reference/#gadgets.window <br>
 * The Wave Gadgets API adds an additional method on top of the set documented
 * there.
 * @name gadgets.window
 */
gadgets.window = gadgets.window || {};

// we wrap these in an anonymous function to avoid storing private data
// as members of gadgets.window.
(function() {

  var oldWidth;

  /**
   * Parse out the value (specified in px) for a CSS attribute of an element.
   *
   * @param {Element} elem the element with the attribute to look for.
   * @param {string} attr the CSS attribute name of interest.
   * @returns {number} the value of the px attr of the elem.
   * @private
   */
  function parseIntFromElemPxAttribute(elem, attr) {
    var style = window.getComputedStyle(elem, "");
    var value = style.getPropertyValue(attr);
    value.match(/^([0-9]+)/);
    return parseInt(RegExp.$1, 10);
  }

  /**
   * For Webkit-based browsers, calculate the width of the gadget iframe by
   * iterating through all elements in the gadget, starting with the body tag.
   * It is not sufficient to only account body children elements, because
   * CSS style position "float" may place a child element outside of the
   * containing parent element. Not counting "float" elements may lead to
   * undercounting.
   *
   * @returns {number} the width of the gadget.
   * @private
   */
  function getWidthForWebkit() {
    var result = 0;
    var queue = [ document.body ];

    while (queue.length > 0) {
      var elem = queue.shift();
      var children = elem.childNodes;

      for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (typeof child.offsetLeft !== 'undefined' &&
            typeof child.scrollWidth !== 'undefined') {
          // scrollHeight already accounts for border-bottom, padding-bottom.
          var right = child.offsetLeft + child.scrollWidth +
              parseIntFromElemPxAttribute(child, "margin-right");
          result = Math.max(result, right);
        }
        queue.push(child);
      }
    }

    // Add border, padding and margin of the containing body.
    return result
        + parseIntFromElemPxAttribute(document.body, "border-right")
        + parseIntFromElemPxAttribute(document.body, "margin-right")
        + parseIntFromElemPxAttribute(document.body, "padding-right");
  }

  /**
   * Adjusts the gadget width
   * @param {number=} opt_width An optional preferred width in pixels. If not
   *     specified, will attempt to fit the gadget to its content.
   * @member gadgets.window
   */
  gadgets.window.adjustWidth = function(opt_width) {
    var newWidth = parseInt(opt_width, 10);
    var widthAutoCalculated = false;
    if (isNaN(newWidth)) {
      widthAutoCalculated = true;

      // Resize the gadget to fit its content.

      // Get the width of the viewport
      var vw = gadgets.window.getViewportDimensions().width;
      var body = document.body;
      var docEl = document.documentElement;
      if (document.compatMode === 'CSS1Compat' && docEl.scrollWidth) {
        // In Strict mode:
        // The inner content height is contained in either:
        //    document.documentElement.scrollWidth
        //    document.documentElement.offsetWidth
        // Based on studying the values output by different browsers,
        // use the value that's NOT equal to the viewport width found above.
        newWidth = docEl.scrollWidth !== vw ?
                     docEl.scrollWidth : docEl.offsetWidth;
      } else if (navigator.userAgent.indexOf('AppleWebKit') >= 0) {
        // In Webkit:
        // Property scrollWidth and offsetWidth will only increase in value.
        // This will incorrectly calculate reduced width of a gadget
        // (ie: made smaller).
        newWidth = getWidthForWebkit();
      } else if (body && docEl) {
        // In Quirks mode:
        // documentElement.clientWidth is equal to documentElement.offsetWidth
        // except in IE.  In most browsers, document.documentElement can be used
        // to calculate the inner content width.
        // However, in other browsers (e.g. IE), document.body must be used
        // instead.  How do we know which one to use?
        // If document.documentElement.clientWidth does NOT equal
        // document.documentElement.offsetWidth, then use document.body.
        var sw = docEl.scrollWidth;
        var ow = docEl.offsetWidth;
        if (docEl.clientWidth !== ow) {
          sw = body.scrollWidth;
          ow = body.offsetWidth;
        }

        // Detect whether the inner content width is bigger or smaller
        // than the bounding box (viewport).  If bigger, take the larger
        // value.  If smaller, take the smaller value.
        if (sw > vw) {
          // Content is larger
          newWidth = sw > ow ? sw : ow;
        } else {
          // Content is smaller
          newWidth = sw < ow ? sw : ow;
        }
      }
    }

    // Only make the RPC call if width has changed
    if (newWidth !== oldWidth &&
        !isNaN(newWidth) &&
        !(widthAutoCalculated && newWidth === 0)) {
      oldWidth = newWidth;
      gadgets.rpc.call(null, "setIframeWidth", null, newWidth);
    }
  };
}());
