'use strict';
/**
 * @ngdoc service
 * @name Auth
 * @description
 *  인증 관련 기능. 로그인 후 현재 사용자에 대한 정보를 _user 에 저장함. 로그아웃 하면 _user = null 처리
 */
app.service('Auth', function ($http, $q, $rootScope, $timeout, $window) {

  var service = this;
  this._user = null;

  /**
   * 현재 사용자 정보 저장 => 이 과정이 클라이언트에서의 로그인 처리임
   * @memberof Auth
   * @param {Object} u 로그인 사용자 정보 객체
   */
  this.setCurrentUser = function(u) {
    console.log(u);
    service._user = u;
    $window.localStorage.setItem('hcm_assistant', JSON.stringify(u));    // localStorage 에도 저장
    $timeout(function(){
      $rootScope.$broadcast('user:set', u);   // 여기서 broadcast 하면 user-panel directive 에서 $scope.on 으로 받아서 사용
    }, 500);
  };

  /**
   * 현재 사용자 정보 삭제
   * @memberof Auth
   */
  this.removeCurrentUser = function() {
    service._user = null;
    $window.localStorage.removeItem('hcm_assistant');  // localStorage 에서도 삭제
    $rootScope.$broadcast('user:unset');  // 여기서 broadcast 하면 user-panel directive 에서 $scope.on 으로 받아서 사용
  };

  /**
   * 현재 사용자 정보 얻기
   * @memberof Auth
   * @returns {Promise} Future object
   */
  this.currentUser = function() {
    var d = $q.defer();
    if(service._user) {   // _user 에 정보가 있는 경우
      d.resolve(service._user);
    } else if($window.localStorage.getItem('hcm_assistant')) {   // _user 에는 없지만 localStorage 에 있는 경우
      var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));
      console.log('setting current user');
      service.setCurrentUser(user);
      d.resolve(service._user);
    } else {
      d.resolve(null);
    }
    return d.promise;
  };
});
'use strict';
/**
 * @ngdoc service
 * @name Database
 * @description
 *  UDML(IR, IP Database)로부터 데이터를 얻는 기능
 */
app.service('Database', function ($http, $q) {

  this.categories = {};
  this.brands = {};
  this.devices = {};
  this.current = {};

  /**
   * entertainment device 인지 체크
   * @memberof Database
   * @param {String} deviceType device type name
   * @returns {Boolean}
   */
  this.checkIfEntertainment = function(deviceType) {
    return deviceType === 'Televisions' || deviceType === 'Satellite Set Top Boxes'|| deviceType === 'Cable and Fios Set Top Boxes'|| deviceType === 'DVR' ? true: false;
  };

  /**
   * categories (device_types) 저장
   * @memberof Database
   * @param {Object} categories
   */
  this.setCategories = function(categories) {
    this.categories = categories;
  };

  /**
   * categories (device_types) 얻기
   * @memberof Database
   * @returns {Object}
   */
  this.getCategories = function() {
    return this.categories;
  };

  /**
   * 현재 category (device_type) 저장
   * @memberof Database
   * @param {String} category device type
   */
  this.setCurrentCategory = function(category) {
    this.current.category = category;
  };

  /**
   * 현재 category (device_type) 얻기
   * @memberof Database
   * @returns {String} device type
   */
  this.getCurrentCategory = function() {
    return this.current.category;
  };

  /**
   * brands 저장
   * @memberof Database
   * @param {Object} brands
   */
  this.setBrands = function(brands) {
    this.brands = brands;
  };

  /**
   * brands 얻기
   * @memberof Database
   * @returns {Object}
   */
  this.getBrands = function() {
    return this.brands;
  };

  /**
   * 현재 brand 저장
   * @memberof Database
   * @param brand
   */
  this.setCurrentBrand = function(brand) {
    this.current.brand = brand;
  };

  /**
   * 현재 brand 얻기
   * @memberof Database
   * @returns {*}
   */
  this.getCurrentBrand = function() {
    return this.current.brand;
  };

  /**
   * devices 저장
   * @memberof Database
   * @param {Object} devices
   */
  this.setDevices = function(devices) {
    this.devices = devices;
  };

  /**
   * devices 얻기
   * @memberof Database
   * @returns {Object}
   */
  this.getDevices = function() {
    return this.devices;
  };

  /**
   * 현재 momdel 저장
   * @memberof Database
   * @param model
   */
  this.setCurrentModel = function(model) {
    this.current.model = model;
  };

  /**
   * 현재 model 얻기
   * @memberof Database
   * @returns {*}
   */
  this.getCurrentModel = function() {
    return this.current.model;
  };

  /**
   * device category 얻기
   * @memberof Database
   * @returns {Promise} Future object
   */
  this.retreiveDeviceTypes = function() {
    var self = this,
        d = $q.defer();

    // device category 얻기 API 호출
    $http.get('/urcassistant/api/db/device_types').success(function(response) {
      console.log(response);
      if(response.result) {
        self.setCategories(response.types);
        d.resolve(response.types);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * brand 목록 얻기
   * @memberof Database
   * @param {String} type device type
   * @returns {Promise} Future object
   */
  this.retrieveDeviceBrands = function(type) {

    var self = this,
        d = $q.defer();

    // brand 목록 얻기 API 호출
    $http.get('/urcassistant/api/db/brands/' + type).success(function(response) {
      if(response.result) {
        self.setBrands(response.brands);
        d.resolve(response.brands);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * device 목록 얻기
   * @memberof Database
   * @param {String} type device type
   * @param {String} brand brand name
   * @param {String} query search query
   * @returns {Promise} Future object
   */
  this.searchModels = function(type, brand, query) {
    console.log('query: ' + query);
    var self = this,
        d = $q.defer(),
        url = '/urcassistant/api/db/search/' + type + '/' + brand;
    
    url += !query || query === '' ?  ''  : '/' + query;

    // device 목록 얻기 API 호출
    $http.get(url).success(function(response) {
      if(response.result) {
        self.setDevices(response.devices);
        d.resolve(response.devices);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * popular device 목록 얻기
   * @memberof Database
   * @param {String} type device type
   * @param {String} brand brand name
   * @returns {Promise} Future object
   */
  this.searchPopularModels = function(type, brand) {
    var self = this,
      d = $q.defer(),
      url = '/urcassistant/api/db/search_popular/' + type + '/' + brand;

    // device 목록 얻기 API 호출
    $http.get(url).success(function(response) {
      if(response.result) {
        self.setDevices(response.devices);
        d.resolve(response.devices);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 해당 device 데이터 얻기 - 2015.2.18 현재 프로토콜 문서 정의 내용과 아래 코드의 파라미터가 다름. 문의필요.
   * @memberof Database
   * @param {String} type device type
   * @param {String} brand brand name
   * @param {Number} modelId
   * @param codeset
   * @param dbType
   * @returns {Promise} Future object
   */
  this.getDeviceInfo = function(type, brand, modelId, codeset, dbType) {
    var d = $q.defer();
    var url = '/urcassistant/api/db/device/' + type + '/' + brand + '/' + modelId + '/' + codeset + '/' + dbType;
    console.log(url);

    // 해당 device 데이터 얻기 API 호출
    $http.get(url)
    .success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.device);
      } else {
        d.reject(response.error);
      }
    })
    .error(function (error) {
      d.reject(error);
    });

    return d.promise;

  };

  /**
   * 현재 데이터 초기화
   * @memberof Database
   */
  this.clearData = function() {
    this.current = {};
  };
});
'use strict';
/**
 * @ngdoc service
 * @name Devices
 * @description
 *  device 관련 기능
 */
app.service('Devices', function ($http, $q, Rooms) {

  this.icons = [];
  this.menuBtnPages = [];
  this.hardBtnPages = [];
  this.currentData = {};
  this.functions = [];
  this.currentDevice = {};

  /**
   * Learn codes from an IR remote 메뉴에 나오는 hard button 목록 설정
   * @memberof Devices
   */
  this.initHardBtnPages = function() {
    this.hardBtnPages = [{btns:[{name:'VOL +',id:275},{name:'PREV CH',id:278},{name:'CH +',id:279},{name:'VOL -',id:276},{name:'MUTE',id:277},{name:'CH -',id:280}]},{btns:[{name:'MENU',id:305},{name:'UP',id:322},{name:'GUIDE',id:304},{name:'LEFT',id:320},{name:'SELECT',id:324},{name:'RIGHT',id:321},{name:'INFO',id:306},{name:'DOWN',id:323},{name:'EXIT',id:307}]},{btns:[{name:'SKIP -',id:295},{name:'PLAY',id:288},{name:'SKIP +',id:294},{name:'REW',id:292},{name:'PAUSE',id:291},{name:'FWD',id:293},{name:'STOP',id:289},{name:'REC',id:296},{name:'YELLOW',id:548},{name:'BLUE',id:549},{name:'RED',id:550},{name:'GREEN',id:551}]},{btns:[{name:'1',id:337},{name:'2',id:338},{name:'3',id:339},{name:'4',id:340},{name:'5',id:341},{name:'6',id:342},{name:'7',id:343},{name:'8',id:344},{name:'9',id:345},{name:'/',id:346},{name:'0',id:336},{name:'ENT',id:348}]}];

  };

  /**
   * icons 저장
   * @memberof Devices
   * @param {Array} icons icons array
   */
  this.setIcons = function(icons) {
    this.icons = icons;
  };

  /**
   * icons 얻기
   * @memberof Devices
   * @returns {Array} icons array
   */
  this.getIcons = function() {
    return this.icons;
  };

  /**
   * icon 목록이 있는 json 파일로부터 데이터 얻기
   * @memberof Devices
   * @returns {Promise} Future object
   */
  this.getInfoJson = function() {
    return $http.get('/file/images/device_icons/info.json');
  };

  /**
   * device data 저장
   * @memberof Devices
   * @param {Object} data device data
   */
  this.setCurrentData = function(data) {
    this.currentData = data;
  };

  /**
   * device data 얻기
   * @memberof Devices
   * @returns {Object}
   */
  this.getCurrentData = function() {
    return this.currentData;
  };

  /**
   * add device 하는 중 device 임시 저장
   * @memberof Devices
   * @param {Object} data device data
   */
  this.setCurrentDevice = function(device) {
    this.currentDevice = device;
  };

  /**
   * add device 하는 중 임시 device 데이터 얻기
   * @memberof Devices
   * @returns {Object}
   */
  this.getCurrentDevice = function() {
    return this.currentDevice;
  };

  this.setMenuBtnPages = function(pages) {
    this.menuBtnPages = pages;
  };

  this.getMenuBtnPages = function() {
    return this.menuBtnPages;
  };

  this.setHardBtnPages = function(pages) {
    this.hardBtnPages = pages;
  };

  this.getHardBtnPages = function() {
    return this.hardBtnPages;
  };


  this.initFunctions = function() {
     this.functions = [];
  };

  this.setFunctions = function(id, funcs) {

    for(var index = 0; index < this.functions.length; index++) {
      if(this.functions[String(id)] !== undefined) {
        this.functions[String(id)] = angular.copy(funcs);
        return;
      }
    }

    this.functions[String(id)] = angular.copy(funcs);
  };

  this.getFunctions = function(id) {
    if(this.functions[String(id)] !== undefined) {
      return this.functions[String(id)];
    }
    return null;
  };


  this.fetchFunctions = function(roomId, deviceId) {
    var d = $q.defer();
    $http.post('/urcassistant/api/device/get_con_dev/' + roomId + '/' + deviceId).success(function(response) {
      if (response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });
    return d.promise;
  };


  this.fetchPunchDevice = function(roomId, deviceId) {

    var d = $q.defer();
    $http.post('/urcassistant/api/device/get_punch/' + roomId + '/' + deviceId).success(function(response) {
      if (response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });
    return d.promise;
    
  };

  this.createOne = function(roomId, data) {
    var d = $q.defer();

    $http.post('/urcassistant/api/device/create/' + roomId, data).success(function (response) {
      if (response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

  this.createCustomOne = function(roomId, data) {
    var d = $q.defer();

    $http.post('/urcassistant/api/device/create_custom/' + roomId, data).success(function (response) {
      if (response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

  this.makeBlankMenuButton = function(btnId, pgBtnIdx, props ) {
    return {  id: btnId, 
              page_btn_idx: pgBtnIdx, 
              display_text: null, 
              repeat_min: props.repeat.min, 
              repeat_macro: props.repeat.macro, 
              repeatSetting: 'default',
              room_id: props.room_id,
              device_id: props.device_id ? props.device_id : -1,
              activity: '',
              auto_wait: 0,
              edit_type: 1,
              func: null,
              hidden_option: 0,
              image_name: '',
              link_id: -1,
              macro: '',     
              popup: 0,
              press_hold: true };
  };     


  this.makeBlankMenuPage = function(props) {
    var pg = { id:0, btns: [] };

    for (var i=0, j=8192; i < 6; i++, j++) {
      pg.btns.push({  id: j,
                      page_btn_idx: i,
                      display_text: null, 
                      repeat_min: props.repeat.min,
                      repeat_macro: props.repeat.macro,
                      repeatSetting: 'default',
                      room_id: props.room_id,
                      device_id: props.device_id ? props.device_id : -1,  
                      activity: '',
                      auto_wait: 0,
                      edit_type: 1,
                      func: null,
                      hidden_option: 0,
                      image_name: '',
                      link_id: -1,
                      macro: '',     
                      popup: 0,
                      press_hold: true });
    }

    console.log(pg);
    return pg;
  };

  this.setBtnDefaults = function(button) {
    if (!button.hasOwnProperty('activity')) { button.activity = ''; }
    if (!button.hasOwnProperty('auto_wait')) { button.auto_wait = 0; }
    if (!button.hasOwnProperty('edit_type')) { button.edit_type = 1; }
    if (!button.hasOwnProperty('func')) { button.func = null; }
    if (!button.hasOwnProperty('hidden_option')) { button.hidden_option = 0; }
    if (!button.hasOwnProperty('image_name')) { button.image_name = ''; }
    if (!button.hasOwnProperty('macro')) { button.macro = ''; }
    if (!button.hasOwnProperty('link_id')) { button.link_id = -1; }
    if (!button.hasOwnProperty('popup')) { button.popup = 0; }
    if (!button.hasOwnProperty('press_hold')) { button.press_hold = true; }
  };

  this.addHardBtnProps = function (props) {
    var self = this;
    _.forEach(self.hardBtnPages, function(hardBtnPage) {
      _.forEach(hardBtnPage.btns, function(btn) {

        if (!btn.hasOwnProperty('display_text')) {
          btn.display_text = null;
          btn.repeat_min = props.repeat.min;
          btn.repeat_macro = props.repeat.macro;
          btn.repeatSetting = 'default';
          btn.device_id = props.device_id;
          btn.room_id = props.room_id;
          self.setBtnDefaults(btn);
        }
      });
    });
  };


  this.getOne = function(roomId, deviceId) {
    var deviceProps,
        self = this,
        d = $q.defer();

    
    function assignBtnFields(btn, macro, props) {
      if ( macro.hasOwnProperty('repeat_macro') && macro.hasOwnProperty('repeat_min') ) {
        _.assign(btn, { repeat_min: macro.repeat_min,
                        repeat_macro: macro.repeat_macro,
                        repeatSetting:'custom' });
      } else {
        _.assign(btn, { repeat_min: props.repeat.min,
                        repeat_macro: props.repeat.macro,
                        repeatSetting:'default' });
      }

      btn.func = _.where(props.dbCon, {'id': macro.func})[0]; 

      console.log('press_hold', macro.press_hold);
      
      if (macro.hasOwnProperty('press_hold')) {
        btn.press_hold = macro.press_hold ? true:false;
      } else {
        btn.press_hold = btn.func.press_hold ? true:false;
      }
    }

    $http.post('/urcassistant/api/device/get/' + roomId + '/' + deviceId)
    .success(function(response) {
      console.log(response);
      if (response.result) {
        self.menuBtnPages = [];
        self.initHardBtnPages();

        deviceProps = _.omit(response.data, 'pages');
        console.log(deviceProps);


        if (response.data.pages.length=== 0) {
          self.menuBtnPages.push( self.makeBlankMenuPage(deviceProps) );
          self.addHardBtnProps(deviceProps);
        } else {          
          if (response.data.pages.length === 1 && response.data.pages[0].id === -1) {
            console.log('1 page and its a hardBtnPage');
            self.menuBtnPages.push( self.makeBlankMenuPage(deviceProps) );
          }

          _.forEach(response.data.pages, function(page) {
            var pgToAdd = { btns: [] },
                pageIds;

            for (var i=0; i < 6; i++) {
              pgToAdd.btns.push({ page_btn_idx: i, display_text: null });
            }

            // Hard button manipulation

            if (page.id === -1) {
              _.forEach(page.btns, function(btn) {
                _.forEach(self.hardBtnPages, function(hardBtnPage) {
                  _.forEach(hardBtnPage.btns, function(button) {
                    if (button.id === btn.id) {
                      var macro = JSON.parse(btn.macro)[0];

                      _.assign(button, btn);
                      assignBtnFields(button, macro, deviceProps);
                      
                    }
                  });
                });
              });

              return;
            }

            pgToAdd.id = page.id;

            // Menu page button manipulation

            _.forEach(page.btns, function(btn) {
              var macro = JSON.parse(btn.macro)[0],
                  newBtn = _.clone(btn);

              assignBtnFields(newBtn, macro, deviceProps);

              pgToAdd.btns.splice(newBtn.page_btn_idx,1,newBtn);
            });

            // Filling in the rest of the page

            pageIds = _(pgToAdd.btns).pluck('id').value();
            if(pageIds.filter(Number).length < 6) {

              //Mathematical equation to get the correct starting id of the page to be added
              var min = 8192 + (pgToAdd.id * 6),
                btnId = min;
              console.log(btnId);

              for (var idx = 0; idx < 6; idx++) {
                var button = pgToAdd.btns[idx];
                button.id = btnId;
                //if there is no repeat setting on the btn then add the default
                if ( !button.hasOwnProperty('repeatSetting') ) {
                  button.repeat_min = deviceProps.repeat.min;
                  button.repeat_macro = deviceProps.repeat.macro;
                  button.repeatSetting = 'default';
                }
                if (!button.hasOwnProperty('room_id')) { button.room_id = roomId; }
                if (!button.hasOwnProperty('device_id')) { button.device_id = deviceId; }     
                
                self.setBtnDefaults(button);

                btnId++;
              }
            }

            self.menuBtnPages.push({ id: pgToAdd.id , btns: pgToAdd.btns });
          });

          self.addHardBtnProps(deviceProps);
        }


        d.resolve(deviceProps);
      } else {
        d.reject( response.error);
      }
    })
    .error(function(error) {
      alert('Please try again');
      d.reject(error);
    });
    return d.promise;

  };



  this.storeOne = function(roomId, deviceId, data) {
    var d = $q.defer();
    $http.post('/urcassistant/api/device/store/' + roomId + '/' + deviceId, data).success(function (response) {
      if (response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }).error(function () {
      d.reject(error);
    });
    return d.promise;
  };

});

'use strict';

app.service('Rooms', function ($http, $q, Systems) { 

  this.getDevices = function (id) {
    return Systems.getRoom(id).devices;
  };

  this.create = function (data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    $http.post('/urcassistant/api/room/create/' + sysId, data).success(function (response) {
      if (response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

  //TODO: Add these functions to service

  this.get = function (id) {

  };

  this.fetch = function (id) {

  };

  this.edit = function (roomId, data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    $http.post('/urcassistant/api/room/edit/' + sysId + '/' + roomId, data).success(function (response) {
      if (response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

  this.delete = function (roomId) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    $http.post('/urcassistant/api/room/delete/' + sysId + '/' + roomId).success(function (response) {
      if (response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

  this.setRemote = function (roomId, data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    $http.post('/urcassistant/api/room/set_remote/' + sysId + '/' + roomId, data).success(function (response) {
      console.log(response);
      if (response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

  this.delRemote = function (roomId, data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    $http.post('/urcassistant/api/room/del_remote/' + sysId + '/' + roomId, data).success(function (response) {
      console.log(response);
      if (response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };


  this.baseStations = function (action, roomId, data) {
    var d = $q.defer(),
        url = '/urcassistant/api/room/',
        sysId = Systems.getCurrentSystem().id;

    
    switch(action) {
      case 'add':
        url += 'add_bstation/';
        break;
      case 'edit':
        url += 'edit_bstation/';
        break;
      case 'delete':
        url += 'del_bstation/';
        break;    
      default:
        break;
    }
    

    $http.post(url + sysId + '/' + roomId, data).success(function (response) {
      console.log(response);
      if (response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }).error(function (error) {
      d.reject(error);
    });
    return d.promise;
  };

 



});
'use strict';
/**
 * @ngdoc service
 * @name Systems
 * @description
 *  system 관련 기능
 */
app.service('Systems', function ($http, $q, $window) {

  this.system = null ;
  this.dataMacro = null;
  this.isChanged = false;
  this.currentRoom = { 'id': null };
  this.roomDevices = null;
  this.mainDevice = null;
  this.dataSearchDevices = null;
  this.currentJobId = null;
  this.currentJob = null;

  /**
   * job id 로 부터 job 생성
   * @memberof Systems
   * @param {String} data job ID json string
   * @returns {Promise} Future object
   */
  this.import = function (data) {

    var d = $q.defer();

    // job 생성 API 호출
    $http.post('/urcassistant/api/system/import', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * job id 로 부터 system id 얻기
   * @memberof Systems
   * @param {String} data job ID json string
   * @returns {Promise} Future object
   */
  this.getSystems = function (data) {
    var d = $q.defer();

    // job 생성 API 호출
    $http.post('/urcassistant/api/system/get_systems', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * base station 의 type 들을 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getModelTypes = function() {
    // base station 의 type 들을 얻는 API 호출
    return $http.post('/urcassistant/api/system/types').then(function(response) {
      return response;
    });
  };

  /**
   * remote 의 type 들을 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getRemoteTypes = function() {
    // remote 의 type 들을 얻는 API 호출
    return $http.post('/urcassistant/api/remote/types').then(function(response) {
      return response;
    });
  };

  /**
   * system 생성
   * @memberof Systems
   * @param {String} data system 생성에 필요한 정보들 json string
   * @returns {Promise} Future object
   */
  this.createOne = function (data) {

    var d = $q.defer();

    // system 생성 API 호출
    $http.post('/urcassistant/api/system/create', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.jobId);   // 만들어진 system 의 job ID
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * job 의 상태 설정 (0:init, 1:processing, 2:Ready)
   * @memberof Systems
   * @param {String} data jobId, status json string
   * @returns {Promise} Future object
   */
  this.setStatus = function (data) {

    var d = $q.defer();

    // system 생성 API 호출
    $http.post('/urcassistant/api/system/set_status', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * job 목록 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.jobList = function (options) {

    var d = $q.defer(),
      jsonData;

    if (options) {
      jsonData = JSON.stringify(options);
    }

    // job 목록 얻기 API 호출
    $http.post('/urcassistant/api/system/list', jsonData).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * system 정보 얻어와서 저장
   * @memberof Systems
   * @param {Number} id system ID
   * @returns {Promise} Future object
   */
  this.updateSystem = function (id, data) {

    var self = this,
           d = $q.defer();

    if (!data) {
      data = JSON.stringify({jobId: self.getCurrentJobId()});
    }

    // system 얻기 API 호출
    $http.post('/urcassistant/api/system/get/' + id, data).success(function(response) {
      console.log(response);
      if(response.result) {
        // 현재 system 의 base station 에 MAC 이 있는지 검사하고 없으면 TMP_ 로 시작하는 임의의 값으로 부여
        _.each(response.data.rooms, function(room) {
          _.each(room.bstations, function(bstation) {
            if (!bstation.mac) {
              bstation.mac = 'TMP_' + bstation.name.split(' ')[1];
            }
          });
        });

        self.loadSystem(response.data);   // 얻어온 system 을 저장
        self.setCurrentJobId(JSON.parse(data).jobId);

        var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));    // localStorage 에서 사용자 정보 얻기
        user.system_id = response.data.id;
        user.job_id = self.getCurrentJobId();

        $window.localStorage.setItem('hcm_assistant', JSON.stringify(user));   // 사용자 정보에 system ID, job ID 를 더해서 localStorage 에 저장
        d.resolve(response.data);
      } else {
        d.reject(response.data);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * system 삭제
   * @memberof Systems
   * @param {Number} id system ID
   * @returns {Promise} Future object
   */
  this.deleteSystem = function (id) {

    var self = this,
           d = $q.defer();

    // system 삭제 API 호출
    $http.post('/urcassistant/api/system/delete/' + id).success(function(response) {
      console.log(response);
      if(response.result) {
        _.remove(self.all, {'id': id});   // 저장되어 있는 system 목록에서 삭제할 system 삭제

        if (self.system.id === id) {    // 삭제한 system 이 현재 system 이었다면
          var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));
          user.system_id = null;
          user.job_id = null;
          $window.localStorage.setItem('hcm_assistant', JSON.stringify(user));   // localStorage 에 저장되어 있는 사용자 정보에서 system ID, job ID 삭제
          
          self.system = null;   // 현재 system null 처리
        }

        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * system 저장
   * @memberof Systems
   * @param {Object} system
   */
  this.loadSystem = function(system) {
    this.system = system;   // system 정보를 현재 system 으로 저장

    //$window.localStorage.setItem('system', system.id);
  };

  /**
   * system 정보 얻기
   * @memberof Systems
   * @returns {Object} 현재 system 정보 객체
   */
  this.getCurrentSystem = function() {
    return this.system;
  };

  /**
   * job request data 정보 얻어와서 저장
   * @memberof Systems
   * @param {String} data job id json string
   * @returns {Promise} Future object
   */
  this.getSubmitData = function (data) {
    var self = this,
      d = $q.defer();

    if (!data) {
      data = JSON.stringify({jobId: self.getCurrentJobId()});
    }

    // Job Request Data 얻기 API 호출
    $http.post('/urcassistant/api/system/get_submit_data', data).success(function(response) {
      if(response.result) {
        console.log(response);
        d.resolve(response.data);
      } else {
        d.reject(response.data);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 현재 room ID 얻기
   * @memberof Systems
   * @returns {Number} 현재 room ID
   */
  this.getCurrentRoom = function() {
    console.log('getting curr room id: ' + this.currentRoom.id);
    return this.currentRoom.id;
  };

  /**
   * 현재 room ID 저장
   * @memberof Systems
   * @param {Number} id room ID
   */
  this.setCurrentRoom = function(id) {
    console.log('setting curr room id to ' + id);
    this.currentRoom.id = id;
  };

  /**
   * 현재 system 이 가지고 있는 room 들 중에서 선택한 room 정보 얻기
   * @memberof Systems
   * @param {Number} id room ID
   * @returns {Object|Boolean} room 정보 객체 또는 false
   */
  this.getRoom = function(id) {
    var self = this;
    var room = _.find(self.system.rooms, { 'id': id });
    if (room !== undefined) {
      return room;
    } else {
      return false;
    }
  };

  /**
   * 현재 room 이 가지고 있는 device 들 중에서 선택한 device 정보 얻기
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @returns {Object|Boolean} device 정보 객체 또는 false
   */
  this.getDevice = function(roomId, deviceId) {
    var self = this;
    var room = _.find(self.system.rooms, { 'id': roomId });
    var device = _.find(room.devices, { 'id': deviceId });
    if (device !== undefined) {
      return device;
    } else {
      return false;
    }
  };

  /**
   * room 정보 얻어와서 저장
   * @memberof Systems
   * @param {Number} id room ID
   * @returns {Promise} Future object
   */
  this.updateRoomDevices = function(id) {

    var self = this,
           d = $q.defer();

    // room 얻기 API 호출
    $http.post('/urcassistant/api/room/get/' + this.system.id + '/' + id).success(function(response) {
      if(response.result) {
        console.log(response.data);
        self.setRoomDevices(response.data);   // room 정보 저장
        d.resolve(response.data);
      }
      else {
        d.reject('Unable to retrieve the data for the room. Please try again. If the error continues please log out and then log in again.');
      }
    }).error( function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * room 정보 저장
   * @memberof Systems
   * @param {Object} roomDevices
   */
  this.setRoomDevices = function(roomDevices) {
    this.roomDevices = roomDevices;
  };

  /**
   * 저장된 room 정보 얻기
   * @memberof Systems
   * @returns {Object|null}
   */
  this.getRoomDevices = function() {
    return this.roomDevices;
  };

  /**
   * 해당 deivce ID 와 연계된 button 의 데이터 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @returns {Promise} Future object
   */
  this.updateCurrentMacroForDevice = function(roomId, deviceId) {

    var self = this;
    return self.updateMacro('get_button_macro_with_device', roomId, deviceId, -1);
  };

  /**
   * 해당 room 의 power macro 데이터 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.updateCurrentMacroForPower = function(roomId) {

    var self = this;
    return self.updateMacro('get_power_macro', roomId, -1, -1);
  };

  /**
   * button ID 에 해당하는 button 의 데이터 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {Number} buttonId button ID
   * @returns {Promise} Future object
   */
  this.updateCurrentMacro = function(roomId, deviceId, buttonId) {

    var self = this;
    return self.updateMacro('get_button_macro', roomId, deviceId, buttonId);
  };

  /**
   * button 의 정보 얻어와서 저장
   * @memberof Systems
   * @param {String} type 얻어올 button 정보의 type
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {Number} buttonId button ID
   * @returns {Promise} Future object
   */
  this.updateMacro = function(type, roomId, deviceId, buttonId) {

    var self = this,
           d = $q.defer();
    deviceId = deviceId || null;

    var urlData;
    if(type === 'get_button_macro_with_device') {   // 해당 deivce ID 와 연계된 button 의 데이터 얻기
      if(deviceId < 0) {
        alert('The automated activity could not be saved.  Please check the steps in the command list and try again.');
        return;
      }
      urlData = '/urcassistant/api/btn/get_button_macro_with_device/' + roomId + '/' + deviceId;
    }
    else if(type === 'get_power_macro') {   // 해당 room 의 power macro 데이터 얻기
      urlData = '/urcassistant/api/btn/get_power_macro/' + roomId;
    }
    else if(type === 'get_button_macro') {  // button ID 에 해당하는 button 의 데이터 얻기
      if(buttonId < 0) {
        alert('The automated activity could not be saved.  Please check the steps in the command list and try again.');
        return;
      }
      urlData = '/urcassistant/api/btn/get_button_macro/' + roomId + '/' + deviceId + '/' + buttonId;
    }
    else {
      alert('The automated activity could not be saved.  Please check the steps in the command list and try again.');
      return;
    }

    // 선택된 type 에 따라 정해진 urlData 의 API 호출
    $http.post(urlData).success(function(response) {

      if(response.result) {
        console.log(response.data);
        self.setCurrentMacro(response.data);    // 얻어온 정보를 현재 macro 데이터로 저장
        d.resolve(response.data);
      }
      else {
        alert('Unable to retrieve activity information.  Please try again');
        d.reject('Unable to retrieve activity information.  Please try again');
      }

    }).error(function(error) {
      alert('Please try again');
      d.reject(error);
    });
    return d.promise;
  };

  /**
   * 현재 macro 데이터 저장
   * @memberof Systems
   * @param {Object} dataMacro
   */
  this.setCurrentMacro = function(dataMacro) {
    this.dataMacro = dataMacro;
  };

  /**
   * 현재 macro 데이터 얻기
   * @memberof Systems
   * @returns {Object|null} 현재 macro 데이터
   */
  this.getCurrentMacro = function() {
    return this.dataMacro;
  };

  /**
   * 검색된 device 목록 저장
   * @memberof Systems
   * @param {Array} devices device 목록 array
   */
  this.setSearchDevices = function(devices) {

    this.dataSearchDevices = devices;
  };

  /**
   * 저장되어 있는 검색된 device 목록 얻기
   * @memberof Systems
   * @returns {Array|null} device 목록 array
   */
  this.getSearchDevices = function() {

    return this.dataSearchDevices;
  };

  /**
   * main device 저장
   * @memberof Systems
   * @param {Object} device device 정보 객체
   */
  this.setMainDevice = function(device) {
    this.mainDevice = device;
  };

  /**
   * 저장된 main device 얻기
   * @memberof Systems
   * @returns {Object|null} device 정보 객체
   */
  this.getMainDevice = function() {
    return this.mainDevice;
  };

  /**
   * main device 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.updateMainDevice = function(roomId) {

    var self = this,
           d = $q.defer(),
         url = '/urcassistant/api/device/get_main/' + roomId;

    // main device 얻어오는 API 호출
    $http.post(url)
    .success(function(response) {
      if(response.result) {
        self.setMainDevice(response.data);  // main device 저장
        d.resolve(response.data);
      }
      else {
        alert(response.error);
        d.reject(response.error);
      }

    })
    .error( function(error) {
      alert('Please try again');
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * main device 정보 서버에 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.storeMainDevice = function(roomId) {

    var self = this,
           d = $q.defer(),
         url = '/urcassistant/api/device/store_main/' + roomId,
     mainDev = { data : self.getMainDevice() },
    jsonData = JSON.stringify(mainDev);

    console.log(mainDev);

    // main device 정보 저장 API 호출
    $http.post(url,jsonData)
    .success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }

    })
    .error( function(error) {
      d.reject(error);
    });
    return d.promise;
  };

  /**
   * 현재 job ID 저장
   * @memberof Systems
   * @param {String} id job ID
   */
  this.setCurrentJobId = function(id) {
    this.currentJobId = id;
  };

  /**
   * 현재 job ID 얻기
   * @memberof Systems
   * @returns {String} job ID
   */
  this.getCurrentJobId = function() {
    return this.currentJobId;
  };

  /**
   * 현재 job 저장
   * @memberof Systems
   * @param {Object} job job data
   */
  this.setCurrentJob = function(job) {
    this.currentJob = job;
  };

  /**
   * 현재 job 얻기
   * @memberof Systems
   * @returns {Object} job data
   */
  this.getCurrentJob = function() {
    return this.currentJob;
  };

  /**
   * system 의 timezone 설정
   * @memberof Systems
   * @param {String} data timezone ID/daylight saving option(0: off, 1: on)/time_type(0: 12hour, 1:24hour) json string
   * @returns {Promise} Future object
   */
  this.setTimeZone = function(data) {

    var d = $q.defer(),
      url = '/urcassistant/api/system/set_timezone/' + this.system.id;
    
    // system 의 timezone 설정하는 API 호출
    $http.post(url,data)
    .success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }

    })
    .error( function(error) {
      d.reject(error);
    });
    return d.promise;
    
  };

  /**
   * button 생성
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} mainDeviceId main device ID
   * @param {String} data button text/automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.createCustomButtonMacro = function (roomId, mainDeviceId, data) {
    // button 생성 API 호출
    return $http.post('/urcassistant/api/btn/create/' + roomId + '/' + mainDeviceId, data).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 room 의 power macro 데이터 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {String} data automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.storePowerMacro = function (roomId, data) {
    // 해당 room 의 power macro 데이터 저장하는 API 호출
    return $http.post('/urcassistant/api/btn/store_power_macro/' + roomId, data).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 device ID 와 연계된 button 의 데이터 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {String} data automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.storeDeviceButtonMacro = function (roomId, deviceId, data) {
    // 해당 device ID 와 연계된 button 의 데이터 저장하는 API 호출
    return $http.post('/urcassistant/api/btn/store_button_macro_with_device/' + roomId + '/' + deviceId, data).then(function(response) {
      return response;
    });
  };

  /**
   * button ID 에 해당하는 button 의 데이터 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} mainDeviceId main device ID
   * @param {Number} btnId button ID
   * @param {String} data automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.storeCustomButtonMacro = function (roomId, mainDeviceId, btnId, data) {
    // button ID 에 해당하는 button 의 데이터 저장하는 API 호출
    return $http.post('/urcassistant/api/btn/store_button_macro/' + roomId + '/' + mainDeviceId + '/' + btnId, data).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 room 의 power macro 삭제
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.deletePowerMacro = function(roomId) {
    // 해당 room 의 power macro 삭제하는 API 호출
    return $http.post('/urcassistant/api/btn/delete_power_macro/' + roomId).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 device ID 와 연계된 button 의 macro 삭제
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @returns {Promise} Future object
   */
  this.deleteButtonMacroWithDevice = function(roomId, deviceId) {
    // 해당 device ID 와 연계된 button 의 macro 삭제하는 API 호출
    return $http.post('/urcassistant/api/btn/delete_button_macro_with_device/' + roomId + '/' + deviceId).then(function(response) {
      return response;
    });
  };

  /**
   * button ID 에 해당하는 button 삭제
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {Number} btnId button ID
   * @returns {Promise} Future object
   */
  this.deleteButtonMacro = function(roomId, deviceId, btnId) {
    // button ID 에 해당하는 button 삭제하는 API 호출
    return $http.post('/urcassistant/api/btn/delete_button_macro/' + roomId + '/' + deviceId + '/' + btnId).then(function(response) {
      return response;
    });
  };

});

'use strict';
/**
 * @ngdoc service
 * @name User
 * @description
 *  사용자 정보 관리와 관련된 기능
 */
app.service('User', function ($rootScope, $http, $q, $window, Auth, jwtHelper) {

  /**
   * 로그인
   * @memberof User
   * @param {String} data 사용자 아이디/패스워드 json string
   * @returns {Promise} Future object
   */
  this.login = function(data) {
    var self = this,
        d = $q.defer();

    // 로그인 API 호출
    $http.post('/urcassistant/api/user/login', data).success(function(response) {
      console.log(response);
      if (response.result) {
        var token = jwtHelper.decodeToken(response.token);
        var name = token.sub;
        var id = token.usr_id;
        var user = { id: id, username: name, email: response.email, token: response.token};
        Auth.setCurrentUser(user);
      }
      d.resolve(response); 
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 로그아웃
   * @memberof User
   * @returns {Promise} Future object
   */
  this.logout = function() {
    var d = $q.defer();
    Auth.removeCurrentUser();
    d.resolve();
    return d.promise;
  };

  /**
   * 사용자 패스워드 변경
   * @memberof User
   * @param {String} data 이전 패스워드/변경할 패스워드 json string
   * @returns {Promise} Future object
   */
  this.changePassword = function(data) {
    var d = $q.defer(),
     self = this;

    // 사용자 패스워드 변경 API 호출
    $http.post('/urcassistant/api/user/new_password', data)
    .success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    })
    .error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * company 목록 얻기
   * @memberof User
   * @returns {Promise} Future object
   */
  this.companyList = function (options) {

    var d = $q.defer(),
      jsonData;

    if (options) {
      jsonData = JSON.stringify(options);
    }

    // job 목록 얻기 API 호출
    $http.post('/urcassistant/api/user/company', jsonData).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

});
