1 /*
  2  *  Copyright © 2009 Apple Inc. All rights reserved.
  3  */
  4 
  5 /* ==================== TKTransaction ==================== */
  6 
  7 /**
  8  *  @class
  9  *
 10  *  <p>A transaction allows to run a variety of transitions in sync, no matter in what function or JavaScript run loop
 11  *  the transition itself was applied. Transactions can be nested, and a transaction is only truly commited when there
 12  *  are no other open transactions. In other words, there must be as many calls to {@link TKTransaction.begin} as there
 13  *  are calls to {@link TKTransaction.commit} before any transition in one of those transactions can be applied.
 14  *
 15  *  @since TuneKit 1.0
 16  */
 17 var TKTransaction = {
 18   transitions : [],
 19   openTransactions : 0,
 20   /**
 21    *  The set of default properties that will be applied to any {@link TKTransition} until the next call to {@link TKTransaction.commit}.
 22    *  Any of the properties that can be applied to a {@link TKTransition} can be applied to this object.
 23    *  @type Object
 24    */
 25   defaults : {},
 26   defaultsStates : []
 27 };
 28 
 29 /**
 30  *  Begins a new transaction and makes it the current transaction.
 31  */
 32 TKTransaction.begin = function () {
 33   // reset the group if we're starting fresh
 34   if (this.openTransactions == 0) {
 35     this.transitions = [];
 36     this.defaults = {};
 37   }
 38   // otherwise, archive the current state of defaults
 39   else {
 40     this.defaultsStates.push(this.defaults);
 41     // XXX: should we restore defaults here as well?
 42   }
 43   // increase the number of open transactions
 44   this.openTransactions++;
 45 };
 46 
 47 /**
 48  *  Add Transition
 49  *
 50  *  @private
 51  */
 52 TKTransaction.addTransition = function (transition) {
 53   // first, apply the transaction defaults to the transitions
 54   for (var i in this.defaults) {
 55     if (transition[i] === null) {
 56       transition[i] = this.defaults[i];
 57     }
 58   }
 59   // and add the transition to our array
 60   this.transitions.push(transition);
 61 };
 62 
 63 /**
 64  *  Closes the current transaction.
 65  */
 66 TKTransaction.commit = function () {
 67   // do nothing if we have no open transactions
 68   if (this.openTransactions == 0) {
 69     return;
 70   }
 71   // decrease the number of open transactions
 72   this.openTransactions--;
 73   // if we still have open transactions, just
 74   // restore the previous defaults state
 75   if (this.openTransactions != 0) {
 76     this.defaults = this.defaultsStates.pop();
 77     return;
 78   }
 79   // otherwise, it's time to shake and bake, we'll apply the
 80   // "from" states directly and the "to" states immediately
 81   // after in a new run loop so that the "from" styles have
 82   // been resolved first
 83   var transitions = this.transitions;
 84   for (var i = 0; i < transitions.length; i++) {
 85     transitions[i].applyFromState();
 86   }
 87   setTimeout(function () {
 88     for (var i = 0; i < transitions.length; i++) {
 89       transitions[i].applyToState();
 90     }
 91   }, 0);
 92 };
 93 
 94 TKUtils.setupDisplayNames(TKTransaction, 'TKTransaction');
 95