'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, type) {
    console.log(u);
    service._user = u;

    var itemName;

    if (type === 'dealer') {
      itemName = 'hcm_editor_dealer';
    } else {
      itemName = 'hcm_editor'
    }
    $window.localStorage.setItem(itemName, 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_editor_dealer');  // localStorage 에서도 삭제
    $window.localStorage.removeItem('hcm_editor');  // 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_editor') || $window.localStorage.getItem('hcm_editor_dealer')) {   // _user 에는 없지만 localStorage 에 있는 경우
      if($window.localStorage.getItem('hcm_editor_dealer')) {
        var user = JSON.parse($window.localStorage.getItem('hcm_editor_dealer'));
        console.log('setting current user');

        if (user.virtualEditor) {
          $rootScope.virtualEditor = true;
        } else {
          $rootScope.virtualEditor = null;
        }

        service.setCurrentUser(user, 'dealer');
      }

      if($window.localStorage.getItem('hcm_editor')) {
        var user = JSON.parse($window.localStorage.getItem('hcm_editor'));
        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('/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('/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;
	};

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

		$http.get(url).success(function(response) {
			if(response.result) {
				console.log('response=', response);
				self.setDevices(response.devices);
				d.resolve(response.devices);
			} 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 = '/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) {
		console.log('type=', type, 'brand=', brand);
		var self = this,
			d = $q.defer(),
			url = '/api/db/search_popular/' + type + '/' + brand;
		
		// device 목록 얻기 API 호출
		$http.get(url).success(function(response) {
			if(response.result) {
				console.log('response=', response);
				self.setDevices(response.devices);
				d.resolve(response.devices);
			} else {
				d.reject(response.error);
			}
		}).error(function (error) {
			d.reject(error);
		});

		return d.promise;
	};

	/**
	 * all device 목록 얻기
	 * @memberof Database
	 * @param {String} type device type
	 * @param {String} brand brand name
	 * @returns {Promise} Future object
	 */
	this.searchAllModels = function(type, brand) {
		var self = this,
			d = $q.defer(),
			url = '/api/db/search_all/' + 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 = '/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 Dealer
 * @description
 *  dealer 관련 기능
 */
app.service('Dealer', function ($rootScope, $http, $q, $window, jwtHelper, Auth) {

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

    // 로그인 API 호출
    $http.post('/api/dealer/login', data).success(function(response) {
      if (response.result) {
        var token = jwtHelper.decodeToken(response.token);
        var company = token.company;
        var user = {
          company: company,
          token: response.token,
          optMenuShow: response.opt_menu_show,
          optHelpShow: response.opt_help_show,
          admin: response.admin,
          dealer_username: (JSON.parse(data)).username,
          timestamp: parseInt(+new Date() / 1000, 10)
        };
        Auth.setCurrentUser(user, 'dealer');
      }
      d.resolve(response);
    }).error(function (error) {
      d.reject(error);
    });

    return d.promise;
  };

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

  // dealer company 불러오기
  this.getDealerCompany = function() {
    var dealer = JSON.parse($window.localStorage.getItem('hcm_editor_dealer'));

    if (dealer && typeof dealer.company !== 'undefined') {
      return dealer.company;
    } else {
      return '';
    }
  };

  this.getJobs = function() {
    var  d = $q.defer(),
      url = '/api/dealer/get_jobs';

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

    return d.promise;
  };

  this.getJob = function(data) {
    var  d = $q.defer(),
      url = '/api/dealer/get_job';

    $http.post(url, 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.getSystemToken = function(data) {
    var  d = $q.defer(),
      url = '/api/dealer/get_system_token';

    $http.post(url, 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.setUser = function(systemId, token, username, email, dealertoken) {
    var dealer = JSON.parse($window.localStorage.getItem('hcm_editor_dealer')),
      user;

    if (dealertoken && !dealer.dealertoken) {
      dealer.dealertoken = dealer.token;
    }

    dealer.system_id = systemId;
    dealer.token = token;

    Auth.setCurrentUser(dealer, 'dealer');

    if (username && email) {
      user = angular.copy(dealer);
      user.username = username;
      user.email = email;

      Auth.setCurrentUser(user);
    } else {
      Auth.setCurrentUser(dealer);
    }
  };

  this.createFromExisting = function(data) {
    var  d = $q.defer(),
      url = '/api/dealer/room/create_from_existing';

    $http.post(url, 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.customDevCreate = function(data) {
    var  d = $q.defer(),
      url = '/api/dealer/custom_dev/create';

    $http.post(url, 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.getTemplates = function() {
    var  d = $q.defer(),
      url = '/api/dealer/room/list';

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

    return d.promise;
  };

  this.deleteTemplate = function(id) {
    var  d = $q.defer(),
      url = '/api/dealer/room/delete/' + id;

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

    return d.promise;
  };

  this.templateApplyToNew = function (id, data) {
    var d = $q.defer(),
      url = '/api/dealer/room/apply_to_new/' + id;

    $http.post(url, 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.templateApplyToExisting = function(id, data) {
    var  d = $q.defer(),
      url = '/api/dealer/room/apply_to_existing/' + id;

    $http.post(url, 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.getDevices = function() {
    var  d = $q.defer(),
      url = '/api/dealer/custom_dev/list';

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

    return d.promise;
  };

  this.deleteDevice = function(id) {
    var  d = $q.defer(),
      url = '/api/dealer/custom_dev/delete/' + id;

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

    return d.promise;
  };

  this.getDeviceInfo = function(id) {
    var  d = $q.defer(),
      url = '/api/dealer/custom_dev/get_device_info/' + id;

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

    return d.promise;
  };

  this.deviceApply = function(id, data) {
    var  d = $q.defer(),
      url = '/api/dealer/custom_dev/apply/' + id;

    $http.post(url, 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.createNewTemplate = function(data) {
    var  d = $q.defer(),
      url = '/api/dealer/room/create';

    $http.post(url, 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.getRoom = function (id) {
    var d = $q.defer(),
      url = '/api/dealer/room/get/' + id;

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

    return d.promise;
  };

  this.copyFromTemplate = function (id, data) {
    var d = $q.defer(),
      url = '/api/dealer/room/copy_from_template/' + id;

    $http.post(url, 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.customDevCreateFromTemplate = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/custom_dev/create_from_template';

    $http.post(url, 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.deviceApplyToTemplate = function (id, data) {
    var d = $q.defer(),
      url = '/api/dealer/custom_dev/apply_to_template/' + id;

    $http.post(url, 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.addUserCheck = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/add_user_check';

    $http.post(url, 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.addUserFinal = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/add_user_final';

    $http.post(url, 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.newEmail = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/new_email';

    $http.post(url, 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.newPassword = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/new_password';

    $http.post(url, 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.getUsers = function () {
    var d = $q.defer(),
      url = '/api/dealer/get_users';

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

    return d.promise;
  };

  this.getUserData = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/get_user_data';

    $http.post(url, 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.deleteUser = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/delete_user';

    $http.post(url, 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.getUserCategories = function () {
    var d = $q.defer(),
      url = '/api/dealer/get_user_categories';

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

    return d.promise;
  };

  this.addUserPrepare = function (data) {
    var d = $q.defer(),
      url = '/api/dealer/add_user_prepare';

    $http.post(url, 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 Devices
 * @description
 *  device 관련 기능
 */
app.service('Devices', function ($rootScope, $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;
	};

	// function 들 array 초기화
	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;
	};


	/**
	 * 해당 device 의 connected device(즉, command 목록) 얻기
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {Number} deviceId device ID
	 * @returns {Promise} Future object
	 */
	this.fetchFunctions = function(roomId, deviceId) {
		var d = $q.defer();

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

		// 해당 device 의 connected device(즉, command 목록) 얻기 API 호출
		$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;
	};

	/**
	 * punch 정보 (punch한 Device의 ID) 얻기
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {Number} deviceId device ID
	 * @returns {Promise} Future object
	 */
	this.fetchPunchDevice = function(roomId, deviceId) {

		var d = $q.defer();

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

		// punch 정보 (punch한 Device의 ID) 얻기 API 호출
		$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;
		
	};

	/**
	 * device 생성
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {String} data device 정보 json string
	 * @returns {Promise} Future object
	 */
	this.createOne = function(roomId, data) {
		var d = $q.defer();

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

		// device 생성 API 호출
		$http.post(url, data).success(function (response) {
			if (response.result) {
				d.resolve(response);
			} else {
				d.reject(response.error);
			}
		}).error(function (error) {
			d.reject(error);
		});
		return d.promise;
	};

	/**
	 * learn device 생성
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {String} data device 정보 json string
	 * @returns {Promise} Future object
	 */
	this.createCustomOne = function(roomId, data) {
		var d = $q.defer();

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

		// learn device 생성 API 호출
		$http.post(url, 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);
				}
			});
		});
	};

	// device 정보 얻기
	this.getOne = function(roomId, deviceId) {
		var deviceProps,
				self = this,
				d = $q.defer();
		var aliasDevices = [];

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

			if (btn.hasOwnProperty('hidden')) {
				btn.hidden = btn.hidden ? true:false;
			} else {
				btn.hidden = false;
			}

		}

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

		// 해당 device 얻기 API 호출
		$http.post(url)
		.success(function(response) {
			console.log('response=', response);
			if (response.result) {
				self.menuBtnPages = [];
				self.initHardBtnPages();

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

				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: [] },
								btnIds;

						if (page.page_hidden) {
							pgToAdd.page_hidden = page.page_hidden;
						} else {
							pgToAdd.page_hidden = 0;
						}

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

											if(macro.type == 6 && deviceId != macro.device_id) {
												var aliasDeviceProps = null;
												aliasDeviceProps = _.where(aliasDevices, {'id': macro.device_id})[0]; 
												if(aliasDeviceProps) {
														//console.log('exist aliasDeviceProps=', aliasDeviceProps);
														assignBtnFields(button, macro, aliasDeviceProps);
												} else {
													self.getDeviceData(roomId, macro.device_id).then(function(data) {
														aliasDeviceProps = data;
														//console.log('aliasDeviceProps=', aliasDeviceProps);
														aliasDevices.push(aliasDeviceProps);
														assignBtnFields(button, macro, aliasDeviceProps);
													}).catch();
												}
											} else {
												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);

							if(macro.type == 6 && deviceId != macro.device_id) {
								var aliasDeviceProps = null;
								//console.log('aliasDevices=', aliasDevices);
								aliasDeviceProps = _.where(aliasDevices, {'id': macro.device_id})[0]; 
								if(aliasDeviceProps) {
										//console.log('exist aliasDeviceProps=', aliasDeviceProps);
										assignBtnFields(newBtn, macro, aliasDeviceProps);
								} else {
									self.getDeviceData(roomId, macro.device_id).then(function(data) {
										aliasDeviceProps = data;
										//console.log('aliasDeviceProps=', aliasDeviceProps);
										aliasDevices.push(aliasDeviceProps);
										assignBtnFields(newBtn, macro, aliasDeviceProps);
									}).catch();
								}
							} else {
								assignBtnFields(newBtn, macro, deviceProps);
							}

							///사용하기 편하도록 object type으로 변환.
							newBtn.macro = JSON.parse(newBtn.macro);

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

						// Filling in the rest of the page

						btnIds = _(pgToAdd.btns).pluck('id').value();
						//console.log('btnIds=', btnIds);
						if(btnIds.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=', 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, page_hidden: pgToAdd.page_hidden });
					});

					self.addHardBtnProps(deviceProps);
				}
				console.log('deviceProps=', deviceProps);
				console.log('hardBtnPages=', self.hardBtnPages);
				console.log('menuBtnPages=', self.menuBtnPages);

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

	};

	/**
	 * 해당 device 저장
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {Number} deviceId device ID
	 * @param {String} data 해당 device 의 데이터 json string
	 * @returns {Promise} Future object
	 */
	this.storeOne = function(roomId, deviceId, data) {
		var d = $q.defer();

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

		// 해당 device 저장 API 호출
		$http.post(url, 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;
	};


	/**
	 * device data get
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {Number} deviceId device ID
	 * @returns {Promise} Future object
	 */
	this.getDeviceData = function(roomId, deviceId) {
		var d = $q.defer();

		var url;
		if ($rootScope.virtualEditor) {
			url = '/api/dealer/device/get/' + roomId + '/' + deviceId;
		} else {
			url = '/api/device/get/' + roomId + '/' + deviceId;
		}
		
		// 해당 device 얻기 API 호출
		$http.post(url)
		.success(function(response) {
			console.log(response);
			if (response.result) {
				d.resolve(response.data);
			} else {
				d.reject( response.error);
			}
		})
		.error(function(error) {
			alert('Please try again');
			d.reject(error);
		});
		return d.promise;

	};

	/**
	 * twoway device 생성
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {String} data device 정보 json string
	 * @returns {Promise} Future object
	 */
	this.createTwowayDevice = function(roomId, data) {
		var d = $q.defer();

		// device 생성 API 호출
		$http.post('/api/twoway_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;
	};

	/**
	 * twoway device update
	 * @memberof Devices
	 * @param {Number} roomId room ID
	 * @param {Number} deviceId device ID
	 * @returns {Promise} Future object
	 */
	this.updateTwowayDevice = function(roomId, deviceId) {
		var d = $q.defer();

		// 해당 device update API 호출
		$http.post('/api/twoway_device/update/' + roomId + '/' + deviceId)
			.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;

	};


});

'use strict';

app.factory('Learning', function ($http, $q, Systems) {


	function start(id) {
		var d = $q.defer();
		var canceller = $q.defer(); 

		var cancel = function(reason){
			canceller.resolve(reason);
		};

		var jsonData = JSON.stringify({ systemId: id});
		
		var promise = $http({ method: 'POST', url: '/api/cloud/learn_start', data: jsonData, timeout: canceller.promise });
		
		promise.success(function(response) {
			console.log(response);
			if (response.result) {
				d.resolve(response.result);
			} else {
				d.reject(response.error);
			}
		}).error(function(error) {
			console.log(error);
			d.reject(error);
		});

		return { 
			promise: d.promise,
			cancel: cancel
		};
	}

	

	function attempt(id) {
		var d = $q.defer();
		var canceller = $q.defer(); 

		var jsonData = JSON.stringify({ systemId: id});

		var cancel = function(reason){
			canceller.resolve(reason);
		};

		var promise = $http({ method: 'POST', url: '/api/cloud/learn_data', data: jsonData, timeout: canceller.promise });
		
		promise.success(function(response) {
			if (response.result) {
				d.resolve(response.data);
			} else {
				d.reject(response.error);
			}
		}).error(function(error) {
			d.reject(error);
		});

		return { 
			promise: d.promise,
			cancel: cancel
		};
	}

	return {
		start: start,
		attempt: attempt
	};

});
'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';
/**
 * @ngdoc service
 * @name Rooms
 * @description
 *  room 관련 기능
 */
app.service('Rooms', function ($rootScope, $http, $q, Systems) {

  this.scheEventEdit = false;
  this.scheEventData = null;

  /**
   * 현재 system 이 가지고 있는 room 들 중에서 선택한 room 의 device 정보 얻기
   * @memberof Rooms
   * @param {Number} id room ID
   * @returns {Array} devices 정보 객체 array
   */
  this.getDevices = function (id) {
    return Systems.getRoom(id).devices;
  };

  /**
   * 현재 system 이 가지고 있는 room 들 중에서 선택한 room 의 twoway device 정보 얻기
   * @memberof Rooms
   * @param {Number} id room ID
   * @returns {Array} twoway devices 정보 객체 array
   */
  this.getTwowayDevices = function (id) {
    return Systems.getRoom(id).twoway_devices;
  };

  /**
   * room 생성
   * @memberof Rooms
   * @param {String} data room name/base station type/base station name/MAC json string
   * @returns {Promise} Future object
   */
  this.create = function (data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    // room 생성 API 호출
    $http.post('/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) {

  };

  /**
   * room 이름 변경
   * @memberof Rooms
   * @param {Number} roomId room ID
   * @param {String} data room name json string
   * @returns {Promise} Future object
   */
  this.edit = function (roomId, data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/edit/' + roomId;
    } else {
      url = '/api/room/edit/' + sysId + '/' + roomId;
    }

    // room 이름 변경 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;
  };

  /**
   * room 삭제
   * @memberof Rooms
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.delete = function (roomId) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    // room 삭제 API 호출
    $http.post('/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;
  };

  /**
   * remote 를 room 에 set(기존에 있으면 해당 것을 replace)
   * @memberof Rooms
   * @param {Number} roomId room ID
   * @param {String} data MAC/remote type/remote name/search key json string
   * @returns {Promise} Future object
   */
  this.setRemote = function (roomId, data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    // remote 를 room 에 set 하는 API 호출
    $http.post('/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;
  };

  /**
   * remote 를 해당 room 에서 삭제
   * @memberof Rooms
   * @param {Number} roomId room ID
   * @param {Object} data MAC address
   * @returns {Promise} Future object
   */
  this.delRemote = function (roomId, data) {
    var d = $q.defer(),
        sysId = Systems.getCurrentSystem().id;

    // remote 를 해당 room 에서 삭제하는 API 호출
    $http.post('/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;
  };

  /**
   * base station 추가/설정/삭제 동작
   * @memberof Rooms
   * @param {String} action action type
   * @param {Number} roomId room ID
   * @param {String} data parameters object json string
   * @returns {Promise} Future object
   */
  this.baseStations = function (action, roomId, data) {
    var d = $q.defer(),
        url = '/api/room/',
        sysId = Systems.getCurrentSystem().id;

    
    switch(action) {
      // slave base station 을 room 에 추가
      case 'add':
        url += 'add_bstation/';
        break;
      // base station 의 type, name, lightLevel 을 설정
      case 'edit':
        url += 'edit_bstation/';
        break;
      // base station 을 해당 room 에서 삭제
      case 'delete':
        url += 'del_bstation/';
        break;    
      default:
        break;
    }
    
    // action 에 따른 API 호출
    $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;
  };

  /**
   * Scheduled event 생성
   * @memberof Systems
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @param {String} data scheduled event data json string
   * @returns {Promise} Future object
   */
  this.createScheduledEventMacro = function(systemId, roomId, data) {
    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/create_event/' + roomId;
    } else {
      url = '/api/room/create_event/' + systemId + '/' + roomId;
    }

    // Scheduled event 생성 API 호출
    return $http.post(url, data).then(function (response) {
      return response;
    });
  };

  /**
   * Scheduled event 수정
   * @memberof Systems
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @param {String} data scheduled event data json string
   * @returns {Promise} Future object
   */
  this.setScheduledEventMacro = function(systemId, roomId, data) {
    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/set_event/' + roomId;
    } else {
      url = '/api/room/set_event/' + systemId + '/' + roomId;
    }

    // Scheduled event 생성 API 호출
    return $http.post(url, data).then(function (response) {
      return response;
    });
  };

  /**
   * scheduled event 정보 얻기
   * @memberof Rooms
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @param {String} data event ID json string
   * @returns {Promise} Future object
   */
  this.getEvent = function (systemId, roomId, data) {
    var d = $q.defer();

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/get_event/' + roomId;
    } else {
      url = '/api/room/get_event/' + systemId + '/' + roomId;
    }

    // scheduled event 정보 얻기 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;
  };

  /**
   * scheduled event 목록 얻기
   * @memberof Rooms
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.getEvents = function (systemId, roomId) {
    var d = $q.defer();

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/get_events/' + roomId;
    } else {
      url = '/api/room/get_events/' + systemId + '/' + roomId;
    }

    // scheduled event 목록 얻기 API 호출
    $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;
  };

  /**
   * scheduled event 목록 저장
   * @memberof Rooms
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @param {String} data scheduled events data json string
   * @returns {Promise} Future object
   */
  this.storeEvents = function (systemId, roomId, data) {
    var d = $q.defer();

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/store_events/' + roomId;
    } else {
      url = '/api/room/store_events/' + systemId + '/' + roomId;
    }

    // scheduled event 목록 저장 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;
  };

  /**
   * scheduled event 삭제
   * @memberof Rooms
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @param {String} data event ID json string
   * @returns {Promise} Future object
   */
  this.deleteEvent = function (systemId, roomId, data) {
    var d = $q.defer();

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/del_event/' + roomId;
    } else {
      url = '/api/room/del_event/' + systemId + '/' + roomId;
    }

    // scheduled event 삭제 API 호출
    $http.post(url, 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;
  };

  /**
   * scheduled event state 변경
   * @memberof Rooms
   * @param {Number} systemId system ID
   * @param {Number} roomId room ID
   * @param {String} data event ID, default_state json string
   * @returns {Promise} Future object
   */
  this.changeEventState = function (systemId, roomId, data) {
    var d = $q.defer();

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/room/set_event_state/' + roomId;
    } else {
      url = '/api/room/set_event_state/' + systemId + '/' + roomId;
    }

    // scheduled event state 변경 API 호출
    $http.post(url, 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;
  };

  this.enableScheEventEdit = function() {
    this.scheEventEdit = true;
  };

  this.disableScheEventEdit = function() {
    this.scheEventEdit = false;
  };

  this.getScheEventEdit = function() {
    return this.scheEventEdit;
  };

  /**
   * scheduled event 저장
   * @memberof Rooms
   * @param {Object} data scheduled event data
   */
  this.setScheEventData = function(data) {
    this.scheEventData = data;
  };

  /**
   * scheduled event 얻기
   * @memberof Rooms
   * @returns {Object}
   */
  this.getScheEventData = function() {
    return this.scheEventData;
  };

 



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

});


'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';
/**
 * @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.create = function(data) {
    var d = $q.defer();

    // 사용자 생성 api 호출
    $http.post('/api/user/create', data).
    success(function(response) {
      console.log(response);
      if(response.result) {
        var token = jwtHelper.decodeToken(response.token);    // 서버로 부터 받은 token decode
        var name = token.sub;
        var id = token.usr_id;
        var user = { id: id, username: name, email: response.email, token: response.token, optMenuShow: response.opt_menu_show, optHelpShow: response.opt_help_show, timestamp: parseInt(+new Date() / 1000, 10) };
        Auth.setCurrentUser(user);  // 현재 사용자 정보로 저장 => 클라이언트에서의 로그인 처리
        d.resolve(response);
      }
      else {
        d.reject(response.error);
      }
    }).
    error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 시스템 생성을 위한 로그인
   * @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) {
      if (response.result && response.status) {   // result 와 status 가 모두 true 일 때 로그인 시킴
        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, optMenuShow: response.opt_menu_show, optHelpShow: response.opt_help_show, timestamp: parseInt(+new Date() / 1000, 10) };
        Auth.setCurrentUser(user);
      }
      d.resolve(response);
    }).error(function(error) {
      d.reject(error);
    });

    return d.promise;
  };

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

    // 로그인 API 호출
    $http.post('/api/user/login', data).success(function(response) {
      console.log(response);  // result 와 status 가 모두 true 일 때 로그인 시킴
      if (response.result && response.status) {
        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, optMenuShow: response.opt_menu_show, optHelpShow: response.opt_help_show, timestamp: parseInt(+new Date() / 1000, 10) };
        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;
  };

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

    // 사용자 email 변경 API 호출
    $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;
  };

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

    // 사용자 password 변경 API 호출
    $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;
  };

  /**
   * 패스워드 리셋
   * @memberof User
   * @param {String} data 사용자 email 주소
   * @returns {Promise} Future object
   */
  this.resetPassword = function(data) {
    var d = $q.defer();

    // 패스워드 리셋 API 호출
    $http.post('/api/email/forget_password', JSON.stringify(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;
  };

  /**
   * programming menu help show, advanced menu show 옵션 저장
   * @memberof User
   * @param {String} data option json string
   * @returns {Promise} Future object
   */
  this.setOption = function(data) {
    var d = $q.defer();

    var url;
    if ($rootScope.virtualEditor) {
      url = '/api/dealer/set_option';
    } else {
      url = '/api/user/set_option';
    }

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

  this.getUserInfo = function() {
    var  d = $q.defer(),
      url = '/api/user/user_info';

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

    return d.promise;
  };

});
