﻿function SuperBTMNav() {

    this.j = null;

    this.S = {
        TreeID: '',
        DrawAreaID: '',
        TextOnlyClass: '',
        RootMenuClass: '',
        SubMenuClass: '',

        ItemWidth: 40,
        ItemHeight: 40,
        SubItemWidth: 40,
        OverlapX: 5,
        OverlapY: 5,
        RightToLeft: false,
        MouseOutCloseTimeout: 1500,
        MenuFadeTime: 200, /// FIX THIS VALUE TO "200" 
        SpriteOBJ: null,
        RootSpritesOnly: true,
        GetCloserSubMenus: false,
        HorizNav: true,

        RootMarginTop: 0,
        RootMarginBottom: 0,
        RootMarginLeft: 0,
        RootMarginRight: 0,

        SubsMarginTop: 0,
        SubsMarginBottom: 0,
        SubsMarginLeft: 0,
        SubsMarginRight: 0

    };


    this._idCounter = 0;
    this._idCounterB = 0;
    this._spritePosCounter = 0;
    this._zCounter = 20;
    



    this.AppliesSprites = function(menuItem) {
        if (this.S.SpriteOBJ == null) return false;
        if (this.S.RootSpritesOnly && menuItem.Dept != 0) return false;
        return true;
    }


    this.DrawDraw = function(menuItem) {
        var t = this;

        var isRoot = menuItem.Dept == 0;

        /// WE ARE NOT RE-CREATING THIS ITEM IF IT ALREADY EXISTS IN THE DOM.
        ///
        if (this.j('#' + menuItem.ID).length > 0) return;

        var floatLeft = "";
        if (isRoot && this.S.HorizNav) floatLeft = " float:left;";

        var ml = (isRoot) ? this.S.RootMarginLeft : this.S.SubsMarginLeft;
        var mr = (isRoot) ? this.S.RootMarginRight : this.S.SubsMarginRight;
        var mt = (isRoot) ? this.S.RootMarginTop : this.S.SubsMarginTop;
        var mb = (isRoot) ? this.S.RootMarginBottom : this.S.SubsMarginBottom;

        var w = (isRoot) ? this.S.ItemWidth : this.S.SubItemWidth;

        /// FABRICATING A STYLE FOR TEXT-ONLY ELEMENTS THAT DON'T CONTAIN A CSS CLASS.
        /// 
        var additionalStyle = '';
        if ((!isRoot && this.S.RootSpritesOnly) || this.S.SpriteOBJ == null) {
            if (this.S.TextOnlyClass == '' || this.S.TextOnlyClass == undefined) {
                additionalStyle = 'background-color:#999; border:1px solid #666; padding:10px; ' +
                    'font-family:Verdana; font-size:11px; color:White;';
            }
        }

        var claz = '';
        if (this.S.TextOnlyClass != '' && this.S.TextOnlyClass != undefined)
            claz = ' class="' + this.S.TextOnlyClass + '" '


        var menuItemHtml = '<div ' + claz + ' style="width:' + w + 'px; ' +
                'margin-left:' + ml + 'px; margin-right:' + mr + 'px; ' +
                'margin-top:' + mt + 'px; margin-bottom:' + mb + 'px; ' +
                'cursor:pointer; overflow:hidden; ' + floatLeft + additionalStyle + '" id="' + menuItem.ID + '">' +
                menuItem.Text + '</div>';


        if (!isRoot || !this.S.HorizNav) {

            /// ADDING AN EXTRA DIV TO HELP ENFORCING THE MARGINS. THIS PREVENTS THE KNOW "COLLAPSING BORDERS" EFFECT.
            ///
            menuItemHtml += '<div style="border-bottom:1px solid transparent; visibility:hidden;"></div>';
        }


        ///
        /// CREATING SOME DEFAULT STYLES IF THERE IS NO CLASS SPECIFIED FOR TEXT-ONLY SPRITES.
        ///
        //        if (this.S.TextOnlyClass == '') {


        //            this.j('#' + menuItem.ID).css({
        //                border: '1px solid #666',
        //                padding: '4px',
        //                margin: '4px',
        //                backgroundColor: '#999',
        //                color: 'white'
        //            });
        //        }


        if (this.AppliesSprites(menuItem)) {
            //            menuItemHtml = '<div id="' + menuItem.ID + '" style="' +
            //                'border:1px solid red; cursor:pointer; ' + floatLeft + '">' +
            //                menuItem.Text + '</div>';
        }


        this.j('#' + menuItem.Container.CID).append(menuItemHtml);



        var spriteIsNull = this.S.SpriteOBJ == null;



        if (spriteIsNull) {

            this.j('#' + menuItem.ID).css({ border: '1px solid gray', padding: 10 });

            /// DEALING WITH THE MOUSE-OVER EVENTS
            ///
            this.j('#' + menuItem.ID).bind('mouseover', function() { t.Draw(menuItem); menuItem.MouseOver(); });

            /// DEALING WITH THE MOUSE-OUT EVENTS
            ///
            this.j('#' + menuItem.ID).bind('mouseout', function() { menuItem.MouseOut(); });

        } else {

            /// CREATING THE SPRITE...
            /// WE NEED TO SEND A CALLBACK FOR WHEN THE EVENTS ARE TRIGGERED.

            var textOnly = false;
            if (this.S.RootSpritesOnly && menuItem.Dept > 0) textOnly = true;


            //            var marginTop = this.S.SubsMarginTop;
            //            var marginBottom = this.S.SubsMarginBottom;
            //            var marginRight = this.S.SubsMarginRight;
            //            var marginLeft = this.S.SubsMarginLeft;

            //            /// ADDING MARGINS TO THE ROOT-MENU ELEMENTS.
            //            ///
            //            if (menuItem.Dept == 0) {
            //                marginTop = this.S.RootMarginTop;
            //                marginBottom = this.S.RootMarginBottom;
            //                marginRight = this.S.RootMarginRight;
            //                marginLeft = this.S.RootMarginLeft;
            //            }


            var sprite = this.S.SpriteOBJ.Create(
                '#' + menuItem.ID, {
                    MouseOver: function() { t.Draw(menuItem); menuItem.MouseOver(); },
                    MouseOut: function() { menuItem.MouseOut(); },
                    MouseDown: function() { location.href = menuItem.Link },
                    Rank: menuItem.SpritePosition,
                    Width: (textOnly) ? w : null,
                    TextOnly: textOnly//,
                    //                    MarginTop: marginTop,
                    //                    MarginBottom: marginBottom,
                    //                    MarginRight: marginRight,
                    //                    MarginLeft: marginLeft
                });

            menuItem.Sprite = sprite;

        }

    }



    this.Draw = function(nodeItem) {

        var t = this;

        var childrenCount = nodeItem.ChildrenMenu.length;

        /// GETTING OUTTA HERE, NO CHILDREN.
        ///
        if (childrenCount == 0) return;

        /// HABEMUS CHILDREN. GETTING THE FIRST ONE TO INFER THE CONTAINER.
        var firstMenuItem = nodeItem.ChildrenMenu[0];


        /// CHECKING IF THIS SET OF BUTTONS ALREADY HAS A CONTAINER.
        ///
        var containerExists = this.j('#' + firstMenuItem.Container.CID).length > 0;


        /// CREATING THE DIV CONTAINER LOGIC.
        ///
        firstMenuItem.Container.CreateContainer(
            this.S.DrawAreaID,
            this._zCounter,
            (firstMenuItem.Container.DeptContainer == 0) ? this.S.RootMenuClass : this.S.SubMenuClass
        );
        this._zCounter += 10;



        for (var n = 0; n < childrenCount; n++) {
            var menuItem = nodeItem.ChildrenMenu[n];
            this.DrawDraw(menuItem);
        }


        if (!containerExists) {
            /// APPENDING A CLEAR-BOTH ON THE CONTAINERS SO THE MARGIN-BOTTOM CAN WORK AS EXPECTED.
            ///
            this.j('#' + firstMenuItem.Container.CID).append(
                '<div style="clear:both; display:block; height:0px; width:0px;" />');
        }




        if (nodeItem.IsRoot) {

            /// HMMM... THE ANIMATION LOGIC ?
            /// SHOW SHOW SHOW !!
            this.j('#' + firstMenuItem.Container.CID).show();

            return;

        } else {

            /// HMMM... THE ANIMATION LOGIC ?
            /// SHOW SHOW SHOW !!
            this.j('#' + firstMenuItem.Container.CID).fadeIn();

        }

        var OX = this.S.OverlapX;
        var OY = this.S.OverlapY;
        var horiz = this.S.HorizNav;
        var lToR = !this.S.RightToLeft;


        var cont_bound = this.j.fn.Boundaries(this.j('#' + nodeItem.Container.CID), this.j);

        var cont_off = this.j('#' + nodeItem.Container.CID).offset();

        var cont_height = this.j('#' + nodeItem.Container.CID).outerHeight(false);

        var cont_width = this.j('#' + nodeItem.Container.CID).outerWidth(false);

        var node_off = this.j('#' + nodeItem.ID).offset();

        var subNode_width = this.j('#' + firstMenuItem.Container.CID).outerWidth(false);

        var subNode_bound = this.j.fn.Boundaries(this.j('#' + firstMenuItem.Container.CID), this.j);

        var absLeft = 0;

        var absTop = 0;


        /// CHECKING IF THE MENU TO DISPLAY IS THE FIRST SUBMENU IN A HORIZ LAYOUT.
        /// IF THAT'S THE CASE, THIS MENU DOESN'T GO TO THE RIGHT OF THE TRIGGERING CONTAINER.
        /// IT GOES BELOW.
        ///
        if (horiz && nodeItem.Dept == 0) {

            ///
            /// HANDLING FIRST SET OF SUB-MENU ON HORIZ MENUS ONLY.
            ///

            absTop = cont_off.top + cont_height + cont_bound.MarginBottom - OY;

            var node_height = this.j('#' + nodeItem.ID).outerHeight(false);

            var node_width = this.j('#' + nodeItem.ID).outerWidth(false);

            absLeft = node_off.left - OX;


            ///
            /// IF RIGHT TO LEFT:
            /// 
            if (!lToR) {

                /// IF THE DIRECTION IS INVERTED, WE HAVE NO NEUTRALIZE THE THE RIGHT MARGIN AND ADD
                /// THE LEFT MARGIN TO THE FORMULA.
                ///
                absLeft = node_off.left + node_width - subNode_width -
                    subNode_bound.MarginLeft - subNode_bound.MarginRight + OX;

            }


        } else {

            absTop = node_off.top - OY;

            if (nodeItem.Dept == 0 && !lToR) {

                ///
                /// HANDLING FIRST SET OF SUB MENUS ON RIGHT TO LEFT && VERT-NAVS.
                /// 

                var outerWidth = subNode_width + cont_bound.MarginLeft;

                absLeft = cont_off.left - outerWidth - subNode_bound.MarginLeft -
                    subNode_bound.MarginRight + OX;

            } else {

                ///
                /// HANDLING NON-ROOT MENUS ON VERT && HORIZ MENUS.
                /// 

                absLeft = cont_off.left + cont_width + cont_bound.MarginRight - OX;


                ///
                /// IF RIGHT TO LEFT:
                ///
                if (!lToR) {

                    var outerWidth = subNode_width + subNode_bound.MarginLeft;

                    absLeft = cont_off.left - outerWidth - subNode_bound.MarginLeft -
                        subNode_bound.MarginRight + OX;

                }

            }

        }


        /// APPLYING THE LEFT-TO-RIGHT ALIGNMENT IF REQUIRED.
        ///
        this.j('#' + firstMenuItem.Container.CID).css({
            left: absLeft + 'px',
            top: absTop + 'px'
        });



    }





    this.PopulateNode = function (objNode, parentNode, containerNode) {

        var t = this;

//        var tag = objNode.attr('tagName');
        var tag = this.j(objNode).get(0).nodeName;


        if (tag == "UL") {

            /// THIS NODE CONTAINS CHILDREN. A "UL" CAN ONLY CONTAIN "LI" DIRECTLY IN IT.
            var children = objNode.children('li');

            var newContainer = new BTMNavContainer(this.j, this);
            newContainer.IsRootContainer = false;
            newContainer.CID = "c_" + t._idCounterB++;
            newContainer.ParentContainer = containerNode;
            newContainer.DeptContainer = containerNode.DeptContainer + 1;

            /// STORING THIS NEW CONTAINER IN THE PARENT NODE CONTAINER ARRAY, TO KEEP TRACK OF 
            /// A HIERARCHY.
            parentNode.Container.ChildrenContainer[parentNode.Container.ChildrenContainer.length] = newContainer;

            /// WE ARE SCANNING ALL THE "LI", MAINTAINING THE SAME PARENT.
            children.each(function () {
                t.PopulateNode(t.j(this), parentNode, newContainer);
            });

        } else if (tag == "LI") {

            var linName = "";

            /// THE "LI" TAG CAN CONTAIN "A" OR "UL" TAGS.
            ///
            var children = objNode.children();

            /// CREATING THE MENU-OBJECT
            var oneItem = new BTMNavMenuItem(this.j, this);
            oneItem.Link = "--undefined--";
            oneItem.Text = "--undefined--";
            oneItem.ID = 'm_' + this._idCounter++;


            /// PASSING THE CONTAINER REFERENCE BETWEEN SIBBLINGS (BROS OR SIS).
            /// SIBBLINGS ARE AT THE SAME LEVEL, SO THEY SHARE THE SAME CONTAINER.
            ///
            oneItem.Container = containerNode;
            oneItem.Dept = containerNode.DeptContainer;


            /// NOW WE HAVE TO INCREASE THE SPRITE-POSITION-COUNTER.
            /// BUT WE HAVE TO DO IT IN SOME CASES, NOT ALL OF THEM:
            if (this.S.RootSpritesOnly && oneItem.Dept == 0 || !this.S.RootSpritesOnly)
                oneItem.SpritePosition = ++this._spritePosCounter;


            /// APPENDING THIS MENU NODE TO THE PARENT, SO WE CAN KEEP A HIERARCHY
            ///
            parentNode.ChildrenMenu[parentNode.ChildrenMenu.length] = oneItem;

            /// STORING THIS MENU NODE PARENT'S AS A REFERENCE SO WE CAN KEEP A HIERARCHY :: )
            oneItem.ParentMenu = parentNode;


            /// WE ARE SCANNING ALL THESE FOUND CHILDREN
            children.each(function () {
                t.PopulateNode(t.j(this), oneItem, containerNode);
            });

        } else if (tag == "A") {

            parentNode.Link = objNode.attr('href')
            parentNode.Text = objNode.text();

        } else {

            throw 'not supported error';

        }

    }


    this._to = null;
    this.TimerOn = function() {
        var t = this;
        this._to = setTimeout(function() {
            t.j(document).trigger('CloseEverything');
        }, t.S.MouseOutCloseTimeout);
    }

    this.TimerOff = function() {
        clearTimeout(this._to);
    }


    this.Setup = function(jQuery, settings) {

        this.j = jQuery;

        this.S.TreeID = '#' + settings.TreeID;
        this.S.DrawAreaID = '#' + settings.DrawAreaID;
        this.S.TextOnlyClass = settings.TextOnlyClass;
        this.S.RootMenuClass = settings.RootMenuClass;
        this.S.SubMenuClass = settings.SubMenuClass;
        this.S.SpriteOBJ = settings.SpriteOBJ;
        this.S.RootSpritesOnly = settings.RootSpritesOnly == true;
        this.S.GetCloserSubMenus = settings.GetCloserSubMenus == true;
        this.S.HorizNav = settings.HorizNav == true;
        this.S.RightToLeft = settings.RightToLeft == true;

        this.S.RootMarginTop = isNaN(settings.RootMarginTop) ? 0 : settings.RootMarginTop;
        this.S.RootMarginBottom = isNaN(settings.RootMarginBottom) ? 0 : settings.RootMarginBottom;
        this.S.RootMarginRight = isNaN(settings.RootMarginRight) ? 0 : settings.RootMarginRight;
        this.S.RootMarginLeft = isNaN(settings.RootMarginLeft) ? 0 : settings.RootMarginLeft;

        this.S.SubsMarginTop = isNaN(settings.SubsMarginTop) ? 0 : settings.SubsMarginTop;
        this.S.SubsMarginBottom = isNaN(settings.SubsMarginBottom) ? 0 : settings.SubsMarginBottom;
        this.S.SubsMarginRight = isNaN(settings.SubsMarginRight) ? 0 : settings.SubsMarginRight;
        this.S.SubsMarginLeft = isNaN(settings.SubsMarginLeft) ? 0 : settings.SubsMarginLeft;

        this.S.ItemWidth = isNaN(settings.ItemWidth) ? 40 : settings.ItemWidth;
        this.S.ItemHeight = isNaN(settings.ItemHeight) ? 20 : settings.ItemHeight;
        this.S.SubItemWidth = isNaN(settings.SubItemWidth) ? 40 : settings.SubItemWidth;
        this.S.OverlapX = isNaN(settings.OverlapX) ? 0 : settings.OverlapX;
        this.S.OverlapY = isNaN(settings.OverlapY) ? 0 : settings.OverlapY;

        var tmp = this.S.MouseOutCloseTimeout
        this.S.MouseOutCloseTimeout = isNaN(settings.MouseOutCloseTimeout) ? tmp : settings.MouseOutCloseTimeout;

        tmp = this.S.MenuFadeTime
        this.S.MenuFadeTime = isNaN(settings.MenuFadeTime) ? tmp : settings.MenuFadeTime;


        var t = this;
        this.j(document).bind('MenuOut', function() {
            t.TimerOn();
        });

        this.j(document).bind('MenuOpened', function() {
            t.TimerOff();
        });


        var drawAreaExists = this.j(this.S.DrawAreaID).length == 1;
        if (!drawAreaExists) {
            alert('Can\'t not initialize the BTM NAV VAR, no draw area named [' +
                this.S.DrawAreaID.replace('#', '') + '] was found');
            return;
        }

        var menuExists = this.j(this.S.TreeID).length == 1;
        if (!menuExists) {
            alert('Can\'t not initialize the BTM NAV VAR, no menu named [' +
                this.S.TreeID.replace('#', '') + '] was found');
            return;
        }



        var rootContainer = new BTMNavContainer(this.j, this);
        rootContainer.IsRootContainer = true;
        rootContainer.CID = "c_" + this._idCounterB++;
        rootContainer.DeptContainer = -1;

        var rootItem = new BTMNavMenuItem(this.j, this);
        rootItem.IsRoot = true;
        rootItem.ID = "m_" + this._idCounter++;
        rootItem.Container = rootContainer;
        rootItem.Dept = -1;

        this.PopulateNode(this.j(this.S.TreeID), rootItem, rootContainer);

        this.menuTree = rootItem;

        this.j(this.S.TreeID).hide();

        this.Draw(rootItem);
    }





    /////////////////////////////////////////
    /////////////////////////////////////////
    /////////////////////////////////////////
    //////
    //////  LOGGING 
    //////

    this._isLocalHostVar = undefined;
    this._IsLocalHost = function() {
        if (this._isLocalHostVar == undefined)
            this._isLocalHostVar = document.URL.indexOf("localhost") > -1;
        return this._isLocalHostVar;
    }

    this._myLogger = false;
    this._myLoggerCount = 0;
    this._myLogLevel = 3;
    this.DoLog = function(msg, logLevel) {
        var gotcha = true;

        if (this._myLogLevel != undefined) {
            if (logLevel != this._myLogLevel) return;
        }
        if (this._IsLocalHost()) {
            if (!this._myLogger) {
                this.j('body').append(
                    '<div style="background-color: #FFFFE8; font-size:11px; font-family:arial; ' +
                        'border:2px solid green; position:fixed; width:400px; min-height:400px; ' +
                        'max-height:850px; padding:10px; top:0px; left:70%; overflow:scroll;" id="_logConsole">'
                );
                this._myLogger = true;
            }
            this.j('#_logConsole').prepend('<div class="_logRow">' + (this._myLoggerCount++) + " > " +
                msg + '<br /><br /></div>');
        }
    }

    //////
    //////  END - LOGGING 
    //////
    /////////////////////////////////////////
    /////////////////////////////////////////
    /////////////////////////////////////////


    this.GetNumericPixel = function(string){
        var str = string.replace('px', '');
        var num = parseInt(str);
        if (isNaN(num))num = 0;
        return num;
    }


}




function BTMNavContainer(jQuery, owner) {
    this.CID = null;        /// I'M NAMING IT "CID" INSTEAD OF "ID" BECAUSE I'M EASILY 
                            /// MIXING THIS OBJECT WITH THE MENU ITEM OBJECT.
    this.IsRootContainer = false;
    this.ParentContainer = null;
    this.ChildrenContainer = new Array;

    this._timeout_this = null;
    this._zCounter = 0;

    this.DeptContainer = 0;

    this.j = jQuery;
    this.owner = owner;

    this.Exists = function() {
        var exists = this.j('#' + this.CID).length == 1;
        return exists;
    }


    this.CreateContainer = function(whereSelector, zIndex, cssClass) {

        if (this.Exists()) return;

        this.Extinguish();

        var html = '';

        /// CHECKING IF A CLASS NAME WAS SUPPLIED OR IF A DEFAULT STYLE SHOULD BE CREATED
        /// (FOR VISIBILITY PURPOSES, IF NO CLASS NAME IS PROVIDED A DEFAULT STYLE WILL BE IMPLEMENTED)
        ///
        if ((cssClass + '') == '') {
            html = '<div id="' + this.CID +
                '" style="position:absolute; display:none; background-color:#F5F5F5; border:1px solid #E5E5E5; ' +
                'margin:2px; padding:2px; z-index:' + (zIndex + 4) + '; font-family:Arial; font-size:11px;" />';
        } else {
            html = '<div class="' + cssClass + '" id="' + this.CID +
                '" style="position:absolute; display:none; z-index:' + (zIndex + 4) + '; " />';
        }

        this.j(whereSelector).append(html);
    }


    this.Extinguish = function() {
        this.j('#' + this.CID).remove();
        this.j('#' + this.CID).stop();
    }



    this.CloseSubContainers = function() {
        this.j(this.ChildrenContainer).each(function() {
//            this.CloseContainer();
        });
    }

    this.CloseContainer = function() {
        /// WE ARE NEVER CLOSING THE DEPT-0 CONTAINERS.
        ///
        if (this.Exists()) {
            this.owner.DoLog('<strong>Container closed, CID [' + this.CID + '], exists [true]</strong>');
            this.j(document).trigger('ContainerClosed', [this]);

            var t = this;

            /// REMOVING ALL THE EVENTS FROM THIS CONTAINER AND ALL ITS CHILDREN DOM OBJECTS
            /// TO PREVENT ANOMALIES DURING CLOSING.
            ///
            this.j('#' + this.CID).unbind();
            this.j('#' + this.CID).find('*').unbind();
            this.j('#' + this.CID).fadeOut(t.owner.S.MenuFadeTime, function() { t.Extinguish(); });

        } else {
            this.owner.DoLog('not closed, it doesn\'t exist [' + this.CID + ']');
        }
    }



    var t = this;
    this.j(document).bind('ContainerClosed', function(evtArgs, containerObj) {
//        return;
        /// TESTING IF THE TRIGGERING CONTAINER AND THE HANDLING CONTAINER ARE THE SAME PEOPLE.
        ///
        if (t.CID != containerObj.CID) return;

        /// THE TRIGGER AND THE HANDLER ARE THE SAME.
        /// CLOSING THE SUB-CONTAINERS.
        t.owner.DoLog('<i>Requesting to close sub containers for the container [' + t.CID + ']</i>');


        for (var n = 0; n < containerObj.ChildrenContainer.length; n++) {
            containerObj.ChildrenContainer[n].CloseContainer();
        }

    });





    this.j(document).bind('CloseEverything', function() {
//        return;
        if (t.DeptContainer == 0) {
            t.owner.DoLog('<strong style="color:Maroon;">ABSOLUTE CLOSURE REQUESTED. Starting from root container [' + t.CID + ']</strong>');
            t.CloseSubContainers();
        }
    });



}



function BTMNavMenuItem(jQuery, owner) {

    this.ID = null; //Math.round(Math.random() * 10000);
    this.Text = null;
    this.Link = null;
    this.IsRoot = false;
    this.ChildrenMenu = new Array();
    this.ParentMenu = null;
    this.TimeOutObj = null;
    this.Container = null;
    this.Dept = 0;
    this.j = jQuery;
    this.owner = owner;

    /// THIS PROPERTY IS USED IDENTIFY THIS MENU ITEM WITHIN THE WHOLE SPRITE.
    this.SpritePosition = -1;


    /// THE SPRITE GATEWAY OBJECT SHOULD BE STORED HERE.
    this.Sprite = null;

    ///////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////

    this.Extinguish = function() {
        this.j('#' + this.Container.CID).remove();
    }



    this.MouseOver = function() {
        this.j(document).trigger('MenuOpened', this);
    }


    this.MouseOut = function() {
        this.j(document).trigger('MenuOut', this);
    }



    var t = this;
    this.j(document).bind('MenuOpened', function(evtArgs, menuItemObj) {
        /// CHECKING IF THE MENU ITEM HANDLING THE EVENT IS AT THE SAME LEVEL OF
        /// THE MENU ITEM TRIGGERING IT.
        ///
        if (t.Dept == menuItemObj.Dept) {
            /// CHECKING IF THE MENU TRIGGERING THE EVENT IS THE SAME ID
            /// OF THE MENU HANDLING THE EVENT.
            if (t.ID == menuItemObj.ID) {
                /// THE TRIGGER AND THE HANDLER ARE THE SAME.
                /// TURN ON THE SPRITE AND DON'T DO ANYTHING ELSE...
                if (t.Sprite != null) t.Sprite.TurnOn();

            } else {
                /// THE TRIGGER AND THE HANDLER ARE DIFFERENT.
            /// CLOSING THE CONTAINERS.
                t.owner.DoLog('Requesting to close sub containers for menu [' + t.Text + ']');

                /// TURNING OFF THE SPRITE, IF ANY.
                if (t.Sprite != null) t.Sprite.TurnOff();

                /// OK, WE CHECK IF THE CURRENT ITEM HAS CHILDREN. 
                /// IF IT HAS CHILDREN, THEN WE PICK THE FIRST OF THEM SO WE CAN INFER THE CONTAINER.
                if (t.ChildrenMenu.length > 0) {
                    t.ChildrenMenu[0].Container.CloseContainer();
                } else {
                t.owner.DoLog('nooope, it doesn\'t have sub menu items with containers');
                }
            }
        } else {
        }
    });



    this.j(document).bind('CloseEverything', function() {
//    return;

        if (t.Sprite != null) t.Sprite.TurnOff();

    });



    this.j(document).bind('ContainerClosed', function(evtArgs, containerObj) {
//        return;
        /// CHECKING IF THE CLOSING CONTAINER IS THE CONTAINER FOR THIS ITEM.
        if (t.Container.CID == containerObj.CID) {
            if (t.Sprite != null) t.Sprite.TurnOff(); //t.Sprite.Remove();
        }

    });



}



(function(jq) {

    jq.fn.extend({

        GetNumericPixel: function(string) {
            var num = parseInt(string);
            if (isNaN(num)) num = 0;
            return num;

        },

        ///
        /// HELPER METHOD TO ACT AS AN OBJECT TO SHORT-CIRCUIT SOME THE PROCEDURES
        /// TO GET AN ELEMENT PADDING AND MARGINS
        ///
        Boundaries: function(selector) {

            var obj = jq(selector);

            return {

                MarginTop: jq.fn.GetNumericPixel(obj.css('margin-top')),

                MarginBottom: jq.fn.GetNumericPixel(obj.css('margin-bottom')),

                MarginRight: jq.fn.GetNumericPixel(obj.css('margin-right')),

                MarginLeft: jq.fn.GetNumericPixel(obj.css('margin-left')),

                PaddingTop: jq.fn.GetNumericPixel(obj.css('padding-top')),

                PaddingBottom: jq.fn.GetNumericPixel(obj.css('padding-bottom')),

                PaddingRight: jq.fn.GetNumericPixel(obj.css('padding-right')),

                PaddingLeft: jq.fn.GetNumericPixel(obj.css('padding-left'))

            }

        }

    });

})(jQuery);
