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

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

	/**
	 * system 목록 정보 저장
	 * @memberof Systems
	 * @param {Array} systems 사용자의 system 목록 array
	 */
	this.loadSystems = function(systems) {
		this.all = systems;
	};

	/**
	 * system 목록 반환
	 * @memberof Systems
	 * @returns {Array} 사용자의 system 목록 array
	 */
	this.getAll = function() {
		return this.all;
	};

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

  this.getModelTypesEx = function () {
    // base station 의 type 들을 얻는 API 호출
    return $http.post('/api/system/types_ex').then(function (response) {
      return response;
    });
  };

	/**
	 * remote 의 type 들을 얻기
	 * @memberof Systems
	 * @returns {Promise} Future object
	 */
	this.getRemoteTypes = function() {
		// remote 의 type 들을 얻는 API 호출
		return $http.post('/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('/api/system/create', data).success(function(response) {
			console.log(response);
			if(response.result) {
				d.resolve(response.bstationId);   // 만들어진 Base station 의 ID
			} else {
				d.reject(response.error);
			}
		}, function(error) {
			d.reject(error);
		});

		return d.promise;
	};

	/**
	 * 사용자의 system 목록 얻기
	 * @memberof Systems
	 * @returns {Promise} Future object
	 */
	this.fetch = function () {

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

		// 사용자의 system 목록 얻기 API 호출
		$http.post('/api/system/list').success(function(response) {
			console.log(response);
			if(response.result) {
				self.loadSystems(response.systems);   // system 목록 정보 저장
				d.resolve(response.systems);
			} else {
				d.reject(response.error);
			}
		}, function(error) {
			d.reject(error);
		});

		return d.promise;
	};

	/**
	 * system 이름 변경
	 * @memberof Systems
	 * @param {Number} id system ID
	 * @param {String} data 변경할 system 이름 json string
	 * @returns {Promise} Future object
	 */
	this.editSystem = function (id, data) {

		var d = $q.defer();

		// system 이름 변경 API 호출
		$http.post('/api/system/edit/' + id, data).success(function(response) {
			console.log(response);
			if(response.result) {
				d.resolve(response.result);
			} 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.updateSystem = function (id) {
		var self = this,
					 d = $q.defer();

    if ($rootScope.virtualEditor) {
      Dealer.getRoom(id).then(function (data) {
        var room = data.data;

        // 기존 프로그램과의 호환을 위해 가상의 bstation 생성
        if (!room.bstations) {
          room.bstations = [$rootScope.virtualBstation];
        }

        $rootScope.virtualSystem.id = room.id;
        $rootScope.virtualSystem.rooms = [room];
        self.setCurrentRoom(room.id);

        self.loadSystem(angular.copy($rootScope.virtualSystem));
        d.resolve(angular.copy($rootScope.virtualSystem));
      });
    } else {
      // system 얻기 API 호출
      $http.post('/api/system/get/' + id).success(function (response) {
        console.log(response);
        if (response.result) {
          self.loadSystem(response.data);   // 얻어온 system 를 저장

          var user = JSON.parse($window.localStorage.getItem('hcm_editor'));    // localStorage 에서 사용자 정보 얻기
          user.system_id = response.data.id;
          $window.localStorage.setItem('hcm_editor', JSON.stringify(user));   // 사용자 정보에 system 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('/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_editor'));
					user.system_id = null;
					$window.localStorage.setItem('hcm_editor', JSON.stringify(user));   // localStorage 에 저장되어 있는 사용자 정보에서 system 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;
	};

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

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


		/*
		//for testing in CYR side
		var self = this;
		self.updateMainDevice().then(function(resonse) {
			if(resonse.data.result == true) {
				self.storeMainDevice();
			}
		});
		*/

		/*
		for testing in CYR side
		var jsonData = JSON.stringify( { text : 'who', edit_type : 1, popup : 1, activity : '', macro : ''} );
		$http({
			method: 'POST',
			url: '/api/btn/create/' + id + '/0',
			data : jsonData
		}).
		success(function(data) {
			if(data.result === true) {
				console.log(data.data);
			}
			else {
				alert(data.error);
			}
		}).
		error(function() {
			alert("Retry again");
		});
		*/

		/*
		//for testing in CYR side
		$http.post('/api/device/get/' + this.currentRoom.id + '/1')
		.success(function(data) {
			if (data.result) {
				console.log(data.data);
				data.data.name = 'custom Dev';
				data.data.category = 'TV';
				data.data.target = { type : 1, addr : '', port : 255 };

				var jsonData = JSON.stringify(data.data);

				$http({
					method: 'POST',
					url: '/api/device/createCustom/1/0',
					data : jsonData
				}).
				success(function(data2) {
					if(data.result === true) {
						alert('success');
					}
					else {
						alert(data.error);
					}
				}).
				error(function() {
					alert("Retry again");
				});
			}
		});
		*/

		/*
		//for testing in CYR side
		var jsonData = JSON.stringify( { username : 'cyrpro', password : 'qkqhek1111' } );
		$http({
			method: 'POST',
			url: '/file/HS-C100/312233445566/system.json',
			data : jsonData
		}).
		success(function(data) {
			if(data.result === true) {
				console.log('Data Received');
				console.log(data.data);
			}
			else {
				alert(data.error);
			}
		}).
		error(function() {
			alert("Retry again");
		});
		*/

	};

	/**
	 * Download Data Generate
	 * @returns {Promise} Future object
	 */
	this.prepareDownload = function() {

		return $http({
			method: 'POST',
			url: '/api/download/generate/' + this.system.id
		}).then(function(response) { return response; }, function(error) { return error; } );
	};

	/**
	 * Download stop
	 * @returns {Promise} Future object
	 */
	this.stopDownload = function() {
		return $http({
			method: 'POST',
			url: '/api/download/server_stop/' + this.system.id
		}).then(function(response) { return response; }, function(error) { return error; } );
	};

	/**
	 * 현재 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(),
      url;

    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/get/' + id;
    } else {
      url = '/api/room/get/' + this.system.id + '/' + id;
    }

		// room 얻기 API 호출
    $http.post(url).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;
			}

			if ($rootScope.virtualEditor) {
				urlData = '/api/dealer/btn/get_button_macro_with_device/' + roomId + '/' + deviceId;
			} else {
				urlData = '/api/btn/get_button_macro_with_device/' + roomId + '/' + deviceId;
			}
		}
		else if(type === 'get_power_macro') {   // 해당 room 의 power macro 데이터 얻기
			if ($rootScope.virtualEditor) {
				urlData = '/api/dealer/btn/get_power_macro/' + roomId;
			} else {
				urlData = '/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;
			}

			if ($rootScope.virtualEditor) {
				urlData = '/api/dealer/btn/get_button_macro/' + roomId + '/' + deviceId + '/' + buttonId;
			} else {
				urlData = '/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 들을 해당 system 이 있는 network 에서 search
	 * @memberof Systems
	 * @param {Boolean} filter
	 * @param {String} deviceName
	 * @param {Object} [data]
	 * @returns {Promise} Future object
	 */
	this.searchHardware = function(filter, deviceName, data) {
		// filter (Boolean): true/false to whether or not filter based on assigned devices
		// 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);
		console.log('Data: ' + jsonData);


		function filterDevices (existing, searched) {
			return searched.filter(function(device) {
				//filter out currently existing bstations
				//base equality on bstation mac addr
				return _.pluck(existing, 'mac').indexOf(device.mac) === -1;
			});
		}

		// deviceName 을 가진 device 들을 해당 system 이 있는 network 에서 search 하는 API 호출
    // deviceName : 'BASESTATIONS' => base station, 'CLIENTS' => remote controller
		$http.post('/api/cloud/search/' + deviceName, jsonData)
			.success(function(response) {
				console.log(response);
				if(response.result) {

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

					if (filter) {
            if (deviceName === 'BASESTATIONS') {  // base station
							var existingBStations = _.flatten(_.pluck(self.system.rooms, 'bstations'));
							console.log(existingBStations);
							var availableBStations = filterDevices(existingBStations, searchedDevices);   // 검색된 base station 들 중에서 현재 system 의 room 들이 가지고 있지 않은 것만 filter
							console.log(availableBStations);
							self.setSearchDevices(availableBStations);  // 가지고 있지 않은 (추가 가능한) base station 목록 저장

							resolve.searchedDevices = availableBStations;
							d.resolve(resolve);
						} else if (deviceName === 'CLIENTS') { // remote controller
							var existingRemotes = _.flatten(_.pluck(self.system.rooms, 'remotes'));
							var availableRemotes = filterDevices(existingRemotes, searchedDevices);     // 검색된 remote control 들 중에서 현재 system 의 room 들이 가지고 있지 않은 것만 filter
							self.setSearchDevices(availableRemotes);

							resolve.searchedDevices = availableRemotes; // 가지고 있지 않은 (추가 가능한) remote control 목록 저장
							d.resolve(resolve);
						}
					} else {

						resolve.searchedDevices = searchedDevices;    // 검색된 device 목록 저장
						d.resolve(resolve);

					}

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

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

		return d.promise;
	};

	/**
	 * 검색된 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;

		if ($rootScope.virtualEditor) {
			url = '/api/dealer/device/get_main/' + roomId;
		} else {
			url = '/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,
		 mainDev = { data : self.getMainDevice() },
		jsonData = JSON.stringify(mainDev);

		if ($rootScope.virtualEditor) {
			url = '/api/dealer/device/store_main/' + roomId;
		} else {
			url = '/api/device/store_main/' + roomId;
		}

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

	/**
	 * 해당key에 대한 basestation MAC과 사용된 room 정보 얻기
	 * @memberof Systems
	 * @param {String} data base station type, programming key json string
	 * @returns {Promise} Future object
	 */
	this.checkKey = function(data) {

		var  d = $q.defer(),
			 url = '/api/system/check_key/' + this.system.id;
		
		// 해당 base station 이 현재 사용중인지 유무 판별하는 API 호출
		$http.post(url,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;
	};

	/**
	 * master base station 을 해당 key 를 가진 base station 으로 추가
	 * @memberof Systems
	 * @param {String} data base station type/programming key/room ID json string
	 * @returns {Promise} Future object
	 */
	this.assignMaster = function(data) {
		
		var  d = $q.defer(),
			 url = '/api/system/assign_master/' + this.system.id;
			 console.log('assignMaster data', data);

		// master base station 을 해당 key 를 가진 base station 으로 추가하는 API 호출
		$http.post(url,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;
	};

	/**
	 * master base station 을 해당 key 를 가지는 base station 으로 변경
	 * @memberof Systems
	 * @param {String} data base station type/programming key/원본 master base station MAC json string
	 * @returns {Promise} Future object
	 */
	this.changeMaster = function(data) {

		var  d = $q.defer(),
			 url = '/api/system/change_master/' + this.system.id;
		
		// master base station 을 해당 key 를 가지는 base station 으로 변경하는 API 호출
		$http.post(url,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;
	};

	/**
	 * slave base station 을 변경
	 * @memberof Systems
	 * @param {String} data 원본 slave base station/new base station type/new MAC json string
	 * @returns {Promise} Future object
	 */
	this.changeSlave = function(data) {

		var d = $q.defer(),
			url = '/api/system/change_slave/' + this.system.id;
		
		// slave base station 을 변경하는 API 호출
		$http.post(url,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;
	};

	/**
	 * 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 = '/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;
		
	};

	/**
	 * system 의 home button behavior 설정
	 * @memberof Systems
	 * @param {String} data (option:behavior option(0:top, 1:navigate)) json string
	 * @returns {Promise} Future object
	 */
	this.setHomeButton = function(data) {

		var d = $q.defer(),
			url = '/api/system/set_home_btn/' + 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) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/create/' + roomId + '/' + mainDeviceId;
		} else {
			url = '/api/btn/create/' + roomId + '/' + mainDeviceId;
		}

		// button 생성 API 호출
		return $http.post(url, 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) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/store_power_macro/' + roomId;
		} else {
			url = '/api/btn/store_power_macro/' + roomId;
		}

		// 해당 room 의 power macro 데이터 저장하는 API 호출
		return $http.post(url, 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) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/store_button_macro_with_device/' + roomId + '/' + deviceId;
		} else {
			url = '/api/btn/store_button_macro_with_device/' + roomId + '/' + deviceId;
		}

		// 해당 device ID 와 연계된 button 의 데이터 저장하는 API 호출
		return $http.post(url, 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) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/store_button_macro/' + roomId + '/' + mainDeviceId + '/' + btnId;
		} else {
			url = '/api/btn/store_button_macro/' + roomId + '/' + mainDeviceId + '/' + btnId;
		}

		// button ID 에 해당하는 button 의 데이터 저장하는 API 호출
		return $http.post(url, data).then(function (response) {
			return response;
		});
	};

	/**
	 * 해당 room 의 power macro 삭제
	 * @memberof Systems
	 * @param {Number} roomId room ID
	 * @returns {Promise} Future object
	 */
	this.deletePowerMacro = function(roomId) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/delete_power_macro/' + roomId;
		} else {
			url = '/api/btn/delete_power_macro/' + roomId;
		}

		// 해당 room 의 power macro 삭제하는 API 호출
		return $http.post(url).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) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/delete_button_macro_with_device/' + roomId + '/' + deviceId;
		} else {
			url = '/api/btn/delete_button_macro_with_device/' + roomId + '/' + deviceId;
		}

		// 해당 device ID 와 연계된 button 의 macro 삭제하는 API 호출
		return $http.post(url).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) {
		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/btn/delete_button_macro/' + roomId + '/' + deviceId + '/' + btnId;
		} else {
			url = '/api/btn/delete_button_macro/' + roomId + '/' + deviceId + '/' + btnId;
		}

		// button ID 에 해당하는 button 삭제하는 API 호출
		return $http.post(url).then(function (response) {
			return response;
		});
	};

/**
	 * system 의 variable 정보 얻기
	 * @memberof Systems
	 * @returns {Promise} Future object
	 */
this.getVariables = function (roomId) {

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

	if ($rootScope.virtualEditor) {
		url = '/api/dealer/room/get_vars/' + roomId;
	} else {
			url = '/api/system/get_vars/' + this.system.id;
	}
		
		$http.post(url)
		.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;
		
	};

/**
	 * system 에 variable  추가.
	 * @memberof Systems
	 * @param {String} data = type(0:bool, 1:string, 2:integer)/value(type(0)-> '0','1')(type(1)->string)(type(2)->integer문자열)
	 * @returns {Promise} Future object
	 */
this.addVariable = function (data, roomId) {

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

	if ($rootScope.virtualEditor) {
		url = '/api/dealer/room/add_var/' + roomId;
	} else {
			url = '/api/system/add_var/' + this.system.id;
	}
				
		$http.post(url, 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;
		
	};

/**
	 * system 의 임의의 variable  제거.
	 * @memberof Systems
	 * @param {String} data = id
	 * @returns {Promise} Future object
	 */
this.deleteVariable = function (data, roomId) {

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

	if ($rootScope.virtualEditor) {
		url = '/api/dealer/room/del_var/' + roomId;
	} else {
			url = '/api/system/del_var/' + this.system.id;
	}
		
		$http.post(url, 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;
		
	};

	/**
	 * Help Content HTML 얻기
	 * @memberof Systems
	 * @param {String} menu HTML 파일 이름
	 * @returns {Promise} Future object
	 */
	this.getHelpContent = function(menu) {
		var d = $q.defer();

		$http.get('help_contents/' + menu + '.html')
			.success(function(response) {
				d.resolve(response);
			})
			.error( function(error) {
				d.reject(error);
			});

		return d.promise;
	};

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

	/**
	 * network discovery twoway devices 얻기
	 * @memberof Systems
	 * @param {String} type device type
	 * @returns {Promise} Future object
	 */
	this.getTwowayDevices = function(type) {
		var d = $q.defer();

		this.searchHardware(false, type)
			.then(
				function(data) {
					d.resolve(data);
				},
				function (error) {
					if (error.match('NO DEVICE')) {
						d.resolve({});
					} else {
						d.reject(error);
					}
				}
			);

		return d.promise;
	};

  /**
   * 해당 firmwareType의 version을 얻기
   * @memberof Systems
   * @param {String} deviceType device type
   * @param {String} firmwareType firmware type
   * @returns {Promise} Future object
   */
  this.getFirmwareVersion = function(deviceType, firmwareType, systemId) {
    var  d = $q.defer(),
      data = {
        deviceType: deviceType,
        firmwareType: firmwareType,
				systemId: systemId
      },
      jsonData = JSON.stringify(data);

    $http.post('/api/cloud/firmware_version', jsonData)
      .success(function(response) {
        if(response.result) {
          d.resolve(response);
        } else {
          d.reject(response.error);
        }
      })
      .error( function(error) {
        d.reject(error);
      });

    return d.promise;
  };

  /**
   * twoway category 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getTwowayCategories = function() {
    var  d = $q.defer(),
      url = '/api/system/twoway_categories';

    $http.post(url)
      .success(function(response) {
        if(response.result) {
          d.resolve(response.data);
        } else {
          d.reject(response.error);
        }
      })
      .error( function(error) {
        d.reject(error);
      });

    return d.promise;
  };

  /**
   * twoway brand 얻기
   * @memberof Systems
   * @param {Number} categoryId Category ID
   * @returns {Promise} Future object
   */
  this.getTwowayBrands = function(categoryId) {
    var  d = $q.defer(),
      url = '/api/system/twoway_brands',
      data = {categoryId: categoryId},
      jsonData = JSON.stringify(data);

    $http.post(url, jsonData)
      .success(function(response) {
        if(response.result) {
          d.resolve(response.data);
        } else {
          d.reject(response.error);
        }
      })
      .error( function(error) {
        d.reject(error);
      });

    return d.promise;
  };

  /**
   * twoway model 얻기
   * @memberof Systems
   * @param {Number} brandId Brand ID
   * @returns {Promise} Future object
   */
  this.getTwowayModels = function(brandId) {
    var  d = $q.defer(),
      url = '/api/system/twoway_models',
      data = {brandId: brandId},
      jsonData = JSON.stringify(data);

    $http.post(url, jsonData)
      .success(function(response) {
        if(response.result) {
          d.resolve(response.data);
        } else {
          d.reject(response.error);
        }
      })
      .error( function(error) {
        d.reject(error);
      });

    return d.promise;
  };

  /**
   * twoway model 얻기
   * @memberof Systems
   * @param {String} twoway model 조회에 필요한 정보들 json string
   * @returns {Promise} Future object
   */
  this.getDbTwowayModel = function(data) {
    var  d = $q.defer(),
      url = '/api/system/get_db_twoway_model';

    $http.post(url, 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;
  };

  /**
   * twoway model 추가
   * @memberof Systems
   * @param {String} twoway model 추가에 필요한 정보들 json string
   * @returns {Promise} Future object
   */
  this.addDbTwowayModel = function(data) {
    var  d = $q.defer(),
      url = '/api/system/add_db_twoway_model';

    $http.post(url, 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;
  };

	/**
	 * twoway model 정보 수정
	 * @memberof Systems
	 * @param {String} twoway model 정보 변경에 필요한 정보들 json string
	 * @returns {Promise} Future object
	 */
	this.setDbTwowayModel = function(data) {
		var  d = $q.defer(),
			url = '/api/system/set_db_twoway_model';

		$http.post(url, 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;
	};

  /**
   * system version 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getSystemVersion = function() {
    var  d = $q.defer();

    $http.get('/scripts/version.json')
      .success(function(response) {
        if(response) {
          d.resolve(response.version);
        } else {
          d.reject('error');
        }
      })
      .error( function(error) {
        d.reject(error);
      });

    return d.promise;
  };

	/**
	 * system 환경설정 얻기
	 * @memberof Systems
	 * @returns {Promise} Future object
	 */
	this.getSystemEnv = function() {
		var  d = $q.defer();

		$http.get('/scripts/env.json')
			.success(function(response) {
				if(response) {
					d.resolve(response);
				} else {
					d.reject('error');
				}
			})
			.error( function(error) {
				d.reject(error);
			});

		return d.promise;
	};

  /**
   * change master from factory
   * @memberof Systems
   * @param {String} parameters
   * @returns {Promise} Future object
   */
  this.changeMasterFromFactory = function(systemId, data) {
    var  d = $q.defer(),
      url = '/api/system/change_master_from_factory';

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

  /**
   * set dealer
   * @memberof Systems
   * @param {String} parameters
   * @returns {Promise} Future object
   */
  this.setDealer = function(systemId, data) {
    var  d = $q.defer(),
      url = '/api/system/set_dealer';

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

});

