// Generated by CoffeeScript 1.12.8

/*
LemonLDAP::NG Viewer client

This is the main app file. Other are:
 - struct.json and js/confTree.js that contains the full tree
 - translate.json that contains the keywords translation

This file contains:
 - the AngularJS controller
 */

(function() {
  var llapp;

  llapp = angular.module('llngViewer', ['ui.tree', 'ui.bootstrap', 'llApp', 'ngCookies']);


  /*
  Main AngularJS controller
   */

  llapp.controller('TreeCtrl', [
    '$scope', '$http', '$location', '$q', '$uibModal', '$translator', '$cookies', '$htmlParams', function($scope, $http, $location, $q, $uibModal, $translator, $cookies, $htmlParams) {
      var _download, _getAll, _stoggle, c, id, pathEvent, readError, setHelp;
      $scope.links = window.links;
      $scope.menu = $htmlParams.menu;
      $scope.menulinks = window.menulinks;
      $scope.staticPrefix = window.staticPrefix;
      $scope.formPrefix = window.formPrefix;
      $scope.availableLanguages = window.availableLanguages;
      $scope.waiting = true;
      $scope.showM = false;
      $scope.showT = false;
      $scope.form = 'homeViewer';
      $scope.currentCfg = {};
      $scope.viewPrefix = window.viewPrefix;
      $scope.allowDiff = window.allowDiff;
      $scope.message = {};
      $scope.result = '';
      $scope.translateTitle = function(node) {
        return $translator.translateField(node, 'title');
      };
      $scope.translateP = $translator.translateP;
      $scope.translate = $translator.translate;
      $scope.helpUrl = 'start.html#configuration';
      $scope.setShowHelp = function(val) {
        var d;
        if (val == null) {
          val = !$scope.showH;
        }
        $scope.showH = val;
        d = new Date(Date.now());
        d.setFullYear(d.getFullYear() + 1);
        return $cookies.put('showhelp', (val ? 'true' : 'false'), {
          "expires": d
        });
      };
      $scope.showH = $cookies.get('showhelp') === 'false' ? false : true;
      if ($scope.showH == null) {
        $scope.setShowHelp(true);
      }
      readError = function(response) {
        var e, j;
        e = response.status;
        j = response.statusLine;
        $scope.waiting = false;
        if (e === 403) {
          $scope.message = {
            title: 'forbidden',
            message: '',
            items: []
          };
        } else if (e === 401) {
          console.log('Authentication needed');
          $scope.message = {
            title: 'authenticationNeeded',
            message: '__waitOrF5__',
            items: []
          };
        } else if (e === 400) {
          $scope.message = {
            title: 'badRequest',
            message: j,
            items: []
          };
        } else if (e > 0) {
          $scope.message = {
            title: 'badRequest',
            message: j,
            items: []
          };
        } else {
          $scope.message = {
            title: 'networkProblem',
            message: '',
            items: []
          };
        }
        return $scope.showModal('message.html');
      };
      $scope.showModal = function(tpl, init) {
        var d, modalInstance;
        modalInstance = $uibModal.open({
          templateUrl: tpl,
          controller: 'ModalInstanceCtrl',
          size: 'lg',
          resolve: {
            elem: function() {
              return function(s) {
                return $scope[s];
              };
            },
            set: function() {
              return function(f, s) {
                return $scope[f] = s;
              };
            },
            init: function() {
              return init;
            }
          }
        });
        d = $q.defer();
        modalInstance.result.then(function(msgok) {
          $scope.message = {
            title: '',
            message: '',
            items: []
          };
          return d.resolve(msgok);
        }, function(msgnok) {
          $scope.message = {
            title: '',
            message: '',
            items: []
          };
          return d.reject(msgnok);
        });
        return d.promise;
      };
      $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.log(typeof button.action);
          }
        }
        return $scope.showM = false;
      };
      $scope.home = function() {
        $scope.form = 'homeViewer';
        return $scope.showM = false;
      };
      $scope.downloadConf = function() {
        return window.open($scope.viewPrefix + $scope.currentCfg.cfgNum + '?full=1');
      };
      id = 1;
      $scope._findContainer = function() {
        return $scope._findScopeContainer().$modelValue;
      };
      $scope._findScopeContainer = function() {
        var cs;
        cs = $scope.currentScope;
        while (!cs.$modelValue.type.match(/Container$/)) {
          cs = cs.$parentNodeScope;
        }
        return cs;
      };
      $scope._findScopeByKey = function(k) {
        var cs;
        cs = $scope.currentScope;
        while (!(cs.$modelValue.title === k)) {
          cs = cs.$parentNodeScope;
        }
        return cs;
      };
      _getAll = function(node) {
        var d, d2;
        d = $q.defer();
        d2 = $q.defer();
        if (node._nodes) {
          _stoggle(node);
          d.resolve();
        } else if (node.cnodes) {
          _download(node).then(function() {
            return d.resolve();
          });
        } else if (node.nodes || node.data) {
          d.resolve();
        } else {
          $scope.getKey(node).then(function() {
            return d.resolve();
          });
        }
        d.promise.then(function() {
          var l, len, n, ref, t;
          t = [];
          if (node.nodes) {
            ref = node.nodes;
            for (l = 0, len = ref.length; l < len; l++) {
              n = ref[l];
              t.push(_getAll(n));
            }
          }
          return $q.all(t).then(function() {
            return d2.resolve();
          });
        });
        return d2.promise;
      };
      $scope.down = function() {
        var i, ind, l, len, n, p, ref, tmp;
        id = $scope.currentNode.id;
        p = $scope.currentScope.$parentNodeScope.$modelValue;
        ind = p.nodes.length;
        ref = p.nodes;
        for (i = l = 0, len = ref.length; l < len; i = ++l) {
          n = ref[i];
          if (n.id === id) {
            ind = i;
          }
        }
        if (ind < p.nodes.length - 1) {
          tmp = p.nodes[ind];
          p.nodes[ind] = p.nodes[ind + 1];
          p.nodes[ind + 1] = tmp;
        }
        return ind;
      };
      $scope.up = function() {
        var i, ind, l, len, n, p, ref, tmp;
        id = $scope.currentNode.id;
        p = $scope.currentScope.$parentNodeScope.$modelValue;
        ind = -1;
        ref = p.nodes;
        for (i = l = 0, len = ref.length; l < len; i = ++l) {
          n = ref[i];
          if (n.id === id) {
            ind = i;
          }
        }
        if (ind > 0) {
          tmp = p.nodes[ind];
          p.nodes[ind] = p.nodes[ind - 1];
          p.nodes[ind - 1] = tmp;
        }
        return ind;
      };
      $scope.inSelect = function(value) {
        var l, len, n, ref;
        ref = $scope.currentNode.select;
        for (l = 0, len = ref.length; l < len; l++) {
          n = ref[l];
          if (n.k === value) {
            return true;
          }
        }
        return false;
      };
      $scope.changeRuleTitle = function(node) {
        return node.title = node.comment.length > 0 ? node.comment : node.re;
      };
      $scope.filters = {};
      $scope.execFilters = function(scope) {
        var filter, func, ref;
        scope = scope ? scope : $scope;
        ref = $scope.filters;
        for (filter in ref) {
          func = ref[filter];
          if ($scope.filters.hasOwnProperty(filter)) {
            return window.filterFunctions[filter](scope, $q, func);
          }
        }
        return false;
      };
      $scope.stoggle = function(scope) {
        var node;
        node = scope.$modelValue;
        _stoggle(node);
        return scope.toggle();
      };
      _stoggle = function(node) {
        var a, l, len, len1, len2, m, n, o, ref, ref1, ref2;
        ref = ['nodes', 'nodes_cond'];
        for (l = 0, len = ref.length; l < len; l++) {
          n = ref[l];
          if (node["_" + n]) {
            node[n] = [];
            ref1 = node["_" + n];
            for (m = 0, len1 = ref1.length; m < len1; m++) {
              a = ref1[m];
              node[n].push(a);
            }
            delete node["_" + n];
          }
        }
        if (node._nodes_filter) {
          if (node.nodes) {
            ref2 = node.nodes;
            for (o = 0, len2 = ref2.length; o < len2; o++) {
              n = ref2[o];
              n.onChange = $scope.execFilters;
            }
          }
          $scope.filters[node._nodes_filter] = node;
          return $scope.execFilters();
        }
      };
      $scope.toggle = function(scope) {
        return scope.toggle();
      };
      $scope.download = function(scope) {
        var node;
        node = scope.$modelValue;
        return _download(node);
      };
      _download = function(node) {
        var d, uri;
        d = $q.defer();
        d.notify('Trying to get datas');
        $scope.waiting = true;
        console.log("Trying to get key " + node.cnodes);
        uri = encodeURI(node.cnodes);
        $http.get("" + window.viewPrefix + $scope.currentCfg.cfgNum + "/" + uri).then(function(response) {
          var a, data, l, len;
          data = response.data;
          if (!data) {
            d.reject('Empty response from server');
          } else if (data.error) {
            if (data.error.match(/setDefault$/)) {
              if (node['default']) {
                node.nodes = node['default'].slice(0);
              } else {
                node.nodes = [];
              }
              delete node.cnodes;
              d.resolve('Set data to default value');
            } else {
              d.reject("Server return an error: " + data.error);
            }
          } else {
            delete node.cnodes;
            if (!node.type) {
              node.type = 'keyTextContainer';
            }
            node.nodes = [];
            for (l = 0, len = data.length; l < len; l++) {
              a = data[l];
              if (a.template) {
                a._nodes = templates(a.template, a.title);
              }
              node.nodes.push(a);
            }
            d.resolve('OK');
          }
          return $scope.waiting = false;
        }, function(response) {
          readError(response);
          return d.reject('');
        });
        return d.promise;
      };
      $scope.openCnode = function(scope) {
        return $scope.download(scope).then(function() {
          return scope.toggle();
        });
      };
      setHelp = function(scope) {
        while (!scope.$modelValue.help && scope.$parentNodeScope) {
          scope = scope.$parentNodeScope;
        }
        return $scope.helpUrl = scope.$modelValue.help || 'start.html#configuration';
      };
      $scope.displayForm = function(scope) {
        var f, l, len, n, node, ref;
        node = scope.$modelValue;
        if (node.cnodes) {
          $scope.download(scope);
        }
        if (node._nodes) {
          $scope.stoggle(scope);
        }
        $scope.currentNode = node;
        $scope.currentScope = scope;
        f = node.type ? node.type : 'text';
        if (node.nodes || node._nodes || node.cnodes) {
          $scope.form = f !== 'text' ? f : 'mini';
        } else {
          $scope.form = f;
          $scope.getKey(node);
        }
        if (node.type && node.type === 'simpleInputContainer') {
          ref = node.nodes;
          for (l = 0, len = ref.length; l < len; l++) {
            n = ref[l];
            $scope.getKey(n);
          }
        }
        $scope.showT = false;
        return setHelp(scope);
      };
      $scope.keyWritable = function(scope) {
        var node;
        node = scope.$modelValue;
        if (node.type && node.type.match(/^(?:s(?:aml(?:(?:ID|S)PMetaDataNod|Attribut)e|fExtra)|(?:(?:cmbMod|r)ul|authChoic)e|(?:virtualHos|keyTex)t|menu(?:App|Cat))$/)) {
          return true;
        } else {
          return false;
        }
      };
      $scope.getKey = function(node) {
        var d, i, l, len, n, ref, tmp, uri;
        d = $q.defer();
        if (!node.data) {
          $scope.waiting = true;
          if (node.get && typeof node.get === 'object') {
            node.data = [];
            tmp = [];
            ref = node.get;
            for (i = l = 0, len = ref.length; l < len; i = ++l) {
              n = ref[i];
              node.data[i] = {
                title: n,
                id: n
              };
              tmp.push($scope.getKey(node.data[i]));
            }
            $q.all(tmp).then(function() {
              return d.resolve(node.data);
            }, function(response) {
              d.reject(response.statusLine);
              return $scope.waiting = false;
            });
          } else {
            uri = '';
            if (node.get) {
              console.log("Trying to get key " + node.get);
              uri = encodeURI(node.get);
            } else {
              console.log("Trying to get title " + node.title);
            }
            $http.get("" + window.viewPrefix + $scope.currentCfg.cfgNum + "/" + (node.get ? uri : node.title)).then(function(response) {
              var data;
              data = response.data;
              if ((data.value === null || (data.error && data.error.match(/setDefault$/))) && node['default'] !== null) {
                node.data = node['default'];
              } else {
                node.data = data.value;
              }
              if (node.data && node.data.toString().match(/_Hidden_$/)) {
                node.type = 'text';
                node.data = '######';
              }
              if (node.type && node.type.match(/^(bool|trool|boolOrExpr)$/)) {
                if (typeof node.data === 'string' && node.data.match(/^(?:-1|0|1)$/)) {
                  node.data = parseInt(node.data, 10);
                }
              }
              if (node.type && node.type.match(/^int$/)) {
                node.data = parseInt(node.data, 10);
              } else if (node.type && node.type.match(/^(saml(Service|Assertion)|blackWhiteList)$/) && !(typeof node.data === 'object')) {
                node.data = node.data.split(';');
              }
              $scope.waiting = false;
              return d.resolve(node.data);
            }, function(response) {
              readError(response);
              return d.reject(response.status);
            });
          }
        } else {
          if (node.data.toString().match(/_Hidden_$/)) {
            node.type = 'text';
            node.data = '######';
          }
          d.resolve(node.data);
        }
        return d.promise;
      };
      pathEvent = function(event, next, current) {
        var n;
        n = next.match(new RegExp('#!?/view/(latest|[0-9]+)'));
        if (n === null) {
          return $location.path('/view/latest');
        } else {
          console.log("Trying to get cfg number " + n[1]);
          return $scope.getCfg(n[1]);
        }
      };
      $scope.$on('$locationChangeSuccess', pathEvent);
      $scope.getCfg = function(n) {
        if ($scope.currentCfg.cfgNum !== n) {
          return $http.get("" + window.viewPrefix + n).then(function(response) {
            var d;
            $scope.currentCfg = response.data;
            d = new Date($scope.currentCfg.cfgDate * 1000);
            $scope.currentCfg.date = d.toLocaleString();
            console.log("Metadatas of cfg " + n + " loaded");
            $location.path("/view/" + n);
            return $scope.init();
          }, function(response) {
            return readError(response).then(function() {
              $scope.currentCfg.cfgNum = 0;
              return $scope.init();
            });
          });
        } else {
          return $scope.waiting = false;
        }
      };
      $scope.getLanguage = function(lang) {
        $scope.lang = lang;
        $scope.form = 'white';
        $scope.init();
        return $scope.showM = false;
      };
      $scope.init = function() {
        var tmp;
        tmp = null;
        $scope.waiting = true;
        $scope.data = [];
        $scope.confirmNeeded = false;
        $scope.forceSave = false;
        $q.all([
          $translator.init($scope.lang), $http.get(window.staticPrefix + "struct.json").then(function(response) {
            tmp = response.data;
            return console.log("Structure loaded");
          })
        ]).then(function() {
          console.log("Starting structure binding");
          $scope.data = tmp;
          tmp = null;
          if ($scope.currentCfg.cfgNum !== 0) {
            setScopeVars($scope);
          } else {
            $scope.message = {
              title: 'emptyConf',
              message: '__zeroConfExplanations__'
            };
            $scope.showModal('message.html');
          }
          $scope.form = 'homeViewer';
          return $scope.waiting = false;
        }, readError);
        $scope.activeModule = "viewer";
        return $scope.myStyle = {
          color: '#ffb84d'
        };
      };
      c = $location.path().match(new RegExp('^/view/(latest|[0-9]+)'));
      if (!c) {
        console.log("Redirecting to /view/latest");
        return $location.path('/view/latest');
      }
    }
  ]);

}).call(this);