﻿Type.registerNamespace('BIT.WebControls');


BIT.WebControls.Menu = function(element) 
{
	BIT.WebControls.Menu.initializeBase(this,[element]);
	
	this.addProperty('collapseTimeout', 200);
	this.addProperty('contextMenu', false);
	
	this.addProperty('mainLevel', null);
	this.addProperty('subLevel', null);
	
	this.addProperty('uniqueID', null);
	
	this.addProperty('items', []);
	
	this.addProperty('clientStateField', null);

	this.addProperty('autoPostBack', false);


	this.addProperty('hoverDisabled', false);
	
	this.addProperty('baseResUrl', null);
	this.addProperty('baseImgUrl', null);
	
	this.addProperty('animationType', BIT.WebControls.AnimationType.exp);
    this.addProperty('animationLength', 35);
	
	this.addProperty('useIframe', (Sys.Browser.agent === Sys.Browser.InternetExplorer) && (Sys.Browser.version < 7));
	
	this.addEvent('init');
	this.addEvent('dispose');
	
	this._postbackPending = false;
	this._postbackArg = null;
	this._pageRequestManager = null;
	
	this._animator = null;
	
	this._updateInit = false;
	
	this._prevPath = null;
	
	this._animItems = [];
}

BIT.WebControls.Menu.prototype =
{

    add_init: function(handler) {
        this.get_events().addHandler('init', handler);
        this._updateInit = true;
    },

    set_useIframe: function(value) {
        if (this.get_isInitialized())
            throw Error.invalidOperation();

        this.useIframe = value;
    },

    get_items: function() {
        if (!this.items)
            this.items = [];

        return this.items;
    },

    _getLevelInfo: function(elm) {
        var isMain = (elm == this.get_element())
        return (isMain ? this.get_mainLevel() : this.get_subLevel()) || { orientation: !isMain };
    },

    _updateItems: function(elm, items, addData) {
        if (!elm)
            return;


        var levelInfo = this._getLevelInfo(elm);

        var blocks = elm.rows;

        elm._object = addData ? this : null;



        if (!addData && elm.iframe) {
            $removeFromParent(elm.iframe);
            elm.iframe = null;
        }

        elm.block = addData ? elm.parentNode : null;
        elm.vis = this.contextMenu ? false : (this.get_id() == elm.id);

        if (!levelInfo.orientation)
            blocks = blocks[0].cells;

        var bl = blocks.length;


        elm.checkGroups = addData ? [] : null;

        var childInit = [];

        for (var i = 0, cnt = 0; i < bl; i++) {
            var cell = blocks[i];

            if (levelInfo.orientation)
                cell = cell.cells[0];

            if (typeof (Sys.UI.DomElement.getAttribute(cell, 'ditem')) != 'undefined') {
                var item = null;

                do {
                    if (items.length <= cnt)
                        throw Error.invalidOperation();

                    item = items[cnt++];
                }
                while (item.skipped)

                if (addData) {
                    cell.item = item;
                    cell.table = cell.childNodes[0];
                    cell.parTable = elm;
                    cell.state = { hover: false, path: false };

                    if (item.checkMode)
                        Array.add(elm.checkGroups['_' + item.checkGroup] || (elm.checkGroups['_' + item.checkGroup] = []), cell);

                    if (this._updateInit)
                        this._updateCellLook(cell);
                }

                if (item && item.items) {
                    this._updateItems(cell.subTable || (cell.subTable = $get(elm.id + '_' + (cnt - 1))), item.items, addData);

                    if (addData && cell.subTable)
                        cell.subTable.parElm = cell;
                }


                if (!addData) {

                    if (cell.subTable)
                        cell.subTable.parElm = null;

                    cell.subTable = null;
                    cell.parTable = null;
                    cell.table = null;
                    cell.item = null;
                    cell.affectedCtl = null;
                    cell.state = null;
                }
            }
        }
    },

    _updateLevelPosition: function(elm, bnds, orientation) {
        if (!elm || !bnds || !elm.id)
            return;

        this._setVisiblePath(elm.id);

        var docSize = $getDocSize();

        var pbnds = $getBounds(elm.block.parentNode);

        var y = bnds.y;
        var x = bnds.x;

        var bndse = new Sys.UI.Bounds(x, y, elm.block.scrollWidth, elm.block.scrollHeight);

        if (orientation) {
            x += bnds.width;

            if (x + bndse.width >= docSize.x)
                x -= bndse.width + bnds.width;

            if (y + bndse.height >= docSize.y)
                y -= bndse.height - bnds.height;
        }
        else {
            y += bnds.height;

            if (x + bndse.width >= docSize.x)
                x -= bndse.width - bnds.width;

            if (y + bndse.height >= docSize.y)
                y -= bndse.height + bnds.height;
        }


        with (elm.block.style) {
            top = ((y < 0) ? 0 : y) - pbnds.y + 'px';
            left = ((x < 0) ? 0 : x) - pbnds.x + 'px';
        }


        if (this.useIframe && !elm.iframe)
            elm.iframe = $addIframe(elm.block);
    },

    _itemOverOut: function(cell, isOver) {
        var item = cell.item;

        if (!item)
            return;

        var res = true;
        var func = isOver ? item.onover : item.onout;
        if (func)
            res = new Function('item', 'cell', func).call(this, item, cell.table);

        if (typeof (res) == 'undefined' || res) {
            var levelInfo = this._getLevelInfo(cell.parTable);

            if (isOver) {
                $clearTimeout(this, '_timerId');
                if (cell.subTable) {
                    var bnds = $getBounds(cell);
                    this._updateLevelPosition(cell.subTable, bnds, levelInfo.orientation);
                }
                else {
                    this._setVisiblePath(cell.parTable.id);
                }
            }
            else {
                this.hide();
            }

            cell.state.hover = isOver;
            this._updateCellLook(cell);
        }
    },

    show: function() {
        this.showAt(null, null);
    },


    showAt: function(x, y, width, height) {
        if ((x === null && y !== null) ||
			(y === null && x !== null) ||
			(!this.contextMenu))
            throw Error.invalidOperation();

        var elm = this.get_element();
        var bnds = (x === null) ? $getBounds(elm) : new Sys.UI.Bounds(x, y, width || 0, height || 0);

        this._updateLevelPosition(elm, bnds, !this._getLevelInfo(elm).orientation);

        $clearTimeout(this, '_timerId');
    },

    showNear: function(elmn) {
        if ((!elmn) || (!this.contextMenu))
            throw Error.invalidOperation();

        var bounds = $getBounds(elmn);

        this.showAt(bounds.x, bounds.y, bounds.width, bounds.height);
    },


    hide: function() {
        $setTimeout(this, '_timerId', this._setEmptyPath, this.collapseTimeout);
    },

    _setEmptyPath: function() {
        this._setVisiblePath(this.contextMenu ? '' : this.get_id());
    },

    _setVisiblePath: function(path) {
        var prevPath = (this._prevPath || '');

        if (prevPath == path)
            return;

        while ((prevPath.length > 0) && !(path + '_').startsWith(prevPath + '_')) {
            this._setItemVisibility(prevPath, false);

            if (prevPath == this.get_id()) {
                prevPath = '';
                break;
            }
            prevPath = prevPath.substring(0, prevPath.lastIndexOf('_'));
        }

        if (prevPath != path) {
            this._setItemVisibility(path, true);
            prevPath = path;
        }

        this._prevPath = prevPath;
    },

    _setItemVisibility: function(elmId, vis) {
        var elm = $get(elmId);

        if (elm && elm.block && elm.vis != vis) {

            if (elm.parElm) {
                elm.parElm.state.path = vis;
                this._updateCellLook(elm.parElm);
            }

            var stl = elm.block.style;

            stl.position = 'absolute';
            stl.overflow = 'hidden';

            elm.vis = vis;

            var ai = null;

            for (var i = 0; i < this._animItems.length; i++) {
                if (this._animItems[i].elm == elm) {
                    ai = this._animItems[i];
                    break;
                }
            }

            if (this._animator.get_state() == BIT.WebControls.AnimationState.stopped) {
                this._animator.set_step(0);
                this._animator.set_steps(0);
            }

            var step = this._animator.get_step();
            var steps = this.animationLength / this._animator.get_delay()

            if (ai) {
                ai.step = 2 * step - ai.step - steps;
                ai.vis = vis;
            }
            else {
                var sw = elm.block.scrollWidth;
                var orientation = this._getLevelInfo(elm).orientation;

                if (elm.parElm && orientation) {
                    if (!this._getLevelInfo(elm.parElm.parTable).orientation)
                        sw = Math.max(elm.parElm ? elm.parElm.scrollWidth : 0, elm.block.scrollWidth);
                }

                with (stl) {
                    width = (vis && !orientation) ? '1px' : sw + 'px';
                    height = (vis && orientation) ? '1px' : elm.block.scrollHeight + 'px';
                }

                if (!vis || orientation)
                    elm.style.width = '100%';


                Sys.UI.DomElement.setOpacity(elm.block, vis ? 0 : 1);

                ai = { elm: elm,
                    step: step,
                    steps: steps,
                    orientation: orientation,
                    height: elm.block.scrollHeight,
                    width: elm.block.scrollWidth,
                    vis: vis
                };


                Array.add(this._animItems, ai);
            }


            this.animTime = new Date().getTime();
            this._animator.set_steps(Math.max(this._animator.get_steps(), ai.step + ai.steps + 1));
            this._animator.start();


        }
    },

    _animStepChanged: function(obj, args) {
        for (var i = 0; i < this._animItems.length; i++) {
            var ai = this._animItems[i];
            var step = args.get_step();
            var stl = ai.elm.block.style;
            var val = obj.calc(0, 1, ai.step, ai.steps, !ai.vis)

            if (val > 1 || ai.step + ai.steps <= step) {
                Array.remove(this._animItems, ai);

                if (ai.orientation)
                    stl.height = 'auto';
                else
                    stl.width = 'auto';

                stl.overflow = '';


                Sys.UI.DomElement.setOpacity(ai.elm.block, ai.vis ? 1 : 0);

                if (!ai.vis)
                    stl.top = stl.left = '-1000000px';

                i--;

                if (this._animItems.length == 0)
                    this._animator.stop();
            }
            else {
                if (ai.orientation)
                    stl.height = (val * ai.height) + 'px';
                else
                    stl.width = (val * ai.width) + 'px';

                Sys.UI.DomElement.setOpacity(ai.elm.block, val);
            }
        }
    },

    _itemOver: function(cell) {
        this._itemOverOut(cell, true);
    },

    _itemOut: function(cell) {
        this._itemOverOut(cell, false);
    },


    _updateCellImageLook: function(row, url, className, first) {
        var cells = row.cells;
        var cell = cells[first ? 0 : cells.length - 1];
        var prevSrc = Sys.UI.DomElement.getAttribute(cell, 'prevSrc');

        var flag = (typeof (prevSrc) != 'undefined');

        if (url) {
            url = resolveImageUrl(url, this.baseResUrl, this.baseImgUrl);

            if (!flag) {
                cell = row.insertCell(first ? 0 : -1);
                cell.appendChild(new Image());
                prevSrc = null;
            }

            if (cell.className != className)
                cell.className = className;

            if (prevSrc != url) {
                Sys.UI.DomElement.setAttribute(cell, 'prevSrc', url);
                with (cell.childNodes[0]) { src = url; alt = ''; };
            }
        }
        else if (flag) {
            row.removeChild(cell);
        }
    },

    _itemClick: function(cell) {
        var item = cell.item;

        if (item && isUndefinedOrTrue(item.enabled)) {
            if (item.checkMode) {
                var uncheck = null;

                if (item.checked) {
                    if (item.checkMode == 3)
                        uncheck = false;
                }
                else {
                    if (item.checkMode == 1)
                        uncheck = true;
                }


                if (uncheck !== null) {
                    item.checked = uncheck;
                    this._actClicked(cell);
                    this._updateCellLook(cell);
                }
                else {

                    var cells = cell.parTable.checkGroups['_' + item.checkGroup];

                    var showCell = null;

                    for (var i = 0, cl = cells.length; i < cl; i++) {
                        var ccell = cells[i];
                        citem = ccell.item;

                        if (!!citem.checked != (citem == item)) {
                            citem.checked = !citem.checked;

                            if (!citem.checked)
                                this._updateCellLook(ccell);
                        }
                    }

                    this._actClicked(cell);
                    this._updateCellLook(cell);
                }
            }

            this.saveClientState();

            var res = true;

            if (item.onclick)
                res = new Function('item', 'cell', item.onclick).call(this, item, cell.table);

            if (typeof (res) == 'undefined' || res) {
                if (item.navigateUrl) {
                    if (item.navigateTarget)
                        window.open(resolveUrl(item.navigateUrl, this.baseResUrl), item.navigateTarget);
                    else
                        window.location.href = resolveUrl(item.navigateUrl, this.baseResUrl);
                }
                else if (this.autoPostBack || item.autoPostBack)
                    this._raisePostBack(Array.indexOf(this.get_items(), item));
            }

            this._setEmptyPath();
        }
    },

    _updateCellLook: function(cell) {
        var item = cell.item;

        if (item) {
            var table = cell.table;
            var levelInfo = this._getLevelInfo(cell.parTable);

            var className = (levelInfo.itemCssClass || '');

            var leftUrl = levelInfo.leftImageUrl;
            var rightUrl = levelInfo.rightImageUrl;

            if (!isUndefinedOrTrue(item.enabled)) {
                className += ' ' + (levelInfo.disabledItemCssClass || '');

                if (levelInfo.leftDisabledImageUrl)
                    leftUrl = levelInfo.leftDisabledImageUrl;

                if (levelInfo.rightDisabledImageUrl)
                    rightUrl = levelInfo.rightDisabledImageUrl;
            }

            if (item.selected) {
                className += ' ' + (levelInfo.selectedItemCssClass || '');

                if (levelInfo.leftSelectedImageUrl)
                    leftUrl = levelInfo.leftSelectedImageUrl;

                if (levelInfo.rightSelectedImageUrl)
                    rightUrl = levelInfo.rightSelectedImageUrl;
            }

            if (item.checked) {
                className += ' ' + (levelInfo.checkedItemCssClass || '');

                if (levelInfo.leftCheckedImageUrl)
                    leftUrl = levelInfo.leftCheckedImageUrl;

                if (levelInfo.rightCheckedImageUrl)
                    rightUrl = levelInfo.rightCheckedImageUrl;
            }

            if ((this.hoverDisabled || isUndefinedOrTrue(item.enabled)) && (cell.state.hover || cell.state.path)) {
                className += ' ' + (levelInfo.hoverItemCssClass || '');

                if (levelInfo.leftHoverImageUrl)
                    leftUrl = levelInfo.leftHoverImageUrl;

                if (levelInfo.rightHoverImageUrl)
                    rightUrl = levelInfo.rightHoverImageUrl;
            }

            var row = table.rows[0];

            this._updateCellImageLook(row, leftUrl, levelInfo.leftImageCssClass, true);
            this._updateCellImageLook(row, rightUrl, levelInfo.rightImageCssClass, false);

            className = className.trim()

            if (table.className != className)
                table.className = className;
        }
    },

    _doPostBack: function() {
        this.saveClientState();
        __doPostBack(this.get_uniqueID(), (this._postbackArg === null) ? '' : this._postbackArg + '');
        this._postbackArg = null;
    },

    _raisePostBack: function(arg) {
        this._postbackArg = arg;

        if ((this._pageRequestManager === null) || (!this._pageRequestManager.get_isInAsyncPostBack())) {
            this._doPostBack();
            this._postbackPending = false;
        }
        else {
            this._postbackPending = true;
        }
    },

    _handleEndRequest: function() {
        if ((this._postbackPending === true) && (this._pageRequestManager != null) && (this._pageRequestManager.get_isInAsyncPostBack() === false)) {
            this._postbackPending = false;
            this._doPostBack();
        }
    },

    _actClicked: function(cell) {
        var item = cell.item;

        if (item.affectedCtlBaseID) {
            if (!cell.affectedCtl)
                cell.affectedCtl = $get((item.affectedCtlBaseID || '') + item.affectedCtlID);

            if (cell.affectedCtl) {
                var disp = item.checked ? '' : 'none';

                if (cell.affectedCtl.style.display != disp)
                    cell.affectedCtl.style.display = disp;
            }
        }
    },

    saveClientState: function() {
        if (this.get_clientStateField()) {
            this.get_clientStateField().value = Sys.Serialization.JavaScriptSerializer.serialize(
				({
				    'items': this.items
				})
			);
        }
    },

    initialize: function() {
        BIT.WebControls.Menu.callBaseMethod(this, "initialize");

        this._prevPath = this.contextMenu ? '' : this.get_id();

        window[this.get_id()] = this;

        if (!BIT.WebControls.Animator)
            throw Error.invalidOperation();

        this.raiseEvent('init');

        this._handleEndRequestDelegate = Function.createDelegate(this, this._handleEndRequest);

        this._animStepDelegate = Function.createDelegate(this, this._animStepChanged);

        this._animator = $create(BIT.WebControls.Animator);
        this._animator.set_steps(0);
        this._animator.add_stepChanged(this._animStepDelegate);

        if (Sys.WebForms && Sys.WebForms.PageRequestManager)
            this._pageRequestManager = Sys.WebForms.PageRequestManager.getInstance();

        if (this._pageRequestManager != null)
            this._pageRequestManager.add_endRequest(this._handleEndRequestDelegate);


        this._updateItems(this.get_element(), this.get_items(), true);
        this._updateInit = false;

        this.saveClientState();
    },

    dispose: function() {
        this._updateItems(this.get_element(), this.get_items(), false);

        if (this._pageRequestManager != null)
            this._pageRequestManager.remove_endRequest(this._handleEndRequestDelegate);

        this.raiseEvent('dispose');

        if (this._animator) {
            this._animator.remove_stepChanged(this._animStepDelegate);

            this._animator.dispose();
            this._animator = null;
        }

        this._pageRequestManager = null;

        window[this.get_id()] = null;

        this.mainLevel = null;
        this.subLevel = null;
        this.items = null;
        this.clientStateField = null;

        BIT.WebControls.Menu.callBaseMethod(this, "dispose");
    }
}

BIT.WebControls.Menu.registerClass('BIT.WebControls.Menu', Sys.UI.Control);



if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();