
goog.provide('mu.tutorial.tasks');
goog.provide('mu.tutorial.tasks.Task');

goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.ui.CustomButton');
goog.require('goog.ui.Slider');
goog.require('goog.ui.Toolbar');
goog.require('goog.ui.ToolbarButton');
goog.require('goog.ui.Zippy');

goog.provide('mu.tutorial.tasks.TaskList');

mu.tutorial.tasks.taskLists = {};

mu.tutorial.tasks.defaultCompare = function(t1, t2) {
    return goog.array.defaultCompare(
        t2.priority,
        t1.priority);
};
    
mu.tutorial.tasks.TaskList = function(name, data, container) {
    this.name = name;
    this.container = container;
    this.tasks = [];

    for (var i = 0; i < data.length; i++) {
        this.tasks.push(new mu.tutorial.tasks.Task(data[i], this));
    }

    this.sort()
    this.render();
}

mu.tutorial.tasks.TaskList.prototype.noTasks = function() {
    this.container.appendChild(
        goog.dom.createDom('h2', { 'class': 'empty' }, 'This list is empty!'));
}

mu.tutorial.tasks.TaskList.prototype.render = function() {
    goog.dom.removeChildren(this.container);

    if (this.tasks.length == 0)
        this.noTasks();
    else
        for (var i = 0; i < this.tasks.length; i++) {
            this.tasks[i].makeDom();
        }
}

mu.tutorial.tasks.TaskList.prototype.sort = function() {
    var arr = this.tasks
    for (var i = 0; i < arr.length; i++) {
        arr[i] = {index: i, value: arr[i]};
    }

    function stableCompareFn(obj1, obj2) {
        return mu.tutorial.tasks.defaultCompare(obj1.value, obj2.value) ||
            obj1.index - obj2.index;
    };
    
    goog.array.sort(arr, stableCompareFn);

    var changed = false;
    for (var i = 0; i < arr.length; i++) {
        if (i != arr[i].index)
            changed = true;
        arr[i] = arr[i].value;
    }
    return changed;
}

mu.tutorial.tasks.TaskList.prototype.add = function(task) {
    task.list = this;
    
    goog.array.binaryInsert(
        this.tasks,
        task,
        mu.tutorial.tasks.defaultCompare);
}

mu.tutorial.tasks.TaskList.prototype.remove = function(task) {
    this.container.removeChild(task.element);
    
    goog.array.binaryRemove(
        this.tasks,
        task,
        mu.tutorial.tasks.defaultCompare);

    if (this.tasks.length == 0)
        this.noTasks();
}

mu.tutorial.tasks.switchPanel = function(target, taskList) {
    return function() {
        goog.dom.$('taskList').style.display = "none";
        goog.dom.$('completedTaskList').style.display = "none";
        goog.dom.$('deletedTaskList').style.display = "none";
        goog.dom.$('settings').style.display = "none";
        goog.dom.$(target).style.display = "block";

        if (taskList != undefined)
            mu.tutorial.tasks.taskLists[taskList].render();
    }
}

mu.tutorial.tasks.attachToolbarButton = function(toolbar, label, tooltip, target, taskList) {
    var button = new goog.ui.ToolbarButton(label);
    button.setTooltip(tooltip);
    toolbar.addChild(button, true);
    goog.events.listen(
        button.getContentElement(),
        goog.events.EventType.CLICK,
        mu.tutorial.tasks.switchPanel(target, taskList));
}

mu.tutorial.tasks.attachToolbar = function(container) {
    var toolbar = new goog.ui.Toolbar();

    mu.tutorial.tasks.attachToolbarButton(toolbar, 'Tasks', 'List currently active tasks.', 'taskList', 'active');
    mu.tutorial.tasks.attachToolbarButton(toolbar, 'Completed', 'List completed tasks.', 'completedTaskList', 'completed');
    mu.tutorial.tasks.attachToolbarButton(toolbar, 'Trash', 'List deleted tasks.', 'deletedTaskList', 'deleted');
    mu.tutorial.tasks.attachToolbarButton(toolbar, 'Settings', 'Settings', 'settings');

    toolbar.render(container);
}

mu.tutorial.tasks.Task = function(data, list) {
    this.summary = data.summary;
    this.description = data.description;
    this.previous_priority = data.priority;
    this.priority = data.priority;
    this.list = list;
}

mu.tutorial.tasks.Task.prototype.closeEditor = function() {
    this.contentElement.innerHTML = this.description;
    this.contentElement.style.display = "block";
    this.editorContainer.style.display = "none";
};
 
mu.tutorial.tasks.Task.prototype.openEditor = function(e) {
    this.editorElement.value = this.description;
    this.contentElement.style.display = "none";
    this.editorContainer.style.display = "inline";
};

mu.tutorial.tasks.Task.prototype.save = function(e) {
    this.description = this.editorElement.value;
    this.closeEditor();
};

mu.tutorial.tasks.Task.prototype.moveTo = function(target) {
    this.list.remove(this);
    mu.tutorial.tasks.taskLists[target].add(this);
}

mu.tutorial.tasks.Task.prototype.clickActionButton = function(task, target) {
    return function(e) {
        task.moveTo(target);
        e.stopPropagation();
    };
}

mu.tutorial.tasks.Task.prototype.makeActionButton = function(task, target, name) {
    var button = new goog.ui.CustomButton(name);

    button.addClassName('taskButton');

    button.render(this.summaryControlsDiv);

    goog.events.listen(
        button.getContentElement(),
        goog.events.EventType.CLICK,
        this.clickActionButton(task, target));
}

mu.tutorial.tasks.Task.prototype.makeEditorButton = function(name, callback) {
    var button = new goog.ui.CustomButton(name);

    button.addClassName('editorButton');

    button.render(this.editorContainer);

    goog.events.listen(button.getContentElement(), goog.events.EventType.CLICK,
                       callback, false, this);
}

mu.tutorial.tasks.Task.prototype.makeButtons = function(task) {
    if (task.list.name == 'active') {
        this.makeActionButton(task, 'deleted', 'Delete');
        this.makeActionButton(task, 'completed', 'Done');
    }
    else
        this.makeActionButton(task, 'active', 'Undo');
    
    this.makeEditorButton('Save', this.save);
    this.makeEditorButton('Cancel', this.closeEditor);
}

mu.tutorial.tasks.Task.prototype.reload = function() {
    if (this.priority != this.previous_priority) {
        if (this.list.sort())
            this.list.render();
        this.previous_priority = this.priority;
    }
}

mu.tutorial.tasks.Task.prototype.makeSlider = function(task) {
    if (task.list.name == 'active') {
        var slider = new goog.ui.Slider;
        slider.createDom();
        slider.render(this.sliderDiv);
        slider.setValue(this.priority);

        var task = this;
        slider.addEventListener(
            goog.ui.Component.EventType.CHANGE,
            function() {
                task.priority = slider.getValue();
                task.priorityValueDiv.innerHTML = task.priority;
            });

        goog.events.listen(
            slider.getContentElement(),
            [goog.events.EventType.MOUSEOUT,
             goog.events.EventType.KEYUP],
            function() { task.reload(); });

        goog.events.listen(
            slider.getContentElement(),
            goog.events.EventType.CLICK,
            function(e) { e.stopPropagation(); });
    }
}

mu.tutorial.tasks.Task.prototype.makeSummaryDom = function() {
    this.summaryControlsDiv = goog.dom.createDom('div', { 'class': 'controls' });
    this.sliderDiv = goog.dom.createDom('div', { 'class': 'slider' });
    this.priorityValueDiv = goog.dom.createDom('div', { 'class': 'value' },
                                               this.priority.toString());
    this.priorityDiv =  goog.dom.createDom('div', { 'class': 'priority' },
                                           this.priorityValueDiv,
                                           this.sliderDiv);
    this.summaryDiv = goog.dom.createDom('div', { 'class': 'summary' },
                                         this.summary,
                                         this.summaryControlsDiv,
                                         this.priorityDiv);
}

mu.tutorial.tasks.Task.prototype.makeDescriptionDom = function() {    
    this.contentElement = goog.dom.createDom('div', { 'class': 'description' }, this.description);
    this.editorElement = goog.dom.createDom('textarea', null, '');

    this.editorContainer = goog.dom.createDom('div', {'style': 'display:none;'},
                                              this.editorElement);

    this.descriptionContainer = goog.dom.createDom('div', null,
                                                   this.contentElement,
                                                   this.editorContainer);
}

mu.tutorial.tasks.Task.prototype.makeDom = function() {
    this.makeSummaryDom();
    this.makeDescriptionDom()

    this.element = goog.dom.createDom('div', { 'class': 'task' },
                                      this.summaryDiv,
                                      this.descriptionContainer);

    this.list.container.appendChild(this.element);

    this.makeSlider(this);

    this.makeButtons(this);

    goog.events.listen(this.contentElement, goog.events.EventType.CLICK,
                       this.openEditor, false, this);

    this.zippy = new goog.ui.Zippy(
        this.summaryDiv,
        this.descriptionContainer);
}

mu.tutorial.tasks.makeTasks = function(name, data, container) {
    mu.tutorial.tasks.taskLists[name] =
        new mu.tutorial.tasks.TaskList(name, data, container);
}

