(function () {
  'use strict';

  /*
  diff.html script
  */
  var llapp;
  llapp = angular.module('llngConfDiff', ['ui.tree', 'ui.bootstrap', 'llApp', 'ngCookies'], ['$rootScopeProvider', function ($rootScopeProvider) {
    return $rootScopeProvider.digestTtl(15);
  }]);
  llapp.controller('DiffCtrl', ['$scope', '$http', '$q', '$translator', '$location', function ($scope, $http, $q, $translator, $location) {
    var buildTree, getCfg, init, pathEvent, readDiff, reverseTree, toNodes;
    $scope.links = links;
    $scope.menulinks = menulinks;
    $scope.staticPrefix = staticPrefix;
    $scope.scriptname = scriptname;
    //$scope.formPrefix = formPrefix
    $scope.availableLanguages = availableLanguages;
    $scope.waiting = true;
    $scope.showM = false;
    $scope.cfg = [];
    $scope.data = {};
    $scope.currentNode = null;
    // Import translations functions
    $scope.translateTitle = function (node) {
      return $translator.translateField(node, 'title');
    };
    $scope.translateP = $translator.translateP;
    $scope.translate = $translator.translate;
    $scope.toggle = function (scope) {
      return scope.toggle();
    };
    $scope.stoggle = function (scope, node) {
      $scope.currentNode = node;
      return scope.toggle();
    };
    // Handle menu items
    $scope.menuClick = function (button) {
      if (button.popup) {
        window.open(button.popup);
      } else {
        if (!button.action) {
          button.action = button.title;
        }
        switch (typeof button.action) {
          case 'function':
            button.action($scope.currentNode, $scope);
            break;
          case 'string':
            $scope[button.action]();
            break;
          default:
            console.warn('Unknown action type', typeof button.action);
        }
      }
      return $scope.showM = false;
    };
    // Function to change interface language
    $scope.getLanguage = function (lang) {
      $scope.lang = lang;
      init();
      return $scope.showM = false;
    };
    // function `getCfg(b,n)`:
    // Download configuration metadatas

    //@param b local conf (0 or 1)
    //@param n cfgNumber
    getCfg = function (b, n) {
      var d;
      d = $q.defer();
      if ($scope.cfg[b] == null || $scope.cfg[b] !== n) {
        $http.get(`${confPrefix}${n}`).then(function (response) {
          var date;
          if (response && response.data) {
            $scope.cfg[b] = response.data;
            date = new Date(response.data.cfgDate * 1000);
            $scope.cfg[b].date = date.toLocaleString();
            console.debug(`Metadatas of cfg ${n} loaded`);
            return d.resolve('OK');
          } else {
            return d.reject(response);
          }
        }, function (response) {
          return d.reject('NOK');
        });
      } else {
        d.resolve();
      }
      return d.promise;
    };
    // Intialization function
    // Simply set $scope.waiting to false during $translator and tree root
    // initialization
    init = function () {
      $scope.message = null;
      $scope.currentNode = null;
      $q.all([$translator.init($scope.lang), $http.get(`${staticPrefix}reverseTree.json`).then(function (response) {
        response.data;
        console.debug("Structure loaded");
      })]).then(function () {
        $q.defer();
        return $http.get(`${scriptname}view/diff/${$scope.cfg[0].cfgNum}/${$scope.cfg[1].cfgNum}`).then(function (response) {
          var data;
          data = [];
          data = readDiff(response.data[0], response.data[1]);
          $scope.data = buildTree(data);
          $scope.message = '';
          return $scope.waiting = false;
        }, function (response) {
          return $scope.message = `${$scope.translate('error')} : ${response.statusLine}`;
        });
      });
      // Colorized link
      $scope.activeModule = "viewer";
      return $scope.myStyle = {
        color: '#ffb84d'
      };
    };
    readDiff = function (c1, c2, tr = true) {
      var k, res, tmp, v;
      res = [];
      for (k in c1) {
        v = c1[k];
        if (tr) {
          tmp = {
            title: $scope.translate(k),
            id: k
          };
        } else {
          tmp = {
            title: k
          };
        }
        if (!k.match(/^cfg(?:Num|Log|Author(?:IP)?|Date)$/)) {
          if (v != null && typeof v === 'object') {
            if (v.constructor === 'array') {
              tmp.oldvalue = v;
              tmp.newvalue = c2[k];
            } else if (typeof c2[k] === 'object') {
              tmp.nodes = readDiff(c1[k], c2[k], false);
            } else {
              tmp.oldnodes = toNodes(v, 'old');
            }
          } else {
            tmp.oldvalue = v;
            tmp.newvalue = c2[k];
          }
          res.push(tmp);
        }
      }
      for (k in c2) {
        v = c2[k];
        if (!(k.match(/^cfg(?:Num|Log|Author(?:IP)?|Date)$/) || c1[k] != null)) {
          if (tr) {
            tmp = {
              title: $scope.translate(k),
              id: k
            };
          } else {
            tmp = {
              title: k
            };
          }
          if (v != null && typeof v === 'object') {
            if (v.constructor === 'array') {
              tmp.newvalue = v;
            } else {
              console.debug("Iteration");
              tmp.newnodes = toNodes(v, 'new');
            }
          } else {
            tmp.newvalue = v;
          }
          res.push(tmp);
        }
      }
      return res;
    };
    toNodes = function (c, s) {
      var k, res, tmp, v;
      res = [];
      for (k in c) {
        v = c[k];
        tmp = {
          title: k
        };
        if (typeof v === 'object') {
          if (v.constructor === 'array') {
            tmp[`${s}value`] = v;
          } else {
            tmp[`${s}nodes`] = toNodes(c[k], s);
          }
        } else {
          tmp[`${s}value`] = v;
        }
        res.push(tmp);
      }
      return res;
    };
    reverseTree = [];
    buildTree = function (data) {
      var elem, found, i, j, l, len, len1, len2, m, n, node, offset, path, res;
      if (reverseTree == null) {
        return data;
      }
      res = [];
      for (j = 0, len = data.length; j < len; j++) {
        elem = data[j];
        offset = res;
        path = reverseTree[elem.id] != null ? reverseTree[elem.id].split('/') : '';
        for (l = 0, len1 = path.length; l < len1; l++) {
          node = path[l];
          if (node.length > 0) {
            if (offset.length) {
              found = -1;
              for (i = m = 0, len2 = offset.length; m < len2; i = ++m) {
                n = offset[i];
                if (n.id === node) {
                  //offset = n.nodes
                  found = i;
                }
              }
              if (found !== -1) {
                offset = offset[found].nodes;
              } else {
                offset.push({
                  id: node,
                  title: $scope.translate(node),
                  nodes: []
                });
                offset = offset[offset.length - 1].nodes;
              }
            } else {
              offset.push({
                id: node,
                title: $scope.translate(node),
                nodes: []
              });
              offset = offset[0].nodes;
            }
          }
        }
        offset.push(elem);
      }
      return res;
    };
    $scope.newDiff = function () {
      return $location.path(`/${$scope.cfg[0].cfgNum}/${$scope.cfg[1].cfgNum}`);
    };
    pathEvent = function (event, next, current) {
      var n;
      n = next.match(new RegExp('#!?/(latest|[0-9]+)(?:/(latest|[0-9]+))?$'));
      if (n === null) {
        $location.path('/latest');
      } else {
        $scope.waiting = true;
        $q.all([$translator.init($scope.lang), $http.get(`${staticPrefix}reverseTree.json`).then(function (response) {
          reverseTree = response.data;
          console.debug("Structure loaded");
        }), getCfg(0, n[1]), n[2] != null ? getCfg(1, n[2]) : void 0]).then(function () {
          if (n[2] != null) {
            return init();
          } else {
            if ($scope.cfg[0].prev) {
              $scope.cfg[1] = $scope.cfg[0];
              return getCfg(0, $scope.cfg[1].prev).then(function () {
                return init();
              });
            } else {
              $scope.data = [];
              return $scope.waiting = false;
            }
          }
        }, function () {
          $scope.message = $scope.translate('error');
          return $scope.waiting = false;
        });
      }
      return true;
    };
    return $scope.$on('$locationChangeSuccess', pathEvent);
  }]);

})();