// DOMContentLoaded is fired once the document has been loaded and parsed,
// but without waiting for other external resources to load (css/images/etc)
// That makes the app more responsive and perceived as faster.
// https://developer.mozilla.org/Web/Reference/Events/DOMContentLoaded
window.addEventListener('DOMContentLoaded', function() {

  // We'll ask the browser to use strict code to help us catch errors earlier.
  // https://developer.mozilla.org/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
  'use strict';

  var translate = navigator.mozL10n.get;

  // We want to wait until the localisations library has loaded all the strings.
  // So we'll tell it to let us know once it's ready.
  navigator.mozL10n.once(start);

  //TODO make usage of the i10n support

  function start() {

    //var message = document.getElementById('message');

    // We're using textContent because inserting content from external sources into your page using innerHTML can be dangerous.
    // https://developer.mozilla.org/Web/API/Element.innerHTML#Security_considerations
    //message.textContent = translate('message');
  } 
});


//
// ANGULAR APP 
//
(function(){ 
  var app = angular.module('balanceApp', ['ngRoute']);  
  
 
  //ROUTE CONFIGURATION
  app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/welcome', {
        templateUrl: 'partials/welcome.html',
        controller: 'WelcomeCtrl'
      }).
      when('/index', {
        templateUrl: 'partials/wallet.html',
        controller: 'WalletCtrl'
      }).
      when('/new-card-form', {
        templateUrl: 'partials/new-card-form.html',
        controller: 'NewCardFormCtrl'
      }).
      
      when('/about', {
        templateUrl: 'partials/about.html',
        controller: 'AboutCtrl'
      }).
      
      otherwise({
        redirectTo: '/index'
      });
  }]);
  
  
  
  // WELCOME CONTROLLER
  app.controller('WelcomeCtrl', function($location) {
   this.continue = function() {
     $location.path('/new-card-form');
   }
  });
  
  
  // ABOUT CONTROLLER
  app.controller('AboutCtrl', function($location) {
   
  });
  
  
  
  // WALLET CONTROLLER - list of cards 
  app.controller('WalletCtrl', function ($scope, $http, $location) {
   // Updates cards balance from server and saves it to local storage
   // also updates the UI 
    $scope.finishedUpdating = function() {
      $scope.updatingCards = false;
      var now = Date.now(); //TODO  add this logic to CardStore 
      localStorage.setItem('cards-updated-at', now);
      $scope.cardsUpdatedAt = now;
    };
    
    $scope.about = function() {
      $location.path('/about');
    }
    
   $scope.updateCards = function(forceUpdate) {
     console.log("update cards requested. forceUpdate:" + forceUpdate);
     var now = new Date().now; // ms
     var numCardsUpdating = 0;
     for(var i=0;i<$scope.cards.length; i++) {
       var card = $scope.cards[i];
       var outdated = (now - card.updated_at) >  (360 * 1000); // >5 min => is outdated
       if (outdated || forceUpdate) {
         $scope.updatingCards = true; //to show the progress bar
         numCardsUpdating++; // to know how many cards are being updated
         console.log("Updating card " + card.card_number);
         // TODO the following code is repeated in new-card-form controller
         $http.get('http://saldopanama.herokuapp.com/metrobus/' + card.card_number +'.json').
           success(function(data) {
             numCardsUpdating --;
             if (numCardsUpdating <= 0) {
               $scope.finishedUpdating(); 
             }
             if(data.code == -1) {
               console.log("ERROR:" + data.description)
             } else { 
              console.log("Received Card Info: " + data.data);
              cs = new CardStore();
              cs.update(data); //once added it is automatically saved 
            }
          }).
          error(function(data, status, headers, config) {
            numCardsUpdating--;
            if (numCardsUpdating == 0) {
              $scope.finishedUpdating();
            } 
            // called asynchronously if an error occurs
            // or server returns response with an error status.
            console.log("Dish! Request of new card info failed");
            console.log("Received Status: " + this.status);
            console.log("Received data: " + this.data);
          });
            
       }
     }
   }
   
 $scope.deleteCard = function(cardNumber) {
     console.log("Delete card: " + cardNumber);
     cs.delete(cardNumber)
     $scope.cards = cs.all();
     $scope.deleteMode = false;
     if (this.cards.length == 0) {
       console.log("No cards => redirect to /new-card-form");
       $location.path("/new-card-form");
     }
   };
   
   $scope.updatingCards = false; 
   $scope.deleteMode = false;
   //load all cards
   var cs = new CardStore();
   $scope.cards = cs.all();
   
   $scope.cardsUpdatedAt = localStorage.getItem('cards-updated-at');
   
     //if there are no cards => redirect to add new card
   if ($scope.cards.length == 0) {
     $location.path('/welcome')
   } else {
     $scope.updateCards(false);
   }
  
  
   
  }); //wallet ctrl
  
  
  
  
  // NEW CARD FORM CONTROLLER
  app.controller('NewCardFormCtrl', function($scope, $http, $location) {
    $scope.submitting = false;
    
    // TODO this code is repeated. Make it better
    this.submit = function() { 
      $scope.submitting = true
      $http.get('http://saldopanama.herokuapp.com/metrobus/' + this.cardNumber +'.json').
      success(function(data) {
        if(data.code == -1) {
          alert(data.description);
          console.log("ERROR:" + data.description);
          $scope.submitting = false
        } else { 
         cardData = data.data;
         cardData.alias = $scope.cardAlias;
         console.log(cardData);
         cs = new CardStore();
         cs.update(cardData); //once added it is automatically saved
         
         //set last time any card was updated
         var now = Date.now(); //TODO  add this logic to CardStore 
         localStorage.setItem('cards-updated-at', now);
         $scope.cardsUpdatedAt = now;
         $location.path("/index");
       }
     }).
     error(function(data, status, headers, config) {
       // called asynchronously if an error occurs
       // or server returns response with an error status.
       alert("Hubo un error inesperado al recuperar la información de la tarjeta. Revisa que tienes Internet o el número de la tarjeta.")
       $scope.submitting = false;
       console.log("Dish! Request of new card info failed");
       console.log(this.status);
       console.log(this.data);
       
     });
     
     ; // success
    console.log("submit form requested");
      
    };
  }); // new card form controller
  
  
  
  
  //INTEGER DIRECTIVE To check card number is an integer.
  var INTEGER_REGEXP = /^\-?\d+$/;
  app.directive('integer', function() {
    return {
      require: 'ngModel',
      link: function(scope, elm, attrs, ctrl) {
        ctrl.$validators.integer = function(modelValue, viewValue) {
          console.log("validating modelValue: " + modelValue + " viewValue: " + viewValue)
          if (ctrl.$isEmpty(modelValue)) {
            // consider empty models to be valid
            return true;
          }
          if (INTEGER_REGEXP.test(viewValue)) {
            // it is valid
            return true;
          }
          // it is invalid
          return false;
        };
      }
    };
  });
  
  
})();

