(function()
{
    var moduleName = 'taskListApp';
    var template = require('../../../html/directives/tasklist/tasklist.directive.html');

    angular.module(moduleName)
        .directive('clangTasklist', taskList);

    taskList.$inject = ['$http', 'tasklistService', 'Task', '$anchorScroll'];
    function taskList($http, service, Task, $anchorScroll)
    {
        return {
            restrict: 'E',
            templateUrl: template,
            scope: {},
            controllerAs: 'ctrl',
            bindToController: true,
            controller: controller,
            link: link
        };

        function controller()
        {
            var ctrl = this;

            ctrl.searchTerms = service.searchTerms;
            ctrl.tasks = [];
            ctrl.isMobile = true ;
            ctrl.view_mode = 'list_view';

            ctrl.currentTaskFilter = 'my_tasks';
            ctrl.listViewName = lmsg('projects.tasks.custom_order');

            // Label for view type
            ctrl.listViewName = lmsg('projects.tasks.list_view');

            ctrl.customOrderTitle = lmsg('projects.tasks.display.custom_order');
            ctrl.dateCategoriesTitle = lmsg('projects.tasks.display.due_date');
            ctrl.defaultOrderTitle = lmsg('projects.tasks.display.default_order');

            this.$onInit = function() {
                $anchorScroll.yOffset = angular.element(".claro-navbar")
                ctrl.replaceTasks(service.tasks, service.task_count, service.tasks_per_page, service.currentPage);
                ctrl.countDueDateTypes();

                service.onChange(function(new_tasks, count, limit, current_page)
                {
                    ctrl.replaceTasks(new_tasks, count, limit, current_page)
                    ctrl.countDueDateTypes();
                });
            };

            ctrl.resetNewTask = function()
            {
                ctrl.new_task.loadFromArray(
                    {
                        id: 0,
                        project_id: 0,
                        section_id: 0,
                        title: '',
                        description: '',
                        due_date: '',
                        due_date_formatted: '',
                        due_date_type: 'no_due_date',
                        is_private: false,
                        assigned_to: '',
                        priority: '0',
                        is_complete: false,
                        duration: '',
                        duration_units: ctrl.duration_units,
                        orders: [],

                        is_complete_server: false,
                        is_edit: false
                    });
                ctrl.new_task.assigned_to_id = null;
            };

            ctrl.new_task = new Task();
            ctrl.resetNewTask();

            ctrl.removeTask = function(task)
            {
                // Delete the task from the master list
                var task_list = [];
                for (var i = 0; i < ctrl.tasks.length; i++)
                {
                    if (ctrl.tasks[i].id != task.id)
                        task_list.push(ctrl.tasks[i]);
                }

                ctrl.replaceTasks(task_list);

                // Get full page data to fill in permissions and filter counts
                service.getResultsPage();
            };

            ctrl.countDueDateTypes = function()
            {
                ctrl.due_date_counts = {overdue:0, today:0, tomorrow:0, later:0, no_due_date:0};

                for (var i = 0; i < ctrl.tasks.length; i++)
                {
                    var task = ctrl.tasks[i];

                    switch(task.due_date_type)
                    {
                        case 'overdue':
                        {
                            ctrl.due_date_counts.overdue++;
                            break;
                        }
                        case 'today':
                        {
                            ctrl.due_date_counts.today++;
                            break;
                        }
                        case 'tomorrow':
                        {
                            ctrl.due_date_counts.tomorrow++;
                            break;
                        }
                        case 'later':
                        {
                            ctrl.due_date_counts.later++;
                            break;
                        }
                        default:
                        {
                            ctrl.due_date_counts.no_due_date++;
                            break;
                        }
                    }
                }
            };

            // Can't use the orderBy clause of ng-repeat for this because it automatically reorders it when using drag and drop before I have a chance to get the new order.
            ctrl.putTasksInDisplayOrder = function()
            {
                ctrl.tasks.sort(function(a, b)
                {
                    if (a.orders.my_tasks > b.orders.my_tasks)
                        return 1;
                    if (a.orders.my_tasks < b.orders.my_tasks)
                        return -1;
                    return 0;
                });
            };

            ctrl.replaceTasks = function(new_tasks, count, limit, current_page)
            {
                ctrl.tasks.length = 0;
                for (var i = 0; i < new_tasks.length; i++)
                {
                    var task = new Task();
                    task.loadFromArray(new_tasks[i]);
                    task.due_date_type = new_tasks[i].due_date_type;
                    task.is_complete_server = new_tasks[i].is_complete;
                    task.due_date_formatted = new_tasks[i].due_date_formatted;
                    ctrl.tasks.push(task);
                }

                ctrl.currentTaskFilter = service.currentTaskFilter;
                if (ctrl.view_mode === 'list_view' && ctrl.currentTaskFilter === 'my_tasks')
                    ctrl.putTasksInDisplayOrder();

                ctrl.allTasksCount = count;
                ctrl.tasksPerPage = limit;
                ctrl.currentPage = current_page;
            };

            ctrl.search = function (event)
            {
                // event will only be valid if this came from the search button, typing won't have one.
                if (typeof event === 'object')
                    event.preventDefault();
                ctrl.currentPage = 1;
                service.setSearch(ctrl.searchTerms);
                service.getResultsPage();
            };

            ctrl.taskOrderChanged = function(event)
            {
                var newOrder = [];
                var index = 1;
                var tasks = event.dest.sortableScope.$parent.ctrl.tasks;
                for (var task_index = 0; task_index < tasks.length; task_index++)
                {
                    var id = tasks[task_index].id;
                    for (var i = 0; i < ctrl.tasks.length; i++)
                    {
                        if (ctrl.tasks[i].id == id)
                            ctrl.tasks[i].orders.list = index;
                    }

                    newOrder.push(id);
                }

                $http.post('/api/projects/task/order',
                    {
                        'newOrder': {'order': newOrder},
                        'taskFilter': ctrl.currentTaskFilter
                    }).then(null, function(response)
                {
                    cla.showMessage(response.data.error, response.data.message, true);
                });
            };

            ctrl.dragTaskListeners =
            {
                orderChanged: ctrl.taskOrderChanged,
                containment: '.js-drag-container',
                containerPositioning: 'relative'
            };

            ctrl.userFilterChange = function()
            {
                service.setUser(ctrl.userFilter);
                service.getResultsPage();
            };

            ctrl.startTaskAdd = function(event)
            {
                event.preventDefault();
                ctrl.new_task.is_edit = true;
                ctrl.enableNewTaskPriority();
            };



            ctrl.taskUpdatedCallback = function(task)
            {
                ctrl.countDueDateTypes();
            };

            ctrl.taskDeletedCallback = function(task)
            {
                ctrl.removeTask(task);
            };

            ctrl.taskCompleteToggledCallback = function(task)
            {
                var master_task_index = 0;
                for (var i = 0; i < ctrl.tasks.length; i++)
                {
                    if (ctrl.tasks[i].id == task.id)
                        master_task_index = i;
                }

                if (task.is_complete)
                {
                    task.setComplete(function()
                    {
                        service.getResultsPage();
                    }, function(task, response)
                    {
                        task.is_complete = false;
                        cla.showMessage(response.error, '', true);
                    });
                    ctrl.tasks[master_task_index] = task;
                } else
                {
                    task.setIncomplete(function()
                    {
                        service.getResultsPage();
                    }, function(task, response)
                    {
                        task.is_complete = true;
                        cla.showMessage(response.error, '', true);
                    });
                    ctrl.tasks[master_task_index] = task;
                }
            };

            ctrl.taskAddedCallback = function(task)
            {
                // Add the task to the list manually  to give quick feedback.
                var new_task = angular.extend(new Task(), task);
                new_task.assigned_to = task.assigned_to;
                new_task.source = {name:'', link:''};
                ctrl.tasks.push(new_task);
                ctrl.countDueDateTypes();

                ctrl.resetNewTask();

                // Get full page data to fill in permissions and filter counts
                service.getResultsPage();
            };

            ctrl.enableNewTaskPriority = function()
            {
                var select = $('#new-task-edit-section-0 .js-task-priorities');
                if (select.hasClass('select2-container'))
                    return;

                // This should be automatic but it is invisible still at this point so not processed yet.
                select.val(ctrl.new_task.priority);

                ctrl.colourSelect(select);
            };

            ctrl.updateHistoryLog = function()
            {
                $scope.$root.$broadcast('updateHistoryLog', null);
            };

            ctrl.colourSelect = function(target)
            {
                target.select2({
                    formatResult: function (data)
                    {
                        if (!data.id) { return data.text; }
                        return '<span class="task-priority-option task-priority-' + data.id + '" style="display:inline-block; margin-right:0;">&nbsp</span> ' + data.text;
                    },
                    formatSelection: function formatPrioritySelection (data)
                    {
                        if (!data.id) { return data.text; }
                        return '<span class="task-priority-option task-priority-' + data.id + '" style="display:inline-block; margin-right:0;">&nbsp</span> ' + data.text;
                    },
                    escapeMarkup: function(markup)
                    {
                        return markup;
                    },
                    minimumResultsForSearch: Infinity // Hide search box
                });
            };

            ctrl.pageChanged = function(newPageNumber, source)
            {
                if (source == ctrl.view_mode) {
                    $anchorScroll("js-jump-to-top-of-list");
                    service.changePage(newPageNumber);
                }
            };

            ctrl.getStatusFilter = function()
            {
                return service.currentStatusFilter;
            }

            ctrl.getTaskFilter = function()
            {
                return service.currentTaskFilter;
            }
        }

        function link(scope, element, attr, ctrl)
        {
            ctrl.isMobile = document.body.clientWidth <= 768;

            angular.element(window).on('resize', function(event) {
                ctrl.isMobile = document.body.clientWidth <= 768;
                scope.$digest();
            });
        }
    }
}());
