export function isFunction(p: any) {
  return typeof p === 'function'
}

/**
 * 递归清除显示对象里面所有的Tween
 * @param obj
 * @param isRecursive 默认true,递归移除子级
 */
export function removeTweens(obj: any, isRecursive: boolean = true) {
  if (!obj) return
  FYGE.Tween.removeTweens(obj);
  if (!isRecursive || !obj.children || !obj.children.length) return
  obj.children.forEach((child: any) => {
      removeTweens(child)
  });
}

const inBrowser = !!document // 简单 的 判断 是否在浏览器中

// nextTick 简单原理
// 借助 MutationObserver 来进行处理 下一事件循环
// Mo 会在所有 同步代码执行之后 才会执行回调
const hasMutationObserverBug = false // 这里就简单这样处理吧
export const nextTick = (function () {
  var callbacks: Function[] = []
  var pending = false
  var timerFunc: Function
  function nextTickHandler () {
    pending = false
    // 之所以要slice复制一份出来是因为有的cb执行过程中又会往callbacks中加入内容
    // 比如$nextTick的回调函数里又有$nextTick
    // 这些是应该放入到下一个轮次的nextTick去执行的,
    // 所以拷贝一份当前的,遍历执行完当前的即可,避免无休止的执行下去
    var copies = callbacks.slice(0)
    callbacks = []
    // console.log(copies)
    // for (var i = 0; i < copies.length; i++) {
    //   copies[i]()
    // }
    // 这里专门处理了一下
    for (var i = copies.length - 1; i >= 0; i--) {
      copies[i]()
    }
  }

  if (typeof Promise !== 'undefined') {
    timerFunc = function() {
      Promise.resolve().then(() => {
        nextTickHandler()
      })
    }
  } else if (typeof MutationObserver !== 'undefined' && !hasMutationObserverBug) {
    /* istanbul ignore if */
    // ios9.3以上的WebView的MutationObserver有bug，
    //所以在hasMutationObserverBug中存放了是否是这种情况
    var counter = 1
    // 创建一个MutationObserver,observer监听到dom改动之后后执行回调nextTickHandler
    var observer = new MutationObserver(nextTickHandler)
    var textNode = document.createTextNode(counter + '')
    // 调用MutationObserver的接口,观测文本节点的字符内容
    observer.observe(textNode, {
      characterData: true
    })
    // 每次执行timerFunc都会让文本节点的内容在0/1之间切换,
    // 不用true/false可能是有的浏览器对于文本节点设置内容为true/false有bug？
    // 切换之后将新值赋值到那个我们MutationObserver观测的文本节点上去
    timerFunc = function () {
      counter = (counter + 1) % 2
      textNode.data = counter + ''
    }
  } else {
	  // webpack默认会在代码中插入setImmediate的垫片
    // 没有MutationObserver就优先用setImmediate，不行再用setTimeout
    const context = inBrowser
      ? window
      : typeof global !== 'undefined' ? global : {
        setImmediate
      }
    timerFunc = context.setImmediate || setTimeout
  }
  return function (cb: Function, ctx?: any) {
    var func = ctx
      ? function () { cb.call(ctx) }
      : cb
    callbacks.push(func)
    // 如果pending为true, 就其实表明本轮事件循环中已经执行过timerFunc(nextTickHandler, 0)
    if (pending) return
    pending = true
    timerFunc(nextTickHandler, 0)
  }
})()