text: /*
   * Copyright 2015-2018 Jeeva Kandasamy (jkandasa@gmail.com)
   * and other contributors as indicated by the @author tags.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  // don't forget to declare this service module as a dependency in your main app constructor!
  //http://js2.coffee/#coffee2js
  //https://coderwall.com/p/r_bvhg/angular-ui-bootstrap-alert-service-for-angular-js
  
  myControllerModule.factory('CommonServices', function(TypesFactory, $filter, $cookies, mchelper) {
    var commonService = {};
  
    //get mchelper configurations
    commonService.loadMchelper = function(){
      var mchelperLocal = $cookies.getObject('mchelper');
      if(mchelperLocal){
        mchelper.cfg = mchelperLocal.cfg || {};
        mchelper.user = mchelperLocal.user || {};
        mchelper.languages = mchelperLocal.languages || {};
        mchelper.userSettings = mchelperLocal.userSettings || {};
        mchelper.internal = mchelperLocal.internal || {};
      }
      return mchelper;
    };
  
    //restore store all the configurations locally
    commonService.saveMchelper = function(mchelperRemote){
      mchelper.cfg = mchelperRemote.cfg;
      mchelper.user = mchelperRemote.user;
      mchelper.languages = mchelperRemote.languages;
      mchelper.userSettings = mchelperRemote.userSettings;
      mchelper.internal = mchelperRemote.internal;
      $cookies.putObject('mchelper', mchelper);
    };
  
    //clear local mchelper
    commonService.clearMchelper = function(){
      mchelper.selectedDashboard = undefined;
      mchelper.cfg = {};
      mchelper.user = {};
      mchelper.languages = {};
      mchelper.userSettings = {};
      mchelper.internal = {};
    };
  
    //remove cookies
    commonService.clearCookies = function(){
      var cookies = $cookies.getAll();
      angular.forEach(cookies, function (v, k) {
        $cookies.remove(k);
      });
    };
  
    //Get value nested supported
    commonService.getValue = function(item, key){
      var keys = key.split('.');
      for (var i = 0, n = keys.length; i < n; ++i) {
          var k = keys[i];
          if (k in item) {
              item = item[k];
          } else {
              return;
          }
      }
      return item;
    };
  
    //Match value
    var matchesFilter = function (item, filter) {
      var match = true;
      var value = commonService.getValue(item, filter.id);
      //TODO: there is an issue with sensors action page. filter is not passing the type.
      //workaround, if undefined, set as type 'text'
      if(filter.type === undefined){
        if(angular.isNumber(value)){
          filter.value = parseInt(filter.value);
          filter.type = 'object';
        }else{
          filter.type = 'text';
        }
      }
  
      if(filter.type === 'text' || filter.type ===  'select'){
        if(value){
          match = value.toUpperCase().match(filter.value.toUpperCase()) !== null;
        }else{
          match = false;
        }
      }else if(filter.type === 'array'){
        return value.indexOf(filter.value) > -1;
      }else{
          match = angular.equals(value, filter.value);
      }
      return match;
    };
  
    //Match values with for loop
    var matchesFilters = function (item, filters) {
      var matches = true;
      filters.forEach(function(filter) {
        if (!matchesFilter(item, filter)) {
          matches = false;
          return false;
        }
      });
      return matches;
    };
  
    //Apply filter
    var applyFilters = function (filters, configMap) {
      configMap.filteredList = [];
      if (filters && filters.length > 0) {
        configMap.orgList.forEach(function (item) {
          if (matchesFilters(item, filters)) {
            configMap.filteredList.push(item);
          }
        });
      } else {
        configMap.filteredList = configMap.orgList;
      }
      configMap.filterConfig.resultsCount = configMap.filteredList.length;
    };
  
    // Common filter
    commonService.filterChangeLocal = function (filters, configMap) {
    configMap.filtersText = "";
      filters.forEach(function (filter) {
        configMap.filtersText += filter.title + " : " + filter.value + "\n";
      });
      applyFilters(filters, configMap);
    };
  
    //Select/unselect single row of table
    commonService.selectItem = function (baseScope, item, key){
      if(!key){
        key='id';
      }
      if(baseScope.itemIds.indexOf(item[key]) == -1){
        baseScope.itemIds.push(item[key]);
      }else{
        baseScope.itemIds.splice(baseScope.itemIds.indexOf(item[key]), 1);
      }
    };
  
    // select ALL/NONE of table row function
    commonService.selectAllItems = function (baseScope, key) {
      if(!key){
        key='id';
      }
      if(baseScope.filteredList.length > 0){
        if(baseScope.filteredList.length == baseScope.itemIds.length){
          baseScope.itemIds = [];
        }else{
          baseScope.itemIds = [];
          angular.forEach(baseScope.filteredList, function(value, keyT) {
            baseScope.itemIds.push(value[key]);
          });
        }
      }
    };
  
    // Update row selection of table function
    commonService.updateSelection = function (baseScope) {
      if(baseScope.itemIds.length > 0){
        tmpItemIds = baseScope.itemIds;
        baseScope.itemIds = [];
        angular.forEach(baseScope.filteredList, function(value, key) {
          if(tmpItemIds.indexOf(value.id) != -1){
            baseScope.itemIds.push(value.id);
          }
        });
      }
    };
  
    // get Table configuration
    commonService.getTableConfig = function(){
      return config = {
        itemsPerPage: 15,
        maxPages:10,
        fillLastPage: false
      };
    };
  
  
    // get resources
    commonService.getResources= function(resourceType, resourceId){
      if(resourceType === 'Sensor variable'){
        return TypesFactory.getSensorVariables();
      }else if(resourceType === 'Gateway' || resourceType === 'Gateway state'){
        return TypesFactory.getGateways();
      }else if(resourceType === 'Node' || resourceType === 'Node state'){
        return TypesFactory.getNodes({"gatewayId":resourceId});
      }else if(resourceType === 'Sensors'){
        return TypesFactory.getSensors({"nodeId":resourceId});
      }else if(resourceType === 'Resources group'){
        return TypesFactory.getResourcesGroups();
      }else if(resourceType === 'Alarm definition'){
        return TypesFactory.getAlarmDefinitions();
      }else if(resourceType === 'Timer'){
        return TypesFactory.getTimers();
      }else{
        return null;
      }
    }
  
    // get Table configuration
    commonService.getQuery = function(){
      return query = {
        pageLimit: mchelper.cfg.tableRowsLimit,
        page: 1,
        orderBy: "id",
        order: "asc"
      };
    };
  
    //Apply filters
    commonService.updateFiltersChange = function (remoteScope, filters) {
      //Clears filter
      remoteScope.filterConfig.fields.forEach(function (filter) {
        if(filter.filterType === 'text'){
          remoteScope.query[filter.id]=[];
        }else if(filter.filterType === 'select'){
          remoteScope.query[filter.id] = null;
        }
      });
      //Update filters
      filters.forEach(function (filter) {
        //This is to fix sensors action page
        //console.log(''+angular.toJson(filter));
        if(filter.type === undefined){
          remoteScope.filterConfig.fields.forEach(function (orgFilter) {
            if(filter.id === orgFilter.id){
              filter.type =  orgFilter.filterType;
            }
          });
        }
        if(filter.type === 'text'){
          remoteScope.query[filter.id].push(filter.value);
        }else if(filter.type === 'select'){
          remoteScope.query[filter.id] = filter.value;
        }
      });
  
      //move to page number 1 on filter change
      remoteScope.currentPage = 1;
      remoteScope.query.page=1;
  
      remoteScope.getAllItems();
    };
  
    //Update sort columns(orderBy)
    commonService.updateSortChange = function (remoteScope, sortId, isAscending) {
      if(isAscending){
        remoteScope.query.order = "asc";
      }else{
        remoteScope.query.order = "dsec";
      }
      remoteScope.query.orderBy = sortId.id;
      remoteScope.getAllItems();
    };
  
    //Update page change
    commonService.updatePageChange = function (remoteScope, newPage) {
      remoteScope.query.page = newPage;
      remoteScope.getAllItems();
    };
  
    //Get min number
    commonService.getMin = function(item1, item2){
      return Math.min(item1, item2);
    };
  
    //item for sensor actions
    //--------------------------------------------------
  
    //Defined variable types list
    commonService.getSensorVariablesKnownList = function(){
      var definedVariableTypes = ["Status","Watt","Temperature","Humidity","Pressure","Forecast","Armed","Tripped","Lock status","Percentage","Weight","Stop","Up","Down","Rain","Rain rate",
      "HVAC flow state","HVAC flow mode","HVAC speed","HVAC setpoint cool","HVAC setpoint heat","Variable 1","Variable 2","Variable 3","Variable 4","Variable 5","RGB","RGBW","Distance",
      "Current","Voltage","Impedance", "Volume"];
      return definedVariableTypes;
    };
  
    //Forecast mapper
      var forecastMapper = [
          {
            id:"sunny",
            value:"day-sunny",
          },{
            id:"cloudy",
            value:"day-cloudy",
          },{
            id:"thunderstorm",
            value:"day-thunderstorm",
          },{
            id:"stable",
            value:"day-sunny",
          },{
            id:"unstable",
            value:"sprinkle",
          },{
            id:"na",
            value:"na",
          },
        ];
  
    commonService.getForecastValue = function(key){
      if(key === undefined){
        key = 'na';
      }
      var result = $filter('filter')(forecastMapper, {id: key}, true)[0];
      if(!result){
        return "na";
      }else{
        return result.value
      }
      //return $filter('filter')($scope.forecastMapper, {id: key}, true)[0].value;
    };
  
  
    //Sensor icons
      var sensorIcons = [
          {id:"default", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Door", value:"fa fa-building-o", ucode:"\uf0f7", fname:"FontAwesome"},
          {id:"Motion", value:"fa fa-paw", ucode:"\uf1b0", fname:"FontAwesome"},
          {id:"Smoke", value:"wi wi-smoke", ucode:"\uf062", fname:"weathericons"},
          {id:"Binary", value:"fa fa-power-off", ucode:"\uf011", fname:"FontAwesome"},
          {id:"Dimmer", value:"fa fa-lightbulb-o", ucode:"\uf0eb", fname:"FontAwesome"},
          {id:"Cover", value:"fa fa-archive", ucode:"\uf187", fname:"FontAwesome"},
          {id:"Temperature", value:"wi wi-thermometer", ucode:"\uf055", fname:"weathericons"},
          {id:"Humidity", value:"wi wi-humidity", ucode:"\uf07a", fname:"weathericons"},
          {id:"Barometer", value:"wi wi-barometer", ucode:"\uf079", fname:"weathericons"},
          {id:"Wind", value:"wi wi-windy", ucode:"\uf079", fname:"weathericons"},
          {id:"Rain", value:"wi wi-raindrops", ucode:"\uf04e", fname:"weathericons"},
          {id:"UV", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Weight", value:"fa fa-balance-scale", ucode:"\uf24e", fname:"FontAwesome"},
          {id:"Power", value:"fa fa-bolt", ucode:"\uf0e7", fname:"FontAwesome"},
          {id:"Heater", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Distance", value:"fa fa-binoculars", ucode:"\uf1e5", fname:"FontAwesome"},
          {id:"Light level", value:"wi wi-moon-alt-waxing-crescent-5", ucode:"\uf0d4", fname:"weathericons"},
          {id:"Node", value:"fa fa-sitemap", ucode:"\uf0e8", fname:"FontAwesome"},
          {id:"Repeater node", value:"fa fa-sitemap", ucode:"\uf0e8", fname:"FontAwesome"},
          {id:"Lock", value:"fa fa-lock", ucode:"\uf023", fname:"FontAwesome"},
          {id:"IR", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Water", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Air quality", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Custom", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Dust", value:"wi wi-dust", ucode:"\uf063", fname:"weathericons"},
          {id:"Scene controller", value:"fa fa-picture-o", ucode:"\uf03e", fname:"FontAwesome"},
          {id:"RGB light", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"RGBW light", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Color sensor", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"HVAC", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Multimeter", value:"fa fa-calculator", ucode:"\uf1ec", fname:"FontAwesome"},
          {id:"Sprinkler", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Water leak", value:"fa fa-tint", ucode:"\uf043", fname:"FontAwesome"},
          {id:"Sound", value:"fa fa-volume-up", ucode:"\uf028", fname:"FontAwesome"},
          {id:"Vibration", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Moisture", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Information", value:"fa fa-info", ucode:"\uf129", fname:"FontAwesome"},
          {id:"Gas", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"GPS", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Water quality", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"CPU", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Memory", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"Disk", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
          {id:"PWM", value:"fa fa-eye", ucode:"\uf06e", fname:"FontAwesome"},
        ];
  
    commonService.getSensorIcon = function(key){
      return commonService.getSensorIconData(key).value;
    };
  
    commonService.getSensorIconData = function(key){
      if(key === undefined || key == 'Undefined'){
        key = 'default';
      }
      return $filter('filter')(sensorIcons, {id: key}, true)[0];
    };
  
  
    //RGBA functions
    //Function to convert rgba format to hex color
    commonService.rgba2hex = function rgb2hex(rgb){
      rgb = rgb.replace("rgba","").replace("(","").replace(")","").split(",");
      return "#"
        + ("0" + parseInt(rgb[0],10).toString(16)).slice(-2)
        + ("0" + parseInt(rgb[1],10).toString(16)).slice(-2)
        + ("0" + parseInt(rgb[2],10).toString(16)).slice(-2)
        + ("0" + parseInt((parseFloat(rgb[3],10)*255)).toString(16)).slice(-2);
    };
  
    //Function to convert hex format to RGBA color
    commonService.hex2rgba = function(hex){
      if(hex){
        hex = hex.replace('#','');
        r = parseInt(hex.substring(0,2), 16);
        g = parseInt(hex.substring(2,4), 16);
        b = parseInt(hex.substring(4,6), 16);
        opacity = parseInt(hex.substring(6,8), 16);
        result = 'rgba('+r+','+g+','+b+','+(opacity/255).toFixed(2)+')';
        return result;
      }
      return undefined;
    };
  
    //Get integer value for switch
    commonService.getInteger = function(value){
      if(!value){
        return undefined;
      }else{
        return parseInt(value);
      }
    };
  
    //Switch settings
    commonService.mcbStyle = {
        handleWidth: "60px",
        stateHandleWidth: "35px",
        labelWidth: "3px",
        animate:true,
        size:"small",
      };
  
    //validation methods
    //-----------------------
  
    //Number validation
    commonService.isNumber = function (value) {
      if (isNaN(value)) {
        return false;
      }
      return true;
    };
  
    //is contains space validation
    commonService.isContainsSpace = function (value) {
      if(value !== undefined){
        return !value.match(/\s/g);
      }
      return true;
    };
  
    //is valid JSON
    commonService.isJsonString = function (value) {
      try {
          JSON.stringify(eval('('+value+')'));
          return true;
      } catch(err) {
          return false;
      }
    };
  
    //guid helper
    var s4 = function() {
      return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    }
    //get guid
    commonService.guid = function() {
      return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
    };
  
    //get friendly time
    commonService.getTimestampJson = function(timestamp){
      var timestampJson = {};
      if(timestamp % 31536000000  == 0){
        timestampJson.timestamp = timestamp / 31536000000;
        timestampJson.timeConstant = "31536000000";
        timestampJson.timeConstantString = $filter('translate')('YEARS');
      }else if(timestamp % 86400000  == 0){
        timestampJson.timestamp = timestamp / 86400000;
        timestampJson.timeConstant = "86400000";
        timestampJson.timeConstantString = $filter('translate')('DAYS');
      }else if(timestamp % 3600000  == 0){
        timestampJson.timestamp = timestamp / 3600000;
        timestampJson.timeConstant = "3600000";
        timestampJson.timeConstantString = $filter('translate')('Hours');
      }else if(timestamp % 60000  == 0){
        timestampJson.timestamp = timestamp / 60000;
        timestampJson.timeConstant = "60000";
        timestampJson.timeConstantString = $filter('translate')('Minutes');
      }
      return timestampJson;
    };
  
    //get timestamp
    commonService.getTimestamp = function(timestampJson){
      return timestampJson.timeConstant * timestampJson.timestamp;
    };
  
    //Update mill seconds to readable value
    commonService.updateReadable = function(milliSeconds, item){
       if(milliSeconds % 86400000  == 0){
        item.readableValue = milliSeconds / 86400000;
        item.timeConstant = "86400000";
      }else if(milliSeconds % 3600000  == 0){
        item.readableValue = milliSeconds / 3600000;
        item.timeConstant = "3600000";
      }else if(milliSeconds % 60000  == 0){
        item.readableValue = milliSeconds / 60000;
        item.timeConstant = "60000";
      }else{
        item.readableValue = milliSeconds / 1000;
        item.timeConstant = "1000";
      }
    };
  
    //Get readable value to milliseconds
    commonService.getMilliseconds = function(readableValue, timeConstant){
       return readableValue * timeConstant;
    };
  
    //Update default graph margin settings
    commonService.updateGraphMarginDefault = function(item){
      if(item.marginTop === undefined){
        item.marginTop = 5;
        item.marginRight = 20;
        item.marginBottom = 60;
        item.marginLeft = 65;
      }
    }
  
   return commonService;
  
  });
  