'use strict';

//HCM Installer Auth service

app.service('Auth', function ($http, $q, $rootScope, $timeout, $window) {

  var service = this;
  this._user = null;
  
  this.setCurrentUser = function(u) {
    console.log(u);
    service._user = u;
    $window.localStorage.setItem('hcm_installer', JSON.stringify(u));
    $rootScope.companyName = u.companyName;
    $rootScope.companyId = u.companyId;
    $timeout(function(){
      $rootScope.$broadcast('user:set', u);
    }, 500);
  };

  this.removeCurrentUser = function() {
    service._user = null;
    $window.localStorage.removeItem('hcm_installer');
    $rootScope.companyName = '';
    $rootScope.companyId = '';
    $rootScope.$broadcast('user:unset');
  };

  this.currentUser = function() {
    var d = $q.defer();
    if(service._user) {
      d.resolve(service._user);
    } else if($window.localStorage.getItem('hcm_installer')) {
      var user = JSON.parse($window.localStorage.getItem('hcm_installer'));
      console.log('setting current user');
      service.setCurrentUser(user);
      d.resolve(service._user);
    } else {
      d.resolve(null);
    }
    return d.promise;
  };
});
'use strict';

app.service('Database', function ($http, $q, baseUrl) {

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

  this.setCategories = function(categories) {
    this.categories = categories;
  };

  this.getCategories = function() {
    return this.categories;
  };

  this.setCurrentCategory = function(category) {
    this.current.category = category;
  };
  this.getCurrentCategory = function() {
    return this.current.category;
  };

  this.setBrands = function(brands) {
    this.brands = brands;
  };

  this.getBrands = function() {
    return this.brands;
  };

  this.setCurrentBrand = function(brand) {
    this.current.brand = brand;
  };
  this.getCurrentBrand = function() {
    return this.current.brand;
  };

  this.setDevices = function(devices) {
    this.devices = devices;
  };

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

  this.setCurrentModel = function(model) {
    this.current.model = model;
  };

  this.getCurrentModel = function() {
    return this.current.model;
  };

  this.checkIfEntertainment = function(deviceType) {
    return deviceType === 'Televisions' || deviceType === 'Satellite Set Top Boxes'|| deviceType === 'Cable and Fios Set Top Boxes'|| deviceType === 'DVR' ? true: false;
  };

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

    $http.get('/installer/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;
  };

  this.retrieveDeviceBrands = function(type) {

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

    $http.get(baseUrl + '/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;
  };

  this.searchModels = function(type, brand, query) {
    console.log('query: ' + query);
    var self = this,
        d = $q.defer(),
        url = baseUrl + '/db/search/' + type + '/' + brand;
    
    url += !query || query === '' ?  ''  : '/' + query;

    $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;
  };

  this.getDeviceInfo = function(type, brand, modelId, codeset, dbType) {
    var d = $q.defer();
    var url = baseUrl + '/db/device/' + type + '/' + brand + '/' + modelId + '/' + codeset + '/' + dbType;
    console.log(url);
    $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;

  };

  this.clearData = function() {
    this.current = {};
  };
});
'use strict';
/**
 * @ngdoc service
 * @name Registration
 * @description
 *  system 생성 관련 기능
 */
app.service('Registration', function ($http, $q) {
	this.systemKey = null;
	this.email = null;
	this.mac = null;
  this.systemType = null;

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

  /**
   * base station type 저장
   * @memberof Registration
   * @param {String} type base station type
   */
  this.setSystemType = function(type) {
    this.systemType = type;
  };

  /**
   * base station type 얻기
   * @memberof Registration
   * @returns {String|null} base station type
   */
  this.getSystemType = function(){
    return this.systemType;
  };

  /**
   * programming key 저장
   * @memberof Registration
   * @param {String} key programming key
   */
	this.setSystemKey = function(key) {
		this.systemKey = key;
	};

  /**
   * programming key 얻기
   * @memberof Registration
   * @returns {String|null} programming key
   */
	this.getSystemKey = function(){
		return this.systemKey;
	};

  /**
   * email 저장
   * @memberof Registration
   * @param {String} email email
   */
	this.setEmail = function(email) {
		this.email = email;
	};

  /**
   * email 얻기
   * @memberof Registration
   * @returns {String|null} email
   */
	this.getEmail = function() {
		return this.email;
	};

  /**
   * base station MAC address 저장
   * @memberof Registration
   * @param {String} mac MAC address
   */
	this.setBStationMac = function(mac) {
		this.mac = mac;
	};

  /**
   * base station MAC address 얻기
   * @memberof Registration
   * @returns {String|null} MAC address
   */
	this.getBStationMac = function() {
		return this.mac;
	};

  /**
   * 사용자 등록시 temporary password 를 요청한 email 로 보내기
   * @memberof Registration
   * @param {String} data base station type/programming key/email json string
   * @returns {Promise} Future object
   */
  this.sendTempPswd = function(data) {
    var d = $q.defer(), 
        self = this;

    // 사용자 등록시 temporary password 를 요청한 email 로 보내기 API 호출
    $http.post('/api/email/register_email', data)
      .success(function(response) {
        if(response.result) {
          d.resolve();
        }
        else {
          d.reject(response.error);
        }
      })
      .error(function(error) {
        d.reject('Please try again');
      });
    
    return d.promise;
  };

  /**
   * 저장된 정보 reset
   * @memberof Registration
   */
	this.clearData = function() {
		this.systemKey = null;
		this.email = null;
		this.mac = null;
	};


});

'use strict';

app.service('Requests', function ($q, $http, baseUrl) {
  

  this.submitOne = function(req) {
    var d = $q.defer();

    var request = angular.copy(req);


    _.forEach(request.rooms, function (room) {
      var deviceIds = _.pluck(room.devices, 'id');
      delete room.id;

      if (room.main.punch !== -1) {
        room.main.punch = _.contains(deviceIds, room.main.punch) ? deviceIds.indexOf(room.main.punch):-1;
      }

      _.forEach(room.bstations, function (bstation) {
        delete bstation.id;
      });

      _.forEach(room.devices, function (device) {
        delete device.id;
        if (device.attr.punch !== -1) {
          device.attr.punch = _.contains(deviceIds, device.attr.punch) ? deviceIds.indexOf(device.attr.punch):-1;
        }

        //Activities array manipulation
        var len = device.activities.length;
        while (len--) {
          var activity = device.activities[len];
          if (_.contains(deviceIds, activity.device)) {
            //If device still exists after submission, replace property with index
            activity.device = deviceIds.indexOf(activity.device);
          } else {
            //If device does not exist, remove from activities array
            device.activities.splice(len,1);
          }
        }
      }); 

     delete room.activityDevices;
    });
    console.log(request);

    var json = JSON.stringify({data: request});

    $http.post(baseUrl+'/submit/create', json).success(function(response) {
      if (response.result) {
        d.resolve(response.jobId);
      } else {
        d.reject(response.error);
      }
    }).error(function(data, status, headers, config) {
      var error = status;
      if (status === 500) {
        error +=' Internal Server Error: The server encountered an unexpected condition which prevented it from fulfilling the request.';
      }
      d.reject(error);
    });

    return d.promise;
  };

  this.get = function(type, options) {
    var d = $q.defer();
    var data = { searchType: type };
    if (options) {
      angular.extend(data, options);
    }
    var json = JSON.stringify(data);

    $http.post(baseUrl+'/system/list', json).success(function(response) {
      if (response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

});
'use strict';

app.service('Rooms', function(){

  this.generateOne = function() {
    var id = uuid.v4(),
        name = id.substring(32,36).toUpperCase();

    return {
      id: id,
      name: 'Room ' + name,
      main: { punch: -1 },
      bstations: [{ id: uuid.v4(), name: 'Controller ' + name, type: 'HCM-C1'}],
      devices: [] 
    };
  };

  this.generateBstation = function() {
    var id = uuid.v4();
    return {id: id, name: 'Controller ' + id.substring(32,36).toUpperCase(), type: 'HCM-C1'};
  };

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

  this.system = null;
  this.currentJobId = null;
  this.userInfo = null;
  this.selectedBstation = null;
  this.selectedRemote = null;

  /**
   * 현재 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;
  };

  /**
   * 현재 userInfo 저장
   * @memberof Systems
   * @param {String} userInfo base64 encode 된 username:password
   */
  this.setUserInfo = function(userInfo) {
    this.userInfo = userInfo;
  };

  /**
   * 현재 userInfo 얻기
   * @memberof Systems
   * @returns {String} userInfo
   */
  this.getUserInfo = function() {
    return this.userInfo;
  };

  /**
   * 선택된 bstation 저장
   * @memberof Systems
   * @param {Object} bstation 선택된 base station 정보 객체
   */
  this.setSelectedBstation = function(bstation) {
    this.selectedBstation = bstation;
  };

  /**
   * 선택된 bstation 얻기
   * @memberof Systems
   * @returns {Object} bstation
   */
  this.getSelectedBstation = function() {
    return this.selectedBstation;
  };

  /**
   * 선택된 remote 저장
   * @memberof Systems
   * @param {Object} remote 선택된 remote control 정보 객체
   */
  this.setSelectedRemote = function(remote) {
    this.selectedRemote = remote;
  };

  /**
   * 선택된 remote 얻기
   * @memberof Systems
   * @returns {Object} remote
   */
  this.getSelectedRemote = function() {
    return this.selectedRemote;
  };

  /**
   * job ID 로 system 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getJobSystem = function(data) {
    var d = $q.defer();

    $http.post('/installer/api/system/get_job_system', 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;
  };

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

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

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

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

    // system 얻기 API 호출
    $http.post('/installer/api/system/get/' + id, data).success(function(response) {
      console.log(response);
      if(response.result) {
        self.loadSystem(response.data);   // 얻어온 system 를 저장
        self.setUserInfo(JSON.parse(data).userInfo);    // userInfo 저장

        var user = JSON.parse($window.localStorage.getItem('hcm_installer'));    // localStorage 에서 사용자 정보 얻기
        user.system_id = id;
        user.userInfo = data;

        $window.localStorage.setItem('hcm_installer', JSON.stringify(user));   // 사용자 정보에 system ID, userInfo 를 더해서 localStorage 에 저장

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

    return d.promise;
  };

  /**
   * 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('/installer/api/system/create', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.systemId);   // 만들어진 system 의 ID
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 사용자 생성
   * @memberof Systems
   * @param {String} data 사용자 생성을 위한 정보 json string
   * @returns {Promise} Future object
   */
  this.createUser = function(data) {
    var d = $q.defer();

    // 사용자 생성 api 호출
    $http.post('/installer/api/system/create_user', data).success(function(response) {
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 편집중인 사용자 system 목록 얻기
   * @memberof Systems
   * @param {String} data userInfo, jobId json string
   * @returns {Promise} Future object
   */
  this.getListWorking = function(data) {
    var d = $q.defer();

    // 편집중인 사용자 system 목록 얻기 호출
    $http.post('/installer/api/system/list_working', data).success(function(response) {
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * device 들을 해당 system 이 있는 network 에서 search
   * @memberof Systems
   * @param {String} deviceName device name
   * @param {String} data json string
   * @returns {Promise} Future object
   */
  this.searchHardware = function(deviceName, data) {
    // deviceName (String): hardware device name
    // data (Object): additional data to be passed along with systemId (optional)

    data = data || null; //optional parameter

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

    var currentSystem = self.getCurrentSystem();
    var sendData = { systemId : currentSystem.id };

    //if there is data is present in the arguments passed through append to sendData
    if (data) {
      _.assign(sendData, data);
    }

    var jsonData = JSON.stringify(sendData);

    // deviceName 을 가진 device 들을 해당 system 이 있는 network 에서 search 하는 API 호출
    $http.post('/installer/api/cloud/search/' + deviceName, jsonData)
      .success(function(response) {
        if(response.result) {

          var resolve = {
              searchedDevices: response.data,
              searchKey: response.searchKey
            };

          d.resolve(resolve);

        } else {
          d.reject(response.error);
        }

      }, function(error) {
        console.log(error);
        d.reject(error);
      });

    return d.promise;
  };

  /**
   * MAC이 할당되지 않은 (TMP_로 시작하는 MAC) Base station 에 MAC을 할당
   * @memberof Systems
   * @param {Number} systemId system ID
   * @param {String} data json string
   * @returns {Promise} Future object
   */
  this.assignBaseStation = function(systemId, data) {
    var d = $q.defer();

    $http.post('/installer/api/system/assign_bstation/' + systemId, data).success(function(response) {
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * MAC이 할당되지 않은 (TMP_로 시작하는 MAC) Remote control 에 MAC을 할당
   * @memberof Systems
   * @param {Number} systemId system ID
   * @param {String} data json string
   * @returns {Promise} Future object
   */
  this.assignRemoteControl = function(systemId, data) {
    var d = $q.defer();

    $http.post('/installer/api/system/assign_remote/' + systemId, data).success(function(response) {
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * TV 등 각종 Device 들의 Address 를 세팅
   * @memberof Systems
   * @param {Number} systemId system ID
   * @param {String} data json string
   * @returns {Promise} Future object
   */
  this.assignDevices = function(systemId, data) {
    var d = $q.defer();

    $http.post('/installer/api/system/assign_devices/' + systemId, data).success(function(response) {
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 사용자 데이터 세팅 완료 설정
   * @memberof Systems
   * @param {Number} systemId system ID
   * @param {String} data json string
   * @returns {Promise} Future object
   */
  this.setDone = function(systemId, data) {
    var d = $q.defer();

    $http.post('/installer/api/system/set_done/' + systemId, data).success(function(response) {
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

});
'use strict';
/**
 * @ngdoc service
 * @name Timezones
 * @description
 *  timezone 목록 얻기
 */
app.service('Timezones', function ($http, $q) {

  /**
   * timezone 목록 얻기
   * @memberof Timezones
   * @returns {Promise} Future object
   */
  this.getAll = function() {
    var d = $q.defer();

    // timezone 목록 얻기 API 호출
    $http.get('/api/timezone/list').success(function(response) {
      if (response.result) {
        console.log(response.data);
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }).error(function(error) {
      d.reject(error);
    });
    
    return d.promise;
  };

});
'use strict';

//HCM Installer User

app.service('User', function ($rootScope, $http, $q, $window, baseUrl, Auth, jwtHelper) {

  /**
   * 시스템 생성을 위한 로그인
   * @memberof User
   * @param {String} data 사용자 아이디/패스워드 json string
   * @returns {Promise} Future object
   */
  this.loginForCreate = function(data) {
    var d = $q.defer();

    // 시스템 생성을 위한 로그인 api 호출
    $http.post('/api/user/login_for_create', data).success(function(response) {
      d.resolve(response);
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  this.login = function(data) {
    var self = this,
        d = $q.defer();

    $http.post(baseUrl + '/user/login', data).success(function(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, companyName: response.company, companyId: response.companyId};
        Auth.setCurrentUser(user);
        d.resolve(response); 
      } else {
        d.reject(response.error);
      }
      
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };
  

  this.logout = function() {
    var d = $q.defer();
    Auth.removeCurrentUser();
    d.resolve();
    return d.promise;
  };

  // this.changeEmail = function(data) {
  //   var d = $q.defer(),
  //    self = this;

  //   $http.post('/api/user/new_email', data).
  //   success(function(response) {
  //     console.log(response);
  //     if(response.result) {
  //       d.resolve(response.data);
  //     }
  //     else {
  //       d.reject(response.error);
  //     }
  //   }).
  //   error(function(error) {
  //     d.reject(error);
  //   });

  //   return d.promise;
  // }

  // this.changePassword = function(data) {
  //   var d = $q.defer(),
  //    self = this;

  //   $http.post('/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;
  // }

});
