Your IP : 18.219.40.177


Current Path : /usr/local/mgr5/skins/orion/src/
Upload File :
Current File : //usr/local/mgr5/skins/orion/src/App.List.js

/**
 * App.List
 * manipulation with list
 * @param {object} window global object
 * @param {object|function} $ jQuery
 * @param {object} EventMgr Event manager
 * @param {object} App Application
 * */
App.List = function(window, $, EventMgr, App) {
  'use strict';
  var init = function() {
    EventMgr.bind('clickedGroupItem', fillActiveRows);
    EventMgr.bind('listMultiSelect, mapMultiSelect', activateToolbarGroup);
    EventMgr.bind('listSelect, mapSelect', activateTollbarAll);
    EventMgr.bind('listUnSelect, mapUnSelect', deactivateToolbarAll);
    EventMgr.bind('switchTab', changeActTabId);
    EventMgr.bind('listMultiSelect,listSelect,listLiveFound,listUnSelect',
        statusBarHandler);
    EventMgr.on('#content', '.content .list_table tbody tr',
        'click', rowSelect);
    EventMgr.on('#content', $tableTd(), 'mousedown', preventSelectTd);
    EventMgr.bind('hideToolBtn', toolBtnHide);
    EventMgr.bind('showToolBtn', toolBtnShow);
    EventMgr.bind('appendList', forceRowSelect);
    EventMgr.bind('appendList', bindMoveBtn);
    EventMgr.bind('updatedTableHeight', forceScrollTo);
    EventMgr.bind('comboCtrlShiftAKeyUp', selectAllRow);
    EventMgr.on(mainWrapperSel, selectAllSelector,
        'click', selectAllRow);
    EventMgr.bind('comboCtrlShiftFKeyUp', focusOnSearch);
    EventMgr.bind('updateSelected', toolbarHandlerFuncWrapper);
    EventMgr.on(mainWrapperSel, tableRowSelector, 'touchstart',
        swipeDetectorTouchStart);
    EventMgr.bind('updateTotalList', updateStatusBarTotal);
    EventMgr.bind('updateTotalWithConvert', updateTotalWithConvert);
    EventMgr.bind('upKeyUp', arrowKeyUpHandler);
    EventMgr.bind('downKeyUp', arrowKeyDownHandler);
  },

      pageInfo = window.pageInfo,
      //current tabId (like cont-tab1)!!!
      tabId = '',

      mainWrapperSel = '#main-wrapper',

      tableRowSelector = '.list_table tr',

      selectAllSelector = 'a.select-all',
      /**
       * toolbar rows
       * @param {String} tabIdParam TabId of tab
       * @return {object} jQuery wrap nodes
       */
      $tableRow = function(tabIdParam) {
        var tabId = '';
        if (tabIdParam) {
          tabId = '#' + tabIdParam + ' ';
        }
        return $(tabId + '.content .list_table tbody tr');
      },
      //grouping actions
      $toolbarBtnGroup = function() {
        return $('#' + tabId + ' .toolbar-button__item-img.tb-group')
            .parent();
      },
      //not grouping actions for action
      $toolBarBtnNotGroup = function() {
        return $('#' + tabId + ' .toolbar-button__item-img.tb-not-group')
            .parent();
      },

      $toolBarBtnNoSelEdit = function() {
        return $('#' + tabId + ' .toolbar-button__item-img.tb-nosel')
            .parent();
      },

      $tableTd = function() {
        return 'table td';
      },
      //all toolbar btns
      $toolbarBtnAll = function() {
        return $('#' + tabId + ' .toolbar-button');
      },
      //prevent selected td in ff
      preventSelectTd = function(e) {
        if (e.ctrlKey || e.metaKey || e.shiftKey) {
          e.preventDefault();
        }
      },

      focusOnSearch = function() {
        $('.tab-content_st_active .itsearch').focus();
      },

      changeActTabId = function(e, data) {
        tabId = 'cont-' + data.tabId;
      },

      bindMoveBtn = function(e, data) {
        var curTabId = data.tabId;
        setTimeout(function() {
          EventMgr.trigger('bindHorizScrollControl', {
            leftBtn: '#cont-' + curTabId + ' .toolbar__btn-move_dir_left',
            rightBtn: '#cont-' + curTabId + ' .toolbar__btn-move_dir_right',
            innerBox: '#cont-' + curTabId + ' .toolbar__inner',
            id: curTabId,
            step: 50
          });
        }, 50);
      },

      selectAllRow = function(e) {
        var rows = $('.tab-content_st_active .list_table tbody tr'),
            sRows = $('.tab-content_st_active .list_table tbody tr.selected:not(".filtred")'),
            len = rows.length,
            sLen = sRows.length,
            firstRow;
        e = e || {};
        if (len > 0) {
          firstRow = rows[0];
          if (rows[0].className.match('back-btn')) {
            firstRow = rows[1];
            sLen += 1;
          }
          if (sLen === len) {
            rowSelect.apply(firstRow, [e]);
            rowSelect.apply(firstRow, [e, true]);
          } else {
            rows.removeClass('last-selected');
            rows.removeClass('first-selected');
            $(rows[len - 1]).addClass('last-selected');
            e.shiftKey = true;
            rowSelect.apply(firstRow, [e]);
          }
        }
        if (e.preventDefault) {
          e.preventDefault();
        }
      },

      scrollToSelectRow = function(row, isNextRow, tabId) {
        var MAGIC_NUMBER = 22,
            offsetTop = row ? row.offsetTop : 0,
            scrollId = 'ltwr-' + tabId,
            boxHeight;
        if (offsetTop) {
          offsetTop = isNextRow ? offsetTop + MAGIC_NUMBER : offsetTop - MAGIC_NUMBER
          boxHeight = parseInt($('#ltwr-' + tabId).css('height'), 10);
          ScrollHandler.forceMoveSelectItem(scrollId, offsetTop, boxHeight, 22);
        }
      },

      selectFirstRow = function() {
        var rows = $('.tab-content_st_active .list_table tbody tr'),
            firstRow = rows[0];
        if (firstRow && firstRow.className) {
          if (firstRow.className.match('back-btn')) {
            firstRow = rows[1];
          }
          rowSelect.apply(firstRow, [{}]);
        }
      },

      arrowKeyUpHandler = function(e, d) {
        if (window.document.activeElement && window.document.activeElement.getAttribute('type')) {
          return;
        }
        var actTab = $('.tab-content_st_active'),
            type = actTab.attr('data-tab-type');
        if (type === 'list') {
          var $sRows = $('.tab-content_st_active .list_table tbody tr.selected:not(".filtred")'),
              $prevRow;
          if ($sRows.first().hasClass('first-selected')) {
            $prevRow = $sRows.last().prev();
          } else {
            $prevRow = $sRows.prev();
          }
          if ($prevRow.length) {
            rowSelect.apply($prevRow[0], [d]);
            scrollToSelectRow($prevRow[0], false, actTab.attr('data-tabid'));
          } else if (!$sRows.length) {
            selectFirstRow();
          }
        }
      },

      arrowKeyDownHandler = function(e, d) {
        if (window.document.activeElement && window.document.activeElement.getAttribute('type')) {
          return;
        }
        var actTab = $('.tab-content_st_active'),
            type = actTab.attr('data-tab-type');
        if (type === 'list') {
          var $sRows = $('.tab-content_st_active .list_table tbody tr.selected:not(".filtred")'),
              $nextRow;
          if ($sRows.first().hasClass('first-selected')) {
            $nextRow = $sRows.last().next();
          } else {
            $nextRow = $sRows.next();
          }
          if ($nextRow.length) {
            rowSelect.apply($nextRow[0], [d]);
            scrollToSelectRow($nextRow[0], true, actTab.attr('data-tabid'));
          } else if (!$sRows.length) {
            selectFirstRow();
          }
        }
      },

      //handler of selecting rows
      rowSelect = function(e, fakeCtrl) {
        var self = $(this),
            tabIdOrg = self.parents('.tab-content').attr('data-tabid'),
            tableRows, i, k, elem, lastId, firstId, curId,
            lastIdElem, smthg;
            e = e || window.event;

        tabId = 'cont-' + tabIdOrg;
        if (tabIdOrg === 'tab0') {
          tabId = self.parents('.block-table').attr('id');
        }
        tableRows = $tableRow(tabId);

        //not select if nothing do with
        if (!self.attr('data-elid')) {
          if (!e.ctrlKey && !e.metaKey && !e.shiftKey && !fakeCtrl) {
            tableRows.removeClass('selected')
              .removeClass('last-selected')
              .removeClass('first-selected');
          }
          return;
        }
        //check for link in changelog
        if (e.target && e.target.nodeName === 'A') {
          return true;
        }

        if (!e.ctrlKey && !e.metaKey && !e.shiftKey && !fakeCtrl) {
          tableRows.removeClass('selected')
              .removeClass('last-selected')
              .removeClass('first-selected');
          self.addClass('selected').addClass('last-selected');
          //with SHIFT KEY
        } else if (e.shiftKey) {
          tableRows.removeClass('selected');
          lastIdElem = $('#lt-' + tabIdOrg + ' tr.last-selected');
          lastId = lastIdElem.attr('id');
          firstId = $('#lt-' + tabIdOrg + ' tr.first-selected').attr('id');
          if (!firstId) {
            firstId = lastId;
            lastIdElem.addClass('first-selected');
          }
          curId = self.attr('id');
          if (firstId === undefined) { return; }
          firstId = parseInt(firstId.replace('i-', ''), 10);
          curId = parseInt(curId.replace('i-', ''), 10);
          //go down
          i = 0;
          k = 0;
          if (firstId > curId) {
            i = curId;
            k = firstId;
            //go up
          } else {
            i = firstId;
            k = curId;
          }

          for (i; i <= k; i++) {
            elem = $('tr#i-' + i);
            if (elem.attr('data-elid')) {
              elem.addClass('selected');
            }
          }

          tableRows.removeClass('last-selected');
          self.addClass('last-selected');
          // Remove text selection
          if (document.selection) {
            if (document.selection.type.toLowerCase() !== 'none') {
              document.selection.empty();
            }
          }
          else if (window.getSelection) {
            smthg = window.getSelection(); try {
              smthg.collapseToStart(); } catch (ex) {}
          }
          //with CTRL KEY
        } else {
          //multiselect
          tableRows.removeClass('last-selected').removeClass('first-selected');
          self.toggleClass('selected').addClass('last-selected');
          if (document.selection) {
            if (document.selection.type.toLowerCase() !== 'none') {
              document.selection.empty();}
          }
          else if (window.getSelection) {
            smthg = window.getSelection();
            try { smthg.collapseToStart(); } catch (ex) {}
          }
        }

        toolbarHandler(tabId);
        if (e.preventDefault) {
          e.preventDefault();
        }
      },

      toolbarHandlerFuncWrapper = function(e, data) {
        if (data.tabId) {
          toolbarHandler('cont-' + data.tabId);
        }
      },
      /**
       * Toolbar handlers when selecting elements
       * @param {String} tabId
       */
      toolbarHandler = function(tabId) {
        var len, toolBtnShow, toolBtnHide, toolBtnsRemove,
            $selectedRows = $('#' + tabId + ' tr.selected:not(".filtred")');
        len = $selectedRows.length;
        //trigger events
        if (len === 0) {
          EventMgr.trigger('listUnSelect', {
            tabId: tabId,
            len: len,
            selectedRows: $selectedRows });
        } else if (len > 1) {
          EventMgr.trigger('listMultiSelect', {
            tabId: tabId,
            len: len,
            selectedRows: $selectedRows });
        } else {
          EventMgr.trigger('listSelect', {
            tabId: tabId,
            len: len,
            selectedRows: $selectedRows });
        }
        //hide showed button
        var $showedNodes = $('.toolbtnShow').parent();
        if ($showedNodes.hasClass('active')) {
          $showedNodes.switchClass('notActive', 'active').attr('data-state', 'disabled');
        } else {
          $showedNodes.attr('data-state', null);
        }
        toolBtnShow = $('#' + tabId +
            ' tr.selected.toolbtn-show:not(".filtred")');
        if (toolBtnShow.length > 0) {
          EventMgr.trigger('showToolBtn', {
            toolBtnShow: toolBtnShow, len: len });
        }
        toolBtnHide = $('#' + tabId +
            ' tr.selected.toolbtn-hide:not(".filtred")');
        if (toolBtnHide.length > 0) {
          EventMgr.trigger('hideToolBtn', { toolBtnHide: toolBtnHide });
        }
        toolBtnsRemove = $('#' + tabId +
            ' tr.selected.toolbtn-remove:not(".filtred")');
        if (toolBtnsRemove.length > 0) {
          toolBtnRemove(toolBtnsRemove);
        }
      },
      //force rowSelect [used in warning about not deleted elems]
      forceRowSelect = function(e, data) {
        var tabId = data.tabId,
            keyVar,
            self;
        if (App.Global.warning) {
          /* jslint forin: true */
          for (keyVar in App.Global.warning) {
            self = $('#cont-' + tabId + ' [data-elid="' + App.Common.CSSEscape(keyVar) + '"]');
            rowSelect.apply(self, [{}, true]);
          }
          App.Global.warning = null;
        }
        if (App.Global.selid) {
          var len = App.Global.selid.length;
          while (len--) {
            self = $('#cont-' + tabId +
                ' [data-elid="' + App.Common.CSSEscape(App.Global.selid[len]) + '"]');
            rowSelect.apply(self, [{}, true]);
          }
          App.Global.selid = undefined;
        }
      },

      forceScrollTo = function(e, data) {
        var tabId = data.tabId;
        if (App.Global.scrollTop) {
          setTimeout(function() {
            ScrollHandler.scrollTo('ltwr-' +
                tabId, App.Global.scrollTop, true, true);
            App.Global.scrollTop = undefined;
          }, 10);
        }
      },

      toolBtnRemove = function(elems) {
        var l = elems.length,
            removeClass;
        while (l--) {
          removeClass = elems[l].getAttribute('data-remove');
          removeClass = String(removeClass).replace(/,\s+$/, '');
          $(removeClass).parent().addClass('removed').removeClass('active');
        }
      },

      //disable toolbtn
      toolBtnHide = function(e, data) {
            //selected rows
        var $toolBtnHide = data.toolBtnHide,
            l = $toolBtnHide.length,
            len = l,
            hideClass, hides = {},
            hideClassArray,
            $targetNode,
            duplicate;
        //count hide rules for each toolbtn
        while (l--) {
          //hide class has id button
          hideClass = $toolBtnHide[l].getAttribute('data-hide');
          hideClass = String(hideClass).replace(/,\s+$/, '');
          hideClassArray = hideClass.split(', ');
          duplicate = {};
          for (var i = 0, hLen = hideClassArray.length; i < hLen; i++) {
             hideClass = hideClassArray[i];
             if (duplicate[hideClass]) { continue; }
             if (!hides[hideClass]) {
               hides[hideClass] = 0;
             }
             hides[hideClass] += 1;
             duplicate[hideClass] = true;
          }
        }
        //if all rows in rules - hide btn
        for (var key in hides) {
          if (hides[key] === len) {
            $targetNode = $(key).parent();
            if ($targetNode.hasClass('active')) {
              $targetNode.switchClass('notActive', 'active').attr('data-state', 'disabled');
            }
          }
        }
      },
      //enable toolbtn
      //show rules check
      toolBtnShow = function(e, data) {
        var $toolBtnShow = data.toolBtnShow,
            classArr, len, rules = {}, countRow = data.len, showClass;
        $toolBtnShow.each(function() {
          showClass = this.getAttribute('data-show');
          //for show toolbtn if one value for selected row
          if (countRow > 1) {
            classArr = showClass.split(',');
            len = classArr.length;
            showClass = '';
            while (len--) {
              if (classArr[len] !== ' ' && classArr[len] !== '') {
                if (!rules[classArr[len]]) {
                  rules[classArr[len]] = 1;
                } else {
                  rules[classArr[len]]++;
                }
              }
            }
          } else {
            showClass = String(showClass).replace(/,\s+$/, '');
            $(showClass).parent().switchClass('active', 'notActive').attr('data-state', null);
          }
        });
        //if more one selected rows, check for rules each row
        if (countRow > 1) {
          /* jslint forin:true */
          for (var keyVar in rules) {
            //for group && inert toolbtn
            showClass = keyVar + '.tb-group, ' + keyVar + '.tb-inert';
            $(showClass).parent().switchClass('active', 'notActive').attr('data-state', null);
          }
        }
      },
      /**
       * enabling group's btns
       * disabling not group's btns
       * @param {object} e event object
       * @param {object} data data object
       */
      activateToolbarGroup = function(e, data) {
        tabId = (data) ? (data.tabId) ? data.tabId : tabId : tabId;
        $toolBarBtnNotGroup().switchClass('notActive', 'active')
            .removeClass('removed').attr('data-state', 'noselect');
        $toolbarBtnGroup().switchClass('active', 'notActive')
            .removeClass('removed').attr('data-state', null);
        $toolBarBtnNoSelEdit().switchClass('notActive', 'active').attr('data-state', 'noselect');
      },
      //enabling all toolbar's btns
      activateTollbarAll = function(e, data) {
        tabId = (data) ? (data.tabId) ? data.tabId : tabId : tabId;
        $toolbarBtnAll().switchClass('active', 'notActive')
            .removeClass('removed').attr('data-state', null);
      },

      isDenyByHideRules = function(classes, ovhide) {
        var hides = String(ovhide).split(','),
            l = hides.length,
            hideId;
        while (l--) {
          if (hides[l] && hides[l] !== ' ') {
            hideId = hides[l].replace('#', '');
            if (String(classes).match(hideId)) {
              return true;
            }
          }
        }
        return false;
      },
      /**
       * check for show rules in this row
       * @param {String} classes
       * @param {String} ovshow
       * @return {boolean}
       */
      isAllowByShowRules = function(classes, ovshow) {
        var shows = String(ovshow).split(','),
            l = shows.length,
            showId;
        if (classes.match('toolbtnShow')) {
          while (l--) {
            if (shows[l] && shows[l] !== ' ') {
              showId = shows[l].replace('.', '');
              if (String(classes).match(showId)) {
                return true;
              }
            }
          }
        } else {
          return true;
        }
        return false;
      },
      //get array of name key fields active rows and create url
      fillActiveRows = function(e, data) {
        var activeRows = [],
            elids = [],
            invar = data.invar,
            locTabId = data.invar.tabId,
            $curTab = $('#cont-' + locTabId),
            toolbar = $curTab.find('.toolbar'),
            plid = filterXSS.friendlyAttrValue(toolbar.attr('data-plid') || ''),
            convert = toolbar.attr('data-convert'),
            triggerAction = data.triggerAction || 'listSelectedData',
            j = 0,
            classes = data.classes,
            content = data.__content,
            actRowString;
        $curTab.find('tr.selected:not(".filtred")').each(function() {
          var rowIndex = this.getAttribute('data-index');
          if (content[rowIndex]) {
            if (content[rowIndex]._ovhide) {
              if (isDenyByHideRules(classes, content[rowIndex]._ovhide)) {
                return true;
              }
            }
            if (content[rowIndex]._ovshow) {
              if (!isAllowByShowRules(classes, content[rowIndex]._ovshow)) {
                return true;
              }
            }
          }
          if (j < 10) {
            var elName = String(this.getAttribute('data-elkeyname')),
                elNameLength = elName.length;
            if (elNameLength > 50) {
              elName = elName.substring(0, 50);
              elName += '...';
            }
            activeRows.push('<span class="b-text-wrapper">' +
                window.htmlEncode(elName) +
                '</span>');
          }
          elids.push(String(this.getAttribute('data-elid')).replace(/,\s/g, ', , '));
          j++;
        });
        actRowString = activeRows.join(', ');
        elids = elids.join(', ');
        if (j > 10) {
          actRowString += pageInfo.totalelem.replace(/__s__/, j);
        }
        if (convert) {
          invar.params.tconvert = convert;
        }
        invar.params.elid = elids;
        invar.params.plid = plid || '';
        invar.rows = actRowString;

        EventMgr.trigger(triggerAction, invar);
      },
      //disabling all toolbar's btns exclude "new" and "back" btns
      deactivateToolbarAll = function(e, data) {
        tabId = (data) ? (data.tabId) ? data.tabId : tabId : tabId;
        $toolBarBtnNotGroup().switchClass('notActive', 'active')
            .removeClass('removed').attr('data-state', 'noselect');
        $toolbarBtnGroup().switchClass('notActive', 'active')
            .removeClass('removed').attr('data-state', 'noselect');
        $toolBarBtnNoSelEdit().switchClass('active', 'notActive').attr('data-state', null);
      },
      //recalc total of col in list
      updateStatusBarTotal = function(e, data) {
        if (!data.__headers || !data.__content) {
          return;
        }
        var colName = data.colName,
            content = data.__content,
            index = data.index,
            tabId = data.tabId,
            l = content.length,
            total = 0;
        while (l--) {
          if (content[l][colName]) {
            total += content[l][colName].v - 0;
          }
        }
        $('#cont-' + tabId).find('.sb-result_index_' + index).html(total);
      },

      statusBarHandler = function(e, data) {
        //check for selected row from from
        if (!data.__headers || !data.__content) {
          return;
        }
        var tabId = data.tabId,
            len = data.len,
            headers = data.__headers,
            tableContent = data.__content,
            headersLens = headers.length,
            l, $sbr, $sbs, $1sbr, $1sbs,
            $selectedRows = data.selectedRows,
            selecedCount,
            defPropStat,
            index, total = {}, type, resultSum;
        $1sbr = $('#' + tabId + ' .sb-result_index_0');
        $1sbs = $('#' + tabId + ' .sb-selected_index_0');
        if (len !== 0) {
          //1st total col
          $1sbr.removeClass('sb-result_st_active');
          selecedCount = $1sbs.addClass('sb-selected_st_active')
              .html()
              .replace(/\d{1,100}/, len);
          $1sbs.html(selecedCount);
          //each for all selected elems
          $selectedRows.each(function(i) {
            index = this.getAttribute('data-index');
            l = headersLens;
            while (l--) {
              type = headers[l].type;
              //check for total
              if (headers[l].total) {
                if (tableContent[index] &&
                    tableContent[index][headers[l].name]) {
                  if (type === 'data' || type === 'money') {
                    //calc data
                    total[l] = dataCalc(total[l], tableContent[index][headers[l].name]);
                  } else if (type === 'indicator') {
                    //calc indicator
                    total[l] = indicatorCalc(total[l], tableContent[index][headers[l].name]);
                  } else if (type === 'prop') {
                    //calc props
                    total[l] = propCalc(total[l], tableContent[index][headers[l].name]);
                  }
                }
              }
              //update html here
              if (i === (len - 1)) {
                if (headers[l].total) {
                  //all total
                  $sbr = $('#' + tabId + ' .sb-result_index_' + l)
                      .removeClass('sb-result_st_active');
                  //selected total
                  $sbs = $('#' + tabId + ' .sb-selected_index_' + l)
                      .addClass('sb-selected_st_active');
                  if (type === 'data' || type === 'money') {
                    resultSum = '';
                    /* jslint forin: true */
                    for (var key in total[l]) {
                      if (key === 'TOTAL_FINAL') {
                        continue; 
                      }
                      if (resultSum !== '') {
                        resultSum += '; ';
                      }
                      if (type === 'money') {
                        resultSum += App.Tabs.moneyFormat(total[l][key]) +
                            ' ' + key;
                      } else {
                        resultSum += total[l][key] + ' ' + key;
                      }
                      if (headers[l].convert && headers[l].convert !== 'money') {
                        convertData(headers[l].convert, resultSum, $sbs);
                      }
                    }
                    $sbs.html(pageInfo.total + ': ' + resultSum);
                  } else if (type === 'indicator') {
                    if (headers[l].convert) {
                      convertData(headers[l].convert, total[l], $sbs);
                    } else {
                      $sbs.html(pageInfo.total + ': ' + total[l].c);
                    }
                  } else if (type === 'prop') {
                    defPropStat = $sbr.html();
                    $sbs.html(renderPropsStat(total[l], defPropStat));
                  }
                }
              }
            }
          });
        } else {
          //1st total col
          $1sbr.addClass('sb-result_st_active');
          $1sbs.removeClass('sb-selected_st_active');
          //show default values
          l = headersLens;
          while (l--) {
            if (headers[l].total) {
              $('#' + tabId + ' .sb-result_index_' + l)
                  .addClass('sb-result_st_active');
              $('#' + tabId + ' .sb-selected_index_' + l)
                  .removeClass('sb-selected_st_active');
            }
          }
        }
      },
      //convert data
      convertData = function(name, value, $sbs) {
        var invar = {
          $sbs: $sbs
        };
        //logic for indicator convert
        if (value && value.a !== undefined) {
          invar.__value = value;
          invar.__name = name;
          if (value.a_converted) {
            value = value.b;
            invar.__current = 'b';
          } else {
            value = value.a;
            invar.__current = 'a';
          }
        }

        EventMgr.trigger('ajaxRequest', {
            param: {
              func: 'convert',
              name: name,
              value: value
            },
            invar: invar,
            type: 'get',
            outtype: 'json',
            trfunc: 'updateTotalWithConvert',
            failfunc: 'DoNothing',
            queue: 'multiload'
        });
      },
      /**
       * Calculate data
       * @param {object|undefined} resultC template object with current
       * calculated data
       * @param {number|string} current number
       * @return {object}
       **/
      dataCalc = function(resultC, current) {
        if (current.total && current.total === 'ignore') {
          return resultC;
        }
        if (current.total && current.total === 'final') {
          resultC = {
             TOTAL_FINAL: true,
             '': current.orig || current.v
          };
          return resultC;
        } else if (resultC && resultC.TOTAL_FINAL) {
          return resultC;
        }
        var dec1, dec2 = 0, maxDec = 0, suffix;
        resultC = resultC || {};
        current = current.orig || current.v;
        suffix = current.replace(/[0-9\s\.,-]+/, '');
        current = current.replace(suffix, '').replace(/\s/g, '');
        if ((resultC[suffix] && resultC[suffix].length > 12) ||
            current.length > 12) {
          if (!resultC[suffix]) {
            resultC[suffix] = current;
          } else {
            resultC[suffix] = calcLongNumber(resultC[suffix], current);
          }
        } else {
          //check for suffix like "USD", "EUR"
          if (resultC[suffix]) {
            dec1 = decimalPlaces(resultC[suffix]);
            dec2 = decimalPlaces(current);
            maxDec = dec1 > dec2 ? dec1 : dec2;
          } else {
            maxDec = decimalPlaces(current);
          }
          if (current === '') {
            current = '0';
          }
          if (!resultC[suffix]) {
            resultC[suffix] = parseFloat(current);
          } else {
            resultC[suffix] = parseFloat(resultC[suffix]) + parseFloat(current);
          }
        }
        if (resultC[suffix]) {
          resultC[suffix] = resultC[suffix].toFixed ?
              resultC[suffix].toFixed(maxDec) : resultC[suffix];
        }
        return resultC;
      },

      indicatorCalc = function(resultC, current) {
        resultC = resultC || { a: 0, b: 0, c: 0 };
        current.u = current.u_orig || current.u;
        current.l = current.l_orig || current.l;
        if (resultC.a.length > 12 || current.u.length > 12) {
          resultC.a = calcLongNumber(resultC.a, current.u);
        } else {
          resultC.a = parseInt(resultC.a, 10) + parseInt(current.u, 10);
        }
        if (resultC.b.length > 12 || current.l.length > 12) {
          resultC.b = calcLongNumber(resultC.b, current.l);
        } else {
          resultC.b = parseInt(resultC.b, 10) + parseInt(current.l, 10);
        }
        if (isNaN(resultC.a)) {
          resultC.a = '-';
        }
        if (isNaN(resultC.b)) {
          resultC.b = '-';
        }
        resultC.c = resultC.a + ' / ' + resultC.b;
        return resultC;
      },

      decimalPlaces = function(num)  {
        var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
        if (!match) { return 0; }
        return Math.max(
            0,
            // Number of digits right of decimal point.
            (match[1] ? match[1].length : 0),
            // Adjust for scientific notation.
            - (match[2] ? +match[2] : 0));
      },

      calcLongNumber = function(num1, num2) {

        var calcLongNaturalNumber = function(num1, num2, one) {
          num1 = String($.trim(num1));
          num2 = String($.trim(num2));

          var num1Arr = num1.split('').reverse(),
              num2Arr = num2.split('').reverse(),
              newNum = [],
              bigNum = null,
              next = 0,
              i;
          if (one) { next = 1; }
          var len1 = num1Arr.length,
              len2 = num2Arr.length,
              len = 0,
              firstPart = '';
          if (len1 > len2) {
            len = len2;
            bigNum = num1;
          } else {
            len = len1;
            bigNum = num2;
          }
          for (i = 0; i < len; i++) {
            var tmpNum = parseInt(num1Arr[i], 10) + parseInt(num2Arr[i], 10) +
                next;
            if (tmpNum >= 10) {
              tmpNum = tmpNum - 10;
              next = 1;
            } else {
              next = 0;
            }
            newNum.push(tmpNum);
          }
          if (len1 === len2) {
            if (next === 1) {
              newNum.push(1);
            }
          } else {
            firstPart = bigNum.substr(0 , bigNum.length - i - 1);
            newNum.push(parseInt(bigNum[bigNum.length - i - 1], 10) + next);
          }
          newNum.push(firstPart);
          newNum.reverse();
          return newNum.join('');
        },

            addZeroes = function(str, num) {
              var z = '',
                  i;
              for (i = 0; i < num; i++) {
                z += '0';
              }
              return str + z;
            };

        var result = '';
        if ((String(num1).indexOf('.') !== -1) ||
            (String(num2).indexOf('.') !== -1)) {
          var num1Tail = num1.split('.'),
              num2Tail = num2.split('.'),
              resultTail = '',
              resultHead = '';
          if (num1Tail[1] === undefined) {
            resultTail = num2Tail[1];
          } else if (num2Tail[1] === undefined) {
            resultTail = num1Tail[1];
          } else {
            var len1 = num1Tail[1].length,
                len2 = num2Tail[1].length,
                bigLen = 0;
            if (len1 > len2) {
              bigLen = len1;
              num2Tail[1] = addZeroes(num2Tail[1], len1 - len2);
            } else {
              bigLen = len2;
              num1Tail[1] = addZeroes(num1Tail[1], len2 - len1);
            }
            resultTail = calcLongNaturalNumber(num1Tail[1], num2Tail[1]);
            if (resultTail.length > bigLen) {
              resultHead = calcLongNaturalNumber(num1Tail[0], num2Tail[0], true);
            } else {
              resultHead = calcLongNaturalNumber(num1Tail[0], num2Tail[0]);
            }
            result = resultHead + '.' + resultTail;
          }
        } else {
          result = calcLongNaturalNumber(num1, num2);
        }
        return result;
      },

      propCalc = function(resultC, current) {
        if (resultC === undefined) {
          resultC = [];
        }
        var cStat = current.psp,
            cStatArr, len;
        if (!cStat) { return; }
        cStatArr = cStat.split(':');
        len = cStatArr.length;
        for (var i = 0; i < len; i++) {
          resultC[i] = parseInt(resultC[i] ? resultC[i] : 0, 10) +
              parseInt(cStatArr[i], 10);
        }
        return resultC;
      },

      renderPropsStat = function(self, statAll) {
        if (!self) { return ''; }
        var statAllArr = statAll.split(',');
        for (var i = 0; i < self.length; i++) {
          //ignore error with data
          if (statAllArr[i] === undefined) {
            break;
          }
          statAllArr[i] = statAllArr[i].replace(/>\d+/, '>' + self[i]);
          if (self[i] - 0 === 0) {
            statAllArr[i] = statAllArr[i]
                .replace(/class=\"default\"/, 'class="no"');
          } else {
            statAllArr[i] = statAllArr[i]
                .replace(/class=\"no\"/, 'class="default"');
          }
        }
        return statAllArr.join(', ');
      },

      swipeStarted = false,
      swipeTouch,
      swipeDetecting = false,
      swipeX,
      swipeY,
      swipeElem,

      swipeDetectorTouchStart = function(e) {
        if (e.touches && (e.touches.length !== 1 || swipeStarted)) {
          return;
        }
        swipeDetecting = true;
        swipeTouch = e.originalEvent.changedTouches[0];
        swipeX = swipeTouch.pageX;
        swipeY = swipeTouch.pageY;
        swipeElem = this;
        document.ontouchmove = swipeDetectorTouchMove;
        document.ontouchend = swipeDetectorTouchDrop;
        document.ontouchcancel = swipeDetectorTouchDrop;
      },

      swipeDetectorTouchMove = function(e) {
        var curTouch = e.changedTouches[0];
        if (!swipeStarted && !swipeDetecting) {
          return;
        }
        if (curTouch[0] === swipeTouch) {
          return;
        }
        if (Math.abs(swipeX - curTouch.pageX) >=
            Math.abs(swipeY - curTouch.pageY)) {
          e.preventDefault();
          swipeStarted = true;
        }
        swipeDetecting = false;
        if (swipeStarted) {
          $(swipeElem).trigger('click');
          $(swipeElem).trigger('dblclick');
        }
      },

      swipeDetectorTouchDrop = function(e) {
        document.ontouchmove = null;
        document.ontouchend = null;
        document.ontouchcancel = null;
        swipeStarted = false;
        swipeTouch = null;
        swipeDetecting = false;
        swipeX = null;
        swipeY = null;
        swipeElem = null;
      },

      updateTotalWithConvert = function(e, data) {
        var $targetTotal = data.$sbs,
            value = data.convertValue;
        //logic for indicator
        if (data.__value && data.__current) {
          if (data.__current === 'a') {
            data.__value.a_converted = value;
            convertData(data.__name, data.__value, data.$sbs);
            return;
          } else if (data.__current === 'b') {
            value = data.__value.a_converted + ' / ' + value;
          }
        }
        $targetTotal.html(pageInfo.total + ': ' + value);
      };
  return {
    dataCalc: dataCalc,
    init: init
  };
}(window, $, EventMgr, App);