/* global require,module */

'use strict';

var angular = require('angular');
var Popup = require('./lib/popup');
var directives = angular.module('popups', []);



directives.popup = function(name, options) {
    return directives.directive(name, function() {

        var directive = {
            template: options.template,
            restrict: 'AE',
            transclude: true,
            replace: true,
            scope: {

                'ngIf': '=',
                'ngShow': '=',
                'ngHide': '=',

                'close': '&',

                // 吸附到指定 ID 元素
                'for': '@',

                // 对齐方式，配合 for
                'align': '@',

                // 是否固定定位（跟随滚动条）
                'fixed': '@',

                // 是否是模态浮层
                'modal': '@',

                // 显示持续时间
                'duration': '@'

            },
            controller: ['$scope', '$window', function($scope, $window) {
                this.$close = function() {
                    $window.clearTimeout($scope.$$time);
                    $scope.close();
                    $scope.$apply();
                };

                this.$duration = function(duration) {
                    $window.clearTimeout($scope.$$time);
                    $scope.$$time = $window.setTimeout(function() {
                        $scope.close();
                        $scope.$apply();
                    }, duration);
                };

            }],
            link: function(scope, elem, attrs, superheroCtrl) {

                var $ = angular.element;
                var popup = new Popup(elem[0], true);


                // 要映射的字段
                var map = {
                    'for': 'anchor'
                };

                // 要转换的数据类型
                var type = {
                    'for': 'String@id',
                    'anchor': 'String@id',
                    'fixed': 'Boolean',
                    'modal': 'Boolean'
                };



                var parse = {

                    'String@id': function(value) {
                        return value ? document.getElementById(value) : null;
                    },

                    'Boolean': function(value) {
                        return typeof value === 'string';
                    }
                };


                // 设置属性

                Object.keys(type).forEach(function(key) {
                    var value = attrs[key];

                    if (typeof value === 'undefined') {
                        return;
                    }

                    if (map[key]) {
                        key = map[key];
                    }

                    if (type[key]) {
                        value = parse[type[key]](value);
                    }

                    popup[key] = value;
                });


                // 通过模型控制对话框显示与隐藏

                if (attrs.ngIf) scope.$watch('ngIf', toggle);
                if (attrs.ngShow) scope.$watch('ngShow', toggle);
                if (attrs.ngHide) scope.$watch('ngHide', toggle);


                function toggle(v) {

                    if (typeof v === 'undefined') {
                        return;
                    }

                    var value = true;

                    switch (attrs) {
                        case 'ngIf':
                            value = scope.ngIf;
                            break;
                        case 'ngShow':
                            value = scope.ngShow;
                            break;
                        case 'ngHide':
                            value = !scope.ngHide;
                            break;
                    }

                    if (value) {
                        popup.show(popup.anchor);

                        if (attrs.duration) {
                            superheroCtrl.$duration(Number(attrs.duration));
                        }

                    } else {
                        popup.close();
                    }

                }


                // ESC 快捷键关闭浮层
                function esc(event) {

                    var target = event.target;
                    var nodeName = target.nodeName;
                    var rinput = /^input|textarea$/i;
                    var isBlur = Popup.current === popup;
                    var isInput = rinput.test(nodeName) && target.type !== 'button';
                    var keyCode = event.keyCode;

                    // 避免输入状态中 ESC 误操作关闭
                    if (!isBlur || isInput) {
                        return;
                    }

                    if (keyCode === 27) {
                        superheroCtrl.$close();
                    }
                }


                $(document).on('keydown', esc);


                (options.link || function() {}).apply(this, arguments);


                // ng 销毁事件控制对话框关闭
                // 控制器销毁或者 ng-if="false" 都可能触发此
                // scope.$on('$destroy', callback) >> 这种方式对 ngAnimate 支持不好
                elem.one('$destroy', function() {
                    $(document).off('keydown', esc);
                    popup.close().remove();
                });



            }
        };


        angular.extend(directive.scope, options.scope);


        return directive;
    });
};

module.exports = directives;
@@ -140,16 +140,24 @@
 module('
+angular-
 popups',
@@ -1862,16 +1862,18 @@
         
+//
 'anchor'
@@ -1965,16 +1965,55 @@
 Boolean'
+,%0A                    'align': 'String'
 %0A       
@@ -2440,24 +2440,66 @@
 tion(key) %7B%0A
+                    var item = type%5Bkey%5D;%0A
             
@@ -2529,16 +2529,52 @@
 rs%5Bkey%5D;
+%0A                    var name = key;
 %0A%0A      
@@ -2702,23 +2702,26 @@
     if (
-map%5Bkey
+parse%5Bitem
 %5D) %7B%0A   
@@ -2745,22 +2745,34 @@
     
-key = map%5Bkey%5D
+value = parse%5Bitem%5D(value)
 ;%0A  
@@ -2816,20 +2816,19 @@
     if (
-type
+map
 %5Bkey%5D) %7B
@@ -2856,39 +2856,23 @@
     
-value = parse%5Btype%5Bkey%5D%5D(value)
+name = map%5Bkey%5D
 ;%0A  
@@ -2918,19 +2918,20 @@
   popup%5B
-key
+name
 %5D = valu

修复 `align` 无效的问题