angular.module('gavruk.card', [])

.controller('CardCtrl', function($scope) {
})

.directive('card', function ($compile) {
  return {
    restrict: 'A',
    scope: {
      cardContainer: '@', // required
      width: '@',
      values: '=',
      options: '=',
      messages: '=',
    },
    controller: 'CardCtrl',
    link: function (scope, element, attributes, cardCtrl) {
      var defaultValues = {
        number: '•••• •••• •••• ••••',
        name: 'Full Name',
        expiry: '••/••',
        cvc: '•••'
      };
      var defaultMessages = {
        validDate: 'valid\nthru',
        monthYear: 'month/year',
      };
      var defaultOptions = {
        debug: false,
        formatting: true
      };

      var values = angular.extend(defaultValues, scope.values);
      var messages = angular.extend(defaultMessages, scope.messages);
      var options = angular.extend(defaultOptions, scope.options);


      var opts = {
        // a selector or jQuery object for the container
        // where you want the card to appear
        container: scope.cardContainer, // *required*

        formSelectors: {},

        width: scope.width || 350,

        // Strings for translation - optional
        messages: {
          validDate: messages.validDate,
          monthYear: messages.monthYear
        },

        // Default values for rendered fields - options
        values: {
          number: values.number,
          name: values.name,
          expiry: values.expiry,
          cvc: values.cvc
        },

        formatting: options.formatting, // optional - default true
        debug: options.debug // if true, will log helpful messages for setting up Card
      };

      if (cardCtrl.numberInput && cardCtrl.numberInput.length > 0) {
        opts.formSelectors.numberInput = 'input[name="' + cardCtrl.numberInput[0].name + '"]';
      }
      if (cardCtrl.expiryInput && cardCtrl.expiryInput.length > 0) {
        opts.formSelectors.expiryInput = 'input[name="' + cardCtrl.expiryInput[0].name + '"]';
      }
      if (cardCtrl.cvcInput && cardCtrl.cvcInput.length > 0) {
        opts.formSelectors.cvcInput = 'input[name="' + cardCtrl.cvcInput[0].name + '"]';
      }
      if (cardCtrl.nameInput && cardCtrl.nameInput.length > 0) {
        opts.formSelectors.nameInput = 'input[name="' + cardCtrl.nameInput[0].name + '"]';
      }

      $(element).card(opts);
    }
  };
})

.directive('cardNumber', function($compile) {
  return {
    restrict: 'A',
    scope: {
      ngModel: '='
    },
    require: ['^card', 'ngModel'],
    link: function (scope, element, attributes, ctrls) {
      cardCtrl = ctrls[0];
      cardCtrl.numberInput = element;
      scope.$watch('ngModel', function(newVal, oldVal) {
        if (!oldVal && !newVal) {
          return;
        }
        if (oldVal === newVal && !newVal) {
          return;
        }
        
        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('keyup', false, true);
        element[0].dispatchEvent(evt);
      });
    }
  };
})

.directive('cardName', function($compile) {
  return {
    restrict: 'A',
    scope: {
      ngModel: '='
    },
    require: ['^card', 'ngModel'],
    link: function (scope, element, attributes, ctrls) {
      cardCtrl = ctrls[0];
      cardCtrl.nameInput = element;
      scope.$watch('ngModel', function(newVal, oldVal) {
        if (!oldVal && !newVal) {
          return;
        }
        if (oldVal === newVal && !newVal) {
          return;
        }

        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('keyup', false, true);
        element[0].dispatchEvent(evt);
      });
    }
  };
})

.directive('cardExpiry', function($compile) {
  return {
    restrict: 'A',
    scope: {
      ngModel: '='
    },
    require: ['^card', 'ngModel'],
    link: function (scope, element, attributes, ctrls) {
      cardCtrl = ctrls[0];
      cardCtrl.expiryInput = element;
      scope.$watch('ngModel', function(newVal, oldVal) {
        if (!oldVal && !newVal) {
          return;
        }
        if (oldVal === newVal && !newVal) {
          return;
        }
        
        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('keyup', false, true);
        element[0].dispatchEvent(evt);
      });
    }
  };
})

.directive('cardCvc', function($compile) {
  return {
    restrict: 'A',
    scope: {
      ngModel: '='
    },
    require: ['^card', 'ngModel'],
    link: function (scope, element, attributes, ctrls) {
      cardCtrl = ctrls[0];
      cardCtrl.cvcInput = element;
      scope.$watch('ngModel', function(newVal, oldVal) {
        if (!oldVal && !newVal) {
          return;
        }
        if (oldVal === newVal && !newVal) {
          return;
        }
        
        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('keyup', false, true);
        element[0].dispatchEvent(evt);
      });
    }
  };
});

@@ -51,16 +51,27 @@
 rdCtrl',
+ %5B'$scope',
  functio
@@ -83,16 +83,17 @@
 ope) %7B%0A%7D
+%5D
 )%0A%0A.dire
@@ -105,16 +105,29 @@
 ('card',
+ %5B'$compile',
  functio
@@ -2409,32 +2409,33 @@
 s);%0A    %7D%0A  %7D;%0A%7D
+%5D
 )%0A%0A.directive('c
@@ -2445,16 +2445,29 @@
 Number',
+ %5B'$compile',
  functio
@@ -2893,32 +2893,24 @@
 ;%0A        %7D%0A
-        
 %0A        var
@@ -3050,32 +3050,33 @@
 %7D);%0A    %7D%0A  %7D;%0A%7D
+%5D
 )%0A%0A.directive('c
@@ -3084,16 +3084,29 @@
 rdName',
+ %5B'$compile',
  functio
@@ -3687,32 +3687,33 @@
 %7D);%0A    %7D%0A  %7D;%0A%7D
+%5D
 )%0A%0A.directive('c
@@ -3723,16 +3723,29 @@
 Expiry',
+ %5B'$compile',
  functio
@@ -4171,32 +4171,24 @@
 ;%0A        %7D%0A
-        
 %0A        var
@@ -4336,16 +4336,17 @@
 %7D%0A  %7D;%0A%7D
+%5D
 )%0A%0A.dire
@@ -4361,16 +4361,29 @@
 ardCvc',
+ %5B'$compile',
  functio
@@ -4810,24 +4810,16 @@
       %7D%0A
-        
 %0A       
@@ -4971,11 +4971,12 @@
 %7D%0A  %7D;%0A%7D
+%5D
 );%0A

add inline annotation for minification