text: /*global angular */
  
  /**
   * The main controller for the app. The controller:
   * - retrieves and persists the model via the todoStorage service
   * - exposes the model to the template and provides event handlers
   */
  angular.module('todomvc')
  	.controller('TodoCtrl', function TodoCtrl($scope, $routeParams, $filter, store) {
  		'use strict';
  
  		var todos = $scope.todos = store.todos;
  
  		$scope.newTodo = '';
  		$scope.editedTodo = null;
  
  		$scope.$watch('todos', function () {
  			$scope.remainingCount = $filter('filter')(todos, { completed: false }).length;
  			$scope.completedCount = todos.length - $scope.remainingCount;
  			$scope.allChecked = !$scope.remainingCount;
  		}, true);
  
  		// Monitor the current route for changes and adjust the filter accordingly.
  		$scope.$on('$routeChangeSuccess', function () {
  			var status = $scope.status = $routeParams.status || '';
  			$scope.statusFilter = (status === 'active') ?
  				{ completed: false } : (status === 'completed') ?
  				{ completed: true } : {};
  		});
  
  		$scope.addTodo = function () {
  			var newTodo = {
  				title: $scope.newTodo.trim(),
  				completed: false
  			};
  
  			if (!newTodo.title) {
  				return;
  			}
  
  			$scope.saving = true;
  			store.insert(newTodo)
  				.then(function success() {
  					$scope.newTodo = '';
  				})
  				.finally(function () {
  					$scope.saving = false;
  				});
  		};
  
  		$scope.editTodo = function (todo) {
  			$scope.editedTodo = todo;
  			// Clone the original todo to restore it on demand.
  			$scope.originalTodo = angular.extend({}, todo);
  		};
  
  		$scope.saveEdits = function (todo, event) {
  			// Blur events are automatically triggered after the form submit event.
  			// This does some unfortunate logic handling to prevent saving twice.
  			if (event === 'blur' && $scope.saveEvent === 'submit') {
  				$scope.saveEvent = null;
  				return;
  			}
  
  			$scope.saveEvent = event;
  
  			if ($scope.reverted) {
  				// Todo edits were reverted-- don't save.
  				$scope.reverted = null;
  				return;
  			}
  
  			todo.title = todo.title.trim();
  
  			if (todo.title === $scope.originalTodo.title) {
  				$scope.editedTodo = null;
  				return;
  			}
  
  			store[todo.title ? 'put' : 'delete'](todo)
  				.then(function success() {}, function error() {
  					todo.title = $scope.originalTodo.title;
  				})
  				.finally(function () {
  					$scope.editedTodo = null;
  				});
  		};
  
  		$scope.revertEdits = function (todo) {
  			todos[todos.indexOf(todo)] = $scope.originalTodo;
  			$scope.editedTodo = null;
  			$scope.originalTodo = null;
  			$scope.reverted = true;
  		};
  
  		$scope.removeTodo = function (todo) {
  			store.delete(todo);
  		};
  
  		$scope.saveTodo = function (todo) {
  			store.put(todo);
  		};
  
  		$scope.toggleCompleted = function (todo, completed) {
  			if (angular.isDefined(completed)) {
  				todo.completed = completed;
  			}
  			store.put(todo, todos.indexOf(todo))
  				.then(function success() {}, function error() {
  					todo.completed = !todo.completed;
  				});
  		};
  
  		$scope.clearCompletedTodos = function () {
  			store.clearCompleted();
  		};
  
  		$scope.markAll = function (completed) {
  			todos.forEach(function (todo) {
  				if (todo.completed !== completed) {
  					$scope.toggleCompleted(todo, completed);
  				}
  			});
  		};
  	});