<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/base/iteration_helpers.html">
<link rel="import" href="/base/rect.html">
<script>
'use strict';

tv.exportTo('tv.b', function() {
  /**
   * Adds a {@code getInstance} static method that always return the same
   * instance object.
   * @param {!Function} ctor The constructor for the class to add the static
   *     method to.
   */
  function addSingletonGetter(ctor) {
    ctor.getInstance = function() {
      return ctor.instance_ || (ctor.instance_ = new ctor());
    };
  }

  function instantiateTemplate(selector, doc) {
    doc = doc || document;
    var el = doc.querySelector(selector);
    if (!el)
      throw new Error('Element not found');
    return el.createInstance();
  }

  function tracedFunction(fn, name, opt_this) {
    function F() {
      console.time(name);
      try {
        fn.apply(opt_this, arguments);
      } finally {
        console.timeEnd(name);
      }
    }
    return F;
  }

  function normalizeException(e) {
    if (typeof(e) == 'string') {
      return {
        message: e,
        stack: ['<unknown>']
      };
    }

    return {
      message: e.message,
      stack: e.stack ? e.stack : ['<unknown>']
    };
  }

  function stackTrace() {
    var stack = new Error().stack + '';
    stack = stack.split('\n');
    return stack.slice(2);
  }

  function windowRectForElement(element) {
    var position = [element.offsetLeft, element.offsetTop];
    var size = [element.offsetWidth, element.offsetHeight];
    var node = element.offsetParent;
    while (node) {
      position[0] += node.offsetLeft;
      position[1] += node.offsetTop;
      node = node.offsetParent;
    }
    return tv.b.Rect.fromXYWH(position[0], position[1], size[0], size[1]);
  }

  function clamp(x, lo, hi) {
    return Math.min(Math.max(x, lo), hi);
  }

  function lerp(percentage, lo, hi) {
    var range = hi - lo;
    return lo + percentage * range;
  }

  function deg2rad(deg) {
    return (Math.PI * deg) / 180.0;
  }

  function scrollIntoViewIfNeeded(el) {
    var pr = el.parentElement.getBoundingClientRect();
    var cr = el.getBoundingClientRect();
    if (cr.top < pr.top) {
      el.scrollIntoView(true);
    } else if (cr.bottom > pr.bottom) {
      el.scrollIntoView(false);
    }
  }

  function getUsingPath(path, from_dict) {
    var parts = path.split('.');
    var cur = from_dict;

    for (var part; parts.length && (part = parts.shift());) {
      if (!parts.length) {
        return cur[part];
      } else if (part in cur) {
        cur = cur[part];
      } else {
        return undefined;
      }
    }
    return undefined;
  }

  return {
    addSingletonGetter: addSingletonGetter,

    tracedFunction: tracedFunction,
    normalizeException: normalizeException,
    instantiateTemplate: instantiateTemplate,
    stackTrace: stackTrace,

    windowRectForElement: windowRectForElement,

    scrollIntoViewIfNeeded: scrollIntoViewIfNeeded,

    clamp: clamp,
    lerp: lerp,
    deg2rad: deg2rad,

    getUsingPath: getUsingPath
  };
});
</script>
