var angular = require('angular');
require('../modules');
require('../services/fileService');
require('../services/localforage');
require('./$toast');
require('../services/AudioPlayerService');

var module = angular.module('commons.directives.audioplayer');

module.run(function($rootScope, AudioPlayerService) {
  /**
   * 当程序由前端运行转为后端运行时，停止语音播放。
   */
  $rootScope.$on('pause', function() {
    AudioPlayerService.stopPlayingAudio();
  });

  $rootScope.$on('audio.release', function() {
    AudioPlayerService.stopPlayingAudio();
  });
});

module.directive('playFlag', function() {
  return {
    restrict: 'AE',
    replace: true,
    template: '<div class="play-flag">' +
      '<span class="play-flag-dot"></span>' +
      '</div>'
  };
});

module.directive('audioPlayer', function($q, $timeout, $rootScope,
  AudioFileService, AudioPlayerService, $toast) {
  return {
    restrict: 'A',
    replace: true,
    template: '<div ng-class="{unplay: !audioPlayed}">' +
      '<span ng-if="isSelf" style="padding-right: 5px;">' +
      '<waiting-pointer ng-show="audioLoading" ng-class="{animating: audioLoading}"></waiting-pointer>' +
      '<span class="duration">{{duration}}</span>' +
      '</span>' +
      '<div class="discussion">' +
      '<div class="audio-player" ng-class="{playing: audioPlaying}">' +
      '<sino-speaker-view animate="laba.animate" width="12" height="15" spead="311" direction="{{laba.direction}}" stop-event ng-click="playAudio()"></sino-laba>' +
      '</div>' +
      '</div>' +
      '<span ng-if="!isSelf" style="padding-left: 5px;">' +
      '<span class="duration">{{duration}}</span>' +
      '<play-flag ng-show="!audioPlayed"></play-flag>' +
      '<waiting-pointer ng-show="audioLoading" ng-class="{animating: audioLoading}"></waiting-pointer>' +
      '</span>' +
      '</div>',
    scope: true,
    link: function(scope, element, attrs) {
      var parent = element.parent(),
        grandParent = parent.parent(),
        baseWidth = 65,
        eachWidth = 5,
        maxWidth = window.screen.width * 0.6,
        discussionDom = angular.element(element[0].querySelector('.discussion')),
        media;

      scope.attrs = attrs;
      scope.isSelf = grandParent.hasClass('self');
      scope.audioPlayed = true;
      scope.audioLoading = false;

      scope.duration = attrs.duration ? Math.ceil(attrs.duration) + '\'\'' : '';
      scope.audioPlayed = scope.isSelf || AudioPlayerService.getRead(attrs.audioPlayer);

      scope.laba = {
        direction: scope.isSelf ? 'right' : 'left'
      };

      discussionDom.css('width', Math.min(maxWidth, baseWidth + parseFloat(attrs.duration) * eachWidth) + 'px');
      discussionDom.css('text-align', scope.isSelf ? 'right' : 'left');

      element.bind('click', function() {
        scope.playAudio();
      });

      function stopPlay() {
        scope.laba.animate = false;
        if (media) {
          media.release();
          AudioPlayerService.removePlayingAudio(attrs.audioPlayer);
        }
      }

      function startPlay() {
        AudioPlayerService.stopPlayingAudio();
        media.play();
        AudioPlayerService.addPlayingAudio(attrs.audioPlayer, function() {
          return stopPlay;
        });
        scope.laba.animate = true;
      }

      function isPlaying() {
        return scope.laba.animate;
      }

      function download() {
        var deferred = $q.defer(),
          promise,
          audioId = attrs.audioPlayer,
          fileEntry = AudioPlayerService.getFileEntry(audioId);
        if (fileEntry) {
          deferred.resolve(fileEntry);
          return deferred.promise;
        } else {

          promise = AudioPlayerService.getPromise(audioId);
          if (promise) {
            return promise;
          } else {
            promise = AudioFileService.getAudio(audioId).then(function(fileEntry) {
              return fileEntry;
            }, function() {
              scope.audioLoading = true;
              return AudioFileService.download(audioId);
            });
            promise.then(function(fileEntry) {
              AudioPlayerService.addFileEntry(audioId, fileEntry);
              AudioPlayerService.removePromise(audioId);
            }, function() {
              $toast.showLongCenter('语音获取失败，请检查网络连接。');
            })['finally'](function() {
              scope.audioLoading = false;
            });
            AudioPlayerService.addPromise(audioId, promise);
            return promise;
          }

        }
      }

      function setPlayFlag() {
        AudioPlayerService.setRead(attrs.audioPlayer);
        scope.audioPlayed = true;
      }

      scope.playAudio = function() {
        if (isPlaying()) {
          stopPlay();
          return;
        }
        download().then(function(fileEntry) {
          var successFn;
          if (scope.$$destroyed) {
            return;
          }
          successFn = function() {
            stopPlay();
            $timeout(function() {
              $rootScope.$broadcast('audio.release', attrs.audioPlayer);
            });
          };
          media = new Media(fileEntry.toInternalURL(), successFn);
          if (!scope.isSelf) {
            setPlayFlag();
          }
          startPlay();
        });
      };

      scope.$on('$destroy', function() {
        if (media) {
          media.release();
        }
      });

      window.addEventListener('pause', function() {
        stopPlay();
      });
    }
  };
});
