var angular = require('angular');
require('../modules');
require('../services/CommonService');

var module = angular.module('commons.directives.imageview');
/**
 * 数组去重
 * @param  {Array} arr 需要去重的数组
 * @return {Array}     无重复元素的数组
 */
function unique(arr) {
  var ret = [],
    hash = {};

  for (var i = 0; i < arr.length; i++) {
    var item = arr[i];
    var key = typeof(item) + item;
    if (hash[key] !== 1) {
      ret.push(item);
      hash[key] = 1;
    }
  }

  return ret;
}

module.factory('ImageViewService', function(
  $ionicModal, $rootScope, CoreAppConfig, $ionicSlideBoxDelegate,
  $timeout) {
  var needImageSlideUpdate = true,
    openedModal = false;
  $rootScope.serverUrl = CoreAppConfig.serverUrl;
  $rootScope.imageViewSlideBoxShown = false;

  $ionicModal.fromTemplateUrl('views/commons/modal/imageview.modal.tpl.html', {
    scope: $rootScope,
    animation: 'slide-in-up'
  }).then(function(modal) {
    $rootScope.imageViewModal = modal;
    $rootScope.imageViewSlideBoxHandle = $ionicSlideBoxDelegate.$getByHandle('imageViewSlideBox');
  });

  $rootScope.openModal = function(activeIndex) {
    if (openedModal) {
      $rootScope.imageViewSlideBoxHandle.slide(activeIndex, -1);
    }

    $rootScope.imageViewModal.show().then(function() {
      openedModal = true;
      if (needImageSlideUpdate) {
        $rootScope.imageViewSlideBoxHandle.update();
        $rootScope.imageViewSlideBoxHandle.slide(activeIndex, -1);
        needImageSlideUpdate = false;
      }
      $timeout(function() {
        $rootScope.imageViewSlideBoxShown = true;
      }, 25);

    });
  };

  $rootScope.$watch('imageSrcs', function() {
    needImageSlideUpdate = true;
    $rootScope.imageViewSlideBoxShown = false;
  }, true);

  $rootScope.closeModal = function() {
    $rootScope.imageViewModal.hide();
  };

  $rootScope.$on('modal.hidden', function() {
    $rootScope.imageSrcs = [];
  });

  $rootScope.$on('$destroy', function() {
    $rootScope.imageViewModal.remove();
  });

  $rootScope.getImageWidth = function() {
    return window.screen.width + 'px';
  };

  return {
    openModal: $rootScope.openModal,
    closeModal: $rootScope.closeModal
  };
});

module.directive('imageView', function($rootScope, $timeout, $q,
  ImageViewService, CoreAppConfig, ImageFileService) {
  return {
    replace: true,
    restrict: 'CAE',
    link: function(scope, element, attrs) {
      function getImageId() {
        return attrs.imageId ? attrs.imageId :
          element.attr('ng-src') ? element.attr('ng-src').match(serverRegx)[1] :
          element.attr('src') ? element.attr('src').match(serverRegx)[1] : '';
      }

      var localRegx = /\/([a-z0-9-]+)\.jpg$/i,
        serverRegx = /\/image\/(\S*)\_/i;
      scope.imageId = getImageId();
      scope.size = attrs.size || '150x150';
      /**
       * 点击图片，打开查看大图弹层，并显示该图片的大图。
       */
      element.bind('click', function() {
        $timeout(function() {
          $rootScope.imageSrcs = scope.filterViewImagesFromBody();
          var current = scope.getSrcFromImageElement(element);
          var index = $rootScope.imageSrcs.indexOf(current);
          ImageViewService.openModal(index);
        });
      });

      /**
       * 从当前document.body中获取可点击查看的图片（具有image-view样式），
       * 并将这些图片的src提取出来放到imageSrcs中，方便slide-box组件渲染多张图片。
       */
      scope.filterViewImagesFromBody = function() {
        var viewImages = document.querySelectorAll('img.image-view');
        var imageSrcs = _.map(viewImages, function(image) {
          return scope.getSrcFromImageElement(image);
        });
        return unique(imageSrcs);
      };
      /**
       * 从当前的dom中获取到图片的src元素的值
       * @param  {Object} imageElement 图片的dom
       * @return {String}              图片的链接地址
       */
      scope.getSrcFromImageElement = function(imageElement) {
        var imageURL = angular.element(imageElement).attr('src'),
          imageId,
          size = '500x1000';

        if (isCacheUrl(imageURL)) {
          imageId = imageURL.match(localRegx)[1];
          if (isCacheId(imageId)) {
            return imageURL;
          } else {
            return generateServerSrc(imageId, size);
          }
        } else if (isServerUrl(imageURL)) {
          imageId = imageURL.match(serverRegx)[1];
          return generateServerSrc(imageId, size);
        }
      };
      /**
       * 生成服务器的图片地址。
       * @param  {String} imageId 图片id
       * @param  {String} size    图片
       * @return {String}
       */
      function generateServerSrc(imageId, size) {
        return CoreAppConfig.serverUrl + '/image/' + imageId + '_' + size;
      }
      /**
       * 判断该地址是否为本地缓存地址
       * @param  {String}  url
       * @return {Boolean}
       */
      function isCacheUrl(url) {
        return localRegx.test(url);
      }
      /**
       * 判断地址是否为服务器图片地址
       * @param  {String}  url
       * @return {Boolean}
       */
      function isServerUrl(url) {
        return serverRegx.test(url);
      }
      /**
       * 判断图片id是否为缓存图片的id。
       * 如82A48572-26BA-4850-9B79-B0973619DDBA
       * @param  {String}  id
       * @return {Boolean}    是返回true，否则false
       */
      function isCacheId(id) {
        return /-+/.test(id);
      }

      /**
       * 下载图片，如果本地有，则返回本地图片；如果没有，则从服务器下载。
       * @param  {String} id   图片id
       * @param  {String} size 图片大小
       * @return {Promise}
       */
      function download(id, size) {
        var deferred = $q.defer();
        ImageFileService.getImage(id).then(function(fileEntry) {
          deferred.resolve(fileEntry);
        }, function() {
          ImageFileService.download(id, size).then(function(fileEntry) {
            deferred.resolve(fileEntry);
          }, function() {
            deferred.reject();
          });
        });

        return deferred.promise;
      }
      /**
       * 下载图片并修改组件的src。
       * 如果下载成功（无论本地找到还是从服务器下载到本地），修改其地址；
       * 如果没有下载成功，且该图片不是缓存图片，将其地址修改为服务器图片地址。
       *
       * @param  {FileEntry} fileEntry
       */
      download(scope.imageId, scope.size).then(function(fileEntry) {
        var localSrc = fileEntry.toURL();
        element.attr('src', localSrc);
      }, function() {
        if (!isCacheId(scope.imageId)) {
          element.attr('src', generateServerSrc(scope.imageId, scope.size));
        }
      });
    }
  };
});

module.directive('imageLoading', function() {
  return {
    link: function(scope, element) {
      scope.loading = true;

      element.bind('load', function() {
        scope.$evalAsync(function() {
          scope.loading = false;
        });
      });
    }
  };
});
