1// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5//     You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//     See the License for the specific language governing permissions and
13// limitations under the License.
14(function(shared, scope, testing) {
15
16  var nullTarget = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
17
18  var sequenceNumber = 0;
19  scope.bindPlayerForCustomEffect = function(player) {
20    var target = player.source.target;
21    var effect = player.source.effect;
22    var timing = player.source.timing;
23    var last = undefined;
24    timing = shared.normalizeTimingInput(timing);
25    var callback = function() {
26      var t = callback._player ? callback._player.currentTime : null;
27      if (t !== null) {
28        t = shared.calculateTimeFraction(shared.calculateActiveDuration(timing), t, timing);
29        if (isNaN(t))
30          t = null;
31      }
32      // FIXME: There are actually more conditions under which the effect
33      // should be called.
34      if (t !== last)
35        effect(t, target, player.source);
36      last = t;
37    };
38
39    callback._player = player;
40    callback._registered = false;
41    callback._sequenceNumber = sequenceNumber++;
42    player._callback = callback;
43    register(callback);
44  };
45
46  var callbacks = [];
47  var ticking = false;
48  function register(callback) {
49    if (callback._registered)
50      return;
51    callback._registered = true;
52    callbacks.push(callback);
53    if (!ticking) {
54      ticking = true;
55      requestAnimationFrame(tick);
56    }
57  }
58
59  function tick(t) {
60    var updating = callbacks;
61    callbacks = [];
62    updating.sort(function(left, right) {
63      return left._sequenceNumber - right._sequenceNumber;
64    });
65    updating = updating.filter(function(callback) {
66      callback();
67      var playState = callback._player ? callback._player.playState : 'idle';
68      if (playState != 'running' && playState != 'pending')
69        callback._registered = false;
70      return callback._registered;
71    });
72    callbacks.push.apply(callbacks, updating);
73
74    if (callbacks.length) {
75      ticking = true;
76      requestAnimationFrame(tick);
77    } else {
78      ticking = false;
79    }
80  }
81
82  scope.Player.prototype._register = function() {
83    if (this._callback)
84      register(this._callback);
85  };
86
87})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);
88