'use strict';
/**
 * @ngdoc overview
 * @name hcmEditorApp
 * @description
 * # hcmEditorApp
 *
 * Main module of the application.
 */

/*global app:true*/

var app = angular.module('urcAssistApp', [
  'ngAnimate',
  'ngCookies',
  'ngSanitize',
  'ui.router',
  'ui.bootstrap',
  'ui.sortable',
  'ui.select',
  'mgcrea.ngStrap',
  'checklist-model',
  'vr.directives.slider',
  'angular-loading-bar',
  'ngFx',
  'toastr',
  'xeditable',
  'angular-jwt',
  'ngTable'
]);

app.constant('VERSION', '0.0.4291a');

app.run( function ($rootScope, $state, $stateParams, VERSION, Auth) {

  $rootScope.version = VERSION;
  $rootScope.$state = $state;
  $rootScope.$stateParams = $stateParams;
  $rootScope.previousState = {};

  // $stateChangeSuccess 이벤트가 발생하면 $rootScope.previousState 에 이전 state 의 name 과 params 를 저장
  $rootScope.$on('$stateChangeSuccess',  function (event, toState, toParams, fromState, fromParams) {
    $rootScope.previousState.name = fromState.name;
    $rootScope.previousState.params = fromParams;
  });

  // $stateChangeStart 이벤트가 발생하면 로그인한 사용자 정보를 가져오고 이동할 state 의 로그인 필요여부에 따른 처리를 수행
  $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
    Auth.currentUser().then(function(user) {

      if (!toState.auth) {  // 이동할 state 가 로그인이 필요없는 경우
        console.info('Route does not require authentication.');
      } else {  // 이동할 state 가 로그인이 필요한 경우
        console.info('Route requires authentication.');
      }

      if (user) { // 로그인 되어 있는 경우
        console.info('User is authenticated.');
      } else {  // 로그인 되어 있지 않은 경우
        console.error('User is not authenticated.');
      }

      if (fromState.auth && !toState.auth && user) {  // 로그인 되어 있으면서 로그인 필요 state -> 불필요 state 로 이동
        console.warn('Going from Auth route to non Auth route');
        //event.preventDefault();
      } else if (toState.auth && !user) {   // 로그인 필요 state 로 이동하면서 로그인 되어 있지 않은 경우
        console.error('Routing back to Login page.');
        $state.go('login', {e: 401});   // e=401 파라미터를 가지고 로그인 페이지로 이동
        //event.preventDefault(); 
      } else if (toState.auth && user) {  // 로그인 필요 state 로 이동하면서 로그인 되어 있는 경우
        //console.info('Route requires authentication and user is authenticated.');
      }
    });
  });


});

/**
 * @ngdoc service
 * @name authInterceptor
 * @description
 *  로그인을 하면 서버로 부터 token 을 받고 이를 로그인 사용자 정보에 저장하고 있습니다.
 *  로그인 후 사용할 수 있는 모든 기능들은 서버에 ajax 요청을 할 때 HTTP Header 에 이 token 을 보내줘야 합니다.
 *  authInterceptor 가 HTTP Header 에 Authorization: Bearer {token} 형태로 넣는 역할을 합니다.
 */
app.factory('authInterceptor', function ($rootScope, $q, $injector) {
  return {
    request: function(req) {
      var d = $q.defer();
      $injector.get('Auth').currentUser().then(function(user) {
        if(user) {
          req.headers.Authorization = 'Bearer ' + user.token;
          d.resolve(req);
        } else {
          d.resolve(req);
        }
      });
      return d.promise;
    },
    responseError: function (response) {
      if (response.status === 401) {
        $injector.get('User').logout();
        $injector.get('$state').go('login', {e: '401'});
        return $q.reject(response);
      } else {
        return $q.reject(response);
      }
    }
  };
});

// $httpProvider 의 interceptors 에 authInterceptor 를 추가해서 HTTP request 를 할 때 (ajax 요청할 때) authInterceptor 가 실행되게 함
app.config(function($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
});


// angular-ui ui-router 를 사용한 state, URL 설정
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {

// For any unmatched url, redirect to /state1
// 이하 코드에서 설정하지 않은 URL 의 경우 '/' 로 redirect 시킴
  $urlRouterProvider.otherwise('/login');

// use the HTML5 History API : 이 옵션을 사용하면 주소창에 # 이 생기지 않습니다.
//$locationProvider.html5Mode(true);

// Now set up the states
// state 설정 시작
// state 설정의 옵션 property 중 auth 는 로그인이 필요한 state 인지 아닌지를 구분
  $stateProvider
    // 제일 첫 번째 페이지를 나타내는 url ('/') 에 대한 state 정의. [참고] state 이름 (home) 과 url ('/') 은 일치하지 않아도 됩니다.
    .state('home', {
      auth: true,
      url: '/home',
      template: '<div class="editor-container" >' +
      '<div class="menu container">' +
      '<a class="btn btn-lg btn-menu btn-block" ui-sref="menu.job-list">Select a job from the Job List</a>' +
      '<a class="btn btn-lg btn-menu btn-block" ui-sref="company-list">Create a new job for a Company</a>' +
      '</div></div>',
      controller: function($state, Auth) {

      }
    })

    // 로그인
    .state('login', {
      auth: false,
      url: '/login?e',
      templateUrl: 'views/assistant/login.html',
      controller: 'LoginController'
    })

    // ********************************************************
    // Company and Client List
    // ********************************************************

    .state('company-list', {
      auth: true,
      url: '/company-list',
      templateUrl: 'views/assistant/company-list.html',
      controller: 'CompanyListController',
      resolve: {
        availableModels: function($q, Systems) {
          var d = $q.defer();

          // base station 의 type 들을 얻기
          Systems.getModelTypes().then(
            function(response) {
              if(response.data.result) {
                console.log('Loaded from resolve!');
                console.log(response.data.data);
                d.resolve(JSON.parse(response.data.data));
              } else {
                d.reject();
              }
            },
            function(error) {
              alert('Please try again');
            }
          );
          return d.promise;
        }
      }
    })

    // ********************************************************
    // menu state 설정 시작
    // ********************************************************

    // 상단 메뉴를 클릭해서 나오는 모든 기능은 이 state 의 nested state 입니다.
    .state('menu', {
      auth: true,
      abstract: true,
      url: '/menu',
      // 상단 메뉴와 메뉴의 내용이 나오는 컨테이너 템플릿
      template: '<tabset justified="true">' +
      '<tab ng-repeat="t in tabs"  select="go(t.route)" active="t.active" disabled="t.disabled"><tab-heading ng-bind-html="t.heading"></tab-heading></tab>' +
      '</tabset><div class="pull-right"><button type="button" class="btn btn-default margin-top-sm margin-right-sm margin-bottom-sm" ng-click="viewJobData()" ng-if="editorContainer"><i class="fa fa-eye fa-lg"></i> View Job Request Data</button></div><div ng-class="editorContainer ? \'editor-container\' : \'\'" ui-view></div>',
      controller: function($scope, $state, $sanitize, $modal, toastr, currentSystem, currentUser, Systems) {
        $scope.tabs = [
          { heading: $sanitize('<i class="fa fa-list tab-icon"></i><span class="tab-title">Job List</span>'), route:'menu.job-list', index:"menu.job-list.**", active:false, disabled:false },
          { heading: $sanitize('<i class="fa fa-laptop tab-icon"></i><span class="tab-title">Program Menu</span>'), route:'menu.programming.options', index:"menu.programming.**", active:false, disabled:false },
          { heading: $sanitize('<i class="fa fa-wrench tab-icon"></i><span class="tab-title">Advanced Menu</span>'), route:'menu.advanced.options', index:'menu.advanced.**', active:false, disabled:false },
          { heading: $sanitize('<i class="fa fa-globe tab-icon"></i><span class="tab-title">Job Overview</span>'), route:'menu.job-overview', index:'menu.job-overview.**', active:false, disabled:false },
          { heading: $sanitize('<i class="fa fa-download tab-icon"></i><span class="tab-title">Exit &amp; Commit Job</span>'), route:'menu.exit', index:'menu.exit.**', active:false, disabled:false }
        ];

        $scope.go = function(route){
          $state.go(route);
        };

        $scope.active = function(route){
          var active = $state.includes(route);

          // menu.job-list 가 아닌 경우에만 ui-view 에 "editor-container" class 추가
          if (active && route == 'menu.job-list.**') {
            $scope.editorContainer = false;
          } else if (active) {
            $scope.editorContainer = true;
          }

          return active;
        };

        $scope.$on('$stateChangeSuccess', function() {
          $scope.tabs.forEach(function(tab) {
            tab.active = $scope.active(tab.index);
          });

          // menu.job-list 가 active 인 경우 나머지 tab 들을 disabled
          if (!$scope.editorContainer) {
            $scope.tabs.forEach(function(tab) {
              if (tab.index != 'menu.job-list.**') {
                tab.disabled = true;
              }
            });
          } else {
            $scope.tabs.forEach(function(tab) {
              tab.disabled = false;
            });
          }
        });

        $scope.system = currentSystem.system;
        $scope.jobId = currentSystem.jobId;
        $scope.job = currentSystem.job;

        $scope.popover = { 'device': ''};
        $scope.selectedDevice = {};

        $scope.findPunchDevice = function(devices, index) {
          $scope.popover.punchName = devices[index].name;
        };

        $scope.showActivities = function(room, device) {
          $scope.selectedDevice.room = room;
          $scope.selectedDevice.device = device;
          $scope.selectedDevice.activities = [];

          _.each(room.devices, function(device, i) {
            var obj = {};
            obj.name = device.name;
            obj.type1 = 0;
            obj.type2 = 0;

            _.each($scope.selectedDevice.device.activities, function(activity) {
              if (activity.device == i && activity.type == 1) {
                obj.type1 = 1;
              }
              if (activity.device == i && activity.type == 2) {
                obj.type2 = 1;
              }
            });

            $scope.selectedDevice.activities.push(obj);
          });

          var modal = $modal({
            scope: $scope,
            title: 'Job Request Data Activity',
            template: 'views/assistant/modal-tpls/job-request-data-activity.html',
            show: false
          });

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

        $scope.viewJobData = function(jobId) {
          if (jobId) {
            var jsonData = JSON.stringify({jobId: jobId});

            Systems.getSystems(jsonData)
              .then(function(data) {console.log('get systems', data);
                // systems 배열에 있는 첫 번째 system 의 id 를 구함
                var systemId = data.systems[0].id;

                // 현재 system 으로 update
                Systems.setCurrentRoom(null);
                return Systems.updateSystem(systemId, jsonData).then(
                  function (data) {
                    viewJobRequestData();
                  },
                  function (error) {
                    toastr.error(error);
                  }
                );
              })
              .catch(toastr.error);
          } else {
            viewJobRequestData();
          }

          function viewJobRequestData() {
            $scope.system = Systems.getCurrentSystem();
            $scope.jobId = Systems.getCurrentJobId();

            var jsonData = JSON.stringify({jobId: $scope.jobId});
            Systems.getSubmitData(jsonData)
              .then(function(data) {
                Systems.setCurrentJob(data);
                $scope.job = Systems.getCurrentJob();

                var modal = $modal({
                  scope: $scope,
                  title: 'Job Request Data',
                  template: 'views/assistant/modal-tpls/job-request-data.html',
                  show: false
                });

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

      },
      resolve: {
        // 현재 선택된 system 가져오기
        currentSystem: function($q, $window, Systems) {
          var d = $q.defer();
          if (Systems.getCurrentSystem() && Systems.getCurrentJobId()) {
            console.log('in resolve');
            d.resolve({system: Systems.getCurrentSystem(), jobId: Systems.getCurrentJobId(), job: Systems.getCurrentJob()});
          } else {
            var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));

            if (user.system_id && user.job_id) {
              var jsonData = JSON.stringify({jobId: user.job_id});
              Systems.updateSystem(user.system_id, jsonData).then(function(data) {
                d.resolve({system: Systems.getCurrentSystem(), jobId: Systems.getCurrentJobId()});
              }).catch(function(error) {
                d.reject(error);
              });
            } else {
              d.resolve({});
            }
          }
          return d.promise;
        },
        // 로그인한 사용자 정보 가져오기
        currentUser: function (Auth) {
          return Auth.currentUser();
        }
      }
    })

    // ********************************************************
    // Job List
    // ********************************************************

    .state('menu.job-list', {
      auth: true,
      url: '/job-list',
      templateUrl: 'views/assistant/job-list.html',
      controller: 'JobListController',
      resolve: {
        availableModels: function($q, Systems) {
          var d = $q.defer();

          // base station 의 type 들을 얻기
          Systems.getModelTypes().then(
            function(response) {
              if(response.data.result) {
                console.log('Loaded from resolve!');
                console.log(response.data.data);
                d.resolve(JSON.parse(response.data.data));
              } else {
                d.reject();
              }
            },
            function(error) {
              alert('Please try again');
            }
          );
          return d.promise;
        }
      }
    })

    // ********************************************************
    // Programming Menu
    // ********************************************************

    .state('menu.programming', {
      auth: true,
      abstract: true,
      url: '/programming',
      template: '<div ui-view></div>',
      controller: function ($scope, $state, Systems) {
        var id = Systems.getCurrentRoom();

        $scope.system = Systems.getCurrentSystem();

        if (id === null) {  // 현재 room 이 없으면 system 의 첫 번째 room 을 현재 room 으로 설정
          $scope.room = $scope.system.rooms[0];
          Systems.setCurrentRoom($scope.room.id);
        } else {
          $scope.room = _.find($scope.system.rooms, {'id': id});
        }

        if ($scope.system.rooms.length === 1) {
          $scope.hasOneRoom = true;
        } else {
          $scope.hasOneRoom = false;
        }

        $scope.switchRoom = function(id) {
          Systems.setCurrentRoom(id);
          $scope.room = _.find($scope.system.rooms, {'id': id});
          $state.go('menu.programming.options');
        };
      }
    })

    // Programming 메뉴 첫 화면에 나오는 메뉴 목록
    .state('menu.programming.options', {
      auth: true,
      url: '',
      templateUrl: 'views/assistant/programming-options.html',
      controller: function($scope) {}
    })


    // ********************************************************
    // Programming Menu ---- Adding a device
    // ********************************************************

    .state('menu.programming.add-device', {
      auth: true,
      abstract: true,
      url: '/add-device',
      template: '<div ui-view></div>',
      controller: function($scope) {
        $scope.device = {};
        $scope.query = {};
      },
      resolve: {
        // device types 얻기
        categories: function($q, toastr, Database) {
          var d = $q.defer();
          Database.retreiveDeviceTypes().then(
            function(data) {
              d.resolve(data);
            },
            function(error) {
              toastr.error(error, 'Error');
              d.reject(error);
            }
          );
          return d.promise;
        }
      }
    })

    // device type 선택
    .state('menu.programming.add-device.device-type', {
      auth: true,
      url: '/type',
      templateUrl: 'views/add-devices/device-type.html',
      controller: 'DeviceTypeController'
    })

    // device name 입력
    .state('menu.programming.add-device.device-name', {
      auth: true,
      url: '/name',
      templateUrl: 'views/add-devices/device-name.html',
      controller: 'DeviceNameController'
    })

    // device brand 선택
    .state('menu.programming.add-device.device-brand', {
      auth: true,
      url: '/brand',
      templateUrl: 'views/add-devices/device-brand.html',
      controller: 'DeviceBrandController'
    })

    // device model 선택
    .state('menu.programming.add-device.device-model', {
      auth: true,
      url: '/model',
      templateUrl: 'views/assistant/add-devices/device-model.html',
      controller: 'DeviceModelController',
      resolve: {
        // popular 모델 얻기
        popularDevices: function($q, Database, Devices) {
          var device = Devices.getCurrentDevice(),
            d = $q.defer();

          if (device) {
            Database.searchPopularModels(device.type.name, device.brand.name)
              .then(function(devices) {
                d.resolve(devices);
              })
              .catch(function(error) {
                d.reject(error);
                toastr.error(error, 'Error');
              });
          } else {
            d.resolve({});
          }

          return d.promise;
        }
      }
    })

    // device model 검색
    .state('menu.programming.add-device.device-model-search', {
      auth: true,
      url: '/model-search',
      templateUrl: 'views/assistant/add-devices/device-model-search.html',
      controller: 'DeviceModelSearchController'
    })

    // device 정보 설정 후 생성
    .state('menu.programming.add-device.device-settings', {
      auth: true,
      url: '/settings',
      templateUrl: 'views/add-devices/device-settings.html',
      controller: 'DeviceSettingsController'
    })

    // favorite channels 설정
    .state('menu.programming.add-device.favchannels-option', {
      auth: true,
      url: '/favorite-channels',
      templateUrl: 'views/add-devices/favchannels-option.html',
      controller: 'FavChannelsOptionController'
    })

    // ********************************************************
    // Programming Menu ---- Add a base station
    // ********************************************************

    .state('menu.programming.add-controller', {
      auth: true,
      abstract: true,
      url: '/add-controller',
      template: '<div ui-view></div>',
      resolve: {
        availableModels: function($q, Systems) {
          var d = $q.defer();

          // base station 의 type 들을 얻기
          Systems.getModelTypes().then(
            function(response) {
              if(response.data.result) {
                console.log('Loaded from resolve!');
                console.log(response.data.data);
                d.resolve(JSON.parse(response.data.data));
              } else {
                d.reject();
              }
            },
            function(error) {
              alert('Please try again');
            }
          );
          return d.promise;
        }
      }
    })

    // base station 추가 화면
    .state('menu.programming.add-controller.select', {
      auth: true,
      url: '',
      templateUrl: 'views/assistant/add-controllers/select-controller.html',
      controller: 'SelectBaseController'
    })

    // ********************************************************
    // Programming Menu ---- Add a remote
    // ********************************************************

    .state('menu.programming.add-remote', {
      auth: true,
      url: '/add-remote',
      template: '<div ui-view></div>',
      resolve: {
        availableModels: function($q, Systems) {
          var d = $q.defer();

          // remote 의 type 들을 얻기
          Systems.getRemoteTypes().then(
            function(response) {
              if(response.data.result) {
                console.log('Loaded from resolve!');
                console.log(response.data.data);
                d.resolve(JSON.parse(response.data.data));
              } else {
                d.reject();
              }
            },
            function(error) {
              alert('Please try again');
            }
          );
          return d.promise;
        }
      }
    })

    // remote 추가 화면
    .state('menu.programming.add-remote.select', {
      auth: true,
      url: '',
      templateUrl: 'views/assistant/add-remotes/select-remote.html',
      controller: 'SelectRemoteController'
    })

    // ********************************************************
    // Programming Menu ---- Build a simple activity
    // ********************************************************
    .state('menu.programming.activities', {
      auth: true,
      abstract: true,
      url: '/activities',
      template: '<div ui-view=""></div>',
      controller: 'ActivitiesController'
    })

    // based on device 선택 화면
    .state('menu.programming.activities.choose-device', {
      auth: true,
      url: '/choose-device',
      templateUrl: 'views/activities/choose-device.html',
      controller: 'ChooseActivityDeviceController'
    })

    // simple activity 선택 화면
    .state('menu.programming.activities.devices-to-use', {
      auth: true,
      url: '/devices-to-use',
      templateUrl: 'views/activities/devices-to-use.html',
      controller: 'ActivityDevicesController'
    })

    // command 선택 화면
    .state('menu.programming.activities.commands', {
      auth: true,
      url: '/commands',
      templateUrl: 'views/activities/commands.html',
      controller: 'ActivityDeviceCommandsController'

    })

    // ********************************************************
    // Programming Menu ---- Setting volume punch through
    // ********************************************************
    .state('menu.programming.volume-control', {
      auth: true,
      abstract: true,
      url: '/volume-control/:roomId',
      template: '<div ui-view=""></div>',
      controller: function($scope, deviceId) {
        console.log(deviceId);
        $scope.volumeControl = {};
        $scope.volumeControl.punchFrom = null;
        $scope.volumeControl.punchTo = null;
        $scope.volumeControl.devices = {};

        var dest = angular.copy($scope.room.devices);
        dest.push({id: 0, name: 'Entertainment / Home Menu', punch_vol: deviceId});
        $scope.volumeControl.devices.destination = dest;

        var source = angular.copy($scope.room.devices);
        source.push({id: -1, name: 'None', punch_vol: -1});
        $scope.volumeControl.devices.source = source;
      },
      resolve: {
        // punch 정보 (punch한 Device의 ID)
        deviceId: function($stateParams, Devices) {
          return Devices.fetchPunchDevice($stateParams.roomId, 0);
        }
      }
    })

    // punch to device 선택 화면
    .state('menu.programming.volume-control.punch-to-device', {
      auth: true,
      url: '/punch-to-device',
      templateUrl: 'views/volume-control/punch-to-device.html',
      controller: 'PunchToDeviceController'
    })

    // punch from device 선택 화면
    .state('menu.programming.volume-control.punch-from-device', {
      auth: true,
      url: '/punch-from-device',
      templateUrl: 'views/volume-control/punch-from-device.html',
      controller: 'PunchFromDeviceController'
    })

    // ********************************************************
    // Programming Menu ---- Setting power off
    // ********************************************************

    .state('menu.programming.power-off', {
      auth: true,
      abstract: true,
      url: '/power-off',
      template: '<div ui-view=""></div>',
      controller: 'PowerOffController'
    })

    // device 선택 화면
    .state('menu.programming.power-off.devices-to-use', {
      auth: true,
      url: '/devices-to-use',
      templateUrl: 'views/power-off/devices-to-use.html',
      controller: 'PowerOffDevicesController',
      resolve: {
        // button 의 정보 얻기
        currentMacro: function ($q, Systems) {
          var d = $q.defer();

          // 해당 room 의 power macro 데이터 얻어와서 저장
          Systems.updateCurrentMacroForPower(Systems.getCurrentRoom()).then(
            function(data) {
              console.log(data);
              d.resolve(data);
            },
            function (error) {
              alert(error);
              d.reject(error);
            }
          );
          return d.promise;
        }
      }
    })

    .state('menu.programming.power-off.commands', {
      auth: true,
      url: '/commands',
      templateUrl: 'views/power-off/commands.html',
      controller: 'PowerOffDeviceCommandsController'
    })


    // ********************************************************
    // Programming Menu ---- Switching rooms
    // ********************************************************

    .state('menu.programming.switch-rooms', {
      auth: true,
      url: '/switch-rooms',
      templateUrl: 'views/switch-rooms.html',
      controller: function($scope) {
        var roomId = angular.copy($scope.room.id);

        $scope.switchData = {'roomId': roomId };

      }
    })


    // ********************************************************
    // Advanced Menu
    // ********************************************************

    .state('menu.advanced', {
      auth: true,
      abstract: true,
      url: '/advanced',
      template: '<div ui-view></div>',
      controller: function($scope, Systems) {
        $scope.system = Systems.getCurrentSystem();
      }
    })

    .state('menu.advanced.options', {
      auth: true,
      url: '',
      templateUrl: 'views/assistant/advanced-options.html',
      controller: function($scope) { }
    })

    // ********************************************************
    // Advanced Menu - Add a macro
    // ********************************************************

    .state('menu.advanced.add-macros', {
      auth: true,
      abstract: true,
      url: '/add-macros',
      template: '<div ui-view></div>',
      controller: function($scope) {
        $scope.addMacro = {room: {}, steps: [], button: {}, disablePopup: false,
          doneScreen: {index: 0, devices: []}};
        $scope.macroType = {id : null};
        // macroType id
        // 0 - turn off all
        // 1 - device activity
        // 2 - custom
      }
    })

    .state('menu.advanced.add-macros.choose-room', {
      auth: true,
      url: '/choose-room',
      templateUrl: 'views/add-macros/choose-room.html',
      controller: 'AddMacroRoomController'
    })

    .state('menu.advanced.add-macros.macro-type', {
      auth: true,
      url: '/macro-type',
      templateUrl: 'views/add-macros/macro-type.html',
      controller: 'MacroTypeController'
    })

    .state('menu.advanced.add-macros.button-name', {
      auth: true,
      url: '/button-name',
      templateUrl: 'views/add-macros/button-name.html',
      controller: 'ButtonNameController'
    })


    .state('menu.advanced.add-macros.choose-device', {
      auth: true,
      url: '/choose-device',
      templateUrl: 'views/add-macros/choose-device.html',
      controller: 'ChooseMacroDeviceController'
    })

    .state('menu.advanced.add-macros.finish', {
      auth: true,
      url: '/finish',
      templateUrl: 'views/add-macros/edit-macro.html',
      controller: 'FinishMacroController'
    })

    .state('menu.advanced.add-macros.macro-done', {
      auth: true,
      url: '/macro-complete',
      templateUrl: 'views/add-macros/macro-done.html',
      controller: 'MacroDoneController'
    })

    .state('menu.advanced.add-macros.macro-commands', {
      auth: true,
      url: '/commands',
      templateUrl: 'views/add-macros/macro-commands.html',
      controller: 'MacroCommandsController'
    })


    .state('menu.advanced.add-macros.next-action', {
      auth: true,
      url: '/next',
      template: '<next-action continue-state="menu.advanced.add-macros.macro-type" back-state="menu.advanced.add-macros.choose-room"></next-action>'
    })

    // ********************************************************
    // Advanced Menu - Edit macros
    // ********************************************************

    .state('menu.advanced.edit-macros', {
      auth: true,
      abstract: true,
      url: '/edit-macros',
      template: '<div ui-view></div>',
      controller: function($scope) {
        $scope.addMacro = {'room': {}, 'steps': [], 'button': {}, 'disablePopup': false, 'linkId': null,
          'doneScreen': {'index': 0, 'devices': []}, 'currentDevice': {}};
        $scope.editMacro = {'mainDevice': {}, 'totalItems': 60, 'currentPage': 1 };
        $scope.client = {'page': {}};
        $scope.macroType = {id : null};
      }
    })

    .state('menu.advanced.edit-macros.choose-room', {
      auth: true,
      url: '/choose-room',
      templateUrl: 'views/add-macros/choose-room.html',
      controller: 'EditMacroRoomController'
    })

    .state('menu.advanced.edit-macros.macro-simulator', {
      auth: true,
      url: '/:roomId/simulator',
      templateUrl: 'views/edit-macros/macro-simulator.html',
      controller: 'MacroSimulatorController'
      // ,
      // resolve: {
      //   devices: function($q, $stateParams, toastr, Systems) {
      //     var d = $q.defer();

      //     Systems.updateRoomDevices($stateParams.roomId)
      //     .then(function(data) {
      //       console.log(data);
      //       var roomDevices = Systems.getRoomDevices();
      //       d.resolve(roomDevices.devices);
      //     })
      //     .catch(function (error) {
      //       toastr.error(error);
      //       d.reject(error);
      //     });

      //     return d.promise;
      //   }
      // }

    })

    .state('menu.advanced.edit-macros.finish', {
      auth: true,
      url: '/finish',
      templateUrl: 'views/add-macros/edit-macro.html',
      controller: 'EditMacroController'

    })

    .state('menu.advanced.edit-macros.macro-done', {
      auth: true,
      url: '/macro-complete',
      templateUrl: 'views/add-macros/macro-done.html',
      controller: 'EditMacroDoneController'
    })

    .state('menu.advanced.edit-macros.macro-commands', {
      auth: true,
      url: '/commands',
      templateUrl: 'views/add-macros/macro-commands.html',
      controller: 'EditMacroCommandsController'
    })


    .state('menu.advanced.edit-macros.next-action', {
      auth: true,
      url: '/next',
      template: '<next-action continue-state="menu.advanced.edit-macros.macro-simulator" back-state="menu.advanced.edit-macros.choose-room"></next-action>',
      controller: function ($scope) {

      }
    })



    // ********************************************************
    // Advanced Menu - Add a room
    // ********************************************************

    .state('menu.advanced.add-room', {
      auth: true,
      abstract: true,
      url: '/add-room',
      template: '<div ui-view></div>',
      resolve: {
        availableModels: function($q, Systems) {
          var d = $q.defer();

          // base station 의 type 들을 얻기
          Systems.getModelTypes().then(
            function(response) {
              if(response.data.result) {
                console.log('Loaded from resolve!');
                console.log(response.data.data);
                d.resolve(JSON.parse(response.data.data));
              } else {
                d.reject();
              }
            },
            function(error) {
              alert('Please try again');
            }
          );
          return d.promise;
        }
      }
    })
    .state('menu.advanced.add-room.select', {
      auth: true,
      url: '/select',
      templateUrl: 'views/assistant/add-rooms/select-room.html',
      controller: 'SelectRoomController'
    })
    // .state('menu.advanced.add-room.link-remote', {
    //   url: '/link-remote',
    //   templateUrl: 'views/add-rooms/link-remote.html',
    //   controller: 'LinkRemoteController'
    // })


    // ********************************************************
    // Advanced Menu - Add a remote
    // ********************************************************

    .state('menu.advanced.add-remote', {
      auth: true,
      abstract: true,
      url: '/add-remote',
      template: '<div ui-view></div>',
      controller: function($scope) {
        $scope.addRemote = {'selection': null, 'room': null};
      },
      resolve: {
        searchResults: function ($q, Systems) {
          var d = $q.defer();
          Systems.searchHardware(true, 'hcm-r1').then(
            function(data) {
              console.log(data);
              d.resolve(data);
            },
            function (error) {
              alert(error);
              d.reject(error);
            }
          );
          return d.promise;
        }
      }
    })
    .state('menu.advanced.add-remote.select', {
      auth: true,
      url: '/select',
      templateUrl: 'views/add-remotes/select-remote.html',
      controller: 'SelectRemoteController'
    })
    .state('menu.advanced.add-remote.available-rooms', {
      auth: true,
      url: '/rooms',
      templateUrl: 'views/add-remotes/available-rooms.html',
      controller: 'AvailableRoomsController'
    })


    // ********************************************************
    // Advanced Menu - Edit device UI
    // ********************************************************

    .state('menu.advanced.device', {
      auth: true,
      abstract: true,
      url: '/device',
      template: '<div ui-view></div>',
      controller: function($scope, Systems) {
        $scope.deviceMenu = {'roomId': null, 'deviceId': null};
        $scope.system = Systems.getCurrentSystem();
      }
    })

    .state('menu.advanced.device.select', {
      auth: true,
      url: '/select',
      templateUrl: 'views/device-menu/choose-device.html',
      controller: 'DeviceSelectionController'
    })

    .state('menu.advanced.device.edit-layout', {
      auth: true,
      url: '/edit',
      templateUrl: 'views/device-menu/edit-layout.html',
      controller: 'DeviceMenuLayoutController'
    })

    // ********************************************************
    // Advanced Menu - Edit main menu UI
    // ********************************************************

    .state('menu.advanced.main', {
      auth: true,
      abstract: true,
      url: '/main',
      template: '<div ui-view></div>',
      controller: function($scope) {
        $scope.mainMenu = { 'room': {}, 'mainDevice': {}};
      }
    })

    .state('menu.advanced.main.choose-room', {
      auth: true,
      url: '/choose-room',
      templateUrl: 'views/main-menu/choose-room.html',
      controller: function($scope, $state, Systems) {
        $scope.doNext = function( ) {
          Systems.updateMainDevice($scope.mainMenu.room.id).then(function(response) {
            $state.go('menu.advanced.main.edit-layout');
          }, function(error) {
            alert(error);
          });
        };
      }
    })

    .state('menu.advanced.main.edit-layout', {
      auth: true,
      url: '/edit',
      templateUrl: 'views/main-menu/edit-layout.html',
      controller: 'MainMenuLayoutController'
    })

    // ********************************************************
    // Advanced Menu - Learn an ir device
    // ********************************************************

    .state('menu.advanced.learn-ir', {
      auth: true,
      abstract: true,
      url: '/learn-ir',
      template: '<div ui-view></div>',
      controller: function($scope, Systems) {
        $scope.system = Systems.getCurrentSystem();
        $scope.learnIr = { exists: null, roomId: null, deviceId: null, selectedBtn: null};
      }
    })
    .state('menu.advanced.learn-ir.options', {
      auth: true,
      url: '',
      templateUrl: 'views/learn-ir/new-or-existing.html',
      controller: 'NewOrExistingController'
    })
    .state('menu.advanced.learn-ir.select-device', {
      auth: true,
      url: '/existing',
      templateUrl: 'views/learn-ir/existing-device.html',
      controller: 'ExistingDeviceController'
    })

    .state('menu.advanced.learn-ir.new-device', {
      auth: true,
      url: '/new',
      templateUrl: 'views/learn-ir/new-device.html',
      controller: 'NewDeviceController',
      resolve: {
        categories: function(Database) {
          return Database.retreiveDeviceTypes();
        }
      }
    })

    .state('menu.advanced.learn-ir.edit', {
      auth: true,
      url: '/edit',
      templateUrl: 'views/learn-ir/edit-ir.html',
      controller: 'EditIrController'
    })



    // ********************************************************
    // Job Overview
    // ********************************************************

    .state('menu.job-overview', {
      auth: true,
      url: '/job-overview',
      templateUrl: 'views/assistant/job-overview.html',
      controller: 'JobOverviewController'
    })



    // ********************************************************
    // Account Settings - Change account settings for user
    // ********************************************************

    .state('account-settings', {
      auth: true,
      abstract: true,
      url: '/account-settings',
      template: '<div class="editor-container" ui-view></div>',
      controller: function ($scope, user) {
        $scope.user = user;
      },
      resolve: {
        user: function(Auth) {
          return Auth.currentUser();
        }
      }
    })

    .state('account-settings.main', {
      auth: true,
      url: '',
      templateUrl: 'views/assistant/account/settings.html',
      controller: function ($scope, user) { console.log(user); }
    })

    .state('account-settings.change-password', {
      auth: true,
      url: '/change-password',
      templateUrl: 'views/assistant/account/change-password.html',
      controller: 'ChangePasswordController'
    })


    // ********************************************************
    // System Settings - Change system settings
    // ********************************************************

    .state('system-settings', {
      auth: true,
      abstract: true,
      url: '/system-settings',
      template: '<div class="editor-container" ui-view></div>',
      controller: function ($scope) {

      }
    })

    .state('system-settings.main', {
      auth: true,
      url: '',
      templateUrl: 'views/system-settings.html',
      controller: 'SystemSettingsController',
      resolve: {
        currentSystem: function($q, $window, Systems) {
          var d = $q.defer();
          if (Systems.getCurrentSystem()) {
            console.log('in resolve');
            d.resolve(Systems.getCurrentSystem());
          } else {
            var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));
            Systems.updateSystem(user.system_id).then(function(data) {
              d.resolve(Systems.getCurrentSystem());
            }).catch(function(error) {
              d.reject(error);
            });
          }
          return d.promise;
        },

        timeZones: function($q, Timezones) {
          var d = $q.defer();

          Timezones.getAll().then(function(data) {
            d.resolve(data);
          }).catch(function(error) {
            d.reject(error);
          });

          return d.promise;
        }
      }
    })

    .state('system-settings.delete', {
      auth: true,
      url: '/delete',
      templateUrl: 'views/system-delete.html',
      controller: 'SystemDeleteController',
      resolve: {
        resolvedSystems: function(Systems) {
          return Systems.fetch();
        }
      }
    })

    // ********************************************************
    // Exit & Commit Job
    // ********************************************************


    .state('menu.exit', {
      auth: true,
      url: '/exit',
      template: '<div class="editor-container" >' +
      '<div class="menu container">' +
      '<a class="btn btn-lg btn-menu btn-block" ui-sref="home">Exit this job</a>' +
      '<a class="btn btn-lg btn-menu btn-block" ng-click="commit()">Commit this job as "Ready"</a>' +
      '</div></div>',
      controller: function($scope, $state, toastr, Systems) {
        var jobId = Systems.getCurrentJobId();

        $scope.commit = function() {
          var jsonData = JSON.stringify({jobId: jobId, status: 2});

          Systems.setStatus(jsonData)
            .then(function(data) {
              $state.go('home');
            })
            .catch(toastr.error);
        };
      }
    });
});



