text: /*
  * Tooltip component v0.1.2 for easy.js
  *
  * Copyright (c) 2013 Yiguo Chan
  * Released under the MIT Licenses
  *
  * Mail : chenmnkken@gmail.com
  * Date : 2013-12-14
  */
  define(function(){
  
  'use strict';
  
  var defaults = {
      content     :   null,         // String   工具提示的内容
      duration    :   200,          // Number   动画运行时间
      easing      :   'swing',      // String   缓动函数的名称    
      effects     :   null,         // String   动画效果的名称
      maxWidth    :   200,          // Number   工具提示的最大显示宽度
      position    :   'top',        // String   工具提示显示的方位
      trigger     :   'mouseenter', // String   触发工具提示的事件类型
      zIndex      :   9900,         // Number   工具提示的层级    
      unClose     :   false,        // Boolean  由mouseenter、focus触发的工具提示是否自动关闭
      space       :   12            // Number   工具提示离触发元素的间距
  };
  
  var isIE6 = E.browser.ie && E.browser.version === '6.0',
      $win = E( window ),
      isVisible = false,
      tipCache = {},
      zIndex;
  
  var easyTooltip = {
      
      init : function( o ){
          var trigger = o.trigger,
              unClose = o.unClose,
              target = o.target,   
              isHover = trigger === 'mouseenter',
              timer;
              
          if( isHover ){
              target.on( 'mouseenter.tooltip', function(){
                  var self = this;                    
                  clearTimeout( timer );     
                  
                  timer = setTimeout(function(){
                      easyTooltip.open( o, self );
                  }, 50 );
              });          
  
              if( !unClose ){
                  target.on( 'mouseleave.tooltip', function(){
                      clearTimeout( timer );
                      timer = null;
                      easyTooltip.close( o );
                  });
              }
          }
          else{
              target.on( trigger + '.tooltip', function(){
                  easyTooltip.open( o, this );
              });        
  
              if( trigger === 'focus' && !unClose ){
                  target.on( 'blur.tooltip', function(){
                      easyTooltip.close( o );
                  });            
              }
          }
      },
      
      open : function( o, target ){
          var elem = E( target ),
              trigger = o.trigger,
              euid = target[ E.euid ],                
              tipElem, btnClose, content;
              
          if( tipCache[euid] !== undefined ){
              if( trigger === 'click' ){
                  easyTooltip.close( o );
              }
          
              return;            
          }
          
          tipCache[ euid ] = true;
          content = o.content || elem.attr( 'data-title' );
              
          if( content === null ){
              content = elem.attr( 'title' );
              
              if( content === null ){
                  return;
              }
              
              elem.removeAttr( 'title' ).attr( 'data-title', content );
          }
  
          o.width = elem.outerWidth();
          o.height = elem.outerHeight(); 
  
          tipElem = easyTooltip.createTip( isVisible );
          tipElem.appendTo( o.context.body );
          tipElem.data( 'targetIndex', euid );
          tipElem.find( 's.tt_arrow' )[0].className = 'tt_arrow tt_arrow_' + o.position;
          tipElem.find( 'div.tt_content' ).html( content );
          o.btnClose = tipElem.find( 'a.tt_btn_close' );
          o.tipElem = tipElem;
          o.currentTarget = elem;
  
          isVisible = true;
          easyTooltip.initStyle( o, target );
          elem.fire( 'likeopen' );
          easyTooltip.patterns[ o.effects ].show( o );
  
          if( (trigger !== 'mouseenter' && trigger !== 'focus') || o.unClose ){
              $win.on( 'resize.tooltip', function(){
                  easyTooltip.setPosition( o, true );
              });
          }
      },
      
      createTip : (function(){
          var tipElem;
          
          return function( reCreate ){        
              if( tipElem && tipElem.is(':animated') ){
                  tipElem.stop( true, true );
                  reCreate = false;
              }
              
              tipElem = tipElem && !reCreate ? tipElem :
                  E( '<div class="eui_tooltip" style="z-index:' + ( zIndex++ ) + '">' +
                      '<div class="tt_wrapper">' + 
                          '<s class="tt_arrow"></s>' + 
                          '<a href="#" class="tt_btn_close">&times;</a>' + 
                          '<div class="tt_content"></div>' +
                      '</div>' +
                  '</div>' );
                
              return tipElem;
          };
      })(),
      
      setPosition : function( o, isResize ){
          var cssMap = {},
              space = o.space,
              tipElem = o.tipElem,
              wrapElem = o.wrapElem,
              position = o.position,
              targetWidth = o.width,
              targetHeight = o.height,
              offset = o.currentTarget.offset(),
              offsetTop = offset.top,            
              offsetLeft = offset.left,            
              isTop = position === 'top',
              isLeft = position === 'left',  
              wrapWidth = wrapElem.outerWidth(),
              wrapHeight = wrapElem.outerHeight();
  
          if( isTop || position === 'bottom' ){
              cssMap.left = offsetLeft - wrapWidth / 2 + targetWidth / 2 + 'px';
              
              if( isTop ){
                  cssMap.top = offsetTop - wrapHeight - space + 'px';
              }
              else{
                  cssMap.top = offsetTop + targetHeight + space + 'px';
              }
          }
          else if( isLeft || position === 'right' ){
              cssMap.top = offsetTop - wrapHeight / 2 + targetHeight / 2 + 'px';
              
              if( isLeft ){
                  cssMap.left = offsetLeft - wrapWidth - space + 'px';
              }
              else{
                  cssMap.left = offsetLeft + targetWidth + space + 'px';  
              }
          }
          
          if( !isResize ){
              cssMap.visibility = '';
              cssMap.display = 'none';   
          }
  
          tipElem.css( cssMap );                
      },
      
      initStyle : function( o ){
          var tipElem = o.tipElem,
              trigger = o.trigger,
              btnClose = o.btnClose,
              wrapElem = tipElem.find( 'div.tt_wrapper' ),
              wrapWidth;
              
          if( (trigger !== 'mouseenter' && trigger !== 'focus') || o.unClose ){
              wrapElem.css( 'paddingRight', '25px' );
              btnClose.css( 'display', 'block' )
                  .on( 'click.tooltip', function( e ){
                      easyTooltip.close( o );
                      e.preventDefault();
                  });
          }
          else{
              wrapElem.css( 'paddingRight', '10px' );
              btnClose.css( 'display', 'none' ).un( 'click.tooltip' );
          }
                  
          // 设置tip有布局但不显示
          tipElem.css({
              visibility : 'hidden',
              display : 'block'
          });
  
          // 设置其为inline-block布局，这样可以取得其合适的宽度
          wrapElem.css({
              width : '', 
              display : 'inline-block'
          });
          
          // 修复ie6 inline-block 的bug
          if( isIE6 ){
              wrapElem[0].style.display = 'inline';
              wrapElem[0].style.zoom = 1;
          }
  
          wrapWidth = wrapElem.width();        
          wrapWidth = Math.min( o.maxWidth, wrapWidth );  
  
          // 设置合适的宽度
          wrapElem.css( 'width', wrapWidth + 'px' );   
          
          o.wrapElem = wrapElem;
          easyTooltip.setPosition( o );  
      },
      
      close : function( o ){
          var trigger = o.trigger,
              tipElem = o.tipElem,
              euid;
              
          if( !tipElem ){
              return; 
          }
          
          if( tipElem.is(':animated') ){
              tipElem.stop( true, true );
          } 
          
          isVisible = false;
          euid = tipElem.data( 'targetIndex' );
          delete tipCache[ euid ];
          
          if( o.currentTarget ){
              o.currentTarget.fire( 'likeclose' );
              delete o.currentTarget;
          }
          
          easyTooltip.patterns[ o.effects ].hide( o );        
          
          if( (trigger !== 'mouseenter' && trigger !== 'focus') || o.unClose ){
              $win.un( 'resize.tooltip' );
          }
      }
      
  };
  
  easyTooltip.patterns = {
      
      normal : {
          show : function( o ){
              o.tipElem.css( 'display', 'block' );
          },
          
          hide : function( o ){
              o.tipElem.css( 'display', 'none' ).remove();
              delete o.tipElem;
              isVisible = false;
          }
      },
      
      fade : {
          show : function( o ){
              o.tipElem.fadeIn( o.duration, o.easing );
          },
          
          hide : function( o ){
              o.tipElem.fadeOut( o.duration, o.easing, function(){
                  o.tipElem.remove();
                  delete o.tipElem;
                  isVisible = false;
              });            
          }
      },
  
      slide : {}
      
  };
  
  [ 'show', 'hide' ].forEach(function( item ){
  
      easyTooltip.patterns.slide[ item ] = function( o ){
          if( !o.tipElem ){
              return;
          }    
      
          var tipElem = o.tipElem,
              top = tipElem.css( 'top' ),
              left = tipElem.css( 'left' ),            
              isHide = item === 'hide',
              FROM = 'from',
              TO = 'to',
              animMap = {};
              
          if( isHide ){
              FROM = 'to';
              TO = 'form';
              animMap.complete = function(){
                  tipElem.css({
                          display : 'none',
                          opacity : ''
                      })                    
                      .remove();
                      
                  delete o.tipElem;
                  isVisible = false;
              };
          }
          
          animMap[ FROM ] = {
              opacity : '0'
          };
          
          animMap[ TO ] = { 
              opacity : '1'
          };
          
          switch( o.position ){            
              case 'top' : 
                  animMap[ FROM ].top = parseInt(top) - 30 + 'px';
                  animMap[ TO ].top = top;
              break;
              
              case 'bottom' : 
                  animMap[ FROM ].top = parseInt(top) + 30 + 'px';
                  animMap[ TO ].top = top;
              break;     
  
              case 'left' : 
                  animMap[ FROM ].left = parseInt(left) - 30 + 'px';
                  animMap[ TO ].left = left;
              break;     
  
              case 'right' : 
                  animMap[ FROM ].left = parseInt(left) + 30 + 'px';
                  animMap[ TO ].left = left;
              break;                    
          }
          
          animMap.easing = o.easing;
          animMap.duration = o.duration;       
          tipElem.css( 'display', 'block' ).anim( animMap );        
      };
  
  });
  
  var Tooltip = function( target, options ){
      target = E( target );
      options = options || {};
      
      if( !target.length ){
          return;
      }    
      
      var o = E.merge( defaults, options );
      o.effects = o.effects || 'normal';    
      
      if( isIE6 ){
          o.space -= 6;
      }
      
      zIndex = o.zIndex;
      o.target = target;   
      o.context = target[0].ownerDocument;
      easyTooltip.init( o );
      
      this.__o__ = o;
  };
  
  Tooltip.prototype = {
  
      destroy : function(){
          if( !this.__o__ ){
              return;
          }
          
          var o = this.__o__,
              trigger = o.trigger,
              target = o.target,
              title;
                  
          trigger = trigger === 'mouseenter' ?
              'mouseenter.tooltip mouseleave.tooltip' :
              trigger === 'focus' ?
              'focus.tooltip blur.tooltip' :
              trigger + '.tooltip';
              
          trigger += ' likeopen likeclose';        
  
          target.un( trigger )
              .forEach(function(){
                  // 还原其title值
                  var elem = E( this ),
                      title  = elem.attr( 'data-title' );
                      
                  elem.attr( 'title', title )
                      .removeAttr( 'data-title' );            
              });
          
          this.__o__ = target = o = null;
          delete this.__o__;
      },
      
      on : function( type, fn ){
          if( this.__o__ ){
              var self = this;
              self.__o__.target.on( 'like' + type, function( e ){
                  e.type = type;
                  fn.call( self, e );
                  e.stopPropagation();
              });
          }
          
          return this;
      },
      
      un : function( type ){
          if( this.__o__ ){        
              this.__o__.target.un( 'like' + type );
          }
          
          return this;
      }
      
  };
  
  E.ui.Tooltip = Tooltip;
  
  });