'use strict';
/**
 * @ngdoc controller
 * @name ChangeEmailController
 * @description
 *  email 변경 화면
 */
app.controller('ChangeEmailController', function ($scope, $state, $window, toastr, User, Auth) {
  $scope.save = function () {

    var password = $scope.formData.password;
    var newEmail = $scope.formData.newEmail;
    var jsonData = JSON.stringify( { password : password, email : newEmail });
    
    // 사용자 email 변경
    User.changeEmail(jsonData).then( function() { 
      var user = JSON.parse($window.localStorage.getItem('hcm_editor'));
      angular.extend(user, {'email': newEmail});
      Auth.setCurrentUser(user);
      toastr.success('Successfully changed email!');
      $state.transitionTo('account-settings.main', null, { reload: true, inherit: true, notify: true  });
    }).
    catch(function (error) {
      toastr.error(error);
    });
  };
});

/**
 * @ngdoc controller
 * @name ChangePasswordController
 * @description
 *  password 변경 화면
 */
app.controller('ChangePasswordController', function ($scope, $state, toastr, User) {
  $scope.save = function () {

    var oldPassData = $scope.formData.currentPassword;
    var newPassData = $scope.formData.newPassword;
    var jsonData = JSON.stringify( { old_password : oldPassData, new_password : newPassData });

    // 사용자 password 변경
    User.changePassword(jsonData).then(function (data) {
      toastr.success('Successfully changed password!');
      $state.transitionTo('account-settings.main', null, { reload: true, inherit: true, notify: true  });     
    }).
    catch(function (error) {
      toastr.error(error);
    });
  };
});



'use strict';

/**
 * @ngdoc controller
 * @name ActivitiesController
 * @description
 *  simple activity 설정 화면 (아래 controller 들의 state 를 포함하는 state 의 controller)
 */
app.controller('ActivitiesController', function($scope, Devices) {
  $scope.simpleActivity = { 'currentDevice': null, 'devices': [] };
  $scope.simpleActivity.index = 0;

  // function 들 array 초기화
  Devices.initFunctions();

});

/**
 * @ngdoc controller
 * @name ChooseActivityDeviceController
 * @description
 *  based on device 선택 화면
 */
app.controller('ChooseActivityDeviceController', function ($scope, $state, Systems ) {

  $scope.doNext = function() {

    // 해당 deivce ID 와 연계된 button 의 데이터 얻어와서 저장
    Systems.updateCurrentMacroForDevice($scope.room.id, $scope.simpleActivity.currentDevice.id).then(
      function(data) {
        console.log(data);
        $state.go('menu.programming.activities.devices-to-use');
      },
      function (error) {
        alert(error);
      }
    );
  };
});

/**
 * @ngdoc controller
 * @name ActivityDevicesController
 * @description
 *  simple activity 선택 화면
 */
app.controller('ActivityDevicesController', function ($scope, $state, Systems, Devices, Auth) {
  var dataActivity = Systems.getCurrentMacro();
  $scope.simpleActivity.devices = [];
  console.log(dataActivity);

  var navigate = {};

  if (dataActivity) {
    _.each(dataActivity.activity, function(item) {
      if (item.type === 2 && item.navigate) {
        navigate[item.device_id] = true;
      }
    });
  }

  if(dataActivity && dataActivity.edit_type === 0 && dataActivity.activity.length ) {//simple activity
    _.forEach(dataActivity.activity, function(data) {
      var device = Systems.getDevice($scope.room.id, data.device_id);

      if (device) {
        var obj = {
          'device_id': data.device_id,
          'name': device.name,
          'type': data.type,
          'func': data.func,
          'repeat_min': device.repeat_min,
          'repeat_macro': device.repeat_macro,
          'target_type': device.target_type,
          'target_addr': device.target_addr,
          'target_port': device.target_port
        };
        if (navigate[data.device_id]) {
          obj.navigate = 1;
        }
        $scope.simpleActivity.devices.push(obj);
      }
    });
  }
  else {
    _.forEach($scope.room.devices, function(device) {
      if ($scope.simpleActivity.currentDevice.id === device.id && _.isEmpty($scope.simpleActivity.devices)) {
        var obj = {
          'device_id': device.id,
          'name': device.name,
          'type': 1,
          'func': null,
          'repeat_min': device.repeat_min,
          'repeat_macro': device.repeat_macro,
          'target_type': device.target_type,
          'target_addr': device.target_addr,
          'target_port': device.target_port
        };
        if (navigate[device.id]) {
          obj.navigate = 1;
        }
        $scope.simpleActivity.devices.push(obj);
      }
    });
  }

  $scope.goBack = function() {
    $scope.simpleActivity.devices = [];
    Devices.initFunctions();
    $state.go('menu.programming.activities.choose-device' );
  };

  $scope.doNext = function() {
    $state.go('menu.programming.activities.commands');
  };

  Auth.currentUser().then(function(user) {
    $scope.optMenuShow = user.optMenuShow;
  });
  
  $scope.goAdvanced = function() {
    $state.go('menu.advanced.add-macros.macro-type');
  };

});

/**
 * @ngdoc controller
 * @name ActivityDeviceCommandsController
 * @description
 *  command 선택 화면
 */
app.controller('ActivityDeviceCommandsController', function ($scope, $state, Systems) {

  $scope.goBack = function() {
    if ($scope.simpleActivity.index === 0) {
      $state.go('menu.programming.activities.devices-to-use');
    } else {
      $scope.simpleActivity.index--;
    }
  };

  $scope.incrIdx = function() { $scope.simpleActivity.index++; };


  $scope.finish = function() {
    //Save to server
    var sendData = angular.copy($scope.simpleActivity.devices);

    for (var i=0,  tot=sendData.length; i < tot; i++) {
      sendData[i].func = sendData[i].func.id;
      delete sendData[i].name;
      delete sendData[i].repeat_min;
      delete sendData[i].repeat_macro;
      delete sendData[i].target_type;
      delete sendData[i].target_addr;
      delete sendData[i].target_port;
    }

    var jsonData = JSON.stringify( { auto_wait : 1, edit_type : 0, popup : 1, activity : sendData, macro : []} );
    console.log(jsonData);

    // 해당 device ID 와 연계된 button 의 데이터 저장
    Systems.storeDeviceButtonMacro($scope.room.id, $scope.simpleActivity.currentDevice.id, jsonData).then(function(response) {
      if(response.data.result === true) {
        $state.go('menu.programming.options');
      }
      else {
        alert('Your edit/create action failed.  Please try again.');
      }
    }, function(error){
      alert("Please try again");
    });

  };

});

'use strict';
/**
 * @ngdoc controller
 * @name AdvancedDeviceTypeController
 * @description
 *  device type 선택
 */
app.controller('AdvancedDeviceTypeController', function ($rootScope, $scope, $state, toastr, categories, Systems) {
  var currentSystem = Systems.getCurrentSystem(),
    twowayDevicesCount = 0;

  $scope.twowayDevicesLimit = $rootScope.env.twowayDevicesLimit;

  $scope.allowTwowayDevices = true;
  _.each(currentSystem.rooms, function(room) {
    twowayDevicesCount += room.twoway_devices.length || 0;
  });

  // Advanced Device 는 최대 $scope.twowayDevicesLimit 개까지만 추가할 수 있음
  if (twowayDevicesCount >= $scope.twowayDevicesLimit) {
    $scope.allowTwowayDevices = false;
    toastr.error('There are already ' + $scope.twowayDevicesLimit + ' Advanced Devices in the system.  You must delete one of them before adding another. Go to the Home Overview to delete devices.');
  }

  if (!$scope.device.type) {
    $scope.device.type = {id: categories[0].id, name: categories[0].name, target_type: categories[0].target_type};  // 기본값 설정

    //브랜드 네임이 있으면 추가 한다.
    if(categories[0].brand_name){
      $scope.device.type.brand_name = categories[0].brand_name;
    }

    if (categories[0].variables && categories[0].variables.length) {
      $scope.device.type.variables = categories[0].variables;
    }
  }

  $scope.types = categories;

  // 콤보박스 선택시에 브랜드 네임과 디바이스 네임을 반환한다.
  $scope.getCombolabel = function(item){
    if(item.brand_name){
      return item.name === 'TRF-ZW1' ? item.brand_name + ' ' + 'TRF-ZW' : (item.brand_name === item.name ? item.name : item.brand_name + ' ' + item.name);
    } else {
      return item.name;
    }
  }

  // advanced device type 을 선택할 때 More... 가 나올지 여부 설정
  if ($rootScope.env.advancedDeviceMore) {
    if (!_.findWhere($scope.types, { name: 'More...' })) {
      $scope.types.push({
        name: 'More...'
      });
    }

    // More... 를 선택한 경우 선택가능한 device type 을 Systems.getTwowayCategories 를 통해 다시 불러옴
    $scope.$watch('device.type', function(newVal, oldVal) {
      if (newVal.name === 'More...') {
        $state.go('menu.programming.add-advanced-device.more-device-category');
      }
    });
  }

  $scope.doNext = function () {
    // System에 걸쳐 TRF-ZW1은 한개
    // 이미 등록된 TRF-ZW1 이 있으면 진행하지 않음
    var trfzw1Exist = false;

    _.each(currentSystem.rooms, function(room) {
      _.each(room.twoway_devices, function(twoway_device) {
        if (twoway_device.model === 'TRF-ZW1') {
          trfzw1Exist = true;
        }
      });
    });

    if (trfzw1Exist && $scope.device.type.name === 'TRF-ZW1') {  // system 에 TRF-ZW1 이 존재하는데 TRF-ZW1 을 추가하려고 선택한 경우
      toastr.error('There is already a TRF-ZW in the system.');
    } else {
      if ($scope.device.type.variables && $scope.device.type.variables.length) {
        $scope.device.model = angular.copy($scope.device.type);
        $state.go('menu.programming.add-advanced-device.more-device-name');
      } else {
        $state.go('menu.programming.add-advanced-device.device-name');
      }
    }
  };
});

/**
 * @ngdoc controller
 * @name MoreAdvancedDeviceCategoryController
 * @description
 *  more device category 선택
 */
app.controller('MoreAdvancedDeviceCategoryController', function ($scope, $state, toastr, moreCategories, Systems) {
  delete($scope.device.type);

  var currentSystem = Systems.getCurrentSystem();

  if (!$scope.device.category) {
    $scope.device.category = {id: moreCategories[0].id, name: moreCategories[0].name};  // 기본값 설정
  }
  $scope.categories = moreCategories;

  $scope.$watch('device.category', function(newVal, oldVal) {
    if (newVal && oldVal && newVal.id !== oldVal.id) {
      $scope.device.brand = null;
      $scope.device.model = null;
    }
  });

  $scope.doNext = function () {
    // System에 걸쳐 TRF-ZW1은 한개
    // 이미 등록된 TRF-ZW1 이 있으면 진행하지 않음
    var trfzw1Exist = false;

    _.each(currentSystem.rooms, function(room) {
      _.each(room.twoway_devices, function(twoway_device) {
        if (twoway_device.model === 'TRF-ZW1') {
          trfzw1Exist = true;
        }
      });
    });

    if (trfzw1Exist && $scope.device.category.name === 'TRF-ZW1') {  // system 에 TRF-ZW1 이 존재하는데 TRF-ZW1 을 추가하려고 선택한 경우
      toastr.error('There is already a TRF-ZW in the system.');
    } else {
      $state.go('menu.programming.add-advanced-device.more-device-name');
    }
  };
});

/**
 * @ngdoc controller
 * @name AdvancedDeviceNameController
 * @description
 *  device name 입력
 */
app.controller('AdvancedDeviceNameController', function ($scope, $state, $modal, toastr, Database, Rooms, Devices, Systems) {
  $scope.device.name = $scope.device.type.name === 'TRF-ZW1' ? 'TRF-ZW' : angular.copy($scope.device.type.name);

  // MAC
  if ($scope.device.type.target_type & 0x0001) {
    // discovery
    if ($scope.device.type.target_type & 0x00010000) {
      $scope.device.addType = 'discovery';
    }
    // mac
    else {
      $scope.device.addType = 'mac';
    }
  } else {
    // IP
    if ($scope.device.type.target_type & 0x0002) {
      $scope.device.addType = 'ip';
    }
    // service
    else if ($scope.device.type.target_type & 0x0004) {
      $scope.device.addType = 'service';
    }
  }

  // 같은 이름의 device name 이 이미 등록되어 있음을 알리는 modal
  var modal = $modal({
    scope: $scope,
    title: 'Duplicate device name',
    container: '.editor-container',
    template: 'views/modal-tpls/twoway-duplicate-name.html',
    show: false
  });

  $scope.doNext = function() {
    var deviceNames = _.pluck(Rooms.getTwowayDevices($scope.room.id), 'name');
    if (_.contains(deviceNames, $scope.device.name)) {
      modal.$promise.then(modal.show);
    } else {
      $scope.doNext2();
    }
  };

  $scope.doNext2 = function() {
    if ($scope.device.addType === 'service') {
      $state.go('menu.programming.add-advanced-device.device-review', {'addType': 'service'});
    } else {
      $state.go('menu.programming.add-advanced-device.device-identification', {'addType': $scope.device.addType, 'model': $scope.device.type.name});
    }
  };
});

/**
 * @ngdoc controller
 * @name MoreAdvancedDeviceNameController
 * @description
 *  more device name 입력
 */
app.controller('MoreAdvancedDeviceNameController', function ($scope, $state, $modal, toastr, Database, Rooms, Devices, Systems) {
  // 같은 이름의 device name 이 이미 등록되어 있음을 알리는 modal
  var modal = $modal({
    scope: $scope,
    title: 'Duplicate device name',
    container: '.editor-container',
    template: 'views/modal-tpls/twoway-duplicate-name.html',
    show: false
  });

  $scope.doNext = function() {
    var deviceNames = _.pluck(Rooms.getTwowayDevices($scope.room.id), 'name');
    if (_.contains(deviceNames, $scope.device.name)) {
      modal.$promise.then(modal.show);
    } else {
      $scope.doNext2();
    }
  };

  $scope.doNext2 = function() {
    if ($scope.device.category && $scope.device.category.id) {
      $state.go('menu.programming.add-advanced-device.more-device-brand', {'categoryId': $scope.device.category.id});
    } else {
      // variables 입력 - mac, ip 도 입력해야 할 수 있음
      if ($scope.device.model.variables && $scope.device.model.variables.length) {
        $scope.device.addType = 'variables';
        $state.go('menu.programming.add-advanced-device.more-device-identification');
      }
      // mac 입력
      else if ($scope.device.model.target_type === 1) {
        $scope.device.addType = 'mac';
        $state.go('menu.programming.add-advanced-device.more-device-identification');
      }
      // IP 입력
      else if ($scope.device.model.target_type === 2) {
        $scope.device.addType = 'ip';
        $state.go('menu.programming.add-advanced-device.more-device-identification');
      }
      // device review 화면으로 이동
      else {
        $state.go('menu.programming.add-advanced-device.more-device-review');
      }
    }
  };
});

/**
 * @ngdoc controller
 * @name MoreAdvancedDeviceBrandController
 * @description
 *  more device brand 선택
 */
app.controller('MoreAdvancedDeviceBrandController', function ($scope, $state, $modal, toastr, brands) {
  $scope.brands = brands;

  $scope.$watch('device.brand', function(newVal, oldVal) {
    if (newVal && oldVal && newVal.id !== oldVal.id) {
      $scope.device.model = null;
    }
  });

  $scope.doNext = function() {
    $state.go('menu.programming.add-advanced-device.more-device-model', {'brandId': $scope.device.brand.id});
  };
});

/**
 * @ngdoc controller
 * @name MoreAdvancedDeviceModelController
 * @description
 *  more device model 선택
 */
app.controller('MoreAdvancedDeviceModelController', function ($scope, $state, $modal, toastr, models) {
  $scope.models = models;

  $scope.doNext = function() {
    // variables 입력 - mac, ip 도 입력해야 할 수 있음
    if ($scope.device.model.variables && $scope.device.model.variables.length) {
      $scope.device.addType = 'variables';
      $state.go('menu.programming.add-advanced-device.more-device-identification');
    }
    // mac 입력
    else if ($scope.device.model.target_type === 1) {
      $scope.device.addType = 'mac';
      $state.go('menu.programming.add-advanced-device.more-device-identification');
    }
    // IP 입력
    else if ($scope.device.model.target_type === 2) {
      $scope.device.addType = 'ip';
      $state.go('menu.programming.add-advanced-device.more-device-identification');
    }
    // device review 화면으로 이동
    else {
      $state.go('menu.programming.add-advanced-device.more-device-review');
    }
  };
});

/**
 * @ngdoc controller
 * @name MoreAdvancedDeviceReviewController
 * @description
 *  more device review
 */
app.controller('MoreAdvancedDeviceReviewController', function ($scope, $state, $modal, toastr, Devices, Systems) {
  var d = {
      name: $scope.device.name,
      model: $scope.device.model.name,
      modelId: $scope.device.model.id,
      targetType: $scope.device.model.target_type,
      targetAddr: '""',
      variables: '""'
    },
    jsonData;

  // mac
  if ($scope.device.addType === 'mac') {
    d.targetAddr = $scope.device.key.mac1 + $scope.device.key.mac2 + $scope.device.key.mac3 + $scope.device.key.mac4 + $scope.device.key.mac5 + $scope.device.key.mac6;
    d.targetAddr = d.targetAddr.toUpperCase();
  }
  // IP
  else if ($scope.device.addType === 'ip') {
    d.targetAddr = $scope.device.ip.address + ':' + $scope.device.ip.port;
  }
  // variables
  else if ($scope.device.addType === 'variables') {
    if ($scope.device.model.target_type === 1) {
      d.targetAddr = $scope.device.key.mac1 + $scope.device.key.mac2 + $scope.device.key.mac3 + $scope.device.key.mac4 + $scope.device.key.mac5 + $scope.device.key.mac6;
    } else if ($scope.device.model.target_type === 2) {
      d.targetAddr = $scope.device.ip.address + ':' + $scope.device.ip.port;
    }

    d.variables = [];
    _.each($scope.device.allVariables, function(item) {
      var obj = angular.copy(item);
      delete(obj['$$hashKey']);
      delete(obj.required);
      delete(obj.readonly);
      delete(obj.type);

      d.variables.push(obj);
    });
  }

  jsonData = JSON.stringify(d);

  // device 생성
  $scope.doNext = function() {
    return Devices.createTwowayDevice($scope.room.id, jsonData)
      .then(function(data) {
        console.log(data);

        Systems.updateSystem(Systems.getCurrentSystem().id).then(function() {
          $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
        }).catch(function(error) {
          toastr.error(error);
        });
      })
      .catch(toastr.error);
  };
});

/**
 * @ngdoc controller
 * @name MoreAdvancedDeviceIdentificationController
 * @description
 *  more device 정보 설정
 */
app.controller('MoreAdvancedDeviceIdentificationController', function ($scope, $state, $modal, toastr, Database, Rooms, Devices, Systems) {
  if (typeof $scope.device.key === 'undefined') {
    $scope.device.key = {};
  }
  if (typeof $scope.device.ip === 'undefined') {
    $scope.device.ip = {};
  }

  // mac or IP
  if ($scope.device.addType === 'mac' || $scope.device.addType === 'ip') {
    $scope.doNext = function() {
      $state.go('menu.programming.add-advanced-device.more-device-review');
    };
  }
  // variables
  else if ($scope.device.addType === 'variables') {
    $scope.device.varData = {};
    $scope.device.varUsername = false;
    $scope.device.varPassword = false;
    $scope.device.varPort = false;
    $scope.device.variables = [];

    _.each($scope.device.model.variables, function(item) {
      if (item.name === 'username') {
        $scope.device.varUsername = true;
      }
      if (item.name === 'password') {
        $scope.device.varPassword = true;
      }
      if (item.name === 'device_port') {
        $scope.device.varPort = true;

        if (item['default']) {
          $scope.device.ip.port = +item['default'];
        }
      }

      $scope.device.varData[item.name] = item;
      if (item['default']) {
        $scope.device.varData[item.name].value = item['default'];
      }

      if (item.attr.match('n')) {
        item.required = true;
      } else {
        item.required = false;
      }

      if (item.attr.match('p')) {
        item.type = 'password';
      } else if (item.attr.match('m')) {
        item.type = 'textarea';
      } else {
        item.type = 'text';
      }

      if (item.attr.match('r')) {
        item.readonly = true;
      } else {
        item.readonly = false;
      }

      $scope.device.variables.push(item);
    });

    var upRestLength = $scope.device.varPort ? 3 : 2;   // device_port 가 있는 경우에는 username, password, device_port 까지 3개를 빼고 계산해야 함

    // username/password 가 있는지, 나머지 variables 가 있는지 여부에 따라 페이지 구성이 달라짐
    // 1. username/password 가 있으면서 나머지 variables 도 있는 경우
    if ($scope.device.varUsername && $scope.device.varPassword && $scope.device.variables.length > upRestLength) {
      $scope.device.varType = 'UPV';    // username, password, others
    }
    // 2. username/password 만 있는 경우
    else if ($scope.device.varUsername && $scope.device.varPassword && $scope.device.variables.length === upRestLength) {
      $scope.device.varType = 'UP';     // username, password
    }
    // 3. username/password 가 없으면서 나머지 variables 가 있는 경우
    else if (($scope.device.varPort && $scope.device.variables.length > 1) || (!$scope.device.varPort && $scope.device.variables.length > 0)) {
      $scope.device.varType = 'V';      // 나머지 variables
    }
    // 4. IP/Port 입력만 필요한 경우
    else if ($scope.device.varPort && $scope.device.variables.length === 1) {
      $scope.device.varType = 'IP';
    }

    // mac/ip 입력하는 화면, username/password 입력하는 화면, 나머지 variables 입력하는 화면
    if ($scope.device.model.target_type === 1 || $scope.device.model.target_type === 2) {
      $scope.device.varStep = 'mac_ip';
    } else if ($scope.device.varType === 'UPV' || $scope.device.varType === 'UP') {
      $scope.device.varStep = 'UP';
    } else {
      $scope.device.varStep = 'V';
    }

    $scope.doNext = function() {
      if ($scope.device.varStep === 'mac_ip') {
        if ($scope.device.varUsername && $scope.device.varPassword) {
          $scope.device.varStep = 'UP';
        } else if ($scope.device.varType === 'IP') {
          // review 페이지로 이동
            // json data 생성
            $scope.device.allVariables = [];

            _.each($scope.device.variables, function(item) {
              $scope.device.allVariables.push(item);
            });

            $state.go('menu.programming.add-advanced-device.more-device-review');
        } else {
          $scope.device.varStep = 'V';
        }
      }
      else if ($scope.device.varStep === 'UP' && $scope.device.varType === 'UPV') {
        $scope.device.varStep = 'V';
      }
      // review 페이지로 이동
      else {
        // json data 생성
        $scope.device.allVariables = [];

        _.each($scope.device.variables, function(item) {
          $scope.device.allVariables.push(item);
        });

        $state.go('menu.programming.add-advanced-device.more-device-review');
      }
    };
  }
});

/**
 * @ngdoc controller
 * @name AdvancedDeviceIdentificationController
 * @description
 *  device 추가
 */
app.controller('AdvancedDeviceIdentificationController', function ($rootScope, $scope, $state, $modal, toastr, devices, Database, Rooms, Devices, Systems) {
  $scope.trfZwLink = $rootScope.env.trfZwLink;

  if ($scope.device.addType === 'discovery') {
    $scope.twowayDevices = devices.searchedDevices || [];
  }

  $scope.device.key = {};
  $scope.device.ip = {};

  // discovery
  if ($scope.device.addType === 'discovery') {
    $scope.$watch('device.mac', function() {
      $scope.device.targetAddr = $scope.device.mac;
    });
  }
  // mac
  else if ($scope.device.addType === 'mac') {
    $scope.$watch('device.key', function() {
      $scope.device.targetAddr = $scope.device.key.mac1 + $scope.device.key.mac2 + $scope.device.key.mac3 + $scope.device.key.mac4 + $scope.device.key.mac5 + $scope.device.key.mac6;
      $scope.device.targetAddr = $scope.device.targetAddr.toUpperCase();
    }, true);
  }
  // IP
  else if ($scope.device.addType === 'ip') {
    $scope.$watch('device.ip', function() {
      $scope.device.targetAddr = $scope.device.ip.address + ':' + $scope.device.ip.port;
    }, true);
  }

  $scope.doNext = function() {
    if ($scope.device.addType === 'mac') {
      $state.go('menu.programming.add-advanced-device.device-review', {'addType': 'mac'});
    } else {
      var d = {
          name: $scope.device.name,
          model: $scope.device.type.name,
          modelId: $scope.device.type.id,
          targetType: $scope.device.type.target_type,
          targetAddr: $scope.device.targetAddr,
          variables: '""'
        },
        jsonData = JSON.stringify(d);

      // device 생성
      return Devices.createTwowayDevice($scope.room.id, jsonData)
        .then(function(data) {
          console.log(data);

          Systems.updateSystem(Systems.getCurrentSystem().id).then(function() {
            if ($scope.trfZwLink && $scope.device.type.name === 'TRF-ZW1') {
              $state.go('menu.programming.add-advanced-device.trf-zw-setup');
            } else {
              $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
            }
          }).catch(function(error) {
            toastr.error(error);
          });
        })
        .catch(toastr.error);
    }
  };

  $scope.getTwowayDevices = function(type) {
    Systems.getTwowayDevices(type).then(
      function(data) {
        $scope.twowayDevices = data.searchedDevices || [];
      },
      function(error) {
        toastr.error(error, 'Error');
      }
    );
  };
});

/**
 * @ngdoc controller
 * @name AdvancedDeviceReviewController
 * @description
 *  device review
 */
app.controller('AdvancedDeviceReviewController', function ($scope, $state, $stateParams, $modal, toastr, Devices, Systems) {
  var d, jsonData;

  $scope.doNext = function() {
    if ($stateParams.addType === 'service') {
      d = {
        name: $scope.device.name,
        model: $scope.device.type.name,
        modelId: $scope.device.type.id,
        targetType: $scope.device.type.target_type,
        targetAddr: '""',
        variables: '""'
      };
      jsonData = JSON.stringify(d);

      // device 생성
      return Devices.createTwowayDevice($scope.room.id, jsonData)
        .then(function(data) {
          console.log(data);

          Systems.updateSystem(Systems.getCurrentSystem().id).then(function() {
            $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
          }).catch(function(error) {
            toastr.error(error);
          });
        })
        .catch(toastr.error);
    } else if ($stateParams.addType === 'mac') {
      d = {
        name: $scope.device.name,
        model: $scope.device.type.name,
        modelId: $scope.device.type.id,
        targetType: $scope.device.type.target_type,
        targetAddr: $scope.device.targetAddr,
        variables: '""'
      };
      jsonData = JSON.stringify(d);

      // device 생성
      return Devices.createTwowayDevice($scope.room.id, jsonData)
        .then(function(data) {
          console.log(data);

          Systems.updateSystem(Systems.getCurrentSystem().id).then(function() {
            $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
          }).catch(function(error) {
            toastr.error(error);
          });
        })
        .catch(toastr.error);
    }
  };
});

/**
 * @ngdoc controller
 * @name AdvancedDeviceTrfZwSetupController
 * @description
 *  TRF-ZW setup 안내 페이지
 */
app.controller('AdvancedDeviceTrfZwSetupController', function ($rootScope, $scope, $state) {
  $scope.urcControlRoomLink = $rootScope.env.urcControlRoomLink;
  $scope.urcControlRoomUrl = $rootScope.env.urcControlRoomUrl;

  $scope.finish = function() {
    $state.go('menu.programming.options');
  };
});
'use strict';
/**
 * @ngdoc controller
 * @name SelectBaseController
 * @description
 *  base station 목록 표시 및 추가
 */
app.controller('SelectBaseController', function ($rootScope, $scope, $state, toastr, searchResults, Systems, Rooms ) {
  $scope.searchKey = searchResults.searchKey;
  $scope.baseStations = searchResults.searchedDevices;

  $scope.bsType = 'BASESTATIONS';

  $scope.changedValue = function() {
    if (!$scope.addBStationForm.displayText.$dirty) {
      var bs = $scope.addBaseStation.selection;
      $scope.addBaseStation.displayText =  bs.name + ' ' + bs.mac.slice(10,12);
    }
  };

  $scope.finish = function () {
    var currentSystem = Systems.getCurrentSystem(),
            givenName = $scope.addBaseStation.displayText,
          baseStation = $scope.addBaseStation.selection,
             jsonData = JSON.stringify({ mac : baseStation.mac, type : baseStation.name, name: givenName, lightLevel: 2, searchKey: $scope.searchKey });

    // slave base station 을 room 에 추가
    var addBStation = function(roomId, json) {
      return Rooms.baseStations('add', roomId, json).then(function(data) { 
        toastr.success('Successfully added ' + givenName + '.');
        return Systems.getCurrentSystem().id;
      });
    };

    var updateSystem = function(id) {
      return Systems.updateSystem(id).then(function (data) {
        console.log(data);
        return $state.transitionTo('menu.programming.options', {}, { reload: true, inherit: true, notify: true  });
        //$state.go('menu.programming.option');
      });
    };

    addBStation($scope.room.id, jsonData)
      .then(updateSystem)
      .catch(function(error) {
        toastr.error(error, 'Error');
      });

  };
});
'use strict';
/**
 * @ngdoc controller
 * @name DeviceTypeController
 * @description
 *  device type 선택
 */
app.controller('DeviceTypeController', function ($scope, $state, categories) {
	if (!$scope.device.type) {
		$scope.device.type = {id: categories[0].id, name: categories[0].name, device: categories[0].device};  // 기본값 설정
	}
	$scope.types = categories;

	$scope.doNext = function () {
		$state.go('menu.programming.add-device.device-name');
	};
});

/**
 * @ngdoc controller
 * @name DeviceNameController
 * @description
 *  device name 입력
 */
app.controller('DeviceNameController', function ($scope, $state, $modal, toastr, Database, Rooms) {
	$scope.device.name = angular.copy($scope.device.type.device);

	var getDeviceBrands = function() {
		Database.retrieveDeviceBrands($scope.device.type.name).then(function(data) {
			$state.go('menu.programming.add-device.device-brand');
		}).catch(toastr.error);
	};

	$scope.getBrandsFromDB = getDeviceBrands;

	// 같은 이름의 device name 이 이미 등록되어 있음을 알리는 modal
	var modal = $modal({
		scope: $scope,
		title: 'Duplicate device name',
		container: '.editor-container',
		template: 'views/modal-tpls/duplicate-name.html',
		show: false
	});

	$scope.doNext = function() {
		var deviceNames = _.pluck(Rooms.getDevices($scope.room.id), 'name');
		if (_.contains(deviceNames, $scope.device.name)) {
			modal.$promise.then(modal.show);
		} else {
			getDeviceBrands();
		}
	};
});

/**
 * @ngdoc controller
 * @name DeviceBrandController
 * @description
 *  device brand 선택
 */
app.controller('DeviceBrandController', function ($scope, $state, Database, Devices) {
	$scope.device.brand = null;
	$scope.brands = Database.getBrands();

	$scope.doNext = function () {
		Devices.setCurrentDevice(angular.copy($scope.device));

		$state.go('menu.programming.add-device.device-model');
	};
});

/**
 * @ngdoc controller
 * @name DeviceModelController
 * @description
 *  device popuplar model 선택
 */
app.controller('DeviceModelController', function ($scope, $state, $modal, $http, toastr, popularDevices, Database) {

	$scope.device.model = null;
	$scope.device.info = null;
	$scope.query.value = '';

	$scope.models = popularDevices;
	$scope.models.ir = [];
	$scope.models.ip = [];

	_.forEach(popularDevices.p_ir, function(device, i) {
		device.index = i;
		$scope.models.ir.push(device);
	});

	_.forEach(popularDevices.p_ip, function(device, i) {
		device.index = i;
		$scope.models.ip.push(device);
	});

	if ($scope.models.ir.length) {
		$scope.device.targetType = 1;
	}

	$scope.doNext = function () {
		return Database.getDeviceInfo($scope.device.type.name, $scope.device.brand.name, $scope.device.model.id, $scope.device.targetType, $scope.device.model.type)
			.then(function(data) {
				var attrs = data.attr;
				console.log(attrs);
				if (attrs.codeset === 'ip') {
					$scope.device.targetPort = $scope.device.targetPort || parseInt(attrs.port, 10);
				} else {
					$scope.device.targetPort = 255;
					$scope.device.targetAddr = $scope.room.bstations[0].mac;
				}

				$scope.device.powerOff = false;
				if (data.meta.length) {
					_.each(data.meta, function(meta) {
						if (meta.strid === 'POWER_OFF' || meta.strid === 'POWER_TOGGLE') {
							$scope.device.powerOff = true;
						}
					});
				}

				$state.go('menu.programming.add-device.device-settings');
			})
			.catch(toastr.error);
	};

	// 테스트 팝업 화면 띄우기
	$scope.showTestModal = function() {

		// power on, mute, 나머지 commands 얻기 위해 getDeviceInfo
		Database.getDeviceInfo($scope.device.type.name, $scope.device.brand.name, $scope.device.model.id, $scope.device.targetType, $scope.device.model.type)
			.then(function(data) {
				$scope.device.info = data;
				$scope.device.powerBtn = false;
				$scope.device.powerBtnData = null;
				$scope.device.muteBtn = false;
				$scope.device.muteBtnData = null;

				_.each(data.btns, function(btn) {
					if (btn.def == 'POWER ON' || btn.def == 'POWER TOGGLE') {
						$scope.device.powerBtn = true;
						$scope.device.powerBtnData = btn.cmd;
					}
					if (btn.def == 'MUTE') {
						$scope.device.muteBtn = true;
						$scope.device.muteBtnData = btn.cmd;
					}
				});

				if (data.attr.codeset === 'ip') {
					$scope.device.targetPort = parseInt(data.attr.port, 10);
				} else {
					$scope.device.targetPort = -1;
				}

				var modal = $modal({
					scope: $scope,
					placement: 'top',
					template: 'views/modal-tpls/test-commands.html',
					container: 'body',
					show: false
				});
				modal.$promise.then(modal.show);
			})
			.catch(toastr.error);
	};

	$scope.device.testBstationMac = $scope.room.bstations[0].mac;

	// 테스트 실행
	$scope.btnTest = function(func) {
		var testData = {},
			data;

		if($scope.device.targetType === 2) {
			if (!$scope.device.targetAddr) {
				toastr.error('An IP address is required.');
				return;
			}
		}

		// power on
		if (func == 'power') {
			data = $scope.device.powerBtnData;
		}
		// mute
		else if (func == 'mute') {
			data = $scope.device.muteBtnData;
		}
		// other commands
		else {
			data = func;
		}

		if($scope.device.targetType === 1) {
			testData = { "systemId" : $scope.system.id, "type" : $scope.device.targetType,
				"addr" : $scope.device.testBstationMac, "port" : $scope.device.targetPort, "repeat" : $scope.device.info.attr.rpt_cnt,
				"ir_type": func.type || 0, "data" : data };
		}
		else {
			testData = { "systemId" : $scope.system.id, "type" : $scope.device.targetType,
				"addr" : $scope.device.targetAddr, "port" : $scope.device.targetPort, "repeat" : $scope.device.info.attr.rpt_cnt,
				"ramp_start" : $scope.device.info.attr.ramp_st, "ramp_speed" : $scope.device.info.attr.ramp_sp, "auto_cr" : $scope.device.info.attr.auto_cr,
				"data" : data };
		}

		var jsonTestData = JSON.stringify(testData);

		$http({
			method: 'POST',
			url: '/api/cloud/test',
			data: jsonTestData
		}).
			success(function(data) {
				if(data.result === true) {
					toastr.success('Test command sent');
				}
				else {
					toastr.error(data.error);
				}
			}).
			error(function() {
				toastr.error("Please try again");
			});
	};

	$scope.goSearchModel = function() {
		$state.go('menu.programming.add-device.device-model-search');
	};

	$scope.goAllModels = function() {
		$state.go('menu.programming.add-device.device-model-all');
	};
});

/**
 * @ngdoc controller
 * @name DeviceModelAllController
 * @description
 *  device all model 선택
 */
app.controller('DeviceModelAllController', function ($scope, $state, $modal, $http, toastr, allDevices, Database) {

	$scope.device.model = null;
	$scope.device.info = null;
	$scope.query.value = '';

	$scope.models = allDevices;
	$scope.models.ir = [];
	$scope.models.ip = [];

	_.forEach(allDevices.p_ir, function(device, i) {
		device.index = i;
		$scope.models.ir.push(device);
	});

	_.forEach(allDevices.p_ip, function(device, i) {
		device.index = i;
		$scope.models.ip.push(device);
	});

	if ($scope.models.ir.length) {
		$scope.device.targetType = 1;
	}

	$scope.doNext = function () {
		return Database.getDeviceInfo($scope.device.type.name, $scope.device.brand.name, $scope.device.model.id, $scope.device.targetType, $scope.device.model.type)
			.then(function(data) {
				var attrs = data.attr;
				console.log(attrs);
				if (attrs.codeset === 'ip') {
					$scope.device.targetPort = $scope.device.targetPort || parseInt(attrs.port, 10);
				} else {
					$scope.device.targetPort = 255;
					$scope.device.targetAddr = $scope.room.bstations[0].mac;
				}

				$scope.device.powerOff = false;
				if (data.meta.length) {
					_.each(data.meta, function(meta) {
						if (meta.strid === 'POWER_OFF' || meta.strid === 'POWER_TOGGLE') {
							$scope.device.powerOff = true;
						}
					});
				}

				$state.go('menu.programming.add-device.device-settings');
			})
			.catch(toastr.error);
	};

	// 테스트 팝업 화면 띄우기
	$scope.showTestModal = function() {

		// power on, mute, 나머지 commands 얻기 위해 getDeviceInfo
		Database.getDeviceInfo($scope.device.type.name, $scope.device.brand.name, $scope.device.model.id, $scope.device.targetType, $scope.device.model.type)
			.then(function(data) {
				$scope.device.info = data;
				$scope.device.powerBtn = false;
				$scope.device.powerBtnData = null;
				$scope.device.muteBtn = false;
				$scope.device.muteBtnData = null;

				_.each(data.btns, function(btn) {
					if (btn.def == 'POWER ON' || btn.def == 'POWER TOGGLE') {
						$scope.device.powerBtn = true;
						$scope.device.powerBtnData = btn.cmd;
					}
					if (btn.def == 'MUTE') {
						$scope.device.muteBtn = true;
						$scope.device.muteBtnData = btn.cmd;
					}
				});

				if (data.attr.codeset === 'ip') {
					$scope.device.targetPort = parseInt(data.attr.port, 10);
				} else {
					$scope.device.targetPort = -1;
				}

				var modal = $modal({
					scope: $scope,
					placement: 'top',
					template: 'views/modal-tpls/test-commands.html',
					container: 'body',
					show: false
				});
				modal.$promise.then(modal.show);
			})
			.catch(toastr.error);
	};

	$scope.device.testBstationMac = $scope.room.bstations[0].mac;

	// 테스트 실행
	$scope.btnTest = function(func) {
		var testData = {},
			data;

		if($scope.device.targetType === 2) {
			if (!$scope.device.targetAddr) {
				toastr.error('An IP address is required.');
				return;
			}
		}

		// power on
		if (func == 'power') {
			data = $scope.device.powerBtnData;
		}
		// mute
		else if (func == 'mute') {
			data = $scope.device.muteBtnData;
		}
		// other commands
		else {
			data = func;
		}

		if($scope.device.targetType === 1) {
			testData = { "systemId" : $scope.system.id, "type" : $scope.device.targetType,
				"addr" : $scope.device.testBstationMac, "port" : $scope.device.targetPort, "repeat" : $scope.device.info.attr.rpt_cnt,
				"ir_type": func.type || 0, "data" : data };
		}
		else {
			testData = { "systemId" : $scope.system.id, "type" : $scope.device.targetType,
				"addr" : $scope.device.targetAddr, "port" : $scope.device.targetPort, "repeat" : $scope.device.info.attr.rpt_cnt,
				"ramp_start" : $scope.device.info.attr.ramp_st, "ramp_speed" : $scope.device.info.attr.ramp_sp, "auto_cr" : $scope.device.info.attr.auto_cr,
				"data" : data };
		}

		var jsonTestData = JSON.stringify(testData);

		$http({
			method: 'POST',
			url: '/api/cloud/test',
			data: jsonTestData
		}).
			success(function(data) {
				if(data.result === true) {
					toastr.success('Test command sent');
				}
				else {
					toastr.error(data.error);
				}
			}).
			error(function() {
				toastr.error("Please try again");
			});
	};
});

/**
 * @ngdoc controller
 * @name DeviceModelSearchController
 * @description
 *  device model 검색
 */
app.controller('DeviceModelSearchController', function ($scope, $state, $modal, $http, toastr, Database) {

	$scope.device.model = null;
	$scope.device.info = null;
	$scope.query.value = '';


	$scope.doNext = function () {
		return Database.getDeviceInfo($scope.device.type.name, $scope.device.brand.name, $scope.device.model.id, $scope.device.targetType, $scope.device.model.type)
			.then(function(data) {
				var attrs = data.attr;
				console.log(attrs);
				if (attrs.codeset === 'ip') {
					$scope.device.targetPort = $scope.device.targetPort || parseInt(attrs.port, 10);
				} else {
					$scope.device.targetPort = 255;
					$scope.device.targetAddr = $scope.room.bstations[0].mac;
				}

				$scope.device.powerOff = false;
				if (data.meta.length) {
					_.each(data.meta, function(meta) {
						if (meta.strid === 'POWER_OFF' || meta.strid === 'POWER_TOGGLE') {
							$scope.device.powerOff = true;
						}
					});
				}

				$state.go('menu.programming.add-device.device-settings');
			})
			.catch(toastr.error);
	};

	// 테스트 팝업 화면 띄우기
	$scope.showTestModal = function() {

		// power on, mute, 나머지 commands 얻기 위해 getDeviceInfo
		Database.getDeviceInfo($scope.device.type.name, $scope.device.brand.name, $scope.device.model.id, $scope.device.targetType, $scope.device.model.type)
			.then(function(data) {
				$scope.device.info = data;
				$scope.device.powerBtn = false;
				$scope.device.powerBtnData = null;
				$scope.device.muteBtn = false;
				$scope.device.muteBtnData = null;

				_.each(data.btns, function(btn) {
					if (btn.def == 'POWER ON' || btn.def == 'POWER TOGGLE') {
						$scope.device.powerBtn = true;
						$scope.device.powerBtnData = btn.cmd;
					}
					if (btn.def == 'MUTE') {
						$scope.device.muteBtn = true;
						$scope.device.muteBtnData = btn.cmd;
					}
				});

				if (data.attr.codeset === 'ip') {
					$scope.device.targetPort = parseInt(data.attr.port, 10);
				} else {
					$scope.device.targetPort = -1;
				}

				var modal = $modal({
					scope: $scope,
					placement: 'top',
					template: 'views/modal-tpls/test-commands.html',
					container: 'body',
					show: false
				});
				modal.$promise.then(modal.show);
			})
			.catch(toastr.error);
	};

	$scope.device.testBstationMac = $scope.room.bstations[0].mac;

	// 테스트 실행
	$scope.btnTest = function(func) {
		var testData = {},
			data;

		if($scope.device.targetType === 2) {
			if (!$scope.device.targetAddr) {
				toastr.error('An IP address is required.');
				return;
			}
		}

		// power on
		if (func == 'power') {
			data = $scope.device.powerBtnData;
		}
		// mute
		else if (func == 'mute') {
			data = $scope.device.muteBtnData;
		}
		// other commands
		else {
			data = func;
		}

		if($scope.device.targetType === 1) {
			testData = { "systemId" : $scope.system.id, "type" : $scope.device.targetType,
				"addr" : $scope.device.testBstationMac, "port" : $scope.device.targetPort, "repeat" : $scope.device.info.attr.rpt_cnt,
				"ir_type": func.type || 0, "data" : data };
		}
		else {
			testData = { "systemId" : $scope.system.id, "type" : $scope.device.targetType,
				"addr" : $scope.device.targetAddr, "port" : $scope.device.targetPort, "repeat" : $scope.device.info.attr.rpt_cnt,
				"ramp_start" : $scope.device.info.attr.ramp_st, "ramp_speed" : $scope.device.info.attr.ramp_sp, "auto_cr" : $scope.device.info.attr.auto_cr,
				"data" : data };
		}

		var jsonTestData = JSON.stringify(testData);

		$http({
			method: 'POST',
			url: '/api/cloud/test',
			data: jsonTestData
		}).
			success(function(data) {
				if(data.result === true) {
					toastr.success('Test command sent');
				}
				else {
					toastr.error(data.error);
				}
			}).
			error(function() {
				toastr.error("Please try again");
			});
	};
});

/**
 * @ngdoc controller
 * @name DeviceSettingsController
 * @description
 *  device 정보 설정 후 생성
 */
app.controller('DeviceSettingsController', function ($rootScope, $scope, $state, toastr, types, Systems, Database, Devices) {
  if ($rootScope.virtualEditor) {
    $scope.wireless_ir_port = 1;
    $scope.irPortOptions = [{name: 'All', value: 255}, {name: '1', value: 1}, {name: '2', value: 2}, {
      name: '3',
      value: 3
    }, {name: '4', value: 4}];
  } else {
    var bstationType = $scope.room.bstations[0].type,
      irInfo = _.find(types, {name: bstationType});

    $scope.wireless_ir_port = irInfo.wireless_ir_port;

    if (irInfo.wired_ir_port_all && irInfo.wired_ir_port == 4) {
      $scope.irPortOptions = [{name: 'All', value: 255}, {name: '1', value: 1}, {name: '2', value: 2}, {
        name: '3',
        value: 3
      }, {name: '4', value: 4}];
    } else if (irInfo.wired_ir_port_all && irInfo.wired_ir_port == 5) {
      $scope.irPortOptions = [{name: 'All', value: 255}, {name: '1', value: 1}, {name: '2', value: 2}, {
        name: '3',
        value: 3
      }, {name: '4', value: 4}, {name: '5', value: 5}];
    } else if (!irInfo.wired_ir_port_all && irInfo.wired_ir_port == 4) {
      $scope.irPortOptions = [{name: '1', value: 1}, {name: '2', value: 2}, {name: '3', value: 3}, {
        name: '4',
        value: 4
      }];
    } else if (!irInfo.wired_ir_port_all && irInfo.wired_ir_port == 5) {
      $scope.irPortOptions = [{name: '1', value: 1}, {name: '2', value: 2}, {name: '3', value: 3}, {
        name: '4',
        value: 4
      }, {name: '5', value: 5}];
    }
  }

	$scope.ir = {target:0, port:255};
	$scope.ir.target = ($scope.device.targetPort ? 1:2);
	$scope.ir.port = ($scope.device.targetPort  ? $scope.device.targetPort :255);

	$scope.isEntDevice = Database.checkIfEntertainment($scope.device.type.name);

	$scope.doNext = function () {
		if($scope.device.targetType === 1) {	
			console.log('ir.target = ', $scope.ir.target);
			if(1 == $scope.ir.target  )
				$scope.device.targetPort  = $scope.ir.port ;
			else
				$scope.device.targetPort  = 0;
		}
		console.log($scope.device.targetPort );

		if ($scope.isEntDevice) {   // entertainment device 인 경우

			$state.go('menu.programming.add-device.favchannels-option');

		} else {  // entertainment device 가 아닌 경우
			var d = angular.copy($scope.device);
			d.favEnable = 0;
			d.favDelay = 400;
			d.favEnter = 0;
			d.type = d.type.name;
			d.brand = d.brand.name;
			d.dbType = parseInt(d.model.type, 10);
			d.modelId = parseInt(d.model.id, 10);
			d.model = d.model.name;
			var jsonData = JSON.stringify(d);

			// device 생성
			return Devices.createOne($scope.room.id, jsonData)
				.then(function(data) {
					console.log(data);
					var id = Systems.getCurrentSystem().id;
					return Systems.updateSystem(id);  
				})
				.then(function (data) {
					$state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
					toastr.success('Successfully added ' + d.name + '.');
				})
				.catch(toastr.error);
		}
	};
});

/**
 * @ngdoc controller
 * @name FavChannelsOptionController
 * @description
 *  favorite channels 설정
 */
app.controller('FavChannelsOptionController', function ($scope, $state, $modal, toastr, Systems, Devices) {

	$scope.device.favEnable = $scope.device.favEnable || 1;
	$scope.device.favDelay = $scope.device.favDelay || 400;
	$scope.device.favEnter = $scope.device.favEnter || 1;

	$scope.finish = function () {

		var d = angular.copy($scope.device);
		d.type = d.type.name;
		d.brand = d.brand.name;
		d.dbType = parseInt(d.model.type, 10);
		d.modelId = parseInt(d.model.id, 10);
		d.model = d.model.name;

		var jsonData = JSON.stringify(d);
		console.log(jsonData);

		// device 생성
		return Devices.createOne($scope.room.id, jsonData)
			.then(function(data) {
				console.log(data);
				var id = Systems.getCurrentSystem().id;
				return Systems.updateSystem(id);  
			})
			.then(function (data) {
				$state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
				toastr.success('Successfully added ' + d.name + '.');
			})
			.catch(toastr.error);
	};
});

'use strict';
/**
 * @ngdoc controller
 * @name AddMacroRoomController
 * @description
 *  room 선택 화면
 */
app.controller('AddMacroRoomController', function ($scope, $state, toastr, Systems) {
	$scope.system = Systems.getCurrentSystem();


	$scope.doNext = function() {
		// room 정보 얻어와서 저장
		return Systems.updateRoomDevices($scope.addMacro.room.id)
		.then(function(data) {
			var roomDevices = Systems.getRoomDevices();
			$scope.addMacro.room.devices = roomDevices.devices;

			// dev_type이 twoway(1)인 device를 모두 제거하는 과정에서 $scope.addMacro.room.devices 에서 SNP-2 가 제거되는데 SNP-2 가 있는 목록이 "Add jump to" 에서 필요해서 copy 를 만듬
			$scope.addMacro.room.devicesAndSNP2 = angular.copy(roomDevices.devices);

			// twoway_devices 중 TRF-ZW 추가한 device 목록 생성
			$scope.addMacro.room.allDevices = angular.copy($scope.addMacro.room.devices);

			_.each($scope.system.rooms, function(room) {
				var trfzw = _.find(room.twoway_devices, {model: 'TRF-ZW1'});
				if (trfzw) {
					if (!trfzw.data) {
						trfzw.data = [];
					}
					$scope.addMacro.room.allDevices.push(trfzw);

					return false;
				}
			});

			$state.go('menu.advanced.add-macros.macro-type');
		})
		.catch(toastr.error);
	};
});

/**
 * @ngdoc controller
 * @name MacroTypeController
 * @description
 *  macro type 선택 화면
 */
app.controller('MacroTypeController', function ($rootScope, $scope, $state, toastr, Systems) {
  // Advanced Menu 의 Automate activities on the Entertainment Menu 메뉴를 클릭해서 들어온 경우
  // Programming Menu 의 Setup a simple activity 메뉴에서 넘어온 경우.
  //   => currentRoom 을 선택된 room 으로 설정함
  if (!$scope.addMacro.room.id) {
    var currentRoomId,
      timer;

    // currentRoom 이 설정되었는지 0.1초에 한번씩 확인
    timer = setInterval(function() {
      currentRoomId = Systems.getCurrentRoom();

      if (currentRoomId) {
        clearInterval(timer);

        $scope.addMacro.room = _.findWhere($scope.system.rooms, {
          id: currentRoomId
        });
        console.log('room', $scope.addMacro.room);

        // 아래의 코드는 AddMacroRoomController 의 doNext 에서 하는 동작임
        Systems.updateRoomDevices($scope.addMacro.room.id)
          .then(function(data) {
            var roomDevices = Systems.getRoomDevices();
            $scope.addMacro.room.devices = roomDevices.devices;

            // dev_type이 twoway(1)인 device를 모두 제거하는 과정에서 $scope.addMacro.room.devices 에서 SNP-2 가 제거되는데 SNP-2 가 있는 목록이 "Add jump to" 에서 필요해서 copy 를 만듬
            $scope.addMacro.room.devicesAndSNP2 = angular.copy(roomDevices.devices);

            // twoway_devices 중 TRF-ZW 추가한 device 목록 생성
            $scope.addMacro.room.allDevices = angular.copy($scope.addMacro.room.devices);

            _.each($scope.system.rooms, function(room) {
              var trfzw = _.find(room.twoway_devices, {model: 'TRF-ZW1'});
              if (trfzw) {
                if (!trfzw.data) {
                  trfzw.data = [];
                }
                $scope.addMacro.room.allDevices.push(trfzw);

                return false;
              }
            });

            $state.go('menu.advanced.add-macros.macro-type');
          })
          .catch(toastr.error);
      }
    }, 100);
  }

	var steps = $scope.addMacro.steps;
	while(steps.length > 0) {
		steps.pop();
	}
	$scope.addMacro.currentDevice = {};
	$scope.addMacro.button = {};
	$scope.addMacro.doneScreen = {'index': 0,'device': {}, 'devices': []};
	$scope.addMacro.disablePopup = false;

	$scope.navigateTo = function(state) {

		var base = 'menu.advanced.add-macros';
		switch (state) {
			case 'Turn Off All':
				$scope.macroType.id = 0;
				// 해당 room 의 power macro 데이터 얻어와서 저장
				Systems.updateCurrentMacroForPower($scope.addMacro.room.id).then( function(data) {
					console.log(data);
					$state.go(base + '.finish');
				}).catch(toastr.error);

				break;
			case 'Device Activity':
				$scope.macroType.id =  1;
				$state.go(base + '.choose-device');
				break;
			case 'Custom Button':
				$scope.macroType.id = 2;
				$state.go(base + '.button-name');
				break;
			case 'Scheduled Event':
				$scope.macroType.id = 3;
				$state.go(base + '.button-name');
				break;
			default:
				//do nothing
		}
	};

});

/**
 * @ngdoc controller
 * @name ButtonNameController
 * @description
 *  entertainment page button 생성할 button name 입력 화면
 */
app.controller('ButtonNameController', function ($scope, $state) {
	$scope.doNext = function() {
		$state.go('menu.advanced.add-macros.finish');
	};
});

/**
 * @ngdoc controller
 * @name ChooseMacroDeviceController
 * @description
 *  entertainment page device 생성할 device 선택 화면
 */
app.controller('ChooseMacroDeviceController', function ($scope, $state) {
	$scope.doNext = function() {
		$state.go('menu.advanced.add-macros.finish');
	};
});

/**
 * @ngdoc controller
 * @name FinishMacroController
 * @description
 *  macro device, commands 입력
 */
app.controller('FinishMacroController', function ($scope, $timeout, $state, $modal, toastr, Rooms, Devices, Systems) {
	var scheEventData = Rooms.getScheEventData();

	function isJsonString(str) {
		try {
			JSON.parse(str);
		} catch (e) {
			return false;
		}
		return true;
	}

	$scope.isJsonString = isJsonString;

	function cleanUp(type, roomId, arr) {
		console.log('cleanUp-arr=', arr);
		var filteredSteps = [];
		var steps =  isJsonString(arr) ? JSON.parse(arr):arr ;
		_.forEach(steps, function (step) {
			var device;
			var variable;

			if (type === 'macro') {
				if (step.type === 1) {
					device = Systems.getDevice(roomId, step.device_id);
					if (device) {
						step.name = device.name + ': ' + _.find(device.funcs, {'id': step.func}).name;
						filteredSteps.push(step);
					}
				} else if (step.type === 2) {
					step.name = 'Delay ' + step.value/1000 + ' seconds';
					filteredSteps.push(step);
				} else if (step.type === 3 && step.to.type === 1) {
					device = Systems.getDevice(roomId, step.to.value);
					if (device) {
						step.name = 'Jump to ' + device.name;
						filteredSteps.push(step);
					}
				} else if (step.type === 4) {
					variable = _.find($scope.system.variables, {'id': step.cond.id});
					if (variable) {
						if(variable.type == 0){
							name = 'If: ' + variable.name + ', ' + (step.cond.value == 1 ? 'True':'False');
						} else{
							name = 'If: ' + variable.name + ' ' +  step.cond.operate + ' ' + step.cond.value;
						} 

						step.name = name;

						step.steps = [{name:'True', steps:[]}, {name:'False', steps:[]}];

						filteredSteps.push(step);

						if(step.true){
							step.steps[0].steps = cleanUp('macro', roomId, step.true);
						}

						if(step.false){
							step.steps[1].steps = cleanUp('macro', roomId, step.false);
						}
					}
				}
				else if (step.type === 5) {
					variable = _.find($scope.system.variables, {'id': step.id});
					if (variable) {
						var dispValue = step.value;
						if(variable.type == 0){
							if(step.value == 0){
								dispValue = 'false' ;
							}
							else if(step.value == 1){
								dispValue = 'true' ;
							}
							else if(step.value == 2){
								dispValue = 'invert' ;
							}
						}

						step.name = 'VAR ' + variable.name + '= ' + dispValue;
						filteredSteps.push(step);
					}
				} else if (step.type === 16) {
					_.each($scope.system.rooms, function(room) {
						device = _.find(room.twoway_devices, {model: 'TRF-ZW1'});

						if (device) {
							var scene = _.find(device.data, {id: step.id});

							if (scene) {
								step.name = 'S : ' + scene.name + ' (' + scene.room + ')';
								filteredSteps.push(step);
							}

							return false;
						}
					});
				}
			} else {
				device = Systems.getDevice(roomId, step.device_id);
				if (device) {
					step.name = device.name;
					step.funcs = device.funcs;
					filteredSteps.push(step);
				}

			}
		});
		return filteredSteps;
	}

	// scheduled event 수정하러 들어온 경우
	if (scheEventData) {
		$scope.addMacro.room = scheEventData.room;
		$scope.addMacro.steps = cleanUp('macro', $scope.addMacro.room.id, scheEventData.event.macro);
		$scope.addMacro.button.name = scheEventData.event.display_text;
		$scope.addMacro.disablePopup = false;
		$scope.addMacro.doneScreen.index = 0;
		$scope.addMacro.doneScreen.devices = [];

		$scope.macroType.id = 3;

		// room 정보 얻어와서 저장
		Systems.updateRoomDevices($scope.addMacro.room.id)
			.then(function(data) {
				var roomDevices = Systems.getRoomDevices();
				$scope.addMacro.room.devices = roomDevices.devices;

				// dev_type이 twoway(1)인 device를 모두 제거하는 과정에서 $scope.addMacro.room.devices 에서 SNP-2 가 제거되는데 SNP-2 가 있는 목록이 "Add jump to" 에서 필요해서 copy 를 만듬
				$scope.addMacro.room.devicesAndSNP2 = angular.copy(roomDevices.devices);

				///dev_type이 twoway(1)인 device를 모두 제거.
				var item = null;
				while(item = _.where($scope.addMacro.room.devices, {'dev_type': 1})[0]) {
					var idx = $scope.addMacro.room.devices.indexOf(item);
					$scope.addMacro.room.devices.splice(idx, 1);
				}

				// twoway_devices 중 TRF-ZW 추가한 device 목록 생성
				$scope.addMacro.room.allDevices = angular.copy($scope.addMacro.room.devices);

				var system = Systems.getCurrentSystem();
				_.each(system.rooms, function(room) {
					var trfzw = _.find(room.twoway_devices, {model: 'TRF-ZW1'});
					if (trfzw) {
						if (!trfzw.data) {
							trfzw.data = [];
						}
						$scope.addMacro.room.allDevices.push(trfzw);

						return false;
					}
				});
			})
			.catch(toastr.error);
	}


	$scope.remove = function(scope) {
		scope.remove();
	};

	$scope.options = {
		accept: function(sourceNodeScope, destNodesScope, destIndex) {
			//console.log('sourceNodeScope=', sourceNodeScope);
			//console.log('destNodesScope=', destNodesScope);
			if (sourceNodeScope.$modelValue.type == null || destNodesScope.nodropEnabled || destNodesScope.outOfDepth(sourceNodeScope)) {
				return false;
			}

	        var subDepth = 0;
	        function countSubDepth(scope) {
				var i, childNodesScope,
					count = 0,
					nodes = scope.childNodes();

				//console.log('childNodes=', nodes);

				for (i = 0; i < nodes.length; i++) {
					childNodesScope = nodes[i].$childNodesScope;

					if (childNodesScope && childNodesScope.childNodesCount() > 0) {
						count = 1;
						countSubDepth(childNodesScope);
					}
				}
				subDepth += count;				
			}

			var maxSubDepth = function (scope) {
				subDepth = 0;
				if (scope.hasChild()) {
					countSubDepth(scope.$childNodesScope);
					subDepth++;
				}
				return subDepth;
			};

			/*
			console.log('sourceNodeScope.childNodes()=', sourceNodeScope.childNodes());
			console.log('sourceNodeScope.childNodesCount()=', sourceNodeScope.childNodesCount());
			console.log('maxSubDepth(sourceNodeScope)=', maxSubDepth(sourceNodeScope));
			console.log('destNodesScope.depth()=', destNodesScope.depth());
			console.log('destNodesScope.maxDepth=', destNodesScope.maxDepth);
			console.log('destNodesScope.$treeScope.maxDepth=', destNodesScope.$treeScope.maxDepth);
			*/			

			//angular-ui-tree module의 maxSubDepth function에서 sub depth count를 child node 존재 유무를 기준으로 함.
			//그래서 2depth인 tree인 경우 depth count를 0으로 return하여 outOfDepth function을 호출해도 제대로된 결과를 받지 못하고,
			// (max-depth -1) depth인 tree에 2depth의 tree를 drag/drop하면 삽입이 됨.
			//그래서, 별도의 maxSubDepth function을 구현함.
			var sumDepth =  (maxSubDepth(sourceNodeScope)+1) + destNodesScope.depth();
			var maxDepth = destNodesScope.maxDepth || destNodesScope.$treeScope.maxDepth;

			if(sumDepth  > maxDepth){
				return false;
			}

			return true;
		},
	};

	var getRootNodesScope = function() {
		return angular.element(document.getElementById("tree-root")).scope();
	};

	$scope.collapseAll = function() {
		var scope = getRootNodesScope();
		scope.collapseAll();
	};

	$scope.expandAll = function() {
		var scope = getRootNodesScope();
		scope.expandAll();
	};


	$scope.addStep = function (device, func, twowayDevice) {
		if (twowayDevice) {
			return {'name': 'S : ' + func.name + ' (' + func.room + ')', 'type': 16, 'sub_type': 'scene', 'id': func.id, 'cmd': 1 };		// 1 : Activate, 2 : Deactivate
		} else {
			return {'name': device.name + ': ' + func.name, 'type': 1, 'device_id': device.id, 'func': func.id };
		}
	};

	$scope.deleteAll = function() {
		var arr = $scope.addMacro.steps;
		while(arr.length > 0) {
			arr.pop();                     
		}
	};

	$scope.goBack = function() {
		if ($scope.macroType.id === 1) {
			$state.go('menu.advanced.add-macros.choose-device');
		} else if ($scope.macroType.id === 2) {
			$state.go('menu.advanced.add-macros.button-name');
		} else {
			$state.go('menu.advanced.add-macros.macro-type');
		}
	};

	$scope.doNext = function() {
		if ($scope.macroType.id === 3) {
			$state.go('menu.advanced.add-macros.macro-schedule');
		} else {
			$state.go('menu.advanced.add-macros.macro-done');
		}
	};

	$scope.refreshScenes = function(device) {
		Devices.updateTwowayDevice($scope.addMacro.room.id, device.id)
			.then(function(data) {
				console.log(data);

				var item = _.where($scope.addMacro.room.allDevices, {'id': device.id})[0];
				item.data = data;
			}, function() {
				var modal = $modal({
					scope: $scope,
					title: "Couldn't refresh the list",
					container: '.editor-container',
					template: 'views/modal-tpls/refresh-the-list.html',
					show: false
				});

				modal.$promise.then(modal.show);
			})
			.catch(toastr.error);
	};

});

/**
 * @ngdoc controller
 * @name MacroDoneController
 * @description
 *  macro 설정 완료 화면
 */
app.controller('MacroDoneController', function ($scope, $state, toastr, Systems) {
	$scope.addMacro.doneScreen.index = 0;

	$scope.goBack = function() {
		$state.go('menu.advanced.add-macros.finish');
	};

	function cleanUp(steps) {
		var filteredSteps = steps;
		_.forEach(filteredSteps, function (step) {
			delete step.name; 
			if(step.type == 4){
				console.log('cleanUp-step=', step);
				if(0 < step.steps[0].steps.length) {						
					step.steps[0].steps = cleanUp(step.steps[0].steps);
					step.true = angular.copy(step.steps[0].steps);					
				}
				if(0 < step.steps[1].steps.length) {
					step.steps[1].steps = cleanUp(step.steps[1].steps);
					step.false = angular.copy(step.steps[1].steps);					
				}
				delete step.steps;
			}
		});
		return filteredSteps;
	}

	$scope.doNext = function() {
		if ($scope.addMacro.disablePopup) {
			var steps =  angular.copy($scope.addMacro.steps);
			steps = cleanUp(steps);
			console.log('steps=', steps);

			//var autoWait = $scope.addMacro.autoWait ? 1:0;
			var jsonData = JSON.stringify( { auto_wait: 1 , edit_type: 1, popup: 0, activity: [], macro: steps } );
			console.log('jsonData=', jsonData);

			var handleSuccess = function(response) {
				if(response.data.result === true) {
					$state.go('menu.advanced.add-macros.next-action');
				} else {
					toastr.error('Your edit/create action failed.  Please try again.');
				}
			};

			var handleError = function(error){
				toastr.error("Please try again");
			};

			if ($scope.macroType.id === 0) {
				// 해당 room 의 power macro 데이터 저장
				Systems.storePowerMacro($scope.addMacro.room.id, jsonData).then(handleSuccess, handleError);
			} else if ($scope.macroType.id === 1) {
				// 해당 device ID 와 연계된 button 의 데이터 저장
				Systems.storeDeviceButtonMacro($scope.addMacro.room.id, $scope.addMacro.currentDevice.id, jsonData).then(handleSuccess, handleError);
			} else if ($scope.macroType.id === 2) {
				jsonData = { "text": $scope.addMacro.button.name, "auto_wait": 1 , "edit_type": 1, "popup": 0, "activity": [], "macro": steps } ;
				// button 생성
				Systems.createCustomButtonMacro($scope.addMacro.room.id, $scope.addMacro.room.main_device_id, jsonData).then(handleSuccess, handleError);
			}
		} else {
			$state.go('menu.advanced.add-macros.macro-commands');
		}
	};

});

/**
 * @ngdoc controller
 * @name MacroScheduleController
 * @description
 *  macro schedule 설정 화면
 */
app.controller('MacroScheduleController', function ($scope, $state, toastr, Rooms, Systems) {
	var scheEventData = Rooms.getScheEventData();

	// scheduled event 수정하러 들어온 경우
	if (scheEventData) {
		$scope.scheduledEvent = {
			option: scheEventData.event.option,
			day_week: scheEventData.event.day_week,
			time: scheEventData.event.time
		};
	}

	var i,
		temp,
		temp2;

	if (!$scope.scheduledEvent.option) {
		$scope.scheduledEvent.option = 0;
	}
	if (!$scope.scheduledEvent.day_week) {
		$scope.scheduledEvent.day_week = 0;
	}
	if (!$scope.scheduledEvent.time) {
		$scope.scheduledEvent.hour = '01';
		$scope.scheduledEvent.minute = '00';
		$scope.scheduledEvent.ampm = 'AM';
	} else {
		temp = $scope.scheduledEvent.time.split(':');

		if (+temp[0] > 12) {
			$scope.scheduledEvent.hour = '' + (+temp[0] - 12);
			if (+$scope.scheduledEvent.hour < 10) {
				$scope.scheduledEvent.hour = '0' + $scope.scheduledEvent.hour;
			}

			$scope.scheduledEvent.ampm = 'PM';
		} else if (+temp[0] == 12) {
			$scope.scheduledEvent.hour = '' + temp[0];
			$scope.scheduledEvent.ampm = 'PM';
		} else if (+temp[0] == 0) {
			$scope.scheduledEvent.hour = '12';
			$scope.scheduledEvent.ampm = 'AM';
		} else {
			$scope.scheduledEvent.hour = '' + temp[0];
			$scope.scheduledEvent.ampm = 'AM';
		}
		$scope.scheduledEvent.minute = '' + temp[1];
	}

	$scope.scheduledEvent.hours = [];
	$scope.scheduledEvent.minutes = [];

	for (i = 1; i <= 12; i++) {
		if (i < 10) {
			$scope.scheduledEvent.hours.push('0' + i)
		} else {
			$scope.scheduledEvent.hours.push('' + i);
		}
	}

	for (i = 0; i < 60; i++) {
		if (i < 10) {
			$scope.scheduledEvent.minutes.push('0' + i)
		} else {
			$scope.scheduledEvent.minutes.push('' + i);
		}
	}

	$scope.scheduledEvent.day = {
		'sun': 0,
		'mon': 0,
		'tue': 0,
		'wed': 0,
		'thu': 0,
		'fri': 0,
		'sat': 0
	};

	if ($scope.scheduledEvent.day_week !== 0) {
		temp2 = +$scope.scheduledEvent.day_week;

		if (temp2 === 127) {
			$scope.scheduledEvent.everyday = true;
		} else {
			if (temp2 >= 64) {
				$scope.scheduledEvent.day.sat = '64';
				temp2 -= 64;
			}
			if (temp2 >= 32) {
				$scope.scheduledEvent.day.fri = '32';
				temp2 -= 32;
			}
			if (temp2 >= 16) {
				$scope.scheduledEvent.day.thu = '16';
				temp2 -= 16;
			}
			if (temp2 >= 8) {
				$scope.scheduledEvent.day.wed = '8';
				temp2 -= 8;
			}
			if (temp2 >= 4) {
				$scope.scheduledEvent.day.tue = '4';
				temp2 -= 4;
			}
			if (temp2 >= 2) {
				$scope.scheduledEvent.day.mon = '2';
				temp2 -= 2;
			}
			if (temp2 >= 1) {
				$scope.scheduledEvent.day.sun = '1';
				temp2 -= 1;
			}
		}
	}

	function generateTime() {
		if ($scope.scheduledEvent.ampm == 'PM' && $scope.scheduledEvent.hour == '12') {
			return '12:' + $scope.scheduledEvent.minute + ':00';
		} else if ($scope.scheduledEvent.ampm == 'AM' && $scope.scheduledEvent.hour == '12') {
			return '00:' + $scope.scheduledEvent.minute + ':00';
		} else if ($scope.scheduledEvent.ampm == 'PM') {
			return (+$scope.scheduledEvent.hour + 12) + ':' + $scope.scheduledEvent.minute + ':00';
		} else {
			return $scope.scheduledEvent.hour + ':' + $scope.scheduledEvent.minute + ':00';
		}
	}

	$scope.goBack = function() {
		$state.go('menu.advanced.add-macros.finish');
	};

	function cleanUp(steps) {
		var filteredSteps = steps;
		_.forEach(filteredSteps, function (step) {
			delete step.name; 
			if(step.type == 4){
				console.log('cleanUp-step=', step);
				if(0 < step.steps[0].steps.length) {						
					step.steps[0].steps = cleanUp(step.steps[0].steps);
					step.true = angular.copy(step.steps[0].steps);					
				}
				if(0 < step.steps[1].steps.length) {
					step.steps[1].steps = cleanUp(step.steps[1].steps);
					step.false = angular.copy(step.steps[1].steps);					
				}
				delete step.steps;
			}
		});
		return filteredSteps;
	}

	$scope.doNext = function() {
		$scope.scheduledEvent.day_week = 0;

		var days = _.values($scope.scheduledEvent.day);

		if ($scope.scheduledEvent.everyday) {
			$scope.scheduledEvent.day_week = 127;
		} else {
			_.each(days, function(day) {
				$scope.scheduledEvent.day_week += +day;
			});
		}

		$scope.scheduledEvent.time = generateTime();

		var steps =  angular.copy($scope.addMacro.steps);
		steps = cleanUp(steps);
		console.log('steps=', steps);

		var	systemId = Systems.getCurrentSystem().id,
			data = {
				display_text: $scope.addMacro.button.name,
				image_name: '' ,
				macro: steps,
				default_state: 1,
				option: $scope.scheduledEvent.option,
				day_week: $scope.scheduledEvent.day_week,
				time: $scope.scheduledEvent.time
			},
			jsonData;

		if (scheEventData) {
			data.id = scheEventData.event.id;
		}

		jsonData = JSON.stringify( data )
		console.log('jsonData=', jsonData);

		// scheduled event 수정
		if (scheEventData) {
			Rooms.setScheduledEventMacro(systemId, $scope.addMacro.room.id, jsonData).then(function(response) {
				if(response.data.result === true) {
					Systems.updateSystem(systemId).then(function () {
						Rooms.setScheEventData(null);
						$state.go('menu.advanced.add-macros.next-action');
					});
				} else {
					toastr.error('Your edit/create action failed.  Please try again.');
				}
			}, function(error){
				toastr.error("Please try again");
			});
		}
		// scheduled event 생성
		else {
			Rooms.createScheduledEventMacro(systemId, $scope.addMacro.room.id, jsonData).then(function(response) {
				if(response.data.result === true) {
					Systems.updateSystem(systemId).then(function () {
						Rooms.setScheEventData(null);
						$state.go('menu.advanced.add-macros.next-action');
					});
				} else {
					toastr.error('Your edit/create action failed.  Please try again.');
				}
			}, function(error){
				toastr.error("Please try again");
			});
		}
	};

});


app.controller('MacroCommandsController', function ($scope, $state, toastr, Systems) {

	$scope.goBack = function() {
		if ($scope.addMacro.doneScreen.index === 0) {
			$state.go('menu.advanced.add-macros.macro-done' );
		} else {
			$scope.addMacro.doneScreen.index--;
		}
	};

	function cleanUp(steps) {
		var filteredSteps = steps;
		_.forEach(filteredSteps, function (step) {
			delete step.name; 
			if(step.type == 4){
				console.log('cleanUp-step=', step);
				if(0 < step.steps[0].steps.length) {						
					step.steps[0].steps = cleanUp(step.steps[0].steps);
					step.true = angular.copy(step.steps[0].steps);					
				}
				if(0 < step.steps[1].steps.length) {
					step.steps[1].steps = cleanUp(step.steps[1].steps);
					step.false = angular.copy(step.steps[1].steps);					
				}
				delete step.steps;
			}
		});
		return filteredSteps;
	}

	$scope.doNext = function() {
		var len = $scope.addMacro.doneScreen.devices.length;
		if ($scope.addMacro.doneScreen.index + 1 === len) {

			//var autoWait = $scope.addMacro.autoWait ? 1:0;
			var steps =  angular.copy($scope.addMacro.steps);
			steps = cleanUp(steps);
			console.log('steps=', steps);

			var activityData = angular.copy($scope.addMacro.doneScreen.devices);

			_.forEach(steps, function(step) { delete step.name; });
			_.forEach(activityData, function(activity) {
				activity.func = activity.func.id;
				delete activity.name;
				delete activity.repeat_min;
				delete activity.repeat_macro;
				delete activity.target_type;
				delete activity.target_addr;
				delete activity.target_port;
				delete activity.funcs;
			});

			var jsonData = JSON.stringify( { auto_wait: 1 , edit_type: 1, popup: 1, activity: activityData, macro: steps } );
			console.log(jsonData);

			var handleSuccess = function(response) {
				if(response.data.result === true) {
					$state.go('menu.advanced.add-macros.next-action');
				} else {
					toastr.error('Your edit/create action failed.  Please try again.');
				}
			};

			var handleError = function(error){
				toastr.error("Please try again");
			};

			if ($scope.macroType.id === 0) {
				// 해당 room 의 power macro 데이터 저장
				Systems.storePowerMacro($scope.addMacro.room.id, jsonData).then(handleSuccess, handleError);
			} else if ($scope.macroType.id === 1) {
				// 해당 device ID 와 연계된 button 의 데이터 저장
				Systems.storeDeviceButtonMacro($scope.addMacro.room.id, $scope.addMacro.currentDevice.id, jsonData).then(handleSuccess, handleError);
			} else if ($scope.macroType.id === 2) {
				jsonData = JSON.stringify( { text: $scope.addMacro.button.name, auto_wait: 1 , edit_type: 1, popup: 1, activity: activityData, macro: steps } );
				// button 생성
				Systems.createCustomButtonMacro($scope.addMacro.room.id, $scope.addMacro.room.main_device_id, jsonData).then(handleSuccess, handleError);
			}
		} else {
			$scope.addMacro.doneScreen.index++;
		}

	};
});


'use strict';
/**
 * @ngdoc controller
 * @name SelectRemoteController
 * @description
 *  remote 목록을 표시하고 선택 후 remote 를 room 에 set 하는 화면
 */
app.controller('SelectRemoteController', function ($rootScope, $scope, $filter, $state, searchResults, toastr, Systems, Rooms) {
  $scope.searchKey = searchResults.searchKey;
  $scope.remotes = searchResults.searchedDevices;

  $scope.remoteType = 'CLIENTS';

  $scope.goBack = function () {
    $state.go('menu.programming.options');
  };

  $scope.doNext = function () {

    var currentSystem = Systems.getCurrentSystem(),
        remote = $scope.addRemote.selection,
        jsonData = JSON.stringify({ mac : remote.mac, name: remote.name + ' ' + remote.mac.slice(10,12) , type: remote.name, searchKey: $scope.searchKey });

    // remote 를 room 에 set(기존에 있으면 해당 것을 replace)
    var setRemote = function(roomId, json) {
      return Rooms.setRemote(roomId, json).then(function(data) { 
        toastr.success('Successfully added the remote with ID ' + $filter('remoteId')(remote.mac) +  ' to ' + $scope.addRemote.room.name + '.');
        return Systems.getCurrentSystem().id;
      });
    };

    var updateSystem = function(id) {
      return Systems.updateSystem(id).then(function (data) {
        console.log(data);
        return $state.transitionTo('menu.programming.options', {}, { reload: true, inherit: true, notify: true  });
      });
    };

    setRemote($scope.addRemote.room.id, jsonData)
      .then(updateSystem)
      .catch(function(error) {
        toastr.error(error, 'Error');
      });
  };

});


// app.controller('AvailableRoomsController', function ($scope, $filter, $state, toastr, Systems, Rooms) {

//   $scope.system = Systems.getCurrentSystem();

//   $scope.doNext = function () {

//     var remote = $scope.addRemote.selection,
//         jsonData = JSON.stringify({ mac : remote.mac, name: remote.name + ' ' + remote.mac.slice(10,12) , type: remote.name });

//     var setRemote = function(roomId, json) {
//       return Rooms.setRemote(roomId, json).then(function(data) { 
//         toastr.success('Successfully added the remote with ID ' + $filter('remoteId')(remote.mac) +  ' to ' + $scope.addRemote.room.name + '.');
//         return Systems.getCurrentSystem().id;
//       });
//     };

//     var updateSystem = function(id) {
//       return Systems.updateSystem(id).then(function (data) {
//         console.log(data);
//         return $state.transitionTo('menu.advanced.options', {}, { reload: true, inherit: true, notify: true  });
//       });
//     }

//     setRemote($scope.addRemote.room.id, jsonData)
//       .then(updateSystem)
//       .catch(function(error) {
//         toastr.error(error, 'Error');
//       });
//   };

// });

'use strict';
/**
 * @ngdoc controller
 * @name SelectRoomController
 * @description
 *  base station 목록 표시 후 base station 선택과 함께 room 생성 화면
 */
app.controller('SelectRoomController', function ($rootScope, $scope, $state, toastr, searchResults, Systems, Rooms ) {
  $scope.searchKey = searchResults.searchKey;
  $scope.addRoom = {'name': null, 'baseStation': null};
  $scope.baseStations = searchResults.searchedDevices;

  $scope.bsType = 'BASESTATIONS';

  $scope.finish = function() {
    var currentSystem = Systems.getCurrentSystem();
    var baseStation = $scope.addRoom.baseStation;
    var jsonData = JSON.stringify({ name: $scope.addRoom.name, 
                                    bstationName: baseStation.name + ' ' + baseStation.mac.slice(10,12), 
                                    bstationMac: baseStation.mac, 
                                    type: baseStation.name });

    // room 생성
    var createRoom = function(json) {
      return Rooms.create(json).then(function(data) { 
        toastr.success('Successfully added ' + $scope.addRoom.name + '.');
        return Systems.getCurrentSystem().id;
      });
    };

    var updateSystem = function(id) {
      return Systems.updateSystem(id).then(function (data) {
        console.log(data);
        //return $state.transitionTo('menu.advanced.add-room.link-remote', {}, { reload: true, inherit: true, notify: true  });
        $state.go('menu.advanced.options');
      });
    };

    createRoom(jsonData)
      .then(updateSystem)
      .catch(toastr.error);

  };
});

app.controller('LinkRemoteController', function ($scope, $state, Systems ) {
  
  $scope.doNext = function() {
    $state.go('menu.advanced.add-remote.select');
  };
});

'use strict';
/**
 * @ngdoc controller
 * @name DbEditController
 * @description
 *  db edit 화면
 */
app.controller('DbEditController', function($scope, $state, $sanitize, $modal, $timeout, toastr, categories, Systems) {
  $scope.tabs = [
    { heading: $sanitize('<i class="fa fa-laptop tab-icon"></i><span class="tab-title">Programming Menu</span>'), route:'menu.programming.options', active:true },
    { heading: $sanitize('<i class="fa fa-wrench tab-icon"></i><span class="tab-title">Advanced Menu</span>'), route:'menu.advanced.options', active:false },
    { heading: $sanitize('<i class="fa fa-globe tab-icon"></i><span class="tab-title">Home Overview</span>'), route:'menu.system-overview', active:false },
    { heading: $sanitize('<i class="fa fa-download tab-icon"></i><span class="tab-title">Download</span>'), route:'menu.download', active:false }
  ];

  $scope.go = function(route){
    // programming 메뉴로는 이동할 필요 없음, 로딩시 programming 메뉴가 active tab 이라서 자동으로 이동하는 것을 막기 위해 예외 처리.
    if (route !== 'menu.programming.options') {
      $state.go(route);
    }
  };

  $scope.dbEdit = {};
  $scope.dbEdit.categories = categories;
  $scope.dbEdit.versions = [
    {
      name: 'Alpha',
      value: 3
    },
    {
      name: 'Beta + Alpha',
      value: 2
    },
    {
      name: 'Public + Beta + Alpha',
      value: 0
    }
  ];

  $scope.dbEdit.category = null;
  $scope.dbEdit.brand = null;
  $scope.dbEdit.model = null;

  $scope.dbEdit.newCategory = {
    id: null,
    name: null
  };
  $scope.dbEdit.newBrand = {
    id: null,
    name: null
  };
  $scope.dbEdit.newModel = {
    id: null,
    name: null
  };

  $scope.selectCategory = function(category) {
    $scope.dbEdit.brand = null;
    $scope.dbEdit.model = null;

    Systems.getTwowayBrands(category.id).then(function(response) {
      $scope.dbEdit.brands = response;
    }, function(error) {
      toastr.error(error);
    });
  };

  $scope.selectBrand = function(brand) {
    $scope.dbEdit.model = null;

    Systems.getTwowayModels(brand.id).then(function(response) {
      $scope.dbEdit.models = response;
    }, function(error) {
      toastr.error(error);
    });
  };

  $scope.selectModel = function(model) {
    //console.log(model);
  };

  $scope.addCategory = function() {
    var newCategory = angular.copy($scope.dbEdit.newCategory);
    if (!$scope.dbEdit.categories || !$scope.dbEdit.categories.length) {
      $scope.dbEdit.categories = [newCategory];
    } else {
      $scope.dbEdit.categories.push(newCategory);
    }
    $scope.dbEdit.category = newCategory;

    $scope.dbEdit.newCategory = {
      id: null,
      name: null
    };
  };

  $scope.addBrand = function() {
    var newBrand = angular.copy($scope.dbEdit.newBrand);
    if (!$scope.dbEdit.brands || !$scope.dbEdit.brands.length) {
      $scope.dbEdit.brands = [newBrand];
    } else {
      $scope.dbEdit.brands.push(newBrand);
    }
    $scope.dbEdit.brand = newBrand;

    $scope.dbEdit.newBrand = {
      id: null,
      name: null
    };
  };

  $scope.addModel = function() {
    var newModel = angular.copy($scope.dbEdit.newModel);
    if (!$scope.dbEdit.models || !$scope.dbEdit.models.length) {
      $scope.dbEdit.models = [newModel];
    } else {
      $scope.dbEdit.models.push(newModel);
    }
    $scope.dbEdit.model = newModel;

    $scope.dbEdit.newModel = {
      id: null,
      name: null
    };
  };

  $scope.getDbTwowayModel = function() {
    var data = {
        categoryId: $scope.dbEdit.category.id,
        category: $scope.dbEdit.category.name,
        brandId: $scope.dbEdit.brand.id,
        brand: $scope.dbEdit.brand.name,
        modelId: $scope.dbEdit.model.id,
        model: $scope.dbEdit.model.name
      },
      jsonData = JSON.stringify(data);

    Systems.getDbTwowayModel(jsonData).then(function(response) {
      $scope.dbEdit.version = _.find($scope.dbEdit.versions, function(obj) {
        return obj.value === response.version;
      });
      $scope.dbEdit.major = response.major;

      var obj = angular.copy(response);
      delete(obj.major);
      delete(obj.name);
      delete(obj.version);

      $scope.dbEdit.data = JSON.stringify(obj);

      toastr.success('Success: Get');
    }, function(error) {
      toastr.error(error);
    });
  };

  $scope.addDbTwowayModel = function() {
    try {
      var parsedData = JSON.parse($scope.dbEdit.data);
      if (!parsedData.variables) {
        parsedData.variables = "";
      }

      var data = {
          categoryId: $scope.dbEdit.category.id,
          category: $scope.dbEdit.category.name,
          brandId: $scope.dbEdit.brand.id,
          brand: $scope.dbEdit.brand.name,
          modelId: $scope.dbEdit.model.id,
          model: $scope.dbEdit.model.name,
          data: JSON.stringify(parsedData),
          version: $scope.dbEdit.version.value,
          major: $scope.dbEdit.major || 0
        },
        jsonData = JSON.stringify(data);

      Systems.addDbTwowayModel(jsonData).then(function(response) {
        toastr.success('Success: Add New');
      }, function(error) {
        toastr.error(error);
      });
    } catch(e) {
      toastr.error('Module data is invalid. Please check JSON format.');
    }
  };

  $scope.setDbTwowayModel = function() {
    try {
      var parsedData = JSON.parse($scope.dbEdit.data);
      if (!parsedData.variables) {
        parsedData.variables = "";
      }

      var data = {
          categoryId: $scope.dbEdit.category.id,
          category: $scope.dbEdit.category.name,
          brandId: $scope.dbEdit.brand.id,
          brand: $scope.dbEdit.brand.name,
          modelId: $scope.dbEdit.model.id,
          model: $scope.dbEdit.model.name,
          data: JSON.stringify(parsedData),
          version: $scope.dbEdit.version.value,
          major: $scope.dbEdit.major || 0
        },
        jsonData = JSON.stringify(data);

      Systems.setDbTwowayModel(jsonData).then(function(response) {
        toastr.success('Success: Set');
      }, function(error) {
        toastr.error(error);
      });
    } catch(e) {
      toastr.error('Module data is invalid. Please check JSON format.');
    }
  };

  $scope.showModal = function(mode) {
    var templateUrl = 'views/modal-tpls/db-edit/' + mode + '.html';

    var modal = $modal({
      scope: $scope,
      template: templateUrl,
      container: 'body',
      show: false
    });
    modal.$promise.then(modal.show);
  };

  $scope.clearAll = function() {
    $scope.dbEdit.brands = [];
    $scope.dbEdit.models = [];

    $scope.dbEdit.category = null;
    $scope.dbEdit.brand = null;
    $scope.dbEdit.model = null;
    $scope.dbEdit.version = null;
    $scope.dbEdit.major = 0;
    $scope.dbEdit.data = null;

    $scope.dbEdit.newCategory = {
      id: null,
      name: null
    };
    $scope.dbEdit.newBrands = {
      id: null,
      name: null
    };
    $scope.dbEdit.newModels = {
      id: null,
      name: null
    };

    toastr.success('Success: Clear All');
  };
});

'use strict';


app.controller('AddToDealerController', function ($rootScope, $scope, $state, $modal, toastr, currentSystem, Dealer, Systems, User) {

  $scope.setDealer = function() {
    var systemId = currentSystem.id;

    var jsonData = JSON.stringify($scope.credentials);

    Systems.setDealer(systemId, jsonData)
      .then( function(data) {
        if(data.result) {
          $rootScope.dealerCompany = data.company;

          var modal = $modal({
            scope: $scope,
            title: '',
            placement: 'top',
            template: 'views/modal-tpls/dealer/dealer-system-added.html',
            backdrop: 'static',
            show: false
          });

          modal.$promise.then(modal.show);
        } else {
          toastr.error(data.error);
        }
      })
      .catch(toastr.error);

    // 일반 사용자에서 logout 하고 delaer 로 로그인 후 system 선택 후 home overview 화면으로 이동
    // system 선택 후 home overview 화면으로 이동하는 코드는 DealerJobsListController 의 $scope.selectSystem function 과 같음
    $scope.dealerLogin = function () {
      User.logout();

      Dealer.login(jsonData)
        .then(function (data) {
          if (data.result) {
            // dealer company 불러오기
            $rootScope.dealerCompany = Dealer.getDealerCompany();

            Dealer.getSystemToken(JSON.stringify({system_id: systemId})).then(function (data) {
              if (data.result) {
                // token 갱신
                var token = data.token;
                Dealer.setUser(systemId, token, false, false, true);   // dealer token 보존

                User.getUserInfo().then(function (data) {
                  // token 갱신
                  Dealer.setUser(systemId, token, data.username, data.email);

                  // system select
                  Systems.setCurrentRoom(null);

                  Systems.updateSystem(systemId).then(
                    function () {
                      $state.go('menu.system-overview');
                    },
                    function (error) {
                      toastr.error(error);
                    }
                  );
                }).catch(toastr.error);
              } else {
                toastr.error(data.error);
              }
            })
              .catch(toastr.error);
          } else {
            toastr.error(data.error);
          }
        })
        .catch(toastr.error);
    };
  };

  $scope.forgot = function() {
    var modal = $modal({
      scope: $scope,
      title: '',
      placement: 'top',
      template: 'views/modal-tpls/dealer/dealer-forgot-password.html',
      backdrop: 'static',
      show: false
    });

    modal.$promise.then(modal.show);
  };
});

app.controller('DealerJobsListController', function ($rootScope, $scope, $state, $modal, toastr, jobsList, Systems, Dealer, User) {
  $rootScope.virtualEditor = null;

  $scope.jobsList = jobsList;
  $scope.selectedJob = null;

  $scope.viewDetails = function(job) {
    $scope.selectedJob = null;

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

    Dealer.getJob(jsonData).then(function(data) {
      if(data.result) {
        $scope.selectedJob = data.job;
        console.log($scope.selectedJob);

        var modal = $modal({
          scope: $scope,
          title: '',
          placement: 'top',
          template: 'views/modal-tpls/dealer/dealer-customer-details.html',
          show: false
        });

        modal.$promise.then(modal.show);
      } else {
        toastr.error(data.error);
      }
    })
    .catch(toastr.error);
  };

  // system 을 선택할 경우, 해당 system 의 user 권한으로 작업을 수행하기 위해 그 user 의 token 으로 업데이트함
  $scope.selectSystem = function() {
    if (!$scope.selectedJob) {
      return;
    }

    var jsonData = JSON.stringify({system_id: $scope.selectedJob.id});

    Dealer.getSystemToken(jsonData).then(function(data) {
      if(data.result) {
        // token 갱신
        var token = data.token;
        Dealer.setUser($scope.selectedJob.id, token, false, false, true);   // dealer token 보존

        User.getUserInfo().then(function(data) {
          // token 갱신
          Dealer.setUser($scope.selectedJob.id, token, data.username, data.email);

          // system select
          Systems.setCurrentRoom(null);

          Systems.updateSystem($scope.selectedJob.id).then(
            function () {
              $state.go('menu.system-overview');
            },
            function (error) {
              toastr.error(error);
            }
          );
        }).catch(toastr.error);
      } else {
        toastr.error(data.error);
      }
    })
      .catch(toastr.error);
  };

});

app.controller('FileExplorerController', function ($scope, $state, $modal, toastr, Systems) {

  

});

app.controller('ExportTemplateChooseRoomController', function ($scope, $state, $modal, toastr, Systems) {

  $scope.doNext = function() {
    $state.go('file-explorer.export-template');
  };

});

app.controller('ExportTemplateController', function ($scope, $state, $modal, toastr, Systems, Dealer) {
  
  $scope.showHelpModal = function() {
    var modal = $modal({
      scope: $scope,
      title: '',
      placement: 'top',
      template: 'views/modal-tpls/dealer/export-template-help.html',
      show: false
    });

    modal.$promise.then(modal.show);
  };
  
  $scope.finish = function() {
    var jsonData = JSON.stringify({
      roomId: $scope.exportTemplate.room.id,
      name: $scope.exportTemplate.filename
    });

    Dealer.createFromExisting(jsonData).then(function(data) {
      if (data.result) {
        var modal = $modal({
          scope: $scope,
          title: '',
          content: 'This room template has been exported to your Dealer Account File Explorer.',
          placement: 'top',
          template: 'views/modal-tpls/dealer/file-explorer.html',
          backdrop: 'static',
          show: false
        });

        modal.$promise.then(modal.show);
      }
    })
      .catch(toastr.error);
  };

});

app.controller('ExportDeviceChooseRoomController', function ($scope, $state, $modal, toastr, Systems) {

  $scope.doNext = function() {
    $state.go('file-explorer.export-device-choose-device');
  };

});

app.controller('ExportDeviceChooseDeviceController', function ($scope, $state, $modal, toastr, Systems) {

  $scope.doNext = function() {
    $state.go('file-explorer.export-device');
  };

});

app.controller('ExportDeviceController', function ($rootScope, $scope, $state, $modal, toastr, Systems, Dealer) {

  $scope.finish = function() {
    var jsonData = JSON.stringify({
      roomId: $scope.exportDevice.room.id,
      deviceId: $scope.exportDevice.device.id,
      name: $scope.exportDevice.filename
    });

    if ($rootScope.virtualEditor) {
      Dealer.customDevCreateFromTemplate(jsonData).then(function (data) {
        if (data.result) {
          var modal = $modal({
            scope: $scope,
            title: '',
            content: 'This entertainment device file has been exported to your Dealer Account File Explorer.',
            placement: 'top',
            template: 'views/modal-tpls/dealer/file-explorer.html',
            backdrop: 'static',
            show: false
          });

          modal.$promise.then(modal.show);
        }
      })
        .catch(toastr.error);
    } else {
      Dealer.customDevCreate(jsonData).then(function (data) {
        if (data.result) {
          var modal = $modal({
            scope: $scope,
            title: '',
            content: 'This entertainment device file has been exported to your Dealer Account File Explorer.',
            placement: 'top',
            template: 'views/modal-tpls/dealer/file-explorer.html',
            backdrop: 'static',
            show: false
          });

          modal.$promise.then(modal.show);
        }
      })
        .catch(toastr.error);
    }
  };

});

app.controller('ImportTemplateController', function ($rootScope, $scope, $state, $modal, toastr, templates, Systems, Dealer) {

  $scope.importTemplate.templates = templates;

  $scope.copyFromTemplate = function () {
    var jsonData = JSON.stringify({roomId: $scope.importTemplate.template.id});

    Dealer.copyFromTemplate(Systems.getCurrentRoom(), jsonData).then(function (data) {
      if (data.result) {
        console.log(data);

        var modal = $modal({
          scope: $scope,
          title: '',
          placement: 'top',
          template: 'views/modal-tpls/dealer/import-template-finish-virtual-editor.html',
          backdrop: 'static',
          show: false
        });

        modal.$promise.then(modal.show);
      }
    })
      .catch(toastr.error);
  };

  $scope.finish = function () {
    if ($rootScope.virtualEditor) {
      $state.go('menu.programming.options');
    }
  };

  $scope.select = function(template) {
    $scope.importTemplate.template = template;

    if ($rootScope.virtualEditor) {
      var modal = $modal({
        scope: $scope,
        title: '',
        placement: 'top',
        template: 'views/modal-tpls/dealer/import-template-warning-virtual-editor.html',
        backdrop: 'static',
        show: false
      });

      modal.$promise.then(modal.show);
    } else {
      $state.go('file-explorer.import-template-choose-room');
    }
  };

  $scope.delete = function(template) {
    $scope.importTemplate.template = template;

    var modal = $modal({
      scope: $scope,
      title: '',
      placement: 'top',
      template: 'views/modal-tpls/dealer/delete-item.html',
      backdrop: 'static',
      show: false
    });

    modal.$promise.then(modal.show);
  };

  $scope.deleteItem = function() {
    var currentRoomDelete = false;
    // 현재 load 된 room 을 삭제한 경우
    if ($scope.importTemplate.template.id === Systems.getCurrentRoom()) {
      currentRoomDelete = true;
    }

    Dealer.deleteTemplate($scope.importTemplate.template.id).then(function(data) {
      if (data.result) {
        $scope.importTemplate.template = null;

        Dealer.getTemplates().then(
          function(response) {
            $scope.importTemplate.templates = response.templates;

            if (currentRoomDelete) {
              $state.go('dealer-jobs-list');
            }
          },
          function(error) {
            toastr.error(error);
          }
        );
      }
    })
      .catch(toastr.error);
  };

});

app.controller('ImportTemplateChooseRoomController', function ($rootScope, $scope, $state, $modal, toastr, Systems, Dealer) {

  $scope.importTemplateApplyToExisting = function() {
    var jsonData;

    if ($rootScope.virtualEditor) {
      jsonData = JSON.stringify({roomId: $scope.importTemplate.template.id});

      Dealer.copyFromTemplate(Systems.getCurrentRoom(), jsonData).then(function (data) {
        if (data.result) {
          console.log(data);

          var modal = $modal({
            scope: $scope,
            title: '',
            placement: 'top',
            template: 'views/modal-tpls/dealer/import-template-finish-virtual-editor.html',
            backdrop: 'static',
            show: false
          });

          modal.$promise.then(modal.show);
        }
      })
        .catch(toastr.error);
    } else {
      jsonData = JSON.stringify({roomId: $scope.importTemplate.room.id, name: $scope.importTemplate.template.name});

      Dealer.templateApplyToExisting($scope.importTemplate.template.id, jsonData).then(function (data) {
        if (data.result) {
          console.log(data);

          var modal = $modal({
            scope: $scope,
            title: '',
            placement: 'top',
            template: 'views/modal-tpls/dealer/import-template-finish.html',
            backdrop: 'static',
            show: false
          });

          modal.$promise.then(modal.show);
        }
      })
        .catch(toastr.error);
    }
  };
  
  $scope.finish = function() {
    if ($rootScope.virtualEditor) {
      $state.go('menu.programming.options');
    } else {
      Systems.updateSystem(Systems.getCurrentSystem().id).then(function () {
        Systems.setCurrentRoom($scope.importTemplate.room.id);
        $state.go('menu.programming.options');
      });
    }
  };
  
  $scope.doNext = function() {
    if ($scope.importTemplate.room.id === 'new') {
      $state.go('file-explorer.import-template-choose-bstation');
    } else {
      var modal = $modal({
        scope: $scope,
        title: '',
        placement: 'top',
        template: 'views/modal-tpls/dealer/import-template-warning.html',
        backdrop: 'static',
        show: false
      });

      modal.$promise.then(modal.show);
    }
  };

});

app.controller('ImportTemplateChooseBstationController', function ($scope, $state, $modal, toastr, searchResults, Systems, Dealer) {

  $scope.bsType = 'BASESTATIONS';
  $scope.baseStations = searchResults.searchedDevices;

  $scope.finish = function() {
    var jsonData = JSON.stringify({
      systemId: Systems.getCurrentSystem().id,
      name: $scope.importTemplate.room.name,
      type: $scope.importTemplate.baseStation.name,
      bstationName: $scope.importTemplate.baseStation.name,
      bstationMac: $scope.importTemplate.baseStation.mac
    });

    Dealer.templateApplyToNew($scope.importTemplate.template.id, jsonData).then(function (data) {
      if (data.result) {
        console.log(data);

        var modal = $modal({
          scope: $scope,
          title: '',
          placement: 'top',
          template: 'views/modal-tpls/dealer/import-template-new-room-finish.html',
          backdrop: 'static',
          show: false
        });

        modal.$promise.then(modal.show);
      }
    })
      .catch(toastr.error);
  };

  $scope.doNext = function () {
    var currentSystem = Systems.getCurrentSystem();
    Systems.updateSystem(currentSystem.id).then(function () {
      Systems.setCurrentRoom(currentSystem.rooms[currentSystem.rooms.length - 1].id);   // 방금 추가한 room 을 선택
      $state.go('menu.programming.options');
    });
  };

});

app.controller('ImportDeviceController', function ($scope, $state, $modal, toastr, devices, Systems, Dealer) {

  $scope.importDevice.devices = devices;

  $scope.select = function(device) {
    $scope.importDevice.device = device;
    
    $state.go('file-explorer.import-device-choose-room', {deviceId: $scope.importDevice.device.id});
  };

  $scope.delete = function(device) {
    $scope.importDevice.device = device;
    
    var modal = $modal({
      scope: $scope,
      title: '',
      placement: 'top',
      template: 'views/modal-tpls/dealer/delete-item.html',
      backdrop: 'static',
      show: false
    });

    modal.$promise.then(modal.show);
  };

  $scope.deleteItem = function() {
    Dealer.deleteDevice($scope.importDevice.device.id).then(function(data) {
      if (data.result) {
        $scope.importDevice.device = null;

        Dealer.getDevices().then(
          function(response) {
            $scope.importDevice.devices = response.devices;
          },
          function(error) {
            toastr.error(error);
          }
        );
      }
    })
      .catch(toastr.error);
  };

});

app.controller('ImportDeviceChooseRoomController', function ($rootScope, $scope, $state, $modal, device, toastr, Systems, Dealer) {
  _.extend($scope.importDevice.device, device);
  $scope.importDevice.device.target_type = $scope.importDevice.device.type;

  $scope.selections = $scope.importDevice;

  $scope.lightLevels = [ {'value': 0, 'label': 'Off'}, {'value': 1, 'label': 'Low'}, {'value': 2, 'label': 'Medium'}, {'value': 3, 'label': 'High'}];
  $scope.irPortOptions = [{name: 'All', value: 255}, {name: '1', value: 1}, {name: '2', value: 2}, {
    name: '3',
    value: 3
  }, {name: '4', value: 4}];

  $scope.ir = {target:0, port:255};



  $scope.editDevice = function() {
    var targetPort;

    if ($scope.selections.device.target_type === 1) {
      if ($scope.ir.target === 2) {
        targetPort = 0;
      } else {
        targetPort = $scope.ir.port;
      }
    } else {
      targetPort = $scope.selections.device.target_port;
    }

    var obj = {
      name: $scope.selections.device.device_name,
      targetType: $scope.selections.device.target_type,
      targetAddr: $scope.selections.device.target_addr,
      targetPort: targetPort,
      favEnable: 0,
      favDelay: 400,
      favEnter: 0,
      repeatMin: $scope.selections.device.repeat_min,
      repeatMacro: $scope.selections.device.repeat_macro,
      rampStart: $scope.selections.device.ramp_start,
      rampSpeed: $scope.selections.device.ramp_speed,
      roomId: $scope.selections.room.id
    };
    if (typeof $scope.selections.device.attr != 'undefined' && typeof $scope.selections.device.attr.auto_cr != 'undefined') {
      obj.autoCr = $scope.selections.device.attr.auto_cr;
    }

    var jsonData = JSON.stringify(obj);

    if ($rootScope.virtualEditor) {
      Dealer.deviceApplyToTemplate($scope.selections.device.id, jsonData).then(function (data) {
        if (data.result) {
          console.log(data);
          Systems.updateSystem(Systems.getCurrentSystem().id).then(function () {
            Systems.setCurrentRoom($scope.selections.room.id);
            $state.go('menu.programming.options');
          });
        }
      })
        .catch(toastr.error);
    } else {
      Dealer.deviceApply($scope.selections.device.id, jsonData).then(function (data) {
        if (data.result) {
          console.log(data);
          Systems.updateSystem(Systems.getCurrentSystem().id).then(function () {
            Systems.setCurrentRoom($scope.selections.room.id);
            $state.go('menu.programming.options');
          });
        }
      })
        .catch(toastr.error);
    }
  };

  $scope.cancelEdit = function() {

  };

  $scope.$watch('selections.device', function(newVal, oldVal) {
    $scope.selections.device.target_type = +newVal.target_type;
  }, true);

  $scope.doNext = function() {
    var modal = $modal({
      scope: $scope,
      title: 'Edit this device',
      template: 'views/modal-tpls/dealer/edit-device.html',
      backdrop: 'static',
      show: false
    });

    modal.$promise.then(modal.show);
  };

});

app.controller('VirtualEditorController', function ($rootScope, $scope, $state, $modal, $window, toastr, Systems) {

  $scope.exitVirtualEditor = function() {
    $rootScope.virtualEditor = null;
    var user = JSON.parse($window.localStorage.getItem('hcm_editor_dealer'));
    delete(user.virtualEditor);
    $window.localStorage.setItem('hcm_editor_dealer', JSON.stringify(user));

    $state.go('dealer-jobs-list');
  };

});

app.controller('VirtualEditorStartNewTemplateController', function ($rootScope, $scope, $state, $modal, $window, toastr, Systems, Dealer) {

  $scope.finish = function() {
    var jsonData = JSON.stringify({
      name: $scope.startNewTemplate.name
    });

    Dealer.createNewTemplate(jsonData).then(function(data) {
      if (data.result) {
        var roomId = data.roomId;

        Dealer.getRoom(roomId).then(function (data) {
          var room = data.data;

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

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

          $rootScope.virtualEditor = true;
          var user = JSON.parse($window.localStorage.getItem('hcm_editor_dealer'));
          user.virtualEditor = 1;
          user.room_id = roomId;
          $window.localStorage.setItem('hcm_editor_dealer', JSON.stringify(user));

          $state.go('menu.programming.options');
        })
          .catch(toastr.error);
      }
    })
      .catch(toastr.error);
  };

});

app.controller('VirtualEditorEditTemplateController', function ($rootScope, $scope, $state, $modal, $window, toastr, Systems, Dealer) {

  $scope.select = function(template) {
    $scope.editTemplate.template = template;

    Dealer.getRoom(template.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];
      Systems.loadSystem($rootScope.virtualSystem);
      Systems.setCurrentRoom(room.id);

      $rootScope.virtualEditor = true;
      var user = JSON.parse($window.localStorage.getItem('hcm_editor_dealer'));
      user.virtualEditor = 1;
      user.room_id = template.id;
      $window.localStorage.setItem('hcm_editor_dealer', JSON.stringify(user));

      $state.go('menu.programming.options');
    })
      .catch(toastr.error);
  };

});

app.controller('RegisterDealerController', function ($rootScope, $scope, $state, $stateParams, $http, toastr, email, Dealer, User) {
  // As3AQCjg58mH
  // VDTLGbXjS5RIWG
  // npLieg8pVH8
  // IuY82RFBx

  $scope.credentials = {
    creation_id: $stateParams.creationId,
    email: email,
    username: email,
    password: null
  };
  $scope.confirmed_password = null;

  $scope.register = function () {
    var jsonData = JSON.stringify($scope.credentials);

    Dealer.addUserFinal(jsonData).then(function (data) {
      if (data.result) {
        User.logout();
        window.location = '/';
      }
    })
      .catch(toastr.error);
  };

  // add_user_prepare 테스트용
  /*
   $scope.addUserPrepare = function() {
   var url = '/api/dealer/add_user_prepare',
   data = {
   email: 'master@linkit.kr',
   account_type: 'Dealer Installer/Programmer',
   first_name: 'Youngguk',
   last_name: 'Kim',
   phone_number: '01032047694'
   },
   jsonData = JSON.stringify(data);

   $http.post(url, jsonData)
   .success(function(response) {
   console.log(response);
   });
   };
   $scope.addUserPrepare();
   */

});

app.controller('DealerAccountSettingsController', function ($scope, $state, $stateParams, $http, toastr, Dealer, Auth) {

  $scope.dealerInfo.selectedUser = null;
  $scope.dealerInfo.addUser = {};
  $scope.dealerInfo.userData = null;

  Auth.currentUser().then(function (user) {
    $scope.dealerInfo.currentUser = user;
  });

});

app.controller('DealerChangeEmailController', function ($scope, $state, $modal, toastr, Dealer, User) {

  $scope.dealerInfo.changeEmail = {};

  $scope.save = function () {
    $scope.dealerInfo.changeEmail.old_email = $scope.dealerInfo.currentUser.dealer_username;
    var jsonData = JSON.stringify($scope.dealerInfo.changeEmail);

    Dealer.newEmail(jsonData).then(function (data) {
      if (data.result) {
        var modal = $modal({
          scope: $scope,
          title: 'Email Address Changed',
          content: 'The email address for this account has been changed. You will need to log in again with your new account credentials.',
          template: 'views/modal-tpls/dealer/dealer-settings-complete.html',
          backdrop: 'static',
          show: false
        });

        modal.$promise.then(modal.show);
      }
    })
      .catch(toastr.error);
  };

  $scope.finish = function () {
    User.logout();
    window.location = '/';
  };

});

app.controller('DealerChangePasswordController', function ($scope, $state, $modal, Dealer, User) {

  $scope.dealerInfo.changePassword = {};

  $scope.save = function () {
    $scope.dealerInfo.changePassword.email = $scope.dealerInfo.currentUser.dealer_username;
    var jsonData = JSON.stringify($scope.dealerInfo.changePassword);

    Dealer.newPassword(jsonData).then(function (data) {
      if (data.result) {
        var modal = $modal({
          scope: $scope,
          title: 'Password Changed',
          content: 'The password for this account has been changed. You will need to log in again with your new account credentials.',
          template: 'views/modal-tpls/dealer/dealer-settings-complete.html',
          backdrop: 'static',
          show: false
        });

        modal.$promise.then(modal.show);
      }
    })
      .catch(toastr.error);
  };

  $scope.finish = function () {
    User.logout();
    window.location = '/';
  };

});

app.controller('DealerSelectUserController', function ($scope, $state, $stateParams, toastr, users, Dealer) {

  $scope.users = users;

  $scope.doNext = function () {
    $state.go('dealer-account-settings.user-info');
  };

});

app.controller('DealerUserInfoController', function ($scope, $state, $modal, toastr, Dealer) {

  var jsonData = JSON.stringify({email: $scope.dealerInfo.selectedUser.email});

  Dealer.getUserData(jsonData).then(function (data) {
    if (data.result) {
      $scope.dealerInfo.userData = data.data;
    }
  })
    .catch(toastr.error);

  $scope.delete = function () {
    var modal = $modal({
      scope: $scope,
      title: '',
      placement: 'top',
      template: 'views/modal-tpls/dealer/delete-user.html',
      backdrop: 'static',
      show: false
    });

    modal.$promise.then(modal.show);
  };

  $scope.deleteUser = function () {
    Dealer.deleteUser(jsonData).then(function (data) {
      if (data.result) {
        $state.go('dealer-account-settings.main');
      }
    })
      .catch(toastr.error);
  };

});

app.controller('DealerAddUserController', function ($scope, $state, $modal, toastr, categories, Dealer) {

  $scope.categories = categories;
  $scope.dealerInfo.addUser.account_type = $scope.categories[0].value;

  $scope.doNext = function () {
    var jsonData = JSON.stringify($scope.dealerInfo.addUser);

    Dealer.addUserPrepare(jsonData).then(function (data) {
      if (data.result) {
        $state.go('dealer-account-settings.main');
      }
    })
      .catch(toastr.error);
  };

});

'use strict';
/**
 * @ngdoc controller
 * @name DeviceSelectionController
 * @description
 *  room, device 선택 화면
 */
app.controller('DeviceSelectionController', function ($scope, $state, toastr, Devices) {
	$scope.doNext = function() {
		// device 정보 얻기
		Devices.getOne($scope.deviceMenu.roomId, $scope.deviceMenu.deviceId).then(function (data) {

			Devices.setCurrentData(data);
			$state.go('menu.advanced.device.edit-layout');

		}).catch(toastr.error);
	};

});

/**
 * @ngdoc controller
 * @name DeviceMenuLayoutController
 * @description
 *  device button layout 편집 화면
 */
app.controller('DeviceMenuLayoutController', function ($scope, $state, $modal, toastr, Systems, Devices) {

	$scope.finish = function() {

		var pages = [],
				hardPages = angular.copy($scope.deviceMenu.hard.pages),
				hardBtns = _.flatten(hardPages, 'btns'),
				menuPages = angular.copy($scope.deviceMenu.menu.pages),
				pageId = 0,
				buttonId = 8192;

		function rewriteMacro(btn) {
			var newMacro = {};
			if(btn.macro) {
				///Devices Service의 getOne function을 통해 Device정보를 얻어 올때 각 button의 macro data를 object로 변환하였으나
				///혹시 몰라서 macro가 string type인 경우에 대해서도 처리.
				newMacro = angular.isObject(btn.macro) ? btn.macro[0] : JSON.parse(btn.macro)[0];
			}

			if(btn.func) {
				if (_.isEmpty(newMacro)) {
					newMacro.type = 1;
					newMacro.device_id = parseInt($scope.deviceMenu.deviceData.id, 10);
				}

				console.log('rewriteMacro-btn=', btn);
			
				newMacro.func = btn.func.id;

				if (btn.repeatSetting === 'custom') {
					newMacro.repeat_min = btn.repeat_min;
					newMacro.repeat_macro = btn.repeat_macro;
				} else {
					delete newMacro.repeat_min;
					delete newMacro.repeat_macro;
				}

				if (!btn.press_hold) {
					newMacro.press_hold = 0;
				} else {
					newMacro.press_hold = 1;
				}
			}

			//console.log('rewriteMacro- newMacro=', newMacro);
			return JSON.stringify([newMacro]);
		}

		_.remove(hardBtns, function(button) {
			return !button.display_text;
		});

		_.forEach(hardBtns, function(hardBtn) {
			hardBtn.macro = rewriteMacro(hardBtn);
			hardBtn.page_btn_idx = -1;
			delete hardBtn.func;
			delete hardBtn.repeatSetting;
			delete hardBtn.repeat_min;
			delete hardBtn.repeat_macro;
			delete hardBtn.press_hold;
			delete hardBtn.name;
		});


		pages.push({ id: -1, btns: hardBtns });

		_.forEach(menuPages, function(page) {
			if (_.filter(page.btns, 'display_text').length) {
				page.id = pageId;
				pageId++;

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

				_.remove(page.btns, function(button) {
					return !button.display_text;
				});

				_.forEach(page.btns, function(btn) {

					if (btn.display_text) {

						btn.id = buttonId;
						buttonId++;

						btn.hidden = (true == btn.hidden ? 1:0);

						btn.macro = rewriteMacro(btn);

						delete btn.func;
						delete btn.repeatSetting;
						delete btn.repeat_min;
						delete btn.repeat_macro;
						delete btn.press_hold;
					}

				});

				pages.push(page);
			}
		});

	 
		var returnDevice = angular.copy($scope.deviceMenu.deviceData); 
		_.assign(returnDevice, {pages: pages});

		//if these properties are seleceted as `None` on the client their properties will be null
		//in that case, they to be changed to -1 
		
		returnDevice.meta_pwr_on =  returnDevice.meta_pwr_on || -1;
		returnDevice.meta_pwr_off = returnDevice.meta_pwr_off || -1;
		returnDevice.meta_pwr_toggle = returnDevice.meta_pwr_toggle || -1;
		returnDevice.meta_in_toggle = returnDevice.meta_in_toggle || -1;
		

		var jsonData = JSON.stringify({ data: returnDevice });

		// 해당 device 저장
		Devices.storeOne($scope.deviceMenu.roomId, $scope.deviceMenu.deviceId, jsonData).then(function(data) {
			// system update
			Systems.updateSystem($scope.system.id);

			$state.go('menu.advanced.options');
		}, function (error) {
			toastr.error(error, 'Error');
		});

	};

});

'use strict';
/**
 * @ngdoc controller
 * @name EditMacroRoomController
 * @description
 *  room 선택 화면
 */
app.controller('EditMacroRoomController', function ($scope, $state, toastr, Systems) {
	$scope.system = Systems.getCurrentSystem();


	$scope.doNext = function() {
		// room 정보 얻어와서 저장
		return Systems.updateRoomDevices($scope.addMacro.room.id)
		.then(function(data) {
			var roomDevices = Systems.getRoomDevices();
			$scope.addMacro.room.devices = roomDevices.devices;

			// dev_type이 twoway(1)인 device를 모두 제거하는 과정에서 $scope.addMacro.room.devices 에서 SNP-2 가 제거되는데 SNP-2 가 있는 목록이 "Add jump to" 에서 필요해서 copy 를 만듬
			$scope.addMacro.room.devicesAndSNP2 = angular.copy(roomDevices.devices);

			// twoway_devices 중 TRF-ZW 추가한 device 목록 생성
			$scope.addMacro.room.allDevices = angular.copy($scope.addMacro.room.devices);

			_.each($scope.system.rooms, function(room) {
				var trfzw = _.find(room.twoway_devices, {model: 'TRF-ZW1'});
				if (trfzw) {
					if (!trfzw.data) {
						trfzw.data = [];
					}
					$scope.addMacro.room.allDevices.push(trfzw);

					return false;
				}
			});

			$state.go('menu.advanced.edit-macros.macro-simulator', {roomId: $scope.addMacro.room.id});
		})
		.catch(toastr.error);
	};
});

/**
 * @ngdoc controller
 * @name MacroSimulatorController
 * @description
 *  macro 를 수정할 button, device 선택 화면
 */
app.controller('MacroSimulatorController', function ($scope, $state, $modal, toastr, Systems) {
  // Advanced Menu 의 Edit your automated activities 메뉴를 클릭해서 들어온 경우
  //   => currentRoom 을 선택된 room 으로 설정함
  $scope.addMacro.room = $scope.room;

  // 아래의 코드는 EditMacroRoomController 의 doNext 에서 하는 동작임
  Systems.updateRoomDevices($scope.addMacro.room.id)
    .then(function (data) {
      var roomDevices = Systems.getRoomDevices();
      $scope.addMacro.room.devices = roomDevices.devices;

      // dev_type이 twoway(1)인 device를 모두 제거하는 과정에서 $scope.addMacro.room.devices 에서 SNP-2 가 제거되는데 SNP-2 가 있는 목록이 "Add jump to" 에서 필요해서 copy 를 만듬
      $scope.addMacro.room.devicesAndSNP2 = angular.copy(roomDevices.devices);

      // twoway_devices 중 TRF-ZW 추가한 device 목록 생성
      $scope.addMacro.room.allDevices = angular.copy($scope.addMacro.room.devices);

      _.each($scope.system.rooms, function (room) {
        var trfzw = _.find(room.twoway_devices, {model: 'TRF-ZW1'});
        if (trfzw) {
          if (!trfzw.data) {
            trfzw.data = [];
          }
          $scope.addMacro.room.allDevices.push(trfzw);

          return false;
        }
      });

      $state.go('menu.advanced.edit-macros.macro-simulator', {roomId: $scope.addMacro.room.id});
    })
    .catch(toastr.error);

	$scope.editMacro.currentPage = 1;

	//$scope.addMacro.room.devices = devices;

	function updateMainDevice() {
		// main device 얻어와서 저장
		Systems.updateMainDevice($scope.addMacro.room.id).then(function(data) {
			console.log(data);
			$scope.editMacro.mainDevice = data;
			$scope.client.page = angular.copy($scope.editMacro.mainDevice.pages[$scope.editMacro.currentPage - 1]);
			var numPages = $scope.editMacro.mainDevice.pages.length;
			$scope.editMacro.totalItems = numPages * 6;
		})
		.catch(toastr.error);
		
		updatePowerMacro();
	}

  updateMainDevice();

	function isJsonString(str) {
		try {
			JSON.parse(str);
		} catch (e) {
			return false;
		}
		return true;
	}

	$scope.isJsonString = isJsonString;

	$scope.editPowerMacro = function() {
		$scope.macroType.id = 0;

		var roomId = $scope.addMacro.room.id;
		// 해당 room 의 power macro 데이터 얻어와서 저장
		Systems.updateCurrentMacroForPower(roomId).then( function(data) {
			console.log(data);
			$scope.addMacro.steps = cleanUp('macro', roomId, data.macro);
			//$scope.addMacro.autoWait = data.auto_wait ? true:false;
			$scope.addMacro.doneScreen.devices = cleanUp('activity', roomId, data.activity);
			$scope.addMacro.disablePopup = data.popup ? false:true;
			$state.go('menu.advanced.edit-macros.finish');
		}).catch(function (error) {
			alert(error);
		});
	};

	function cleanUp(type, roomId, arr) {
		//console.log(arr);
		var filteredSteps = [];
		var steps =  isJsonString(arr) ? JSON.parse(arr):arr ;
		_.forEach(steps, function (step) {
			var device;
			var variable;

			if (type === 'macro') {
				if (step.type === 1) {
					device = Systems.getDevice(roomId, step.device_id);
					if (device) {
						step.name = device.name + ': ' + _.find(device.funcs, {'id': step.func}).name;
						filteredSteps.push(step);
					}
				} else if (step.type === 2) {
					step.name = 'Delay ' + step.value/1000 + ' seconds';
					filteredSteps.push(step);
				} else if (step.type === 3 && step.to.type === 1) {
					//device = Systems.getDevice(roomId, step.to.value);
					device =  _.find($scope.addMacro.room.devicesAndSNP2, { 'id': step.to.value });		// Systems.getDevice 에서 device 를 찾으면, "dev_type이 twoway(1)인 device를 모두 제거." 주석 처리된 부분에 의해 Add jump to 에서 추가한 SNP-2 가 보이지 않게 되어서 $scope.addMacro.room.devicesAndSNP2 에서 device 를 찾음
					if (device) {
						step.name = 'Jump to ' + device.name;
						filteredSteps.push(step);
					}
				} else if (step.type === 4) {
					variable = _.find($scope.system.variables || $scope.system.rooms[0].variables, {'id': step.cond.id});		// virtual editor 에는 system 에 variables 가 없어서 rooms[0].variables 를 사용. virtual editor 에는 room 이 1개만 있어서 rooms[0] 을 사용함.
					if (variable) {
						if(variable.type == 0){
							name = 'If: ' + variable.name + ', ' + (step.cond.value == 1 ? 'True':'False');
						} else{
							name = 'If: ' + variable.name + ' ' +  step.cond.operate + ' ' + step.cond.value;
						} 

						step.name = name;

						step.steps = [{name:'True', steps:[]}, {name:'False', steps:[]}];

						filteredSteps.push(step);

						if(step.true){
							step.steps[0].steps = cleanUp('macro', roomId, step.true);
						}

						if(step.false){
							step.steps[1].steps = cleanUp('macro', roomId, step.false);
						}
					}
				}
				else if (step.type === 5) {
					variable = _.find($scope.system.variables || $scope.system.rooms[0].variables, {'id': step.id});	// virtual editor 에는 system 에 variables 가 없어서 rooms[0].variables 를 사용. virtual editor 에는 room 이 1개만 있어서 rooms[0] 을 사용함.
					if (variable) {
						var dispValue = step.value;
						if(variable.type == 0){
							if(step.value == 0){
								dispValue = 'false' ;
							}
							else if(step.value == 1){
								dispValue = 'true' ;
							}
							else if(step.value == 2){
								dispValue = 'invert' ;
							}
						}

						step.name = 'VAR ' + variable.name + '= ' + dispValue;
						filteredSteps.push(step);
					}
				} else if (step.type === 16) {
					_.each($scope.system.rooms, function(room) {
						device = _.find(room.twoway_devices, {model: 'TRF-ZW1'});

						if (device) {
							var scene = _.find(device.data, {id: step.id});

							if (scene) {
								step.name = 'S : ' + scene.name + ' (' + scene.room + ')';
								filteredSteps.push(step);
							}

							return false;
						}
					});
				}
			} else {
				device = Systems.getDevice(roomId, step.device_id);
				if (device) {
					step.name = device.name;
					step.funcs = device.funcs;
					filteredSteps.push(step);
				}

			}
		});
		return filteredSteps;
	}



	$scope.editBtnMacro = function(btn) {
		//console.log(btn);
		var roomId = angular.copy($scope.addMacro.room.id);
		var activity =  btn.activity ? JSON.parse(btn.activity):[];

		$scope.addMacro.steps = cleanUp('macro', roomId, btn.macro);
		console.log('$scope.addMacro.steps=', $scope.addMacro.steps);
		//$scope.addMacro.autoWait = btn.auto_wait ? true:false;
		$scope.addMacro.doneScreen.devices = cleanUp('activity', roomId, activity);
		$scope.addMacro.disablePopup = btn.popup ? false:true;
		$scope.addMacro.linkId = btn.link_id;
		$scope.addMacro.btnId = btn.id;

	
		$scope.macroType.id = btn.link_id !== -1? 1:2;
		
		switch ($scope.macroType.id) {
			case 1:
				$scope.addMacro.currentDevice = _.find($scope.addMacro.room.devices, {'id': btn.link_id});
				break;
			case 2:
				$scope.addMacro.button.name = btn.display_text;
				break;
			default:
				break;
		}
		$state.go('menu.advanced.edit-macros.finish');
	};

	$scope.pageChanged = function(page) {
		$scope.client.page = angular.copy($scope.editMacro.mainDevice.pages[page - 1]);
	};
	
	function updatePowerMacro() {
		// 해당 room 의 power macro 데이터 얻어와서 저장
		Systems.updateCurrentMacroForPower($scope.addMacro.room.id).then( function(data) {
			$scope.powerMacro = data.macro;
		}).catch(function (error) {
			toastr.error(error);
		});
	}
	
	$scope.deleteMacro = function(mode, linkId, roomId, deviceId, btnId) {
		var handleSuccess = function(response) {
			if(response.data.result === true) {
				toastr.success('Automated Activity has been deleted');
				updateMainDevice();
			} else {
				toastr.error('Delete failed to work. Please try again.');
			}
		};

		var handleError = function(error){
			toastr.error(error, 'Error');
		};
		
		if (mode === 'power') {
			// 해당 room 의 power macro 삭제
			Systems.deletePowerMacro($scope.addMacro.room.id).then(handleSuccess, handleError);
		} else if (mode === 'device-btn') {
			if (linkId == '-1') {
				// button ID 에 해당하는 button 삭제
				Systems.deleteButtonMacro(roomId, deviceId, btnId).then(handleSuccess, handleError);
			} else {
				// 해당 device ID 와 연계된 button 의 macro 삭제
				Systems.deleteButtonMacroWithDevice(roomId, linkId).then(handleSuccess, handleError);
			}
		}
	};
	
	$scope.deleteMacroModal = function(mode, linkId, roomId, deviceId, btnId) {
		var scope = $scope.$new();
		scope.data = {
			mode: mode,
			linkId: linkId,
			roomId: roomId,
			deviceId: deviceId,
			btnId: btnId
		};
		
		var modal = $modal({
			scope: scope,
			template: 'views/modal-tpls/delete-macro.html',
			container: 'body',
			show: false
		});
		modal.$promise.then(modal.show);
	};

});

/**
 * @ngdoc controller
 * @name EditMacroController
 * @description
 *  macro device, commands 입력
 */
app.controller('EditMacroController', function ($scope, $timeout, $state, $modal, toastr, Devices, Systems) {

	$scope.selectedItem = {};

	$scope.remove = function(scope) {
		scope.remove();
	};

	$scope.options = {
		accept: function(sourceNodeScope, destNodesScope, destIndex) {
			//console.log('sourceNodeScope=', sourceNodeScope);
			//console.log('destNodesScope=', destNodesScope);
			if (sourceNodeScope.$modelValue.type == null || destNodesScope.nodropEnabled || destNodesScope.outOfDepth(sourceNodeScope)) {
				return false;
			}

	        var subDepth = 0;
	        function countSubDepth(scope) {
				var i, childNodesScope,
					count = 0,
					nodes = scope.childNodes();

				//console.log('childNodes=', nodes);

				for (i = 0; i < nodes.length; i++) {
					childNodesScope = nodes[i].$childNodesScope;

					if (childNodesScope && childNodesScope.childNodesCount() > 0) {
						count = 1;
						countSubDepth(childNodesScope);
					}
				}
				subDepth += count;				
			}

			var maxSubDepth = function (scope) {
				subDepth = 0;
				if (scope.hasChild()) {
					countSubDepth(scope.$childNodesScope);
					subDepth++;
				}
				return subDepth;
			};

			/*
			console.log('sourceNodeScope.childNodes()=', sourceNodeScope.childNodes());
			console.log('sourceNodeScope.childNodesCount()=', sourceNodeScope.childNodesCount());
			console.log('maxSubDepth(sourceNodeScope)=', maxSubDepth(sourceNodeScope));
			console.log('destNodesScope.depth()=', destNodesScope.depth());
			console.log('destNodesScope.maxDepth=', destNodesScope.maxDepth);
			console.log('destNodesScope.$treeScope.maxDepth=', destNodesScope.$treeScope.maxDepth);
			*/

			//angular-ui-tree module의 maxSubDepth function에서 sub depth count를 child node 존재 유무를 기준으로 함.
			//그래서 2depth인 tree인 경우 depth count를 0으로 return하여 outOfDepth function을 호출해도 제대로된 결과를 받지 못하고,
			// (max-depth -1) depth인 tree에 2depth의 tree를 drag/drop하면 삽입이 됨.
			//그래서, 별도의 maxSubDepth function을 구현함.
			var sumDepth =  (maxSubDepth(sourceNodeScope)+1) + destNodesScope.depth();
			var maxDepth = destNodesScope.maxDepth || destNodesScope.$treeScope.maxDepth;

			if(sumDepth  > maxDepth){
				return false;
			}

			return true;
		},
	};

	var getRootNodesScope = function() {
		return angular.element(document.getElementById("tree-root")).scope();
	};

	$scope.collapseAll = function() {
		var scope = getRootNodesScope();
		scope.collapseAll();
	};

	$scope.expandAll = function() {
		var scope = getRootNodesScope();
		scope.expandAll();
	};


	$scope.addStep = function (device, func, twowayDevice) {
		if (twowayDevice) {
			return {'name': 'S : ' + func.name + ' (' + func.room + ')', 'type': 16, 'sub_type': 'scene', 'id': func.id, 'cmd': 1 };		// 1 : Activate, 2 : Deactivate
		} else {
			return {'name': device.name + ': ' + func.name, 'type': 1, 'device_id': device.id, 'func': func.id };
		}
	};

	$scope.deleteAll = function() {
		var arr = $scope.addMacro.steps;
		while(arr.length > 0) {
			arr.pop();                     
		}
	};

	$scope.goBack = function() {
		$state.go('menu.advanced.edit-macros.macro-simulator', {roomId: $scope.addMacro.room.id});
	};

	$scope.doNext = function() {
		$state.go('menu.advanced.edit-macros.macro-done');
	};

	$scope.refreshScenes = function(device) {
		Devices.updateTwowayDevice($scope.addMacro.room.id, device.id)
			.then(function(data) {
				console.log(data);

				var item = _.where($scope.addMacro.room.allDevices, {'id': device.id})[0];
				item.data = data;
			}, function() {
				var modal = $modal({
					scope: $scope,
					title: "Couldn't refresh the list",
					container: '.editor-container',
					template: 'views/modal-tpls/refresh-the-list.html',
					show: false
				});

				modal.$promise.then(modal.show);
			})
			.catch(toastr.error);
	};

});

/**
 * @ngdoc controller
 * @name EditMacroDoneController
 * @description
 *  macro 설정 완료 화면
 */
app.controller('EditMacroDoneController', function ($scope, $state, toastr, Systems) {
	$scope.addMacro.doneScreen.index = 0;

	$scope.goBack = function() {
		$state.go('menu.advanced.edit-macros.finish');
	};

	function cleanUp(steps) {
		var filteredSteps = steps;
		_.forEach(filteredSteps, function (step) {
			delete step.name; 
			if(step.type == 4){
				console.log('cleanUp-step=', step);
				if(0 < step.steps[0].steps.length) {						
					step.steps[0].steps = cleanUp(step.steps[0].steps);
					step.true = angular.copy(step.steps[0].steps);					
				}
				if(0 < step.steps[1].steps.length) {
					step.steps[1].steps = cleanUp(step.steps[1].steps);
					step.false = angular.copy(step.steps[1].steps);					
				}
				delete step.steps;
			}
		});
		return filteredSteps;
	}

	$scope.doNext = function() {
		if ($scope.addMacro.disablePopup) {
			var steps =  angular.copy($scope.addMacro.steps);
			steps = cleanUp(steps);
			console.log('steps=', steps);

			//var autoWait = $scope.addMacro.autoWait ? 1:0;
			var jsonData = JSON.stringify( { auto_wait: 1 , edit_type: 1, popup: 0, activity: [], macro: steps } );
			console.log('jsonData=', jsonData);

			var handleSuccess = function(response) {
				if(response.data.result === true) {
					$state.go('menu.advanced.edit-macros.next-action');
				} else {
					toastr.error('Your edit/create action failed.  Please try again.');
				}
			};

			var handleError = function(error){
				toastr.error("Please try again");
			};

			if ($scope.macroType.id === 0) {
				// 해당 room 의 power macro 데이터 저장
				Systems.storePowerMacro($scope.addMacro.room.id, jsonData).then(handleSuccess, handleError);
			} else if ($scope.macroType.id === 1) {
				// 해당 device ID 와 연계된 button 의 데이터 저장
				Systems.storeDeviceButtonMacro($scope.addMacro.room.id, $scope.addMacro.linkId, jsonData).then(handleSuccess, handleError);
			} else {
				// button ID 에 해당하는 button 의 데이터 저장
				Systems.storeCustomButtonMacro($scope.addMacro.room.id, $scope.addMacro.room.main_device_id, $scope.addMacro.btnId, jsonData).then(handleSuccess, handleError);
			}
		} else {
			$state.go('menu.advanced.edit-macros.macro-commands');
		}
	};

});


app.controller('EditMacroCommandsController', function ($scope, $state, toastr, Systems) {

	$scope.goBack = function() {
		if ($scope.addMacro.doneScreen.index === 0) {
			$state.go('menu.advanced.edit-macros.macro-done' );
		} else {
			$scope.addMacro.doneScreen.index--;
		}
	};


	function cleanUp(steps) {
		var filteredSteps = steps;
		_.forEach(filteredSteps, function (step) {
			delete step.name; 
			if(step.type == 4){
				console.log('cleanUp-step=', step);
				if(0 < step.steps[0].steps.length) {						
					step.steps[0].steps = cleanUp(step.steps[0].steps);
					step.true = angular.copy(step.steps[0].steps);					
				}
				if(0 < step.steps[1].steps.length) {
					step.steps[1].steps = cleanUp(step.steps[1].steps);
					step.false = angular.copy(step.steps[1].steps);					
				}
				delete step.steps;
			}
		});
		return filteredSteps;
	}


	$scope.doNext = function() {
		var len = $scope.addMacro.doneScreen.devices.length;
		if ($scope.addMacro.doneScreen.index + 1 === len) {
			//var autoWait = $scope.addMacro.autoWait ? 1:0;
			var steps =  angular.copy($scope.addMacro.steps);
			steps = cleanUp(steps);
			console.log('steps=', steps);

			var activityData = angular.copy($scope.addMacro.doneScreen.devices);

			_.forEach(steps, function(step) { delete step.name; });
			_.forEach(activityData, function(activity) {
				activity.func = activity.func.id;
				delete activity.name;
				delete activity.repeat_min;
				delete activity.repeat_macro;
				delete activity.target_type;
				delete activity.target_addr;
				delete activity.target_port;
				delete activity.funcs;
			});

			var jsonData = JSON.stringify( { auto_wait: 1 , edit_type: 1, popup: 1, activity: activityData, macro: steps } );

			var handleSuccess = function(response) {
				if(response.data.result === true) {
					$state.go('menu.advanced.edit-macros.next-action');
				} else {
					toastr.error('Your edit/create action failed.  Please try again.');
				}
			};

			var handleError = function(error){
				toastr.error('Please try again');
			};

			if ($scope.macroType.id === 0) {
				Systems.storePowerMacro($scope.addMacro.room.id, jsonData).then(handleSuccess, handleError);
			} else if ($scope.macroType.id === 1) {
				Systems.storeDeviceButtonMacro($scope.addMacro.room.id, $scope.addMacro.linkId, jsonData).then(handleSuccess, handleError);
			} else {
				Systems.storeCustomButtonMacro($scope.addMacro.room.id, $scope.addMacro.room.main_device_id, $scope.addMacro.btnId, jsonData).then(handleSuccess, handleError);
			}
		} else {
			$scope.addMacro.doneScreen.index++;
		}

	};
});

'use strict';
/**
 * @ngdoc controller
 * @name NewOrExistingController
 * @description
 *  existing device, new device 선택 화면
 */
app.controller('NewOrExistingController', function ($scope, $state) {
	
	$scope.doNext = function() {
		if ($scope.learnIr.exists) {
			$state.go('menu.advanced.learn-ir.select-device');   
		} else {
			$state.go('menu.advanced.learn-ir.new-device');
		}
	};
});

/**
 * @ngdoc controller
 * @name ExistingDeviceController
 * @description
 *  room, device 선택 화면
 */
app.controller('ExistingDeviceController', function ($scope, $state, toastr, Devices) {
	
	$scope.doNext = function() {
		// device 정보 얻기
		Devices.getOne($scope.learnIr.roomId, $scope.learnIr.deviceId).then(function (data) {
			Devices.setCurrentData(data);
			$state.go('menu.advanced.learn-ir.edit');
		}).catch(toastr.error);
	};
});

/**
 * @ngdoc controller
 * @name NewDeviceController
 * @description
 *  새 device 정보 입력 화면
 */
app.controller('NewDeviceController', function ($scope, $state, Devices, categories) {
	$scope.types = _.pluck(categories, 'name');
	$scope.learnIr.room = _.find($scope.system.rooms, {'id': $scope.room.id});
	$scope.learnIr.device = { target: {} }; 
	$scope.learnIr.device.category = categories[0].name;
	$scope.learnIr.device.target.type = 1;
	$scope.learnIr.device.target.port = 255;
	//$scope.learnIr.device.target.addr = null;
	//$scope.learnIr.device.target.addr = $scope.learnIr.room.bstations[0].mac;

	$scope.doNext = function () {
		var tempDeviceData = { id: '-1', name: $scope.learnIr.device.name, meta_in_toggle: -1, meta_pwr_toggle: -1, meta_pwr_on: -1, meta_pwr_off: -1,  repeat: {min: 1, macro: 3}, dbCon: [], dbKey: [] };
		Devices.initHardBtnPages();
		Devices.addHardBtnProps(tempDeviceData);
		Devices.setCurrentData(tempDeviceData);
		$state.go('menu.advanced.learn-ir.edit');
	};
});

/**
 * @ngdoc controller
 * @name EditIrController
 * @description
 *  button learn 화면
 */
app.controller('EditIrController', function ($scope, $state, toastr, Devices, Systems) {
	

	function handleSuccess(data) {
		$state.go('menu.advanced.options');
	}

	function handleError(error) {
		toastr.error(error, 'Error');
	}

	$scope.goBack = function() {
		if ($scope.learnIr.exists) {
			$state.go('menu.advanced.learn-ir.select-device');   
		} else {
			$state.go('menu.advanced.learn-ir.new-device');
		}
	};

	$scope.finish = function() {
		var pages = [],
				hardPages = angular.copy($scope.learnIr.hard.pages),
				hardBtns = _.flatten(hardPages, 'btns'),
				menuPages = angular.copy($scope.learnIr.menu.pages),
				pageId = 0,
				buttonId = 8192;

		function rewriteMacro(btn) {
			var newMacro = {};
			if(btn.macro) {
				///Devices Service의 getOne function을 통해 Device정보를 얻어 올때 각 button의 macro data를 object로 변환하였으나
				///혹시 몰라서 macro가 string type인 경우에 대해서도 처리.
				newMacro = angular.isObject(btn.macro) ? btn.macro[0] : JSON.parse(btn.macro)[0];
			}

			if(btn.func) {
				if (_.isEmpty(newMacro)) {
					newMacro.type = 1;
					newMacro.device_id = parseInt($scope.learnIr.deviceData.id, 10);
				}

				console.log('rewriteMacro-btn=', btn);
			
				newMacro.func = btn.func.id;

				if (btn.repeatSetting === 'custom') {
					newMacro.repeat_min = btn.repeat_min;
					newMacro.repeat_macro = btn.repeat_macro;
				} else {
					delete newMacro.repeat_min;
					delete newMacro.repeat_macro;
				}

				if (!btn.press_hold) {
					newMacro.press_hold = 0;
				} else {
					newMacro.press_hold = 1;
				}
			}

			//console.log('rewriteMacro- newMacro=', newMacro);
			return JSON.stringify([newMacro]);
		}

		_.remove(hardBtns, function(button) {
			return !button.display_text;
		});

		_.forEach(hardBtns, function(hardBtn) {
			hardBtn.macro = rewriteMacro(hardBtn);
			hardBtn.page_btn_idx = -1;
			delete hardBtn.func;
			delete hardBtn.repeatSetting;
			delete hardBtn.repeat_min;
			delete hardBtn.repeat_macro;
			delete hardBtn.press_hold;
			delete hardBtn.name;
		});


		pages.push({ id: -1, btns: hardBtns });

		_.forEach(menuPages, function(page) {
			if (_.filter(page.btns, 'display_text').length) {
				page.id = pageId;
				pageId++;

				_.remove(page.btns, function(button) {
					return !button.display_text;
				});

				_.forEach(page.btns, function(btn) {

					if (btn.display_text) {

						btn.id = buttonId;
						buttonId++;

						btn.hidden = (true == btn.hidden ? 1:0);
						
						btn.macro = rewriteMacro(btn);

						delete btn.func;
						delete btn.repeatSetting;
						delete btn.repeat_min;
						delete btn.repeat_macro;
						delete btn.press_hold;
					}

				});

				pages.push(page);
			}
		});

		var data = angular.copy($scope.learnIr.deviceData); 

		data.meta_pwr_on =  data.meta_pwr_on || -1;
		data.meta_pwr_off = data.meta_pwr_off || -1;
		data.meta_pwr_toggle = data.meta_pwr_toggle || -1;
		data.meta_in_toggle = data.meta_in_toggle || -1;
		
		var jsonData;
		
		if ($scope.learnIr.exists) {
			_.assign(data, {pages: pages});    
			jsonData = JSON.stringify({ data: data });
			Devices.storeOne($scope.learnIr.roomId, $scope.learnIr.deviceId, jsonData).then(handleSuccess, handleError);
		} else {
			var device = $scope.learnIr.device;
			_.assign(data, { pages: pages, 
											 name: device.name,
											 category: device.category,
											 brand: device.brand,
											 model: device.model,
											 target: device.target
										 });
			jsonData = JSON.stringify({ data: data });
			console.log(data);

			// learn device 생성
			Devices.createCustomOne($scope.learnIr.room.id, jsonData)
			.then(function(data) {
				var id = Systems.getCurrentSystem().id;
				return Systems.updateSystem(id);
			})
			.then(handleSuccess)
			.catch(handleError);
		}

	};

	var currentRoom;
	if ($scope.$parent.learnIr && $scope.$parent.learnIr.room) {
		currentRoom = $scope.$parent.learnIr.room;
		console.log('currentRoom', currentRoom);
	} else if ($scope.learnIr) {
		currentRoom = _.where($scope.system.rooms, {
			id: $scope.learnIr.roomId
		})[0];
	}

	if (currentRoom) {
		var masterBstation = _.where(currentRoom.bstations, {
			master: 1
		})[0];
console.log('masterBstation', masterBstation);
		$scope.masterBstaion = masterBstation;
	}
});

'use strict';
/**
 * @ngdoc controller
 * @name LoginController
 * @description
 *  로그인, 비밀번호 리셋 관련
 */
app.controller('LoginController', function ($rootScope, $scope, $state, $stateParams, toastr, Systems, Auth, User, Dealer) {
  // 로그인이 필요한 url 에 로그인 없이 접근하면 e=401 파리미터를 가지고 /login 으로 오는데 그때에 대한 처리
  if (!_.isEmpty($stateParams)) {
    if ($stateParams.e === '401') {
      $scope.error = '<div class="alert alert-warning"><i class="fa fa-lg fa-warning"></i>&nbsp;&nbsp;You must log in to access this page.</div>';
    }
  }

  // 이미 로그인한 사용자면 system-overview 메뉴로 이동시킴
  Auth.currentUser().then(function(user) {
    if(user) {
      $state.go('menu.system-overview');
    }
  });

  // dealer 로그인인지 검사
  $scope.dealerLogin = false;
  $scope.$watch('credentials.username', function (newVal, oldVal) {
    if (newVal && newVal.match('@')) {
      $scope.dealerLogin = true;
    } else {
      $scope.dealerLogin = false;
    }
  });

  // 로그인 화면에서 아이디/패스워드 입력 후 Sign in 버튼 클릭하면 실행되는 함수
	$scope.login = function() {
		var jsonData = JSON.stringify( $scope.credentials );  // 아이디/패스워드
		console.log(jsonData);

    // dealer 로그인과 일반 사용자 로그인을 구분
    // dealer
    if ($scope.dealerLogin) {
      Dealer.login(jsonData)
        .then( function(data) {
          if(data.result) {
            // dealer company 불러오기
            $rootScope.dealerCompany = Dealer.getDealerCompany();

            $state.go('dealer-jobs-list');
          } else {
            toastr.error(data.error);
          }
        })
        .catch(toastr.error);
    }
    // 일반 사용자
    else {
      // system-select 화면에서 dealer 에게 assign 된 system 인 경우 user-login-change 로 보내기 위해서 sessionStorage 에 저장
      sessionStorage.setItem('credentials', jsonData);

      // 로그인
      User.login(jsonData)
        .then( function(data) {
          if(data.result) {
            if (data.status) {  // result=true, status=true 일 때 로그인 처리
              if (data.systems.length) {  // 등록된 system 이 있는 경우
                Systems.loadSystems(data.systems);
                $state.go('system-select');
              } else {  // 등록된 system 이 없는 경우
                $scope.loginForm.$setPristine();
                $scope.credentials.password = '';
                toastr.warning('It seems you do not have any systems registered on your account. Please register one <a href="/#/register">here</a>.', 'Warning', { allowHtml: true });
              }
            } else {  // result=true, status=false 인 경우: forgot password 로 reset 했는데 base station 이 없거나 통신문제가 발생한 경우
              $rootScope.systemsInfo = angular.copy(data.info);
              $rootScope.credentials = angular.copy($scope.credentials);
              $state.go('ignore-offline-systems');
            }
          } else {
            if (data.code === 'ACCESS_DENY') {
              window.location = '/user-login-change#/auto-login';
            } else {
              toastr.error(data.error);
              $scope.credentials.password = '';
              $scope.loginForm.$setPristine();
            }
          }
        })
        .catch(toastr.error);
    }
	};

});

/**
 * @ngdoc controller
 * @name IgnoreOfflineController
 * @description
 *  forgot password 로 reset 했는데 base station 이 없거나 통신문제가 발생한 경우의 로그인 처리
 */
app.controller('IgnoreOfflineController', function($rootScope, $scope, $state, $stateParams, $modal, toastr, User, Systems) {
  // LoginController 에서 IgnoreOfflineController 로 데이터를 전달하기 위해 $rootScope 를 사용하였으나 전달이 끝나면 $rootScope 의 프로퍼티를 삭제
  $scope.systemsInfo = angular.copy($rootScope.systemsInfo);
  $scope.credentials = angular.copy($rootScope.credentials);
  delete($rootScope.systemsInfo);
  delete($rootScope.credentials);

  $scope.forceIgnore = false;
  $scope.ignore = false;
  $scope.processing = false;

  _.each($scope.systemInfo, function(obj) {
    if (obj.connection == 2) {  // 2의 값이 하나라도 나온 경우는 system들이 복구가 안되는 상황이므로 반드시 ignore 하여 로그인해야함
      $scope.forceIgnore = true;
      $scope.ignore = true;
    }
  });

  $scope.goBack = function() {
    $state.go('login');
  };

  $scope.doNext = function() {
    var modal = $modal({
      scope: $scope,
      template: 'views/modal-tpls/ignore-offline.html',
      container: 'body',
      show: false
    });
    modal.$promise.then(modal.show);
  };

  $scope.reset = function() {
    if ($scope.ignore) {  // ignore 에 체크한 경우 bstationChk=0 값을 넣어서 로그인
      $scope.credentials.bstationChk = 0;
    }

    $scope.processing = true;
    login($scope.credentials);
  };

  function login(credentials) {
    var jsonData = JSON.stringify(credentials);

    User.login(jsonData)
      .then( function(data) {
        if(data.result) {
          if (data.status) {
            if (data.systems.length) {
              Systems.loadSystems(data.systems);
              $state.go('system-select');
            } else {
              toastr.warning('It seems you do not have any systems registered on your account. Please register one <a href="/#/register">here</a>.', 'Warning', { allowHtml: true });
            }
          } else {
            $rootScope.systemsInfo = angular.copy(data.info);
            $rootScope.credentials = angular.copy($scope.credentials);
            $state.go('ignore-offline-systems', {}, {reload: true});
          }
        } else {
          toastr.error(data.error);
        }

        $scope.processing = false;
      })
      .catch(toastr.error);
  }
});

/**
 * @ngdoc controller
 * @name IgnoreOfflineCreateController
 * @description
 *  forgot password 로 reset 했는데 base station 이 없거나 통신문제가 발생한 경우의 system 생성을 위한 로그인 처리
 */
app.controller('IgnoreOfflineCreateController', function($rootScope, $scope, $state, $stateParams, $modal, toastr, User, Registration) {
  // RegisterController 에서 IgnoreOfflineController 로 데이터를 전달하기 위해 $rootScope 를 사용하였으나 전달이 끝나면 $rootScope 의 프로퍼티를 삭제
  $scope.systemsInfo = angular.copy($rootScope.systemsInfo);
  $scope.credentials = angular.copy($rootScope.credentials);
  delete($rootScope.systemsInfo);
  delete($rootScope.credentials);

  $scope.forceIgnore = false;
  $scope.ignore = false;
  $scope.processing = false;

  _.each($scope.systemInfo, function(obj) {
    if (obj.connection == 2) {  // 2의 값이 하나라도 나온 경우는 system들이 복구가 안되는 상황이므로 반드시 ignore 하여 로그인해야함
      $scope.forceIgnore = true;
      $scope.ignore = true;
    }
  });

  $scope.goBack = function() {
    $state.go('login');
  };

  $scope.doNext = function() {
    var modal = $modal({
      scope: $scope,
      template: 'views/modal-tpls/ignore-offline.html',
      container: 'body',
      show: false
    });
    modal.$promise.then(modal.show);
  };

  $scope.reset = function() {
    if ($scope.ignore) {  // ignore 에 체크한 경우 bstationChk=0 값을 넣어서 로그인
      $scope.credentials.bstationChk = 0;
    }

    $scope.processing = true;
    loginForCreate($scope.credentials);
  };

  function loginForCreate(credentials) {
    var jsonData = JSON.stringify(credentials);

    User.loginForCreate(jsonData).then(function(data) {
      if(data.result) {
        if (data.status) {
          Registration.setSystemKey($scope.credentials.key);
          Registration.setBStationMac(data.mac);
          Registration.setSystemType($scope.credentials.modelType);

          $state.go('add-new-system');
        } else {
          $rootScope.systemsInfo = angular.copy(data.info);
          $rootScope.credentials = angular.copy($scope.credentials);
          $state.go('ignore-offline-systems-for-create', {}, {reload: true});
        }
      } else {
        toastr.error(data.error);
      }

      $scope.processing = false;
    }).catch(toastr.error);
  }
});

/**
 * @ngdoc controller
 * @name ForgotController
 * @description
 *  로그인 화면 하단의 "Forgot your password?" 를 클릭해서 들어온 경우 password reset 처리
 */
app.controller('ForgotController', function ($scope, $state, toastr, Auth, User){
  $scope.forgot = {};

  // 로그인 된 상태에서 접근하면 system-overview 로 이동
  Auth.currentUser().then(function(user) {
    if(user) {
      $state.go('menu.system-overview');
    }
  });

  $scope.resetPassword = function() {

    var jsonData = JSON.stringify( $scope.forgot );
    console.log(jsonData);

    // reset password
    User.resetPassword($scope.forgot)
      .then(function() {
        toastr.success('Your password has been reset.');
        $state.go('login');
      })
      .catch(toastr.error);
    
  };
});

'use strict';
/**
 * @ngdoc controller
 * @name MainMenuLayoutController
 * @description
 *  entertainment main screen layout 편집 화면
 */
app.controller('MainMenuLayoutController', function ($rootScope, $scope, $state, $filter, $timeout, toastr, Rooms, Systems, Devices) {
	// scheduled event 기능을 eng, alpha 버전에서만 보이게 하기 위한 처리
	if ($rootScope.version.substr(-1) === 'e' || $rootScope.version.substr(-1) === 'a') {
		$scope.isAlpha = true;
	} else {
		$scope.isAlpha = false;
	}

	$scope.mainMenu.changingIcon = false;
	$scope.mainMenu.mainDevice.btns = [];
	$scope.mainMenu.mainDevice.id = Systems.getMainDevice().id;

	$scope.mainMenu.showBtnsType = 'devices';  // devices/events

	// icon 목록이 있는 json 파일로부터 데이터 얻기
	Devices.getInfoJson().success(function (data) {
		Devices.setIcons(data);
		$scope.mainMenu.deviceIcons = Devices.getIcons();

		console.log($scope.mainMenu.deviceIcons);
	}).error(function () {

	});

	// (1) mainDevice btns

	var btnIndexOffset = 0;

	_.forEach(Systems.getMainDevice().pages, function(page) {
		 _.forEach(page.btns, function(btn) {
			console.log(btn);
			btn.hidden_option = btn.hidden_option ? true:false;
			btn.hidden = btn.hidden ? true:false;
			btn.page_btn_idx += btnIndexOffset;
			$scope.mainMenu.mainDevice.btns.push(btn);
		 });
		 btnIndexOffset += 6;
	});

	$scope.mainMenu.mainDevice.btns = _($scope.mainMenu.mainDevice.btns).sortBy('page_btn_idx').value();
	console.log($scope.mainMenu.mainDevice.btns);

	$scope.deleteDevice = function (btn) {
		_.remove($scope.mainMenu.mainDevice.btns, { id: btn.id });
	};

	$scope.makeCopy = function(obj) {
		return angular.copy(obj);
	};

	$scope.isEmpty = function(obj) {
		return _.isEmpty(obj);
	};


	$scope.switchToImageView = function() {
		$scope.mainMenu.selectedImgName = angular.copy($scope.mainMenu.selectedBtn.image_name);
		$scope.mainMenu.changingIcon = true;
	};
	
	$scope.saveImage = function() {
		$scope.mainMenu.selectedBtn.image_name = angular.copy($scope.mainMenu.selectedImgName);
		$scope.mainMenu.changingIcon = false;
	};

	$scope.replaceButton = function (btnId) {
		var idx = _.findIndex($scope.mainMenu.mainDevice.btns, {'id': btnId});
		$scope.mainMenu.mainDevice.btns[idx] = $scope.mainMenu.selectedBtn;
	};

	$scope.clearSelectedBtn = function() {
		$timeout(function() {
				$scope.mainMenu.selectedBtn = {};
		}, 200);
	};

	// (2) scheduled events

	// scheduled event 목록 얻기
	Rooms.getEvents(Systems.getCurrentSystem().id, $scope.mainMenu.room.id).then(function(data) {
		$scope.mainMenu.scheEvents = data;

    _.forEach($scope.mainMenu.scheEvents, function(event) {
      event.hidden_option = event.hidden_option ? true:false;
      event.hidden = event.hidden ? true:false;
    });
	}).catch(function(error) {
		alert(error);
	});

	$scope.deleteEvent = function (event) {
		_.remove($scope.mainMenu.scheEvents, { id: event.id });

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

		Rooms.deleteEvent(Systems.getCurrentSystem().id, $scope.mainMenu.room.id, jsonData)
			.then(function(data) {
				Systems.updateSystem(Systems.getCurrentSystem().id);
			})
			.catch(toastr.error);
	};

	$scope.switchToEventImageView = function() {
		$scope.mainMenu.selectedEventImgName = angular.copy($scope.mainMenu.selectedEvent.image_name);
		$scope.mainMenu.changingEventIcon = true;
	};

	$scope.saveEventImage = function() {
		$scope.mainMenu.selectedEvent.image_name = angular.copy($scope.mainMenu.selectedEventImgName);
		$scope.mainMenu.changingEventIcon = false;
	};

	$scope.replaceEvent = function (eventId) {
		var idx = _.findIndex($scope.mainMenu.scheEvents, {'id': eventId});
		$scope.mainMenu.scheEvents[idx] = $scope.mainMenu.selectedEvent;
	};

	$scope.clearSelectedEvent = function() {
		$timeout(function() {
			$scope.mainMenu.selectedEvent = {};
		}, 200);
	};

	// (3) 공통

	$scope.finish = function() {
		if ($scope.mainMenu.showBtnsType === 'devices') {
			var numPages = Math.ceil($scope.mainMenu.mainDevice.btns.length / 6);
			var pages = [];

			for (var pageId = 0; pageId < numPages; pageId++ ) {
				var page = {id: pageId};
				var start = pageId * 6;

				page.btns = $scope.mainMenu.mainDevice.btns.slice(start, start+6);
				for (var index = 0; index < page.btns.length; index++) {
					page.btns[index].page_btn_idx = index;
					page.btns[index].hidden_option = page.btns[index].hidden_option ? 1 : 0;
					page.btns[index].hidden = page.btns[index].hidden ? 1 : 0;
					console.log('finish- page.btn=', page.btns[index])
				}
				pages.push(page);
			}
			console.log(pages);

			Systems.setMainDevice({id: $scope.mainMenu.mainDevice.id, pages: pages});

			// main device 정보 서버에 저장
			Systems.storeMainDevice($scope.mainMenu.room.id).then(function(data) {
				// system 정보 얻어와서 저장
				Systems.updateSystem(Systems.getCurrentSystem().id).then(
					function (data) {
						console.log(data);
						$state.transitionTo($state.current, null, { reload: true, inherit: true, notify: true  });
					},
					function (error) {
						alert(error);
					}
				);

			}, function(error) {
				alert(error);
			});
		} else if ($scope.mainMenu.showBtnsType === 'events') {
			_.forEach($scope.mainMenu.scheEvents, function(event, i) {
				event.hidden_option = event.hidden_option ? 1 : 0;
				event.hidden = event.hidden ? 1 : 0;
				event.order = i;
			});

			var jsonData = JSON.stringify({data: $scope.mainMenu.scheEvents});

			Rooms.storeEvents(Systems.getCurrentSystem().id, $scope.mainMenu.room.id, jsonData).then(function(data) {
				Systems.updateSystem(Systems.getCurrentSystem().id).then(
					function (data) {
						console.log(data);
						$state.transitionTo($state.current, null, { reload: true, inherit: true, notify: true  });
					},
					function (error) {
						alert(error);
					}
				);
			}, function(error) {
				alert(error);
			});
		}

	};
});

'use strict';
/**
 * @ngdoc controller
 * @name PowerOffController
 * @description
 *  power off 설정 화면 (아래 controller 들의 state 를 포함하는 state 의 controller)
 */
app.controller('PowerOffController',  function ($scope, room, Devices) {
  Devices.initFunctions();
  $scope.powerOff = { 'devices': [], 'device': {} };
  $scope.powerOff.index = 0;

  $scope.room = room;
});

/**
 * @ngdoc controller
 * @name PowerOffDevicesController
 * @description
 *  device 선택 화면
 */
app.controller('PowerOffDevicesController', function ($scope, $state, $http, Systems, Devices, Auth, currentMacro) {

  var currentSystem = Systems.getCurrentSystem(),
       dataActivity = currentMacro;
  console.log(dataActivity);

  if(dataActivity && dataActivity.edit_type === 0 && dataActivity.activity.length ) {
    _.forEach(dataActivity.activity, function(data) {
      var device = Systems.getDevice($scope.room.id, data.device_id);

      if (device) {
        $scope.powerOff.devices.push({
          'device_id': data.device_id,
          'name': device.name,
          'type': data.type,
          'func': data.func,
          'repeat_min': device.repeat_min,
          'repeat_macro': device.repeat_macro,
          'target_type': device.target_type,
          'target_addr': device.target_addr,
          'target_port': device.target_port
        });
      }
    });
  }
  // else {
  //   _.forEach($scope.room.devices, function(device) {
  //     if ( _.isEmpty($scope.powerOff.devices)) {
  //       $scope.powerOff.devices.push({
  //         'device_id': device.id,
  //         'name': device.name,
  //         'type': 0,
  //         'func': null,
  //         'repeat_min': device.repeat_min,
  //         'repeat_macro': device.repeat_macro,
  //         'target_type': device.target_type,
  //         'target_addr': device.target_addr,
  //         'target_port': device.target_port,
  //       });
  //     }
  //   });
  // }

  $scope.doNext = function() {

    $state.go('menu.programming.power-off.commands');
  };

  Auth.currentUser().then(function(user) {
    $scope.optMenuShow = user.optMenuShow;
  });

  $scope.goAdvanced = function() {
    $state.go('menu.advanced.add-macros.macro-type');
  };

});

/**
 * @ngdoc controller
 * @name PowerOffDeviceCommandsController
 * @description
 *  command 선택 화면
 */
app.controller('PowerOffDeviceCommandsController', function ($scope, $state, Systems, Devices) {

  $scope.goBack = function() {
    if ($scope.powerOff.index === 0) {
      $scope.powerOff.devices = [];
      Devices.initFunctions();
      $state.go('menu.programming.power-off.devices-to-use' );
    } else {
      $scope.powerOff.index--;
    }
  };


  $scope.incrIdx = function() { $scope.powerOff.index++; };

  $scope.finish = function() {
    //Save to server

    var sendData = angular.copy($scope.powerOff.devices);

    for (var i=0,  tot=sendData.length; i < tot; i++) {
      sendData[i].func = sendData[i].func.id;
      delete sendData[i].name;
      delete sendData[i].repeat_min;
      delete sendData[i].repeat_macro;
      delete sendData[i].target_type;
      delete sendData[i].target_addr;
      delete sendData[i].target_port;
      delete sendData[i].funcs;
    }

    var jsonData = JSON.stringify( { auto_wait : 1, edit_type : 0, popup : 1, activity : sendData, macro : [] } );
    console.log(jsonData);

    // 해당 room 의 power macro 데이터 저장
    Systems.storePowerMacro($scope.room.id, jsonData).then(function(response) {
      if(response.data.result === true) {
        $state.go('menu.programming.options');
      }
      else {
        alert('Your edit/create action failed. Please try again.');
      }
    }, function(error){
      alert("Please try again");
    });
  };

});

'use strict';
/**
 * @ngdoc controller
 * @name RegisterController
 * @description
 *  새로운 system 을 등록
 */
app.controller('RegisterController', function ($rootScope, $scope, $state, toastr, availableModels, Registration, Auth, User) {

  // 로그인 된 상태에서 접근하면 system-overview 로 이동
  Auth.currentUser().then(function(user) {
    if(user) {
      $state.go('menu.system-overview');
    }
  });

  // 초기값 설정
  $scope.register = {
    option: 'existing',   // existing account 로 생성
    modelType: availableModels[0]
  };
  $scope.availableModels = availableModels;

  $scope.doNext = function() {
    var key = $scope.register.key.first + $scope.register.key.second + $scope.register.key.third + $scope.register.key.fourth,
        key = key.toUpperCase(),
        type = $scope.register.modelType;
    console.log(key);

		if ($scope.register.option === 'create') {    // 사용자 생성을 하면서 system 생성
      Registration.setSystemKey(key);
      Registration.setSystemType(type);
			$state.go('send-email');
		} else if ($scope.register.option === 'existing') {   // existing account 로 로그인 하면서 system 생성

			var jsonData = JSON.stringify({ key: key, modelType: type, username: $scope.register.username, password: $scope.register.password });
			console.log(jsonData);

      // 시스템 생성을 위한 로그인
			User.loginForCreate(jsonData).then(function(data) {
				if(data.result) {
          if (data.status) {  // result 와 status 가 모두 true 일 때
            Registration.setSystemKey(key);
            Registration.setBStationMac(data.mac);
            Registration.setSystemType(type);

            $state.go('add-new-system');
          } else {  // status=false: forgot password 로 reset 했는데 base station 이 없거나 통신문제가 발생한 경우
            $rootScope.systemsInfo = angular.copy(data.info);
            $rootScope.credentials = {
              key: key,
              modelType: type,
              username: $scope.register.username,
              password: $scope.register.password
            };
            $state.go('ignore-offline-systems-for-create');
          }
				} else {
					toastr.error(data.error);
          $scope.register.password = '';
          $scope.registerForm.$setPristine();
				}
			}).catch(toastr.error);
		} 
	};
});

/**
 * @ngdoc controller
 * @name SendEmailController
 * @description
 *  사용자 등록시 temporary password 발송
 */
app.controller('SendEmailController', function ($scope, $state, toastr, Registration, Auth) {

  // 로그인 된 상태에서 접근하면 system-overview 로 이동
  Auth.currentUser().then(function(user) {
    if(user) {
      $state.go('menu.system-overview');
    }
  });

	var keyData = Registration.getSystemKey(),
      type = Registration.getSystemType();

	$scope.doNext = function() {

		var emailData = $scope.email;

		var jsonData = JSON.stringify( { modelType: type, key: keyData, email: emailData });
		console.log(jsonData);

    // 사용자 등록시 temporary password 를 요청한 email 로 보내기
    Registration.sendTempPswd(jsonData).then(function(data) {
      Registration.setEmail(emailData);
      $state.go('add-user');
    })
    .catch(toastr.error);
	};
});



app.controller('AddUserController', function ($scope, $timeout, $state, toastr, Registration, Auth, User) {

  // 로그인 된 상태에서 접근하면 system-overview 로 이동
  Auth.currentUser().then(function(user) {
    if(user) {
      $state.go('menu.system-overview');
    }
  });

  $scope.doNext = function() {
		var user = {};
  	user.username = $scope.user.username;
		user.password = $scope.user.password;
		user.tempPassword = $scope.user.tempPassword;
		user.userEmail = $scope.user.email;
		user.email = Registration.getEmail();
		user.key = Registration.getSystemKey();
		user.modelType = Registration.getSystemType();

		var jsonData = JSON.stringify(user);
		console.log(jsonData);

		User.create(jsonData).
			then(function(data) {
				Registration.setBStationMac(data.mac);
        
        $timeout(function() {
          $state.go('add-new-system');  
        }, 500);
        		
			}).
			catch(toastr.error);
	};
});

/**
 * @ngdoc controller
 * @name AddNewSystemController
 * @description
 *  사용자 생성
 */
app.controller('AddNewSystemController', function ($scope, $state, toastr, timeZones, Registration, Systems) {

  $scope.baseStationMac = Registration.getBStationMac();
  $scope.timeZones = timeZones;
  $scope.system = {};
  $scope.system.timezone_dst = true;
  $scope.timeFormat = 'hh:mm:ss a';
  //$scope.system.timeZone = null;

  // DST: daylight saving time true/false 설정
  $scope.checkDST = function() {
    if ($scope.system.timeZone.s_time === '0.0.0 00:00:00') {
      $scope.system.timezone_dst = false;
    } else {
      $scope.system.timezone_dst = true;
    }
  };

 	$scope.doNext = function() {

 		var systemName = $scope.system.name,
          roomName = $scope.system.roomName,
   customerAddress = $scope.system.customerAddress,
     customerPhone = $scope.system.customerPhone,
      customerName = $scope.system.customerName,
     installerName = $scope.system.installerName,
           macAddr = Registration.getBStationMac(),
           keyData = Registration.getSystemKey(),
              type = Registration.getSystemType();

		var jsonData = JSON.stringify( { systemName: systemName, 
                                      modelType: type, 
                                      key: keyData,
                                      timezone_id:  $scope.system.timeZone.id,
                                      timezone_dst: $scope.system.timezone_dst ? 1:0,
                                      time_type: $scope.timeFormat === 'hh:mm:ss a' ? 0:1 ,
                                      roomName: roomName,
                                      customerAddress: customerAddress,
                                      customerPhone: customerPhone,
                                      customerName: customerName,
                                      installerName: installerName,
                                      bstationMac: macAddr, 
                                      bstationName: type + ' ' + macAddr.slice(10,12)  } );

		console.log(jsonData);

    // system 생성
	  Systems.createOne(jsonData)
      .then(function(data) {
  			return Systems.fetch();
      })
      .then(function(data) {
        $state.go('system-select');
      })
      .catch(function(error) {
        toastr.error(error, 'Error');
      });
	};
});

'use strict';


app.controller('SystemSelectController', function ($scope, $state, $modal, toastr, resolvedSystems, Devices, Systems) {

  	$scope.systems = resolvedSystems;

    $scope.doNext = function(){
      Systems.setCurrentRoom(null);

      var selectedSystem = _.findWhere($scope.systems, {
        id: $scope.choice
      });

      // dealer 에게 assign 된 system 인 경우
      if (selectedSystem.dealer_id) {
        // user-login-change 로 이동시킴
        window.location = '/user-login-change#/auto-login/' + $scope.choice + '/' + selectedSystem.dealer_id;
      }
      // 일반 system
      else {
        return Systems.updateSystem($scope.choice).then(
          function (data) {
            var masterBstation;
            _.each(data.rooms, function(room) {
              if (!masterBstation) {
                masterBstation = _.where(room.bstations, {
                  master: 1
                })[0];
              }
            });
            if (!masterBstation) {
              $state.go('recovery-bstation', {rooms: angular.toJson(data.rooms)});
              return;
            }

            // TRF-ZW data update
            _.each(data.rooms, function(room) {
              var trfzw = _.find(room.twoway_devices, {model: 'TRF-ZW1'});
              if (trfzw) {
                Devices.updateTwowayDevice(room.id, trfzw.id)
                  .then(function(data) {
                    trfzw.data = data;
                  }, function() {
                    var modal = $modal({
                      container: '.editor-container',
                      template: 'views/modal-tpls/connection-problem.html',
                      show: false
                    });

                    modal.$promise.then(modal.show);
                  })
                  .catch(toastr.error);

                return false;
              }
            });

            $state.go('menu.system-overview');
          },
          function (error) {
            toastr.error(error);
          }
        );
      }
    };

});

/**
 * @ngdoc controller
 * @name SystemDeleteController
 * @description
 *  system 목록 표시, system 삭제 화면
 */
app.controller('SystemDeleteController', function ($rootScope, $scope, $state, toastr, resolvedSystems, Systems, User) {

    var currentSystemId = Systems.getCurrentSystem().id;
  $scope.currentSystemId = currentSystemId;

    $scope.systems = resolvedSystems;
    $scope.sysToDel = {};

    $scope.deleteSystem = function(){

      // system 삭제
      Systems.deleteSystem($scope.sysToDel.id).then(function (data) {
          // dealer 로그인 상태이면서 삭제하려는 system 이 현재 system 인 경우
          if ($rootScope.dealerCompany && currentSystemId === $scope.sysToDel.id) {
            $state.go('dealer-jobs-list');
          } else {
            // 남은 system 이 없는 경우 system 등록 화면으로 이동
            if (Systems.getAll().length === 0) {
              User.logout().then(function () {
                $state.transitionTo('register', null, {reload: true, inherit: true, notify: true});
              });
            }
            // 삭제한 system 이 현재 system 이었던 경우 system 선택 화면으로 이동
            else if (currentSystemId === $scope.sysToDel.id) {
              $state.go('system-select');
            }
            // 삭제한 system 이 현재 system 이 아니었던 경우 현재 system 의 home overview 화면으로 이동
            else {
              $state.go('menu.system-overview');
            }
          }
        },
        function (error) {
          toastr.error(error);
        }
      );
    };

});

/**
 * @ngdoc controller
 * @name SystemSettingsController
 * @description
 *  system 설정 메인 화면
 */
app.controller('SystemSettingsController', function ($scope, $modal, $http, $window, timeZones, currentSystem, Auth) {

  $scope.system = currentSystem;
  $scope.timeZones = timeZones;

  $scope.factoryUser = false;

  $scope.currentUser = JSON.parse($window.localStorage.getItem('hcm_editor'));

  // 현재 로그인한 사용자가 factory_user.json 에 있는지 검사
  $http.get('/scripts/factory_user.json')
    .success(function(response) {
      if (response && response.users) {
        Auth.currentUser().then(function(user) {
          if (response.users.indexOf(user.username) > -1) {
            $scope.factoryUser = true;
          }
        });
      }
    });

});

/**
 * @ngdoc controller
 * @name ChangeMasterFromFactoryController
 * @description
 *  factory master change 화면
 */
app.controller('ChangeMasterFromFactoryController', function ($rootScope, $scope, $state, toastr, searchResults, Systems) {
  $scope.baseStations = searchResults.searchedDevices;
  $scope.bsReplace = {};

  var systemId = Systems.getCurrentSystem().id;

  var orgMac = Systems.getCurrentSystem().rooms[0].bstations[0].mac;

  $scope.doNext = function() {
    var jsonData = JSON.stringify({ modelType: $scope.bsReplace.target.name, mac: $scope.bsReplace.target.mac, org_mac: orgMac });
    Systems.changeMasterFromFactory(systemId, jsonData)
      .then(function(data) {
        Systems.updateSystem(systemId).then(function () {
          $state.go('system-settings.change-master-from-factory-success');
        });
      })
      .catch(toastr.error);
  };
});

app.controller('ChangeMasterFromFactorySuccessController', function ($rootScope, $scope, $state) {
  $scope.doNext = function() {
    $state.go('system-settings.main');
  };
});

/**
 * @ngdoc controller
 * @name ReplaceMainController
 * @description
 *  변경할 base station 선택 화면
 */
app.controller('ReplaceMainController', function  ($scope, $state){

  $scope.doNext = function () {
    if ($scope.bsReplace.selection.master) {
      $state.go('system-settings.replace.master');
    } else {
      $state.go('system-settings.replace.slave');
    }
  };
});

app.controller('ReplaceMasterController', function  ($rootScope, $scope, $state, Systems, availableModels){
  $scope.bsReplace.modelType = availableModels[0];
  $scope.availableModels = availableModels;


  $scope.doNext = function () {
    var key = $scope.bsReplace.key.first + $scope.bsReplace.key.second + $scope.bsReplace.key.third + $scope.bsReplace.key.fourth,
        key = key.toUpperCase(),
        type = $scope.bsReplace.modelType,
        jsonData = JSON.stringify({ modelType: type, key: key});

    console.log(jsonData);
    Systems.checkKey(jsonData).then(function(data) {
      console.log(data);
      $scope.bsReplace.target = data;
      $state.go('system-settings.replace.target');
    })
    .catch(function(error) {
      alert(error);
    });
  };
  
});

app.controller('ReplaceSlaveController', function  ($rootScope, $scope, $state, searchResults){
  $scope.baseStations = searchResults.searchedDevices;

  $scope.bsType = 'BASESTATIONS';

  $scope.doNext = function () {
    //$scope.bsReplace.target = angular.copy($scope.bsReplace.bsSelect);
    $state.go('system-settings.replace.target');
  };
});

app.controller('ReplaceTargetController', function  ($scope, $state, toastr, Systems, Rooms){
  // base station 이름 변경: modelType + macAddress 맨 끝 2자리 ex) HS-C100 EE
  function editBstation() {
    var roomId,
      bstation = {},
      orgMac = $scope.bsReplace.selection.mac,
      mac,
      type;

    _.each($scope.system.rooms, function(room) {
      _.each(room.bstations, function(bstation) {
        if (bstation.mac == orgMac) {
          roomId = room.id;
        }
      });
    });

    if ($scope.bsReplace.selection.master) {
      mac = $scope.bsReplace.key.first + $scope.bsReplace.key.second + $scope.bsReplace.key.third + $scope.bsReplace.key.fourth;
      mac = mac.toUpperCase();
      mac = mac.substr(4);
      type = $scope.bsReplace.modelType;
    } else {
      mac = $scope.bsReplace.target.mac;
      type = $scope.bsReplace.target.name;
    }

    bstation.mac = mac;
    bstation.type = type;
    bstation.name = type + ' ' + mac.substr(10);
    bstation.light_level = 2;

    var jsonData = JSON.stringify( { name : bstation.name, mac: bstation.mac, type: bstation.type, lightLevel: bstation.light_level } );
    // base station 의 type, name, lightLevel 을 설정

    Rooms.baseStations('edit', roomId, jsonData).
      then(function(data) {

      }).
      catch(toastr.error);
  }

  var changeMaster = function(json) {
    return Systems.changeMaster(json).then(function(data) { 
      return Systems.getCurrentSystem().id;
    });
  };

  var changeSlave = function(json) {
    return Systems.changeSlave(json).then(function(data) { 
      return Systems.getCurrentSystem().id;
    });
  };

  var updateSystem = function(id) {
    editBstation();

    return Systems.updateSystem(id).then(function (data) {
      console.log(data);
      return $state.transitionTo('system-settings.replace.prompt', {}, { reload: true, inherit: true, notify: true  });
    });
  };


  $scope.replace = function () {

    if ($scope.bsReplace.selection.master) {
      var key = $scope.bsReplace.key.first + $scope.bsReplace.key.second + $scope.bsReplace.key.third + $scope.bsReplace.key.fourth,
          key = key.toUpperCase(),
          type = $scope.bsReplace.modelType;


      changeMaster(JSON.stringify({ org_mac: $scope.bsReplace.selection.mac, modelType: type, key: key}))
        .then(updateSystem)
        .catch(function (error) {
          alert(error);
        });
      

    } else {

      changeSlave(JSON.stringify({ org_mac: $scope.bsReplace.selection.mac, new_mac: $scope.bsReplace.target.mac, modelType: $scope.bsReplace.target.name }))
        .then(updateSystem)
        .catch(function (error) {
          alert(error);
        });
    }
    
  };
});

app.controller('ReplacePromptController', function  ($scope, $state){
  
});

/**
 * @ngdoc controller
 * @name SystemOverviewController
 * @description
 *  system overview 화면
 */
app.controller('SystemOverviewController', function ($rootScope, $scope, $http, $modal, $popover, $state, toastr, types, Systems, Rooms, Database, Devices) {
  $scope.types = types;

  // scheduled event 기능을 eng, alpha 버전에서만 보이게 하기 위한 처리
  if ($rootScope.version.substr(-1) === 'e' || $rootScope.version.substr(-1) === 'a') {
    $scope.isAlpha = true;
  } else {
    $scope.isAlpha = false;
  }

  $scope.system = Systems.getCurrentSystem();
  $scope.selections = { 'selectedRoom': {}, 'selectedBstation': {}, 'selectedRemote': {}, 'selectedDevice': {}};

  var favoriteOptionModal = $modal({
    scope: $scope,
    title: 'Add Favorite Channels to this device',
    placement: 'top',
    template: 'views/modal-tpls/system-overview/fav-option.html',
    container: '#system-overview',
    show: false
  });

  $scope.popover = { 'device': '', 'twowayDevice': ''};

  $scope.findPunchDevice = function(room) {
    $scope.popover.punchName = _.find(room.devices, { 'id': $scope.popover.device.punch_vol }).name;
  };

  $scope.findPunchTwowayDevice = function(room) {
    var trfzw = _.find($scope.system.rooms[0].twoway_devices, {model: 'TRF-ZW1'}),
      item = _.find(trfzw.extra_info.punch, {roomId: room.id});

    $scope.popover.punchName = _.find(room.devices, { 'id': item.from }) ? _.find(room.devices, { 'id': item.from }).name : '';
  };

  $scope.containsMaster = function(room) {
    return _.contains(_.pluck(room.bstations, 'master'), 1);
  };

  $scope.changeValue = function(value) {
    return value/1000;
  };

  $scope.isEntDevice = Database.checkIfEntertainment;

  $scope.showFavModal = function (room, device) {
    angular.copy(room, $scope.selections.selectedRoom);
    angular.copy(device, $scope.selections.selectedDevice);

    favoriteOptionModal.$promise.then(favoriteOptionModal.show);
  };


  $scope.toggleFavorite = function(room, device) {
    var currentSystem = Systems.getCurrentSystem(),
            roomIndex = _.findIndex(currentSystem.rooms, { 'id': room.id }),
          deviceIndex = _.findIndex(currentSystem.rooms[roomIndex].devices, { 'id': device.id }),
        currentDevice = currentSystem.rooms[roomIndex].devices[deviceIndex];

    if (!_.isEqual(currentDevice, device)) {
      var jsonData =  { "favOption": device.fav_option, "favDelay": device.fav_delay, "favEnter": device.fav_enter  };
      console.log(jsonData);

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

      // favorite option 변경 API 호출
      $http({
        method: 'POST',
        url: url,
        data : jsonData
      }).
      success(function(data) {
        if(data.result) {
          currentDevice.fav_option = device.fav_option;
          currentDevice.fav_delay = device.fav_delay;
          currentDevice.fav_enter = device.fav_enter;
          Systems.loadSystem(currentSystem);
          $state.transitionTo($state.current, null, { reload: true, inherit: true, notify: true  });
        }
        else {
          toastr.error(data.error);
        }
      })
      .error(function(error) {
        toastr.error('Please try again');
      });
    }

  };

  $scope.changeEventState = function(systemId, roomId, eventId, defaultState) {
    if (defaultState) {
      defaultState = 1;
    } else {
      defaultState = 0;
    }

    var jsonData = JSON.stringify({ id: eventId, default_state: defaultState });
    Rooms.changeEventState(systemId, roomId, jsonData)
      .then(function(data) {
        Systems.updateSystem(systemId).then(function () {
        });
      })
      .catch(toastr.error);
  };

  Rooms.disableScheEventEdit();
  Rooms.setScheEventData(null);

  $scope.eventEdit = function(room, event) {
    Rooms.enableScheEventEdit();

    Rooms.setScheEventData({
      room: angular.copy(room),
      event: angular.copy(event)
    });

    $state.go('menu.advanced.add-macros.sche-event-edit');
  };
  
});

'use strict';
/**
 * @ngdoc controller
 * @name PunchToDeviceController
 * @description
 *  punch to device 선택 화면
 */
app.controller('PunchToDeviceController', function ($scope, $state, deviceId) {
  $scope.checkPunchTo = function(id) {
    var index = $scope.volumeControl.punchTo.indexOf(id);

    if (index < 0) {
      $scope.volumeControl.punchTo.push(id);
    } else {
      $scope.volumeControl.punchTo.splice(index, 1);
    }

    $scope.volumeControl.punchTo.sort(function(a, b) {
      return a - b;
    });
  };

  $scope.doNext = function() {
    $state.go('menu.programming.volume-control.punch-from-device');
  };
});

/**
 * @ngdoc controller
 * @name PunchFromDeviceController
 * @description
 *  punch from device 선택 화면
 */
app.controller('PunchFromDeviceController', function ($rootScope, $scope, $state, $http, Systems) {
  $scope.volumeControl.punchToNames = [];

  _.each($scope.volumeControl.punchTo, function(id) {
    var name = _.findWhere($scope.volumeControl.devices.destination, {
      id: id
    })['name'];

    $scope.volumeControl.punchToNames.push(name);
  });


  
  // punch to 에서 선택되었는지 검사
  function currentlySelected(punchFromId) {
    var selected = false;

    if ($scope.volumeControl.punchTo.indexOf(punchFromId) > -1) {
      selected = true;
    }

    return selected;
  }

  _.each($scope.volumeControl.devices.source, function(device) {
    if (device.id != -1) {
      device.currentlySelected = currentlySelected(device.id);
    }
  });


  $scope.setExtraInfo = function(device, punchFrom) {
    var extraInfo = device.extra_info,
      jsonData;

    if (extraInfo) {
      //extraInfo = JSON.parse(extraInfo);

      _.each(extraInfo.punch, function(room) {
        if (room.roomId == $scope.room.id) {
          room.from = punchFrom;
        }
      });
    } else {
      extraInfo = {
        punch: []
      };

      _.each($scope.system.rooms, function(room) {
        extraInfo.punch.push({
          roomId: room.id,
          from: (room.id == $scope.room.id) ? punchFrom : ''
        });
      });
    }

    jsonData = JSON.stringify(extraInfo);

    // set_extra_info API 호출
    $http({
      method: 'POST',
      url: '/api/twoway_device/set_extra_info/' + device.room_id + '/' + device.id,
      data : {
        data: jsonData
      }
    }).
    success(function(data) {

    }).
    error(function() {
      alert("Please try again");
    });
  };

  $scope.finish = function() {
    var punchFrom = $scope.volumeControl.punchFrom,
      punchToData,
      jsonData;

    $scope.volumeControl.punchToTrfzw = [];
    $scope.volumeControl.punchToTwowayDevices = [];
    $scope.volumeControl.punchToNormaDevices = [];

    _.each($scope.volumeControl.punchTo, function(id) {
      var device = _.findWhere($scope.volumeControl.devices.destination, {
        id: id
      });

      if (device.model === 'TRF-ZW1') {
        $scope.volumeControl.punchToTrfzw.push(id);
      }

      if (device.twoway_device && !device.other_room) {
        $scope.volumeControl.punchToTwowayDevices.push(id);
      } else {
        $scope.volumeControl.punchToNormaDevices.push(id);
      }
    });

    // punch 세팅 API 호출
    function punch(url, jsonData, transition) {
      $http({
        method: 'POST',
        url: url,
        data : jsonData
      }).
      success(function(data) {
        if(data.result) {

          if (transition) {
            var currentSystem = Systems.getCurrentSystem();
            Systems.updateSystem(currentSystem.id).then(function (data) {
              $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
            });
          }

        }
        else {
          alert(data.error);
        }
      }).
      error(function() {
        alert("Please try again");
      });
    }

    // step1: TRF-ZW
    //          => $scope.setExtraInfo 호출
    // step2: twoway device
    //          => 다른 room 에 있는 TRF-ZW1 일 경우 '/api/twoway_device/punch/' 는 호출하지 않음
    //          => 나머지 device 는 '/api/twoway_device/punch_multi/' 를 호출
    // step3: normal device

    // step1
    _.each($scope.volumeControl.punchToTrfzw, function(id) {
      var device = _.findWhere($scope.volumeControl.devices.destination, {
        id: id
      });

      // TRF-ZW1 인 경우 set_extra_info 를 수행함
      $scope.setExtraInfo(device, punchFrom.id);
    });

    // step1 이 끝나고 step2, step3 가 없으면 programming options 화면으로 이동
    if (!$scope.volumeControl.punchToTwowayDevices.length && !$scope.volumeControl.punchToNormaDevices.length) {
      var currentSystem = Systems.getCurrentSystem();
      Systems.updateSystem(currentSystem.id).then(function (data) {
        $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
      });
    }
    // step2 또는 step3 가 있는 경우
    else {
      // step2 가 있는 경우
      if ($scope.volumeControl.punchToTwowayDevices.length) {
        punchToData = $scope.volumeControl.punchToTwowayDevices;
        jsonData = JSON.stringify( { punchFrom : punchFrom.id, punchTo : punchToData });

        // punch 세팅 API 호출
        $http({
          method: 'POST',
          url: '/api/twoway_device/punch_multi/' + $scope.room.id,
          data : jsonData
        }).
        success(function(data) {
          if(data.result) {

            // step2 가 끝나고 step3 가 없으면 programming options 화면으로 이동
            if (!$scope.volumeControl.punchToNormaDevices.length) {

              var currentSystem = Systems.getCurrentSystem();
              Systems.updateSystem(currentSystem.id).then(function (data) {
                $state.transitionTo('menu.programming.options', null, { reload: true, inherit: true, notify: true  });
              });

            }
            // step3
            else {
              punchToData = $scope.volumeControl.punchToNormaDevices;
              jsonData = JSON.stringify( { punchFrom : punchFrom.id, punchTo : punchToData });

              var url;
              if ($rootScope.virtualEditor) {
                url = '/api/dealer/device/punch_multi/' + $scope.room.id;
              } else {
                url = '/api/device/punch_multi/' + $scope.room.id;
              }

              // punch 세팅 API 호출
              punch(url, jsonData, true);
            }

          }
          else {
            alert(data.error);
          }
        }).
        error(function() {
          alert("Please try again");
        });
      }
      // step2 가 없고 step3 만 있는 경우
      else {
        punchToData = $scope.volumeControl.punchToNormaDevices;
        jsonData = JSON.stringify( { punchFrom : punchFrom.id, punchTo : punchToData });

        var url;
        if ($rootScope.virtualEditor) {
          url = '/api/dealer/device/punch_multi/' + $scope.room.id;
        } else {
          url = '/api/device/punch_multi/' + $scope.room.id;
        }

        // punch 세팅 API 호출
        punch(url, jsonData, true);
      }
    }

  };
  
});