text: ﻿// start: query expression view models
  function QToken(val) {
      var self = this;
      self.TkType = "";
      self.TkName = val;
      self.DisplayAs = val;
      self.IsExternal = false;
      self.IsEntityAccess = false;
      self.TkClass = "filternode";
      self.SortOrder = 0;
      self.FilterOrder = 0;
      self.CopyToken = function (token) {
          self.TkType = token.TkType;
          self.TkName = token.TkName;
          self.DisplayAs = token.DisplayAs;
          self.IsExternal = token.IsExternal;
          self.IsEntityAccess = token.IsEntityAccess;
          self.TkClass = "filternode " + token.TkType;
      }
  }
  
  function TokenOptions() {
      this.Hint = "";
      this.CurrentExpr = ko.observable("");
      this.QuoteVal = false;
      this.CanBeClosed = true;
      this.IsLocal = false;
      this.Options = [];
  }
  
  function QueryExpresion(sorters, filters) {
      this.OrderTks = [];
      this.FilterTks = [];
      for (var i = 0; i < sorters.length; i++) {
          this.OrderTks.push(sorters[i]);
      }
      for (var i = 0; i < filters.length; i++) {
          this.FilterTks.push(filters[i]);
      }
  }
  
  // end: query expression view model
  
  // start: entity page view model
  
  function MemberStatus(val, act) {
      this.value = val;
      switch (val) {
          case 'OK':
              this.action = 'Normal';
              break;
          case 'Cancelled':
              this.action = 'Cancel';
              break;
          case 'LockedOut':
              this.action = 'Lockout';
              break;
          case 'Expired':
              this.action = 'Expire';
              break;
      }
  }
  
  function Role(data) {
      var self = this;
      self.data = data;
      self.id = data.id;
      self.name = data.name;
      self.path = data.path;
      self.level = ko.observable(data.level);
      self.op = data.op;
      self.modified = ko.computed(function () {
          return self.level() != data.level;
      });
      self.AdjustRoleLevel = function (user, event) {
          var del = self.level() - data.level;
          if (del != 0) {
              $.ajax({
                  url: appRoot + "RoleAdmin/AdjustUserRoleLevel",
                  type: "POST",
                  dataType: "json",
                  contentType: "application/json; charset=utf-8",
                  data: JSON.stringify({ uid: user.data.ID, rid: data.id, del: del }),
                  success: function (content) {
                      if (!content.ok) {
                          alert(content.msg);
                          self.level(data.level);
                      } else {
                          data.level = self.level();
                      }
                  },
                  error: function (jqxhr, textStatus) {
                      alert(jqxhr.responseText);
                      self.level(data.level);
                  },
                  complete: function () {
                  }
              });
          }
      }
  
      self.AdjustThisRoleLevel = function () {
          var del = self.level() - self.data.level;
          if (del != 0) {
              $.ajax({
                  url: appRoot + "RoleAdmin/AdjustUserRoleLevel",
                  type: "POST",
                  dataType: "json",
                  contentType: "application/json; charset=utf-8",
                  data: JSON.stringify({ uid: self.data.uid, rid: self.id, del: del }),
                  success: function (content) {
                      if (!content.ok) {
                          alert(content.msg);
                          self.level(self.data.level);
                      } else {
                          var x = self.level();
                          self.level(self.data.level)
                          self.data.level = x;
                          self.level(x);
                      }
                  },
                  error: function (jqxhr, textStatus) {
                      alert(jqxhr.responseText);
                      self.level(self.data.level);
                  },
                  complete: function () {
                  }
              });
          }
      }
  
      self.RemoveFromUser = function (role) {
          $.ajax({
              url: appRoot + "RoleAdmin/RemoveUserFromRole",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ uid: self.data.uid, rid: self.id }),
              success: function (content) {
                  if (!content.ok) {
                      alert(content.msg);
                  } else {
                      var size = role.UsersInRole().length;
                      for (var i = 0; i < size; i++) {
                          var r = role.UsersInRole()[i];
                          if (r.id == self.id) {
                              role.UsersInRole.remove(r);
                              break;
                          }
                      }
                  }
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
              },
              complete: function () {
              }
          });
      };
  }
  
  function User(data) {
      var self = this;
      self.Initializing = true;
      self.data = data.data;
      self.op_id = 'op_' + data.data.ID;
      self.view_id = 'view_' + data.data.ID;
      self.member = data.member;
      self.edit = data.CanEdit;
      self.roles = ko.observableArray();
      for (var i = 0; i < data.roles.length; i++) {
          self.roles.push(new Role(data.roles[i]));
      }
      self.maxrole = ko.observable(data.maxrole);
      self.availableRoles = ko.observableArray(data.availableRoles);
      self.IsPasswordReset = ko.observable(false);
      var opts = [new MemberStatus('OK'),
                  new MemberStatus('Cancelled'),
                  new MemberStatus('LockedOut'),
                  new MemberStatus('Expired')];
      self.MemberStatusValues = ko.observableArray();
      for (var i = 0; i < opts.length; i++) {
          /*if (opts[i].value != self.member.MemberStatus)*/ {
              self.MemberStatusValues.push(opts[i]);
          }
      }
      self.CurrentMemberStatus = ko.observable(self.member.MemberStatus);
  
      self.ResetPassword = function () {
          if (self.IsPasswordReset()) {
              return;
          }
          $.ajax({
              url: appRoot + "MemberAdmin/ResetUserPassword",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ userId: data.data.ID }),
              success: function (content) {
                  if (!content.ok) {
                      alert(content.msg);
                      return;
                  }
                  alert('New password is: ' + content.newpwd);
                  self.IsPasswordReset(true);
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
              },
              complete: function () {
              }
          });
      };
  
      self.ChangeMemberStatus = function (data, event) {
          var selected = data.CurrentMemberStatus();
          if (selected) {
              if (selected == self.member.MemberStatus) {
                  return;
              }
              $.ajax({
                  url: appRoot + "MemberAdmin/ChangeMemberStatus",
                  type: "POST",
                  dataType: "json",
                  contentType: "application/json; charset=utf-8",
                  data: JSON.stringify({ uid: data.data.ID, status: selected }),
                  success: function (content) {
                      if (!content.ok) {
                          alert(content.msg);
                          return;
                      }
                      self.MemberStatusValues.removeAll();
                      if (content.ok) {
                          self.member.MemberStatus = selected;
                          self.CurrentMemberStatus(selected);
                      }
                      for (var i = 0; i < opts.length; i++) {
                          /*if (opts[i].value != self.member.MemberStatus)*/ {
                              self.MemberStatusValues.push(opts[i]);
                          }
                      }
                  },
                  error: function (jqxhr, textStatus) {
                      alert(jqxhr.responseText);
                  },
                  complete: function () {
                  }
              });
          } else {
              self.CurrentMemberStatus(self.member.MemberStatus);
          }
      };
  
      self.AddToRole = function (data, event, callback) {
          $.ajax({
              url: appRoot + "RoleAdmin/AddUserToRole",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ uid: self.data.ID, rid: data.id }),
              success: function (content) {
                  if (!content.ok) {
                      alert(content.msg);
                      if (callback) {
                          callback(false, null);
                      }
                  } else {
                      if (content.removed.length > 0) {
                          for (var i = 0; i < content.removed.length; i++) {
                              var cnt = self.roles().length;
                              for (var j = 0; j < cnt; j++) {
                                  if (self.roles()[j].data.id == content.removed[i].id) {
                                      var r = self.roles()[j];
                                      self.roles.remove(r);
                                      break;
                                  }
                              }
                              self.availableRoles.push(content.removed[i]);
                          }
                      }
                      self.roles.push(new Role(content.added));
                      var size = self.availableRoles().length;
                      for (var i = 0; i < size; i++) {
                          if (self.availableRoles()[i].id == content.added.id) {
                              var r = self.availableRoles()[i];
                              self.availableRoles.remove(r);
                              break;
                          }
                      }
                      if (callback) {
                          callback(true, content.added);
                      }
                  }
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
                  if (callback) {
                      callback(false, null);
                  }
              },
              complete: function () {
              }
          });
      }
  
      self.RemoveFromRole = function (data, event) {
          $.ajax({
              url: appRoot + "RoleAdmin/RemoveUserFromRole",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ uid: self.data.ID, rid: data.id }),
              success: function (content) {
                  if (!content.ok) {
                      alert(content.msg);
                  } else {
                      var size = self.roles().length;
                      for (var i = 0; i < size; i++) {
                          var r = self.roles()[i];
                          if (r.id == data.id) {
                              self.roles.remove(r);
                              break;
                          }
                      }
                      self.availableRoles.push(content.available);
                  }
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
              },
              complete: function () {
              }
          });
      };
  
      self.Initializing = false;
  }
  
  function UserPage() {
      var self = this;
      self.Index_ = ko.observable();
      self.PageNumber = ko.computed(function () {
          return self.Index_() + 1;
      });
      self.FirstItem = ko.observable({});
      self.LastItem = ko.observable({});
      self.CurrentItem = ko.observable(null);
      self.IsLastPage = ko.observable(false);
      self.IsDataLoaded = ko.observable(false);
      self.IsPageSelected = ko.observable(false);
      self.Items = ko.observableArray([]);
      self.PageLink = ko.computed(function () {
          return "javascript:loadpage(" + self.Index_() + ")";;
      });
  
      self.GetPageItems = function (s, callback) {
          if (self.IsDataLoaded())
              return;
          var qexpr = getQueryExpr();
          var lastItem = null;
          var ipage = self.Index_();
          if (self.Index_() > 0) {
              var blk = s.PageBlocks()[s.CurrBlockIndex()];
              if (blk.Pages()[0].Index_() != ipage) {
                  for (var i = 0; i < blk.Pages().length; i++) {
                      if (blk.Pages()[i].Index_() == ipage - 1) {
                          lastItem = blk.Pages()[i].LastItem();
                          break;
                      }
                  }
              } else {
                  var prvb = s.PageBlocks()[s.CurrBlockIndex() - 1];
                  lastItem = prvb.Pages()[prvb.Pages().length - 1].LastItem();
              }
          }
          $.ajax({
              url: appRoot + "MemberAdmin/GetManagedUsers",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ set: JSON.stringify({ set: setName, pageBlockSize: s.PageBlockSize(), pageSize: s.PageSize_(), setFilter: s.SetFilter, appName: appName }), qexpr: JSON.stringify(qexpr), prevlast: lastItem == null ? null : JSON.stringify(lastItem) }),
              beforeSend: function () {
                  self.Items.removeAll();
              },
              success: function (content) {
                  var items = JSON.parse(content);
                  for (var i = 0; i < items.length; i++)
                      self.Items.push(new User(items[i]));
                  self.IsDataLoaded(true);
                  callback(true);
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
                  callback(false);
              },
              complete: function () {
              }
          });
      }
  }
  
  // end: entity page
  
  // start: page block
  
  function UserPageBlock(idx0, data) {
      var self = this;
      self.BlockIndex = 0;
      self.IsLastBlock = ko.observable(data.IsLastBlock);
      self.BlockCount = data.BlockCount;
      self.Pages = ko.observableArray([]);
      if (data.Pages) {
          for (var i = 0; i < data.Pages.length; i++) {
              var pdata = data.Pages[i];
              var page = new UserPage();
              page.Index_(idx0 + pdata.Index_);
              page.FirstItem(pdata.FirstItem);
              page.LastItem(pdata.LastItem);
              page.IsLastPage(pdata.IsLastPage);
              self.Pages.push(page);
          }
      }
      self.LastPage = function () {
          return self.Pages().length == 0 ? null : self.Pages()[self.Pages().length - 1];
      };
  }
  
  // end: page block
  
  // start: truncated set view model
  
  // must be set 
  var appRoot = null;
  var serviceUrl = null;
  var loadingPage = false;
  var dataSourceId = null;
  var dbName = null;
  var setName = null;
  var adminMaxPriority = 0;
  
  function UserSet(dataServiceUrl) {
      var self = this;
      self.BaseUrl = dataServiceUrl;
      self.TotalEntities = ko.observable(0);
      self.EntityCount = ko.observable(0);
      self.PageCount = ko.observable(0);
      self.SetFilter = "";
      self.AvailableRoles = [];
      // query
      self.CurrentSorters = ko.observable(null);
      self.CurrentFilters = ko.observable(null);
      self.SortersStack = [];
      self.FiltersStack = [];
      self.SorterPath = ko.observableArray();
      self.FilterPath = ko.observableArray();
      self.IsQueryStateChanged = ko.observable(false);
      self.IsQueryInitialized = ko.observable(false);
      // page blocks
      self.PageSize_ = ko.observable(pageSize);
      self.PageSize_.subscribe(function (val) {
          self.IsQueryStateChanged(true);
      });
      //self.PageWindowSize = ko.observable(10);
      self.PageBlockSize = ko.observable(pageBlockSize);
      self.PageBlockSize.subscribe(function (val) {
          self.IsQueryStateChanged(true);
      });
      self.PageCount = ko.observable();
      self.PagesWindow = ko.observableArray([]);
      self.CurrentPage = ko.observable({});
      self.CurrentSelectedUser = ko.observable(null);
  
      self.PageBlocks = ko.observableArray([]);
      self.CurrBlockIndex = ko.observable(0);
      self.CurrentBlock = ko.computed(function () {
          if (self.CurrBlockIndex() < 0 || self.CurrBlockIndex() >= self.PageBlocks().length - 1)
              return null;
          else
              return self.PageBlocks()[self.CurrBlockIndex()];
      });
      self.PrevBlock = ko.computed(function () {
          var idx = self.CurrBlockIndex();
          if (idx > 0) {
              return self.PageBlocks()[idx - 1];
          } else {
              return null;
          }
      });
      self.NextLoadedBlock = ko.computed(function () {
          var idx = self.CurrBlockIndex();
          if (idx >= 0 && idx < self.PageBlocks().length - 1) {
              return self.PageBlocks()[idx + 1];
          } else {
              return null;
          }
      });
      self.MoreNextBlock = ko.computed(function () {
          var idx = self.CurrBlockIndex();
          if (idx >= 0 && idx < self.PageBlocks().length - 1) {
              return true;
          } else {
              return self.PageBlocks().length > 0 && !self.PageBlocks()[self.PageBlocks().length - 1].IsLastBlock();
          }
      });
      self.LastPageBlock = ko.computed(function () {
          return self.PageBlocks().length == 0 ? null : self.PageBlocks()[self.PageBlocks().length - 1];
      });
  
      self.ResetPageState = function () {
          self.CurrBlockIndex(0);
          self.PageBlocks.removeAll();
          self.IsQueryStateChanged(false)
      };
  
      self.GetSetInfo = function () {
          $.ajax({
              url: appRoot + "MemberAdmin/GetSetInfo",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ set: JSON.stringify({ set: setName, setFilter: self.SetFilter, appName: appName }) }),
              beforeSend: function () {
              },
              success: function (content) {
                  var r = JSON.parse(content);
                  self.TotalEntities(r.EntityCount);
                  self.CurrentSorters(new TokenOptions());
                  for (var i = 0; i < r.Sorters.length; i++) {
                      var tk = r.Sorters[i];
                      if (typeof tokenNameMap != 'undefined') {
                          if (tokenNameMap(tk, setName, false)) {
                              self.CurrentSorters().Options.push(tk);
                          }
                      } else {
                          self.CurrentSorters().Options.push(tk);
                      }
                  }
                  self.CurrentSorters().CanBeClosed = true;
                  self.CurrentSorters().isLocal = false;
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
              },
              complete: function () {
              }
          });
      };
  
      self.GetNextSorterOps = function (callback) {
          var qtokens = [];
          for (var i = 0; i < self.SorterPath().length; i++)
              qtokens.push(self.SorterPath()[i]);
          $.ajax({
              url: self.BaseUrl + "/GetNextSorterOps",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ sourceId: dataSourceId, set: setName, sorters: JSON.stringify(qtokens) }),
              beforeSend: function () {
              },
              success: function (content) {
                  self.SortersStack.push(self.CurrentSorters());
                  self.CurrentSorters(new TokenOptions());
                  var r = JSON.parse(content.GetNextSorterOpsResult);
                  self.CurrentSorters().Hint = r.Hint;
                  self.CurrentSorters().CurrentExpr(r.CurrentExpr);
                  self.CurrentSorters().QuoteVal = r.QuoteVal;
                  self.CurrentSorters().CanBeClosed = r.CanBeClosed;
                  self.CurrentSorters().IsLocal = false;
                  for (var i = 0; i < r.Options.length; i++) {
                      var tk = new QToken();
                      tk.CopyToken(r.Options[i]);
                      if (typeof tokenNameMap != 'undefined') {
                          if (tokenNameMap(tk, setName, false)) {
                              self.CurrentSorters().Options.push(tk);
                          }
                      } else {
                          self.CurrentSorters().Options.push(tk);
                      }
                  }
                  callback(true);
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
                  callback(false);
              },
              complete: function () {
              }
          });
      };
  
      self.FilterClosed = ko.observable(false);
  
      self.GetNextFilterOps = function (callback) {
          var qexpr = getQueryExpr();
          $.ajax({
              url: self.BaseUrl + "/GetNextFilterOps",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ sourceId: dataSourceId, set: setName, qexpr: JSON.stringify(qexpr) }),
              beforeSend: function () {
              },
              success: function (content) {
                  if (self.CurrentFilters() != null)
                      self.FiltersStack.push(self.CurrentFilters());
                  var r = JSON.parse(content.GetNextFilterOpsResult);
                  self.FilterClosed(r.CanBeClosed);
                  self.CurrentFilters(new TokenOptions());
                  self.CurrentFilters().Hint = r.Hint;
                  self.CurrentFilters().CurrentExpr(r.CurrentExpr);
                  self.CurrentFilters().QuoteVal = r.QuoteVal;
                  self.CurrentFilters().CanBeClosed = r.CanBeClosed;
                  self.CurrentFilters().IsLocal = false;
                  for (var i = 0; i < r.Options.length; i++) {
                      var tk = new QToken();
                      tk.CopyToken(r.Options[i]);
                      if (typeof tokenNameMap != 'undefined') {
                          if (tokenNameMap(tk, setName, true)) {
                              self.CurrentFilters().Options.push(tk);
                          }
                      } else {
                          self.CurrentFilters().Options.push(tk);
                      }
                  }
                  callback(true);
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
                  callback(false);
              },
              complete: function () {
              }
          });
      };
  
      self.NextPageBlock = function (qexpr, last, callback) {
          if (self.IsQueryStateChanged())
              self.ResetPageState();
          if (self.CurrBlockIndex() < self.PageBlocks().length) {
              callback(true, false);
              return;
          }
          $.ajax({
              url: self.BaseUrl + "/NextPageBlock",
              type: "POST",
              dataType: "json",
              contentType: "application/json; charset=utf-8",
              data: JSON.stringify({ sourceId: dataSourceId, set: JSON.stringify({ set: setName, pageBlockSize: self.PageBlockSize(), pageSize: self.PageSize_(), setFilter: self.SetFilter }), qexpr: JSON.stringify(qexpr), prevlast: last == null ? null : JSON.stringify(last) }),
              beforeSend: function () {
              },
              success: function (content) {
                  var data = JSON.parse(content.NextPageBlockResult);
                  self.EntityCount(data.TotalEntities);
                  self.PageCount(data.TotalPages);
                  if (data.Pages.length == 0) {
                      var lpb = self.LastPageBlock();
                      if (lpb != null) {
                          lpb.IsLastBlock(true);
                          var lp = lpb.LastPage();
                          if (lp != null) {
                              lp.IsLastPage(true);
                              self.CurrBlockIndex(self.CurrBlockIndex() - 1);
                          }
                      } else {
                          self.PagesWindow.removeAll();
                      }
                  }
                  else {
                      var idx0 = 0;
                      for (var i = 0; i < self.CurrBlockIndex() ; i++) {
                          idx0 += self.PageBlocks()[i].BlockCount;
                      }
                      var pb = new UserPageBlock(idx0, data);
                      pb.BlockIndex = self.PageBlocks().length;
                      self.PageBlocks.push(pb);
                      self.PagesWindow.removeAll();
                      for (var i = 0; i < pb.Pages().length; i++) {
                          self.PagesWindow.push(pb.Pages()[i]);
                      }
                  }
                  self.IsQueryStateChanged(false);
                  callback(true, true);
              },
              error: function (jqxhr, textStatus) {
                  alert(jqxhr.responseText);
                  callback(false, false);
              },
              complete: function () {
              }
          });
      };
  }
  
  function tokenSortCmp(a, b) {
      if (a.SortOrder == b.SortOrder) {
          if (a.DisplayAs > b.DisplayAs)
              return 1;
          else if (a.DisplayAs < b.DisplayAs)
              return -1;
          else
              return 0;
      } else {
          return b.SortOrder - a.SortOrder;
      }
  }
  
  function tokenFilterCmp(a, b) {
      if (a.FilterOrder == b.FilterOrder) {
          if (a.DisplayAs > b.DisplayAs)
              return 1;
          else if (a.DisplayAs < b.DisplayAs)
              return -1;
          else
              return 0;
      } else {
          return b.FilterOrder - a.FilterOrder;
      }
  }
  
  function initsortinput(s) {
      if (loadingPage) {
          return;
      }
      var bobj = $("#queryExec");
      enableQuery(false);
      $("#filterOpts").hide();
      var iobj = $("#sortOpts");
      var deleting = false;
      iobj.removeAttr("disabled");
      iobj.css("cursor", "");
      iobj.keydown(function (event) {
          deleting = event.which == 8;
          if (event.which == 13) {
              event.preventDefault();
          }
          else if (event.which == 8 && s.SorterPath().length > 0 && this.value == "") {
              s.SorterPath.pop();
              s.CurrentSorters(s.SortersStack.pop());
              $(this).autocomplete("close");
              var tk = s.SorterPath().length > 0 ? s.SorterPath()[s.SorterPath().length - 1] : null;
              if (tk == null || tk.TkName != "asc" && tk.TkName != "desc") {
                  enableQuery(false);
                  $("#filterOpts").hide();
              } else {
                  enableQuery(true);
                  $("#filterOpts").show();
              }
          }
      });
      iobj.autocomplete({
          minLength: 0,
          delay: 0,
          autoFocus: true,
          source: function (request, response) {
              if (!s.CurrentSorters() || !s.CurrentSorters().Options)
                  return;
              var opts = s.CurrentSorters().Options;
              var arr = opts.filter(function (val) {
                  return val.DisplayAs.toLowerCase().indexOf(request.term.toLowerCase()) == 0;
              }).sort(tokenSortCmp);
              if (arr.length != 1 || deleting) {
                  response($.map(arr, function (item) {
                      return { label: item.DisplayAs == "this" ? item.TkName : item.DisplayAs, value: item.DisplayAs };
                  }));
                  if (arr.length > 1 && !deleting) {
                      //iobj.val(arr[0].DisplayAs);
                  }
              } else {
                  iobj.autocomplete("close");
                  var tk = arr[0];
                  s.SorterPath.push(tk);
                  iobj.val("");
                  iobj.attr("disabled", "disabled");
                  iobj.css("cursor", "progress");
                  if (tk == null || tk.TkName != "asc" && tk.TkName != "desc") {
                      enableQuery(false);
                      $("#filterOpts").hide();
                  } else {
                      enableQuery(true);
                      $("#filterOpts").show();
                      s.IsQueryStateChanged(true);
                  }
                  s.GetNextSorterOps(function (ok) {
                      if (ok) {
                          iobj.removeAttr("disabled");
                          if (s.CurrentSorters().Options.length == 2 && s.CurrentSorters().Options[0].IsExternal) {
                              s.CurrentSorters().Options[0].ImgSrc = "glyphicon glyphicon-chevron-up"; //appRoot + 'Images/control_up.png';
                              s.CurrentSorters().Options[1].ImgSrc = "glyphicon glyphicon-chevron-down"; //appRoot + 'Images/control_down.png';
                          }
                          if (s.CurrentSorters().CanBeClosed && s.CurrentSorters().CurrentExpr() != null && s.CurrentSorters().CurrentExpr() != "") {
                              $('.sortlabel').qtip({
                                  overwrite: true,
                                  content: s.CurrentSorters().CurrentExpr(),
                                  position: {
                                      my: 'left bottom',
                                      at: 'top left',
                                      target: $('.sortlabel')
                                  },
                                  show: {
                                      event: 'mouseover',
                                      ready: false,
                                      solo: true
                                  },
                                  hide: 'mouseout'
                              });
                          }
                      }
                      iobj.focus();
                      iobj.css("cursor", "");
                  });
                  return false;
              }
          },
          select: function (event, ui) {
              var tk = null;
              var opts = s.CurrentSorters().Options;
              for (var i = 0; i < opts.length; i++) {
                  if (opts[i].DisplayAs == ui.item.value) {
                      tk = opts[i];
                      break;
                  }
              }
              if (tk != null) {
                  s.SorterPath.push(tk);
                  iobj.val("");
                  iobj.attr("disabled", "disabled");
                  iobj.css("cursor", "progress");
                  if (tk == null || tk.TkName != "asc" && tk.TkName != "desc") {
                      enableQuery(false);
                      $("#filterOpts").hide();
                  } else {
                      enableQuery(true);
                      $("#filterOpts").show();
                      s.IsQueryStateChanged(true);
                  }
                  s.GetNextSorterOps(function (ok) {
                      if (ok) {
                          iobj.removeAttr("disabled");
                          if (s.CurrentSorters().Options.length == 2 && s.CurrentSorters().Options[0].IsExternal) {
                              s.CurrentSorters().Options[0].ImgSrc = "glyphicon glyphicon-chevron-up"; //appRoot + 'Images/control_up.png';
                              s.CurrentSorters().Options[1].ImgSrc = "glyphicon glyphicon-chevron-down"; //appRoot + 'Images/control_down.png';
                          }
                          if (s.CurrentSorters().CanBeClosed && s.CurrentSorters().CurrentExpr() != null && s.CurrentSorters().CurrentExpr() != "") {
                              $('.sortlabel').qtip({
                                  overwrite: true,
                                  content: s.CurrentSorters().CurrentExpr(),
                                  position: {
                                      my: 'left bottom',
                                      at: 'top left',
                                      target: $('.sortlabel')
                                  },
                                  show: {
                                      event: 'mouseover',
                                      ready: false,
                                      solo: true
                                  },
                                  hide: 'mouseout'
                              });
                          }
                      }
                      iobj.focus();
                      iobj.css("cursor", "");
                  });
                  return false;
              }
          }
      });
  }
  
  function initfilterinput(s) {
      if (loadingPage) {
          return;
      }
      var bobj = $("#queryExec");
      enableQuery(false);
      var iobj = $("#filterOpts");
      var deleting = false;
      iobj.showingHint = false;
      iobj.removeAttr("disabled");
      iobj.css("cursor", "");
      iobj.keydown(function (event) {
          deleting = event.which == 8;
          if (event.which == 13) {
              event.preventDefault();
              if (this.value != "" && s.CurrentFilters().Options.length == 0) {
                  var tk;
                  if (s.CurrentFilters().QuoteVal) {
                      var strv = "";
                      var scnt = 0;
                      for (var i = 0; i < this.value.length; i++) {
                          var c = this.value[i];
                          if (c == '"') {
                              for (j = 0; j < scnt; j++)
                                  strv += '\\';
                              if (scnt % 2 == 0)
                                  strv += '\\';
                              strv += c;
                              scnt = 0;
                          } else if (c == '\\') {
                              scnt++;
                          } else {
                              for (j = 0; j < scnt; j++)
                                  strv += '\\';
                              if (scnt % 2 != 0)
                                  strv += '\\';
                              strv += c;
                              scnt = 0;
                          }
                      }
                      tk = new QToken('"' + strv + '"');
                      tk.TkClass = "filternode StringValue";
                  } else {
                      tk = new QToken(this.value);
                      tk.TkClass = "filternode Value";
                  }
                  if (iobj.showingHint) {
                      $(iobj).qtip('toggle', false);
                      iobj.showingHint = false;
                  }
                  s.FilterPath.push(tk);
                  iobj.val("");
                  iobj.attr("disabled", "disabled");
                  iobj.css("cursor", "progress");
                  s.GetNextFilterOps(function (ok) {
                      if (ok) {
                          iobj.removeAttr("disabled");
                          var closed = s.CurrentFilters().CanBeClosed;
                          enableQuery(closed);
                          if (closed)
                              s.IsQueryStateChanged(true);
                          if (s.CurrentFilters().CanBeClosed && s.CurrentFilters().CurrentExpr() != null && s.CurrentFilters().CurrentExpr() != "") {
                              $('.filterlabel').qtip({
                                  overwrite: true,
                                  content: s.CurrentFilters().CurrentExpr(),
                                  position: {
                                      my: 'left top',
                                      at: 'bottom right',
                                      target: $('.filterlabel')
                                  },
                                  show: {
                                      event: 'mouseover',
                                      ready: false,
                                      solo: true
                                  },
                                  hide: 'mouseout'
                              });
                          }
                      }
                      iobj.focus();
                      iobj.css("cursor", "");
                  });
                  return false;
              }
          }
          else if (event.which == 8 && s.FilterPath().length > 0 && this.value == "") {
              s.FilterPath.pop();
              s.CurrentFilters(s.FiltersStack.pop());
              var closed = s.CurrentFilters().CanBeClosed;
              s.FilterClosed(closed);
              enableQuery(closed);
              if (closed)
                  s.IsQueryStateChanged(true);
          } else {
              if (s.CurrentFilters().Hint != null && s.CurrentFilters().Hint != "") {
                  if (!iobj.showingHint) {
                      $(iobj).qtip({
                          overwrite: true,
                          content: s.CurrentFilters().Hint,
                          position: {
                              my: 'left bottom',
                              at: 'top left',
                              target: $(iobj)
                          },
                          show: {
                              event: "none",
                              ready: true,
                              solo: true
                          },
                          hide: "unfocus",
                          events: {
                              show: function () {
                                  iobj.showingHint = true;
                              },
                              hide: function () {
                                  iobj.showingHint = false;
                              }
                          }
                      });
                      $(iobj).qtip('toggle', true);
                      iobj.showingHint = true;
                  }
              }
              else {
                  if (iobj.showingHint) {
                      $(iobj).qtip('toggle', false);
                      iobj.showingHint = false;
                  }
              }
          }
      });
      iobj.focus(function (event) {
          if (s.CurrentFilters() == null) {
              iobj.attr("disabled", "disabled");
              iobj.css("cursor", "progress");
              s.GetNextFilterOps(function (ok) {
                  if (ok) {
                      iobj.removeAttr("disabled");
                      iobj.focus();
                  }
                  iobj.css("cursor", "");
              });
          }
      });
      iobj.autocomplete({
          minLength: 0,
          delay: 0,
          autoFocus: true,
          source: function (request, response) {
              var opts = s.CurrentFilters().Options;
              var arr = opts.filter(function (val) {
                  return val.DisplayAs.toLowerCase().indexOf(request.term.toLowerCase()) == 0;
              }).sort(tokenFilterCmp);
              if (arr.length != 1 || deleting) {
                  response($.map(arr, function (item) {
                      return { label: item.DisplayAs, value: item.DisplayAs };
                  }));
              } else {
                  iobj.autocomplete("close");
                  var tk = arr[0];
                  s.FilterPath.push(tk);
                  iobj.val("");
                  iobj.attr("disabled", "disabled");
                  iobj.css("cursor", "progress");
                  s.GetNextFilterOps(function (ok) {
                      if (ok) {
                          iobj.removeAttr("disabled");
                          var closed = s.CurrentFilters().CanBeClosed;
                          enableQuery(closed);
                          if (closed)
                              s.IsQueryStateChanged(true);
                          if (s.CurrentFilters().CanBeClosed && s.CurrentFilters().CurrentExpr() != null && s.CurrentFilters().CurrentExpr() != "") {
                              $('.filterlabel').qtip({
                                  overwrite: true,
                                  content: s.CurrentFilters().CurrentExpr(),
                                  position: {
                                      my: 'left bottom',
                                      at: 'top left',
                                      target: $('.filterlabel')
                                  },
                                  show: {
                                      event: 'mouseover',
                                      ready: false,
                                      solo: true
                                  },
                                  hide: 'mouseout'
                              });
                          }
                      }
                      iobj.focus();
                      iobj.css("cursor", "");
                  });
                  return false;
              }
          },
          select: function (event, ui) {
              var tk = null;
              var opts = s.CurrentFilters().Options;
              for (var i = 0; i < opts.length; i++) {
                  if (opts[i].DisplayAs == ui.item.value) {
                      tk = opts[i];
                      break;
                  }
              }
              if (tk != null) {
                  s.FilterPath.push(tk);
                  iobj.val("");
                  iobj.attr("disabled", "disabled");
                  iobj.css("cursor", "progress");
                  s.GetNextFilterOps(function (ok) {
                      if (ok) {
                          iobj.removeAttr("disabled");
                          var closed = s.CurrentFilters().CanBeClosed;
                          enableQuery(closed);
                          if (closed)
                              s.IsQueryStateChanged(true);
                          if (s.CurrentFilters().CanBeClosed && s.CurrentFilters().CurrentExpr() != null && s.CurrentFilters().CurrentExpr() != "") {
                              $('.filterlabel').qtip({
                                  overwrite: true,
                                  content: s.CurrentFilters().CurrentExpr(),
                                  position: {
                                      my: 'left bottom',
                                      at: 'top left',
                                      target: $('.filterlabel')
                                  },
                                  show: {
                                      event: 'mouseover',
                                      ready: false,
                                      solo: true
                                  },
                                  hide: 'mouseout'
                              });
                          }
                      }
                      iobj.focus();
                      iobj.css("cursor", "");
                  });
                  return false;
              }
          }
      });
  }
  
  function getQueryExpr() {
      var sorters = [];
      var filters = [];
      for (var i = 0; i < userSet.SorterPath().length; i++)
          sorters.push(userSet.SorterPath()[i]);
      for (var i = 0; i < userSet.FilterPath().length; i++)
          filters.push(userSet.FilterPath()[i]);
      return new QueryExpresion(sorters, filters);
  }
  
  function _setWait(on) {
      if (on) {
          $(".content-wrapper").css({ "background-color": "rgba(230,230,230,100)" });
          $("html").addClass("waiting");
      } else {
          $(".content-wrapper").css({ "background-color": "rgba(255,255,255,0)" });
          $("html").removeClass("waiting");
      }
  }
  
  function setWait(on) {
      _setWait(on);
      enableQuery(!on);
  }
  
  var queryCompleted = false;
  
  function enableQuery(enable) {
      queryCompleted = enable;
      if (enable) {
          $("#queryExec").removeClass("disabled");
      } else {
          $("#queryExec").addClass("disabled");
      }
  }
  
  function showlist(e) {
      if (!queryCompleted)
          return;
      var qexpr = getQueryExpr();
      if (userSet.IsQueryStateChanged()) {
          userSet.ResetPageState();
      }
      userSet.NextPageBlock(qexpr, null, function (ok, ch) {
          if (ch && userSet.CurrentPage() != null && !(typeof userSet.CurrentPage().Items === 'undefined')) {
              userSet.CurrentPage().Items.removeAll();
          }
          if (ok) {
              userSet.IsQueryInitialized(true);
              if (ch && userSet.PageBlocks().length > 0 && userSet.PageBlocks()[0].Pages().length > 0) {
                  loadpage(0);
              }
          } else {
  
          }
      });
  }
  
  function prevPageBlock() {
      if (loadingPage) {
          return;
      }
      var idx = userSet.CurrBlockIndex();
      if (idx > 0) {
          userSet.CurrBlockIndex(idx - 1);
          userSet.PagesWindow.removeAll();
          var ipage = -1;
          for (var i = 0; i < userSet.PageBlocks()[idx - 1].Pages().length; i++) {
              var p = userSet.PageBlocks()[idx - 1].Pages()[i];
              userSet.PagesWindow.push(p);
              if (p.IsPageSelected()) {
                  ipage = p.Index_();
              }
          }
          loadpage(ipage == -1 ? 0 : ipage);
      }
  }
  
  function nextPageBlock() {
      if (loadingPage) {
          return;
      }
      var idx = userSet.CurrBlockIndex();
      if (idx < userSet.PageBlocks().length - 1) {
          userSet.CurrBlockIndex(idx + 1);
          userSet.PagesWindow.removeAll();
          var ipage = -1;
          for (var i = 0; i < userSet.PageBlocks()[idx + 1].Pages().length; i++) {
              var p = userSet.PageBlocks()[idx + 1].Pages()[i];
              userSet.PagesWindow.push(p);
              if (p.IsPageSelected()) {
                  ipage = p.Index_();
              }
          }
          loadpage(ipage == -1 ? 0 : ipage);
      } else {
          idx = userSet.PageBlocks().length - 1;
          var b = userSet.PageBlocks()[idx];
          if (!b.IsLastBlock()) {
              userSet.CurrBlockIndex(idx + 1);
              var p = b.LastPage();
              if (p == null) {
                  return;
              }
              var qexpr = getQueryExpr();
              userSet.NextPageBlock(qexpr, p.LastItem(), function (ok, ch) {
                  if (ok) {
                      if (userSet.PageBlocks().length > 0 && userSet.PageBlocks()[idx + 1].Pages().length > 0) {
                          loadpage(userSet.PageBlocks()[idx + 1].Pages()[0].Index_());
                      }
                  }
              });
          }
      }
  }
  
  function loadpage(index) {
      if (loadingPage) {
          return;
      }
      loadingPage = true;
      var p = null;
      var p0 = null;
      var blk = userSet.PageBlocks()[userSet.CurrBlockIndex()];
      for (var i = 0; i < blk.Pages().length; i++) {
          var _p = blk.Pages()[i];
          if (_p.Index_() == index) {
              p = _p;
          } else if (_p.IsPageSelected()) {
              p0 = _p;
          }
      }
      setWait(true)
      if (p != null) {
          if (!p.IsDataLoaded()) {
              p.GetPageItems(userSet, function (ok) {
                  if (ok) {
                      updateCurrPage(p, p0);
                      for (var i = 0; i < p.Items().length; i++) {
                          //
                          //p.Items()[i].TobeLoadMsg(serverMessage1);
                      }
                  } else {
  
                  }
                  loadingPage = false;
                  setWait(false)
              });
          } else {
              updateCurrPage(p, p0);
              loadingPage = false;
              setWait(false)
          }
      } else {
          loadingPage = false;
          setWait(false)
      }
  }
  
  function updateCurrPage(p, p0) {
      userSet.CurrentPage(p);
      p.IsPageSelected(true);
      if (p0 != null) {
          p0.IsPageSelected(false);
      }
  }
  
  
  function EditUser(data, event) {
      $('#' + data.op_id).modal('show');
  }
  
  function ShowUser(data, event) {
      $('#' + data.view_id).modal('show');
  }
  
  //function EditUserDone(data, event) {
  //    $('#' + data.data.ID).foundation('reveal', 'close');
  //}
  
  function selectUser(data, event) {
      userSet.CurrentSelectedUser(data);
  }
  
  var userSet = null;
  var appName = '';
  var pageBlockSize = '10';
  var pageSize = '10';
  
  // end set view model
  
  