﻿/// <reference path="~/Scripts/EduDesk.js"/>
/*
Drop Down Menu

To use a dropdown menu you must create an instance of it by giving it a name.
    - edu.DropDown.create("mydropdown", ["SWEEEET", "Yay"]);
    - edu.DropDown.create("mydropdown", [{text: "Sweeet"}, {text: "Yay"}];
    
Now your dropdown is ready to be opened anytime. To open this menu we can either make it pop up
underneath a DOM Element or any X, Y position relative to the top-left of the document.
    - edu.DropDown.show("mydropdown", document.getElementById('myanchor'));
    - edu.DropDown.showAt("mydropdown", 400, 400);

You can also just attach the dropdown to a click event automatically using
    - edu.DropDown.attach_to_element("mydropdown", document.getElementById('myanchor'));

*/

edu = window.edu || {};

edu.DropDown = new function() {
    var menus = {};
    var ele;
    var active = null;


    this.create = function(name, data, params) {
        /// <summary> Creates a Menu to be usable later </summary>
        /// <param name="name" type="String">Name of the Menu</param>
        /// <param name="data" type="Array">Array of Data to be used for making the menu</param>
        /// <param name="params" type="Object">Parameters for the menu: width, css (dictionary), class (string), onItemClick, onMenuShow, onMenuHide</param>
        params = params || {};
        params.width = params.width || "150px";

        menus[name] = { name: name, data: data, params: params, element: null, activeElement: null };
    };

    this.remove = function(name) {
        if (menus[name].element)
            menus[name].element.remove();
        delete menus[name];
    };

    this.show = function(name, obj) {
        /// <summary> Shows a Menu under an element
        /// <param name="obj" type="Object">Parameters for display</param>
        var pos = $(obj).offset();

        // Keep track that this object is marked as active
        $(obj).addClass("activeMenu");
        menus[name].activeElement = obj;

        this.showAt(name, pos.left, pos.top + $(obj).outerHeight());
    };

    function on_document_click(e) {
        if (e.target.nodeName == "SELECT" || e.target.nodeName == "INPUT") {
            $(document).bind("click", e.data, on_document_click);
            return;
        }
        else {
            e.data.hide();
        }
    };

    this.showAt = function(name, x, y) {
        /// <summary> Shows a Menu at a absolute position
        /// <param name="x" type="Number">X coordinate</param>
        /// <param name="y" type="Number">Y coordinate</param>
        if (!ele) init();
        if (active) {
            this.hide();
        }
        
        var element = menus[name].element || createElement(name);

        element.css("left", x)
               .css("top", y)
               .css("z-index", 1000)
               .slideDown("fast");

        var h = function(e) { }
        $(document).unbind("click", on_document_click);
        $(document).bind("click", this, on_document_click);

        active = name;
        if (menus[active].params["onMenuShow"]) menus[active].params["onMenuShow"](active);
    };

    this.hide = function() {
        /// <summary> Hides the currently displayed menu </summary>
        if (active) {
            $(menus[active].element).fadeOut("fast").css("z-index", 0);
            if (menus[active].params["onMenuHide"]) menus[active].params["onMenuHide"](active);

            if (menus[active].activeElement) {
                $(menus[active].activeElement).removeClass("activeMenu");
                menus[active].activeElement = null;
            }
            active = null;
            $(document).unbind("click", on_document_click);
        }
    };

    this.attachGroup = function(ele, menu, group) {
        group = group || "main";
        menus[menu].group = group;

        if (menus[menu].data.length != 0)
            $(ele).bind("click", this, function(e) { if (active != menu) { e.data.show(menu, ele); return false; } });
        $(ele).bind("mouseenter", this, function(e) { if ((active) && (active != menu) && (menus[active].group == group)) e.data.show(menu, ele); });
    };

    this.attach_to_element = function(name, ele) {
        $(ele).click(function(e) {
            edu.DropDown.show(name, ele);
            return false;
        });
    };


    function init() {
        ele = $("<div></div>")
            .css("position", "absolute")
            .css("top", "0px")
            .css("left", "0px")
            .appendTo(document.body)
            .click(function(e) {
                if (active) {
                    var t = $(e.target);
                    var count = 0;
                    while (typeof (t.data("dropDownIndex")) == "undefined") {
                        if (count++ > 10) return;

                        t = $(t.parent().get(0));
                        if (t.data("dropDown"))
                            return true;
                    }

                    var i = t.data("dropDownIndex");
                    if (menus[active].params["onItemClick"]) {
                        menus[active].params["onItemClick"](menus[active].data[i], i);
                    }
                }
            });
    }

    function createElement(name) {
        var data = menus[name].data;
        var _ele = $("<div>")
                    .css("width", menus[name].params["width"])
                    .css("position", "absolute")
                    .css(menus[name].params["css"] || {})
                    .addClass("DropDownMenu")
                    .data("dropDownMenu", name)
                    .appendTo(ele)
                    .hide();

        if (menus[name].params["class"]) {
            _ele.addClass(menus[name].params["class"]);
        }

        for (var i = 0; (i < data.length); i++) {
            var itemE = $("<a></a>");
            if (typeof (data[i]) == 'string') {
                itemE.text(data[i]);
            }
            else {
                for (var p in data[i]) {
                    if (p == "element") {
                        $(data[i][p]).appendTo(itemE);
                    }
                    else if (p == "css") {
                        $.each(data[i][p], function(i, val) {
                            itemE.css(i, val);
                        });
                    }
                    else if (p == "text") {
                        itemE.text(data[i][p]);
                    }
                    else if (p == "click") {
                        itemE.click(data[i][p]);
                    }
                    else {
                        itemE.attr(p, data[i][p]);
                    }
                }
            }
            itemE.addClass("DropDownMenuItem")
                    .data("dropDownIndex", i)
                    .appendTo(_ele);
        }

        if (data.length == 0)
            _ele.css({ "height": '0px', "border": "0" });
        menus[name].element = _ele;

        return _ele;
    }
}
