/*****************************************************************************
 * Project HQ - Open Source Project Management                               *
 * ------------------------------------------------------------------------- *
 * Copyright (c) 2008-2010 Raoul Snyman                                      *
 * ------------------------------------------------------------------------- *
 * This program is free software; you can redistribute it and/or modify it   *
 * under the terms of the GNU General Public License as published by the     *
 * Free Software Foundation; version 2 of the License.                       *
 *                                                                           *
 * This program is distributed in the hope that it will be useful, but       *
 * WITHOUT ANY WARRANTY; without even the implied warranty of                *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General  *
 * Public License for more details.                                          *
 *                                                                           *
 * You should have received a copy of the GNU General Public License along   *
 * with this program; if not, write to the Free Software Foundation, Inc.,   *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     *
 *****************************************************************************/

window["ProjectHQ"] = {
    Namespace: {
        /**
         * Create a Javascript namespace.
         * Based on: http://code.google.com/p/namespacedotjs/
         * Idea behind this is to created nested namespaces that are not ugly.
         * Example:
         *                Namespace(foo.bar);
         *                foo.bar..myFunction = function ()  {   }  ;
         */
        create: function (name, attributes)
        {
            var parts = name.split('.'),
            ns = window,
            i = 0;
            // find the deepest part of the namespace
            // that is already defined
            for (; i < parts.length && parts[i] in ns; i++)
            {
                ns = ns[parts[i]];
            }
            // initialize any remaining parts of the namespace
            for (; i < parts.length; i++)
            {
                ns = ns[parts[i]] = {};
            }
            // copy the attributes into the namespace
            for (var attr in attributes)
            {
                ns[attr] = attributes[attr];
            }
        },
        /**
         * Determine the namespace of a page
         */
        exists: function (namespace)
        {
            page_namespace = ProjectHQ.Namespace.getPageNamespace();
            return (namespace == page_namespace);
        },
        getPageNamespace: function ()
        {
            return $("#content > h2").attr("id");
        }
    }
};

Array.prototype.append = function (elem) {
  this[this.length] = elem;
}

ProjectHQ.Namespace.create("ProjectHQ.Events", {
    // Local variables
    onloadFunctions: Array(),
    // Functions
    bindLoad: function (func)
    {
        this.onloadFunctions.append(func);
    },
    liveClick: function (selector, func)
    {
        $(selector).live("click", func);
    },
    bindClick: function (selector, func)
    {
        $(selector).bind("click", func);
    },
    bindChange: function (selector, func)
    {
        $(selector).bind("change", func);
    },
    bindSubmit: function (selector, func)
    {
        $(selector).bind("submit", func);
    },
    bindBlur: function (selector, func)
    {
        $(selector).bind("blur", func);
    },
    bindPaste: function (selector, func)
    {
        $(selector).bind("paste", func);
    },
    bindKeyUp: function (selector, func)
    {
        $(selector).bind("keyup", func);
    },
    bindKeyDown: function (selector, func)
    {
        $(selector).bind("keydown", func);
    },
    bindKeyPress: function (selector, func)
    {
        $(selector).bind("keypress", func);
    },
    getElement: function(event)
    {
        var targ;
        if (!event)
        {
            var event = window.event;
        }
        if (event.target)
        {
            targ = event.target;
        }
        else if (event.srcElement)
        {
            targ = event.srcElement;
        }
        if (targ.nodeType == 3)
        {
            // defeat Safari bug
            targ = targ.parentNode;
        }
        return $(targ);
    },
    init: function ()
    {
        for (idx in this.onloadFunctions)
        {
            var func = this.onloadFunctions[idx];
            func();
        }
    }
});

ProjectHQ.Namespace.create("ProjectHQ.Widgets", {
    /**
     * Adds a datepicker to an element.
     */
    datePicker: function (selector)
    {
        $(selector).datepicker({showButtonPanel: true, dateFormat: "dd/mm/yy"});
    },
    /**
     * Create a collapsible fieldset.
     */
    collapsibleFieldset: function (selector)
    {
        $("> legend", selector).each(function() {
            var legend = $(this);
            var legend_text = legend.text();
            legend.text("");
            legend.append(
                $("<a>").attr("href", "#").attr("title", "Expand/collapse details")
                    .text(legend_text).click(function (e) {
                        var fieldset = ProjectHQ.Events.getElement(e).parent().parent();
                        var content = $('> div', fieldset);
                        if (fieldset.is('.collapsed'))
                        {
                            fieldset.removeClass('collapsed');
                            content.slideDown('normal');
                        }
                        else
                        {
                            content.slideUp('normal', function() {
                                fieldset.addClass('collapsed');
                            });
                        }
                    })
            );
        });
        $("fieldset.collapsed").each(function() {
            $("> div.content", this).slideUp("normal");
        });
    },
    /**
     * Initialises elastic textareas
     */
    elasticTextarea: function (selector)
    {
        $(selector).elastic();
    }
});

ProjectHQ.Namespace.create("ProjectHQ.Utils", {
    confirmAction: function (selector, message)
    {
        ProjectHQ.Events.bindClick(selector, function () {
            if (confirm(message))
            {
                return true;
            }
            else
            {
                return false;
            }
        });
    }
});

ProjectHQ.Namespace.create("ProjectHQ.General", {
    /**
     * Fades out a message
     */
    fadeMessage: function ()
    {
        $("#message").hide().fadeIn("slow", function() {
            setTimeout("$('#message').fadeOut('slow');", 1500);
        });
    },
    /**
     * Checks for a message and fades it in and out.
     */
    showMessage: function ()
    {
        if ($("#message"))
        {
            setTimeout("ProjectHQ.General.fadeMessage()", 500);
        }
    },
    /**
     * Dynamically hide anything on the page that has a "jshidden" class.
     */
    hideElements: function ()
    {
        $(".jshidden").hide();
    },
    /**
     * Sets the active project
     */
    setProject: function ()
    {
        $('#project-selector > div.content').hide();
        $('#project-throbber').show();
        var project_id = $("#CurrentProject").val();
        $.get('/dashboard/ajax_project/' + project_id, function () {
            window.location.reload();
        });
    }
});

/**
 * Global onload
 *
 * This function below will be executed on all page views.
 */
ProjectHQ.Events.bindLoad(function () {
    // Hide hidden elements
    ProjectHQ.General.hideElements();
    // Bind the change project function to the select
    ProjectHQ.Events.bindChange("#CurrentProject", ProjectHQ.General.setProject);
    // Initialise collapsible fieldsets
    ProjectHQ.Widgets.collapsibleFieldset("fieldset.collapsible");
    // Initialise elastic textareas
    ProjectHQ.Widgets.elasticTextarea("textarea");
    // Show any flash messages
    ProjectHQ.General.showMessage();
    ProjectHQ.Utils.confirmAction("a.link-delete[href^=/milestone/delete]",
        "Are you sure you want to delete this milestone? All tasks and task lists " +
        "associated with this milestone will also be deleted!");
    ProjectHQ.Utils.confirmAction("a.link-delete[href^=/task_list/delete]",
        "Are you sure you want to delete this task list? All tasks associated with " +
        "this task list will also be deleted!");
    ProjectHQ.Utils.confirmAction("a.link-delete[href^=/task/delete]",
        "Are you sure you want to delete this task?");
    ProjectHQ.Utils.confirmAction("a.link-delete[href^=/role/delete]",
        "Are you sure you want to delete this role?");
});

