/** 信息发布标签页布局 */
'use strict';

var angular = require('angular'),
  _ = require('jsUtil');
require('../modules');
require('./sinoswipe');

angular
  .module('infoDisplay.directives')
  .directive('sinoTabs', sinoTabs)
  .controller('SinoTabsController', SinoTabsController);
  
/** @ngInject */
function sinoTabs(sinoSwipe) {
  
  return {
    restrict: 'E',
    require: '^sinoInfoListPage',
    template: function(element, attr) {
      return '' +
        '<div>' +
          '<sino-tabs-navigation-bar items="tabsController.tabs">' +
          '</sino-tabs-navigation-bar>' +
          '<div class="swipe">' +
            '<div ng-transclude class="swipe-wrap">' +
            '</div>' +
          '</div>' +
        '</div>';
    },
    transclude: true,
    controller: 'SinoTabsController',
    controllerAs: 'tabsController',
    link: link
  };
  
  function link(scope, element, attrs, ctrl) {
    init();

    function init() {
      scope.tabsController.swipe = sinoSwipe.getInstance();
      
      scope.tabsController.swipe.slide(scope.selectedIndex);
      scope.tabsController.refreshDomCache();
    }
  }
}

/** @ngInject */
function SinoTabsController($scope, $element, $window, $ionicScrollDelegate) {
  var self = this,
    element = $element[0];
  
  self.scope = $scope;
  self.tabs = [];
  self.tabMap = {};
  self.cacheIndexs = []; // 缓存Tab
  self.swipe;
  self.selectedIndex;
  
  self.addTab = addTab;
  self.refreshDomCache = refreshDomCache;
  self.getSwipe = getSwipe;
  
  $scope.$on('infoModelChange', function(event, selectedItemId, selectedItems) {
    self.selectedIndex = $scope.getSelectedIndex(selectedItemId);
    if (!_.isEmpty(self.tabs)) {
      self.tabs = _.map(selectedItems, function(selectedItem) {
        return self.tabMap[selectedItem.name];
      });
    }
    self.swipe.setup();
    self.swipe.slide(self.selectedIndex);
    self.refreshDomCache(selectedItemId);
  });
  
  $window.addEventListener('transitionend', onTransitionend);
  
  $scope.$on('$destroy', function() {
    if (self.swipe) {
      self.swipe.kill();
      self.swipe = null;
    }
    $window.removeEventListener('transitionend', onTransitionend);
  });
  
  function onTransitionend(event) {
    var target = event.target;
    if ((isSinoTab(target) || hasClass(target, 'pane')) && hasParent(target, element)) {
      var position = self.swipe.getPos();
      if (self.selectedIndex !== position) {
        var selectedItemId = $scope.selectedItems[position].id;
        $scope.$broadcast('infoModelChange', selectedItemId, $scope.selectedItems);
        $scope.$apply(function() {
          self.refreshDomCache(selectedItemId);
        });
      }
    }
  }
  
  function isSinoTab(element) {
    return element && element.tagName.toLowerCase() === 'sino-tab';
  }
  
  function hasClass(element, className) {
    var elementClassName = element? element.className || '' : '';
    return elementClassName.indexOf(className) >= 0;
  }
  
  function hasParent(element, parent) {
    var _parent = element;
    while (_parent != parent) {
      _parent = _parent.parentElement;
      if (_parent === document.body) {
        return false;
      }
    }
    
    return true;
  }
  
  function refreshDomCache(selectedItemId) {
    var selectedIndex = $scope.getSelectedIndex(selectedItemId);
    if (self.tabs && self.tabs[selectedIndex]) {
      self.tabs[selectedIndex].scope.cache = true;
    }
    var alreadyCache = self.cacheIndexs.slice(-1)[0] === selectedIndex;
    if (!alreadyCache) {
      var cacheTab = self.tabs[selectedIndex];
      if (cacheTab) {
        self.cacheIndexs.push(selectedIndex);
      }
      self.cacheIndexs = self.cacheIndexs.slice(-2);
      _.each(self.tabs, function(tab, key) {
        if (self.cacheIndexs.indexOf(key) !== -1) {
          tab.scope.cache = true;
        } else {
          tab.scope.cache = false;
        }
      });
    }
  }

  function addTab(tab) {
    self.tabs.push(tab);
    self.tabMap[tab.name] = tab;
    self.refreshDomCache($scope.selectedItemId);
    self.swipe.setup();
  }
  
  function getSwipe() {
    return self.swipe;
  }
}