/*! Tip
 */
require('./Tip.css')

const z = window.Zving = window.Zving || {}
const Tip = window.Tip = z.Tip = z.Tip || function (targetEl, options) {
  var msg, autoClose, clock, theme
  if (typeof options === 'object') {
    clock = options.clock
    autoClose = options.autoClose
    theme = options.theme // 为空或‘notice’
    msg = options.msg
  } else {
    msg = options
  }
  this.message = msg
  this.autoClose = autoClose || false
  this.clock = clock || 9
  this.theme = theme || '' // info
  this.targetEl = getDom(targetEl)
  this.$targetEl = $(this.targetEl)
  this.id = this.ctype + '_' + this.getDomId(this.targetEl)

  this.targetEl._components = this.targetEl._components || {}
  this.targetEl._components[this.ctype] = this.id

  this.$targetEl.data('Tip', this)
  this.initHtml()
}
const getDom = function (el) {
  if (!el) {
    return el
  }
  if (typeof el === 'string') {
    return document.getElementById(el.replace(/^#/, ''))
  }
  if (!el.nodeName && el.length && el[0] && el[0].nodeName) { // 如果是一个jquery对象
    return el[0]
  }
  return el
}
const isVisible = function (elem) {
  elem = getDom(elem)
  if (
    !elem.parentNode ||
    (elem.tagName !== 'BODY' &&
      elem.parentNode.tagName !== 'BODY' &&
      !elem.offsetParent)
  ) {
    return false // 不在节点内，或为隐藏元素
  }
  var curStyle = elem.currentStyle
  if (!curStyle && window.getComputedStyle) {
    curStyle = window.getComputedStyle(elem, null)
    if (!curStyle) {
      return false
    }
  }
  if (curStyle.display === 'none') {
    return false
  } else if (
    elem.offsetWidth === 0 && elem.offsetHeight === 0 && elem.tagName !== 'TR'
  ) {
    return false
  }
  return true
}
Tip.idSeed = {
  _seed: 0
}
Tip.AutoCloseTips = []
Tip.prototype = {
  ctype: 'Tip',
  getDomId: function (elem) {
    var idSeed = Tip.idSeed
    if (!elem) {
      return 'id' + (++idSeed._seed)
    }
    if (typeof elem === 'string') {
      return 'elem' + (++idSeed._seed)
    }
    if (elem.id) {
      return elem.id
    }
    if (elem.nodeName) {
      if (idSeed[elem.nodeName] === undefined) {
        idSeed[elem.nodeName] = 0
      }
      if (!elem.getAttribute('_id')) {
        elem._id = elem.nodeName.toLowerCase() + (++idSeed[elem.nodeName])
        elem.setAttribute('_id', elem._id)
        return elem._id
      } else {
        return elem.getAttribute('_id')
      }
    }
    window.console && console.error(location.pathname + ' ## node.js -- id ::  参数错误，试图获取非DOM元素的id ' + elem)
  },
  initHtml: function () {
    var arr = []
    arr.push('<div class="bodycontent">' + this.message + '</div>')
    arr.push('<div class="tooltipfang"><span class="fang fangbg">◆</span><span class="fang fangfg">◆</span></div>')
    this.html = arr.join('')
  },
  setMessage: function (msg) {
    this.message = msg
    this.initHtml()
    if (this.el) {
      $('.bodycontent', this.el).html(msg)
    }
  },
  show: function (msg) {
    var me = this
    var ct
    if (msg) {
      me.setMessage(msg)
    }
    if (!this.el || !this.el.parentNode) {
      var div = document.createElement('div')
      div.id = 'comp_tip' + (++Tip.idSeed._seed)
      div.style.position = 'absolute'
      div.style.left = '0px'
      div.style.top = '0px'
      /* 2012-08-31 查找级别较高的溢出隐藏并且相对定位的元素作为提示的父元素，以更在滚动父元素时提示可以跟随滚动 */
      var relativeParentNodes = [document.body]

      ct = this.targetEl.parentNode
      while (ct && ct.tagName) {
        if (ct.tagName === 'DIV' && $(ct).css('position') !== 'static' && (ct.className.indexOf('ui-page') !== -1 || $(ct).css('overflowY') === 'auto' || $(ct).css('overflow') === 'auto')) {
          relativeParentNodes.push(ct)
          if (ct.className.indexOf('ui-page') !== -1) {
            break
          }
        }
        if (ct.tagName === 'BODY') {
          break
        }
        ct = ct.parentNode
      }
      ct = relativeParentNodes[relativeParentNodes.length - 1]
      ct.appendChild(div)
      div.className = 'z-tooltip' + (this.theme ? ' tip_' + this.theme : '') + ' tooltip-callout' + this.clock
      div.innerHTML = this.html
      this.el = div
    } else {
      ct = this.el.parentNode
    }
    var ctPos = $(ct).offset()
    var targetXY = this.$targetEl.offset()
    targetXY.left = targetXY.left - ctPos.left + (ct.tagName === 'BODY' ? 0 : ct.scrollLeft)
    targetXY.top = targetXY.top - ctPos.top + (ct.tagName === 'BODY' ? 0 : ct.scrollTop)
    var targetWH = {
      width: $(this.targetEl).width(),
      height: $(this.targetEl).height()
    }
    if (this.targetEl.getAttribute('ztype') && /date|time/i.test(this.targetEl.getAttribute('ztype')) && this.targetEl.nextSibling && this.targetEl.nextSibling.nodeName.match(/^(img|i|span)$/i)) { // 后边还有图标
      targetWH.width += $(this.targetEl.nextSibling).width()
    }
    $(this.el).show()
    var size = {
      width: $(this.el).width(),
      height: $(this.el).height()
    }
    var pageWidth = $(window).width()
    if (pageWidth - targetXY.left - targetWH.width < 100) {
      this.clock = 3
      if (targetXY.left < 60) {
        this.clock = 5
      }
    }
    var c = this.clock
    var x, y
    if (c === 2 || c === 3 || c === 4) {
      x = targetXY.left - size.width
    }
    if (c === 8 || c === 9 || c === 10) {
      x = targetXY.left + targetWH.width
    }
    if (c === 6 || c === 7 || c === 11 || c === 12) {
      x = targetXY.left
    }
    if (c === 11 || c === 12 || c === 1) {
      y = targetXY.top + targetWH.height
    }
    if (c === 5 || c === 6 || c === 7) {
      y = targetXY.top - size.height
    }
    if (c === 5 || c === 1) {
      x = targetXY.left + targetWH.width - size.width
    }
    if (c === 9 || c === 3) {
      y = targetXY.top + targetWH.height / 2 - size.height / 2
    }

    this.el.className = 'z-tooltip' + (this.theme ? ' tip_' + this.theme : '') + ' tooltip-callout' + this.clock
    this.el.style.left = Math.round(x) + 'px'
    this.el.style.top = Math.round(y) + 'px'
    this.el.style.zIndex = 100000

    if (this.autoClose) {
      Tip.AutoCloseTips.push(this)
    }
  },

  hide: function () {
    if (this.el) {
      $(this.el).hide()
    }
  },
  close: function () {
    if (this.el) {
      this.el.outerHTML = ''
      this.el = null
    }
  },
  destroy: function () {
    $.cleanData(this.$targetEl)
    this.targetEl.onmouseout = this.targetEl.onmouseover = this.targetEl.onclick = null
  }

}

Tip.show = function (ele, options) {
  ele = getDom(ele)
  if (!ele) {
    return
  }
  var autoClose, clock
  if (typeof options === 'string') {
    options = {
      msg: options
    }
  }
  var $ele = $(ele)
  if (!isVisible(ele)) {
    window.console && console.log((ele.id ? 'id为' + ele.id : '') + (ele.name ? ' name为' + ele.name : '') + '的页面元素处于隐藏状态，Tip无法显示')
    return
  }
  var tip
  if ($ele.data('Tip')) {
    tip = $ele.data('Tip')
  } else {
    tip = new Tip(ele, options)
  }
  tip.autoClose = autoClose
  if (clock) {
    tip.clock = clock
  }
  tip.show()
  if (tip.el.style.left === '0px') {
    setTimeout(function () {
      tip.close()
      tip.show()
    }, 200) // 如果没有得到正确的控件位置延迟100毫秒再试一次。
  }
  if (!tip.autoClose) {
    if (!ele._Tips) {
      ele._Tips = []
    }
    ele._Tips.push(tip)
  }
  return tip
}

Tip.getTipCount = function (ele) {
  ele = getDom(ele)
  if (!ele._Tips) {
    return 0
  }
  return ele._Tips.length
}

Tip.close = function (ele) { // 将与ele有关的Tip都关闭掉
  ele = getDom(ele)
  if (ele._Tips) {
    for (var i = 0; i < ele._Tips.length; i++) {
      if (ele._Tips[i]) {
        ele._Tips[i].close()
      }
    }
    ele._Tips = []
  }
}
Tip.closeAll = function () {
  var arr = Tip.AutoCloseTips
  for (var i = arr.length; i > 0; i--) {
    arr[i - 1].close()
    arr.splice(i - 1, 1)
  }
}
$(document).on('mousedown.tip', Tip.closeAll)

$(window).on('unload', function () {
  // console.log('tip.js#190 window unload'+(+new Date()));
  $(document).off('mousedown.tip')
})

module.exports = Tip
