﻿/*  PersianMenu JS v2.0.0 (2011-06-22) (c) 2009-2011 Ali Yoosefi(Yoosefi12@Yahoo.com), Mehdi Halvaie(mehdi.halvaei@gmail.com)*/

/*  Options --------------------------------------------------------------------------------------------------------------------------------------
/*  direction: 'horizontal'     horizontal,vertical
/*  vdirection: 'down'          down,up
/*  hdirection: 'left'          right,left
/*  showdelay: 400              ms
/*  hidedelay: 400              ms
/*  effect: 'fade'              slide,fade,none
/*  speed: 400                  ms                          default:400
/*  rootid: 0                   int                         default:0
/*  clicksense                  bool                        if true the menu starts with a click. default:false
/*  hideonclick                 bool                        if true, clicking of the menu item causes menu to hide. default:true
/*  treemode                    bool                        if true, position of the submenus changes to 'static', otherwise 'absolute', in this mode 'selected' attribute will add to the selected menu item. default:false
/*  ajaxmode                    bool                        if true, subtrees needs a webservice to call. default:false
                                                            in this mode 'haschild' attribute of the menu item must be in the result of the server
/*  webmethod                   string                      a webservice method to get submenus
/*  webmethodparams             json                        a json object to send to the webservice

/*  Event Options --------------------------------------------------------------------------------------------------------------------------------
/*  events.start()                                          fires when user starts using menu
/*  events.leave()                                          fires when user leaves using menu
/*  events.showsubmenu(dropdown)                            fires when a submenu shows(at the start of effect)
/*  events.hidesubmenu(dropdown)                            fires when a submenu hides(at the end of effect)
/*  events.entermenuitem(menuitem)                          fires when mouse enters to menu item
/*  events.leavemenuitem(menuitem)                          fires when mouse leaves to menu item

/*  Menu data ------------------------------------------------------------------------------------------------------------------------------------
/*  array of { ID: 1, Text: 'text', Tip: 'tip', Href: '#', IconPath:'img.jpg', Attr: [{ Name: "MyAdditionalAttr", Value: "TestValue"}], ParentID: 0 } */

$.fn.PersianMenu = function (menudata, options) {
    var container = $(this);
    var plugingfolder = 'Scripts/';
    var indexer = 0;
    var started = false;
    var methods = {
        //-----------------------------------------------------------------------------
        initoptions: function () {
            options.events = typeof (options.events) == 'undefined' ? {} : options.events;
            options.rootid = (!options.rootid || options.rootid == null) ? 0 : options.rootid;
            options.treemode = typeof (options.treemode) != 'boolean' ? false : options.treemode;
            options.ajaxmode = typeof (options.ajaxmode) != 'boolean' ? false : options.ajaxmode;
            options.clicksense = (typeof (options.clicksense) == 'undefined' || options.clicksense == null) ? false : options.clicksense;
            options.hideonclick = (typeof (options.hideonclick) == 'undefined' || options.hideonclick == null) ? true : options.hideonclick;
            options.speed = (options.speed && options.speed != null) ? options.speed : 400;
        },
        //-----------------------------------------------------------------------------
        toStringFA: function (o) {
            if (o.toString() == '[object Window]') return;
            Str = '{';
            for (var key in o) {
                if (!o.hasOwnProperty || o.hasOwnProperty(key)) {
                    if (o[key] != null)
                        if (typeof (o[key]) == 'object')
                            Str += "'" + key + "':" + toStringFA(o[key]) + ",";
                        else {
                            temp = "'";
                            if (typeof (o[key]) == 'boolean' || typeof (o[key]) == 'number') temp = "";
                            else { o[key] = o[key].replace(/'/gi, "\\'"); }
                            Str += "'" + key + "':" + temp + o[key] + temp + ",";
                        }
                }
            }
            if (Str.length > 1) Str = Str.substring(0, Str.length - 1);
            return Str += "}";
        },
        init: function () {
            for (var i = 0; i < menudata.length; ++i) {
                if (menudata[i].ParentID == options.rootid) {
                    var _level0_icon = $("<img/>").attr('src', menudata[i].IconPath);
                    var _level0_link = $("<a/>").attr('href', menudata[i].Href)
                                            .attr('title', menudata[i].Tip)
                                            .attr('level', 0)
                                            .attr('linkid', menudata[i].ID)
                                            .attr('hover', 'false');
                    //.attr('islast', (i == menudata.length - 1).toString())
                    //.attr('isfirst', (i == 0).toString());
                    if (menudata[i].Attr) {
                        for (var p = 0; p < menudata[i].Attr.length; ++p) {
                            _level0_link.attr(menudata[i].Attr[p].Name, menudata[i].Attr[p].Value);
                        }
                    }

                    if (menudata[i].IconPath && menudata[i].IconPath != null && /*for ie*/menudata[i].IconPath.length > 2) { _level0_link.append(_level0_icon) }
                    _level0_link.append($("<span/>").html(menudata[i].Text)).appendTo(container);

                    var _level0_dropdown = $("<div/>").attr('level', 0)
                                            .attr('dropdownid', menudata[i].ID)
                                            .css('position', options.treemode ? 'static' : 'absolute')
                                            .css('display', 'none')
                                            .css('left', 0)
                                            .appendTo(_level0_link);
                }
            }

            if (!options.ajaxmode) {
                methods.initsubmenus();
                methods.detecthaschilds();
                methods.detectfirstandlast();
            }
            methods.initevents();
        },
        initsubmenus: function (parentid) {
            for (var i = 0; i < menudata.length; ++i) {
                var flag = false;
                if (typeof (parentid) != 'undefined') { flag = menudata[i].ParentID == parentid; }
                else { flag = menudata[i].ParentID != options.rootid; }
                if (flag) {
                    var _leveltop_dropdown = container.find('div[dropdownid="' + menudata[i].ParentID + '"]');
                    var _level1_icon = $("<img/>").attr('src', menudata[i].IconPath);
                    var _level1_link = $("<a/>").attr('href', menudata[i].Href)
                                            .attr('title', menudata[i].Tip)
                                            .attr('level', 1)
                                            .attr('linkid', menudata[i].ID)
                                            .attr('hover', 'false');
                    //.attr('islast', (i == menudata.length - 1).toString())
                    //.attr('isfirst', (i == 0).toString());

                    if (menudata[i].Attr) {
                        for (var p = 0; p < menudata[i].Attr.length; ++p) {
                            _level1_link.attr(menudata[i].Attr[p].Name, menudata[i].Attr[p].Value);
                        }
                    }

                    if (menudata[i].IconPath && menudata[i].IconPath != null && /*for ie*/menudata[i].IconPath.length > 2) { _level1_link.append(_level1_icon); }
                    _level1_link.append($("<span/>").html(menudata[i].Text)).appendTo(_leveltop_dropdown);

                    var _level1_dropdown = $("<div/>").attr('level', 1)
                                            .attr('dropdownid', menudata[i].ID)
                                            .css('position', options.treemode ? 'static' : 'absolute')
                                            .css('display', 'none')
                                            .css('left', 0)
                                            .appendTo(_level1_link);
                }
            }
        },
        //-----------------------------------------------------------------------------
        detecthaschilds: function () {
            container.find('div').each(function () {
                var dropdownid = $(this).attr('dropdownid');
                var link = container.find('a[linkid="' + dropdownid + '"]');
                if ($(this).html().length == 0) {
                    link.attr('haschild', 'false');
                    $(this).remove();
                }
                else {
                    link.attr('haschild', 'true');
                }
            });
        },
        detectfirstandlast: function () {
            container.find('a').attr('isfirst', 'false');
            container.find('a').attr('islast', 'false');
            container.find('a:first-child').attr('isfirst', 'true');
            container.find('a:last-child').attr('islast', 'true'); 
        },
        //-----------------------------------------------------------------------------
        initevents: function () {
            container.find('a').each(function () {
                var start = function ($this) {
                    if (typeof (options.events.entermenuitem) == 'function') { options.events.entermenuitem($this); }
                    var linkid = $this.attr('linkid');
                    var dropdown = container.find('div[dropdownid="' + linkid + '"]');
                    if (dropdown.length > 0 && (dropdown.css('display') == 'none' || dropdown.attr('ishiding') == 'true')) {
                        dropdown.animate({ left: dropdown.css('left') }, options.showdelay, function () {
                            if ($this.attr('hover') == 'true') {
                                if (!options.treemode) { methods.initposition($this, dropdown); }
                                methods.showdropdown(dropdown);

                                if (!options.ajaxmode || dropdown.attr('submenusloaded') == 'true') {

                                } else {
                                    var loadingdiv = $("<div/>").attr('loading', 'true').appendTo(dropdown);
                                    dropdown.attr('submenusloaded', 'true');
                                    var sdata = { ParentID: parseInt(linkid) };

                                    $.extend(sdata, options.webmethodparams);
                                    $.ajax({
                                        type: 'POST', url: options.webmethod, contentType: 'application/json; charset=utf-8', dataType: "json", processData: false, data: methods.toStringFA(sdata),
                                        success: function (recdata) {
                                            dropdown.find("div[loading='true']").remove();
                                            for (var i = 0; i < recdata.d.length; ++i) {
                                                menudata.push(recdata.d[i]);
                                            }
                                            if (!options.treemode) { methods.initposition($this, dropdown); }
                                            methods.initsubmenus(linkid);
                                            methods.initevents();
                                        }
                                    });

                                }

                            }
                        });
                    }
                }

                $(this).unbind('click');
                $(this).unbind('mouseenter');
                $(this).unbind('mouseleave');
                $(this).click(function () {
                    var $this = $(this);
                    var linkid = $this.attr('linkid');
                    if (!options.treemode) {
                        if (options.hideonclick) {
                            var dropdown = container.find('div[dropdownid="' + linkid + '"]:visible');
                            if (dropdown) { methods.hidedropdown(dropdown); }
                        }
                        if (options.clicksense && !started) {
                            start($this);
                            started = true;
                            if (typeof (options.events.start) == 'function') { options.events.start(); }
                        }
                    }
                    else {
                        var visibledropdown = container.find('div[dropdownid="' + linkid + '"]:visible');
                        var hiddendropdown = container.find('div[dropdownid="' + linkid + '"]:hidden');
                        if (visibledropdown.length > 0) { methods.hidedropdown(visibledropdown); $this.removeAttr('selected'); }
                        if (hiddendropdown.length > 0) { start($this); $this.attr('selected', 'true'); }
                        return false;
                    }
                });

                $(this).mouseenter(function () {
                    var $this = $(this);
                    $this.attr('hover', 'true');
                    if (!options.treemode) {
                        if (!options.clicksense || started) {
                            start($this);
                        }
                        if (!options.clicksense && !started) {
                            started = true;
                            if (typeof (options.events.start) == 'function') { options.events.start(); }
                        }
                    }
                });

                $(this).mouseleave(function () {
                    var $this = $(this);
                    $this.attr('hover', 'false');
                    if (!options.treemode) {
                        if (typeof (options.events.leavemenuitem) == 'function') { options.events.leavemenuitem($this); }
                        var linkid = $this.attr('linkid');
                        var dropdown = container.find('div[dropdownid="' + linkid + '"]');
                        if (dropdown.length > 0 && (dropdown.css('display') != 'none' || dropdown.attr('ishiding') == 'true')) {
                            dropdown.animate({ left: dropdown.css('left') }, options.hidedelay, function () {
                                if ($this.attr('hover') != 'true')
                                    methods.hidedropdown(dropdown);
                            });
                        }
                    }
                });
            });
            container.find('div').each(function () {
                $(this).unbind('mouseenter');
                $(this).unbind('mouseleave');
                $(this).mouseenter(function () {
                    var $this = $(this);
                    $this.attr('hover', 'true');
                    if (!options.treemode) {
                        if ($this.attr('ishiding') == 'true') {
                            $this.stop(true, true).show();
                        }
                    }
                });
                $(this).mouseleave(function () {
                    var $this = $(this);
                    $this.attr('hover', 'false');
                    if (!options.treemode) {
                        $this.animate({ left: $this.css('left') }, options.hidedelay, function () {
                            if ($this.find('div[dropdownid]:visible').length == 0)
                                if ($this.attr('hover') != 'true' && $this.parent().attr('hover') != 'true')
                                    methods.hidedropdown($this);
                        });
                    }
                });
            });
        },
        //-----------------------------------------------------------------------------
        hidedropdown: function (dropdown) {
            $(dropdown).attr('ishiding', 'true');
            if (options.effect == 'none')
                dropdown.hide(function () { methods.hideevent(dropdown); });
            if (options.effect == 'fade')
                dropdown.fadeOut(options.speed, function () { methods.hideevent(dropdown); });
            if (options.effect == 'slide')
                dropdown.slideUp(options.speed, function () { methods.hideevent(dropdown); });
        },
        //-----------------------------------------------------------------------------
        showdropdown: function (dropdown) {            
            if (options.effect == 'none')
                dropdown.show(function () { methods.showevent(dropdown); });
            if (options.effect == 'fade')
                dropdown.fadeIn(options.speed, function () { methods.showevent(dropdown); });
            if (options.effect == 'slide')
                dropdown.slideDown(options.speed, function () { methods.showevent(dropdown); });

            if (typeof (options.events.showsubmenu) == 'function') { options.events.showsubmenu(dropdown); }
        },
        //-----------------------------------------------------------------------------
        hideevent: function (dropdown) {
            $(dropdown).attr('ishiding', 'false');
            if (typeof (options.events.hidesubmenu) == 'function') { options.events.hidesubmenu(dropdown); }
            if (container.find('div:visible').length == 0) {
                started = false;
                if (typeof (options.events.leave) == 'function') { options.events.leave(); }
            }
        },
        //-----------------------------------------------------------------------------
        showevent: function (dropdown) {

        },
        //-----------------------------------------------------------------------------
        initposition: function (link, dropdown) {
            var _level = link.attr('level');
            var _width = dropdown.outerWidth()
            var _height = dropdown.outerHeight()
            var _left;
            var _top;
            if (options.direction == "horizontal") {
                if (options.vdirection == "down") {
                    if (options.hdirection == "left") {
                        if (_level == 0) { _left = link.position().left + link.outerWidth() - dropdown.outerWidth(); _top = link.position().top + link.outerHeight(); }
                        if (_level == 1) { _left = link.position().left - dropdown.outerWidth(); _top = link.position().top; }
                    }
                    if (options.hdirection == "right") {
                        if (_level == 0) { _left = link.position().left; _top = link.position().top + link.outerHeight(); }
                        if (_level == 1) { _left = link.position().left + link.outerWidth(); _top = link.position().top; }
                    }
                }
                if (options.vdirection == "up") {
                    if (options.hdirection == "left") {
                        if (_level == 0) { _left = link.position().left + link.outerWidth() - dropdown.outerWidth(); _top = link.position().top - dropdown.outerHeight(); }
                        if (_level == 1) { _left = link.position().left - dropdown.outerWidth(); _top = link.position().top + link.outerHeight() - dropdown.outerHeight(); }
                    }
                    if (options.hdirection == "right") {
                        if (_level == 0) { _left = link.position().left; _top = link.position().top - dropdown.outerHeight(); }
                        if (_level == 1) { _left = link.position().left + link.outerWidth(); _top = link.position().top + link.outerHeight() - dropdown.outerHeight(); }
                    }
                }
            }
            if (options.direction == "vertical") {
                if (options.hdirection == "left") {
                    if (options.vdirection == "down") {
                        if (_level == 0) { _left = link.position().left - dropdown.outerWidth(); _top = link.position().top; }
                        if (_level == 1) { _left = link.position().left - dropdown.outerWidth(); _top = link.position().top; }
                    }
                    if (options.vdirection == "up") {
                        if (_level == 0) { _left = link.position().left - dropdown.outerWidth(); _top = link.position().top + link.outerHeight() - dropdown.outerHeight(); }
                        if (_level == 1) { _left = link.position().left - dropdown.outerWidth(); _top = link.position().top + link.outerHeight() - dropdown.outerHeight(); }
                    }
                }
                if (options.hdirection == "right") {
                    if (options.vdirection == "down") {
                        if (_level == 0) { _left = link.position().left + link.outerWidth(); _top = link.position().top; }
                        if (_level == 1) { _left = link.position().left + link.outerWidth(); _top = link.position().top; }
                    }
                    if (options.vdirection == "up") {
                        if (_level == 0) { _left = link.position().left + link.outerWidth(); _top = link.position().top + link.outerHeight() - dropdown.outerHeight(); }
                        if (_level == 1) { _left = link.position().left + link.outerWidth(); _top = link.position().top + link.outerHeight() - dropdown.outerHeight(); }
                    }
                }
            }

            dropdown.css('left', _left);
            dropdown.css('top', _top);

            methods.initpositionbywindowsize();

        },
        initpositionbywindowsize: function () {
            //var _newleft = dropdown.position().left;
            //var _newtop = dropdown.offset().top;

            //if (_left < 0 || _left + _width > $(window).width()) {
            //alert(_left + " : " + _width + " : " + $(window).width());
            //}
            //else {
            //alert(_left);
            //}   
        }

    }

    methods.initoptions();
    methods.init();
};
