/*
 * Copyright (C) 2005 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License  as
 * published by the Free Software Foundation, either version 3 of  the
 * License, or (at your option) any later version.
 *
 * 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 Affero  General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public  License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @author angus
 */


var layoutModule = {
    ELEMENT_CONTEXTMENU: "element:contextmenu",

    //predefine CSS patterns for element sifting
    SIZEABLE_PATTERN: '.sizeable',
    SIZER_PATTERN: '.sizer',
    MOVEABLE_PATTERN: '.moveable',
    MOVER_PATTERN: '.mover',
    MINIMIZER_PATTERN: '.minimize',
    MINIMIZED_PATTERN: '.minimized .minimize',
    TRUNCATE_PATTERN: '.trunc',
    TREE_LEAF_PATTERN: 'a.>node',
    TREE_CONTAINER_PATTERN: '.collapsible',
    TOOLBAR_CAPSULE_PATTERN: '#toolbar .capsule',
    NAVIGATION_MUTTON_PATTERN: 'li.mutton',
    NAVIGATION_PATTERN: '#navigationOptions li',
    NAVIGATION_HOVER_PATTERN: '#navigationOptions li.over',
    META_LINKS_PATTERN: '#metaLinks #main_logOut_link',
    BUTTON_SET_BUTTON: '.buttonSet > .',
    TABSET_TAB_PATTERN: '.tab',
    BUTTON_PATTERN: '.button',
    PRESSED_PATTERN: '.pressed',
    SELECTED_PATTERN: '.selected',
    LIST_ITEM_PATTERN: '.list.responsive > li',
    LIST_ITEM_WRAP_PATTERN: '.wrap',
    DISCLOSURE_BUTTON_PATTERN: ".disclosure",
    MENU_LIST_PATTERN: '#menu li',
    SEPARATOR_PATTERN: '.separator',	
    MESSAGE_WARNING_PATTERN: '.message.warning',
    COLUMN_NODE_WRAPPER_PATTERN: ".node > .wrap > .column",
    COLUMN_LEAF_WRAPPER_PATTERN: ".leaf > .wrap > .column",
    SEARCH_LOCKUP_PATTERN: ".searchLockup",
    DIALOG_PATTERN: ".dialog",
    DIALOG_LOADING_PATTERN: ".dialog.loading",

    //classes
    ADHOC_MODE_OPTION_CLASS: 'tab mode horizontal', //not used?
    DRAGGING_CLASS: 'dragging',
    COPY_CLASS: 'copy',
    PRESSED_CLASS : 'pressed',
    SELECTED_CLASS : 'selected',
    DISABLED_CLASS : 'disabled',
    HOVERED_CLASS : 'over',
    ERROR_CLASS : 'error',
    UP_CLASS : 'up',
    LAST_CLASS : 'last',
    FIRST_CLASS : 'first',
    SCHEDULED_CLASS: 'scheduled',
    NODE_CLASS: 'node',
    LEAF_CLASS: 'leaf',
    ICON_CLASS: 'icon',	
    OPEN_CLASS: 'open',
    CLOSED_CLASS: 'closed',
    LOADING_CLASS: 'loading',
    NOTHING_TO_DISPLAY_CLASS: 'nothingToDisplay',
    COLLAPSIBLE_CLASS: "collapsible",
    RESPONSIVE_CLASS: "responsive",
    HIDDEN_CLASS: "hidden",
    EMPHASIS_CLASS: "emphasis",    
    ASCENDING_CLASS: "ascending",
    DESCENDING_CLASS: "descending",
    CANCELLABLE_CLASS: "cancellable",
    DROP_TARGET_CLASS: "dropTarget",
    BUTTON_CLASS: "button",
    ONE_COLUMN_CLASS: "oneColumn",
    CONTROL_PAGE_CLASS: "controlPage",

    //attributes
    DISABLED_ATTR_NAME: "disabled",
    SELECTED_ATTR_NAME: "selected",
    OPEN_ATTR_NAME: "open",
    CLOSED_ATTR_NAME: "closed",
    READONLY_ATTR_NAME: "readonly",

    // Predefined DOM elements IDs.
    DIMMER_ID: "pageDimmer",
    PAGE_BODY_ID: "display",
    MENU_ID: "menu",
    MAIN_NAVIGATION_ID: "mainNavigation",
    MAIN_NAVIGATION_HOME_ITEM_ID: "main_home",


    // DnD
    SCROLL_SENSITIVITY: 50,

	//dimmer
	DIMMER_Z_INDEX: 900,

    //Resizable folders/filters/properties/fields panels
    FOLDERS_RESIZABLE_PANEL_ID: 'folders',
    FILTERS_RESIZABLE_PANEL_ID: 'filters',
    PROPERTIES_RESIZABLE_PANEL_ID: 'properties',
    FIELDS_RESIZABLE_PANEL_ID: 'fields',

    FOLDERS_RESIZABLE_PANEL_COOKIE_NAME: 'foldersPanelWidth',
    FOLDERS_MINIMIZED_PANEL_COOKIE_NAME: 'foldersMinimized',

    FILTERS_RESIZABLE_PANEL_COOKIE_NAME: 'filtersPanelWidth',
    FILTERS_MINIMIZED_PANEL_COOKIE_NAME: 'filtersMinimized',

    PROPERTIES_RESIZABLE_PANEL_COOKIE_NAME: 'propertiesPanelWidth',
    PROPERTIES_MINIMIZED_PANEL_COOKIE_NAME: 'propertiesMinimized',

    FIELDS_RESIZABLE_PANEL_COOKIE_NAME: 'fieldsPanelWidth',
    FIELDS_MINIMIZED_PANEL_COOKIE_NAME: 'fieldsMinimized',

    PANEL_WIDTH: 'PanelWidth',
    MINIMIZED: 'Minimized',

    //////////////////////////////////////////////////////////////////////
    // Initialize: Programmatically modifies the DOM objects upfront
    //////////////////////////////////////////////////////////////////////

    initialize: function(container){
		container = $(container) || $(document.body);
		
		//web help
		if (window.webHelpModule) {
			$('helpLink').observe('click',webHelpModule.displayWebHelp); 
		} 

        //truncate matching patterns
        new Truncator(container.select(layoutModule.TRUNCATE_PATTERN));

		//IE7 needs explicit style set (no sensible alternative to browser sniffing here)
		isIE7() && this.fixIE7Sizes();

        //init layout sizers

        container.select(this.SIZEABLE_PATTERN).each(this.createSizer.bind(this));
 		//NW.Dom.select(this.SIZEABLE_PATTERN, container, layoutModule.createSizer);

        //init moveables (note: DOM elements created after page load will need to be initialized for move after creation)
        container.select(this.MOVEABLE_PATTERN).each(this.createMover.bind(this));
 		//NW.Dom.select(this.MOVEABLE_PATTERN, container, layoutModule.createMover);

		//TESTING...
//		var var1 = container.select(this.MOVEABLE_PATTERN);
//		var var2 = NW.Dom.select(this.MOVEABLE_PATTERN, container);
//		var x = var2.length; 		
//		while (x--) {
//			if (var1[x].innerHTML != var2[x].innerHTML) {
//				console.log(var1[x]);
//				console.log(var2[x]);				
//			}	
//		}

        //elements for centering (note: DOM elements created after page load will need to be initialized for center after creation)
        container.select('.centered_horz,.centered_vert').each(function(elem){
            centerElement(elem, {
                horz: elem.match('.centered_horz'),
                vert: elem.match('.centered_vert')
            });
        });
	
		//page dimmer init
        if ($(layoutModule.DIMMER_ID) != null) {
            $(layoutModule.DIMMER_ID).style.zIndex = layoutModule.DIMMER_Z_INDEX;
        } 

		
    },

    //////////////////////////////////////////////////////////////////////
    // panel resizing
    //////////////////////////////////////////////////////////////////////

    createSizer : function(sizeable){
        //sizeable is the element we will resize
        //sizer is the handle we drag to resize it
        var sizer = sizeable.down(this.SIZER_PATTERN); //get first descendant with class sizer
        if (!sizer || matchMeOrUp(sizeable,"." + layoutModule.HIDDEN_CLASS)) {return;}           
        var sizerType = this.getSizerType(sizer);
        var sizerAlign = this.alignmentModule.getSizerAlignment(sizer, sizerType);

        var dragger = new Draggable(sizer);
        dragger.resizeablePanel = sizeable;
        dragger.primaryPanel = $(sizeable).siblings().find(function(s){
            return s.match('.primary')
        });

        var sizerMousedownCallback = function() {
            return function(evt) {
                //set co-ords now - if we wait until drag start it is too late - mouse already moved a bit
                dragger.pointerX = evt.pointerX();
                dragger.pointerY = evt.pointerY();
            }
        }();

        //have to observer at this level - otherwise draggable has already swallowed up event
        sizer.observe('mousedown', sizerMousedownCallback);

        dragger.sizerType = sizerType;
        dragger.alignment = sizerAlign;

        dragger.options = {
            constraint: ((sizerType === 'diagonal') ? '' : sizerType),
            onStart: layoutModule.beginSizerDragging.bind(layoutModule),
            onDrag: layoutModule.respondToDrag.bind(layoutModule),
            onEnd: layoutModule.endSizerDragging.bind(layoutModule)
        }

    },

    getSizerType: function(sizer) {
        return (sizer.match('.horizontal') && 'horizontal') ||
                (sizer.match('.vertical') && 'vertical') ||
                (sizer.match('.diagonal') && 'diagonal');
    },

    alignmentModule: {

        alignments: [
            ['left','right'],
            ['top','bottom']
        ],

        alignmentIndexes: {
            'horizontal':0,
            'vertical':1
        },

        dimensions: ['width','height'],

        /**
         * which edge(s) of the sizeable object is the sizer aligned with
         * @param {Object} sizer
         * @param {Object} sizerType
         * @return (Array) ['left', 'right' or '']['top', 'bottom' or '']
         */
        getSizerAlignment: function(sizer, sizerType){
            var result = ['',''];
            if (sizerType==='diagonal') {
                //diagonals sizer always the same alignment
                return ['right','bottom'];
            }
            var alignmentIndex = this.alignmentIndexes[sizerType]; //0 or 1
            var alignmentStyles = this.alignments[alignmentIndex]; //['left','right'] or ['top','bottom']
            var alignmentOffsets = [0,1].map(
				function(al) {
					return parseInt(sizer.getStyle(alignmentStyles[al]))
			});
            //calculate sizer anchorage by testing which offset is smaller (NaN mean not anchored - therefore not aligned)
			var alignment = (isNaN(alignmentOffsets[0]) || (alignmentOffsets[0] > alignmentOffsets[1])) ? 
				alignmentStyles[1] : alignmentStyles[0];	
            //now set the appropriate element
            result[alignmentIndex] = alignment;
            //e.g. for horizontal: ['right',''];
            return result;
        }
    },

    beginSizerDragging : function(dragger, event) {
        var sizer = dragger.element;
        dragger.parentOffset = [sizer.getStyle(dragger.alignment[0]), sizer.getStyle(dragger.alignment[1])];
        dragger.offsetUnit = 'px'; //TODO: fix me
        dragger.pointerX = dragger.pointerX || event.pointerX();
        dragger.pointerY = dragger.pointerY || event.pointerY();
        dragger.element.addClassName(layoutModule.DRAGGING_CLASS);
    },

    endSizerDragging : function(dragger, event){
        layoutModule.respondToDrag(dragger, event);
        dragger.element.removeClassName(layoutModule.DRAGGING_CLASS);
        //fire custom event so that we can know when we have finished sizing
        document.fire("dragger:sizer", {targetEvent:event, element: dragger.element});
    },

    respondToDrag : function(dragger, event) {
        //no else stmt - diagonal sizer will do both
        if (dragger.sizerType !== 'vertical') { //includes diagonal
            this.resizeOnDrag(dragger, event, 'horizontal');
        }
        if (dragger.sizerType !== 'horizontal') { //includes diagonal
            this.resizeOnDrag(dragger, event, 'vertical');
        }
    },

    resizeOnDrag : function(dragger, event, orientation) {
        //set vars based on dragger orientation
        var dragData = {};
        dragData.axis = (orientation == 'horizontal') ? 0 : 1;
        dragData.myAlignments = this.alignmentModule.alignments[dragData.axis];
        dragData.dimension = this.alignmentModule.dimensions[dragData.axis];
        dragData.sizeProperty = dragData.axis ? 'offsetHeight' : 'offsetWidth';

        var pointerName = dragData.axis ? 'pointerY' : 'pointerX';

        //generic code starts here
        var sizer = dragger.element;
        dragData.sizeableAnchorage = (dragger.alignment[dragData.axis] === dragData.myAlignments[0]) ? dragData.myAlignments[1] : dragData.myAlignments[0];

        var dragDelta = dragger[pointerName] ? event[pointerName]() - dragger[pointerName] : 0;
        dragDelta = (dragger.alignment[dragData.axis] === dragData.myAlignments[1]) ? dragDelta : 0 - dragDelta; //directional correction
        dragData.dragDelta = dragDelta;
        dragger[pointerName] = event[pointerName]();

        this.resizePanelsOnDrag(dragger, dragData);
    },

    resizePanelsOnDrag : function(dragger, dragData) {
        var sizeTracker = this.getSizeTracker();
        sizeTracker.checkpoint(dragger.resizeablePanel[dragData.sizeProperty]);

        //size the panel
		var panelSize = getDimensionInPx(dragger.resizeablePanel, dragData.dimension); //worsk for % or px
        if (this.isInBounds(dragger, dragData) || (!this.isInBounds(dragger, dragData) && dragData.dragDelta < 0)) {
            dragger.resizeablePanel.setStyle(dragData.dimension + ':' + (panelSize + dragData.dragDelta) + 'px');
        }

        //if resizeablePanel is folders panel then put resizeablePanel.width into cookie
        if (dragger.resizeablePanel.id == this.FOLDERS_RESIZABLE_PANEL_ID) {
            new JSCookie(this.FOLDERS_RESIZABLE_PANEL_COOKIE_NAME, dragger.resizeablePanel.getWidth());
        }
        //if resizeablePanel is filters panel then put resizeablePanel.width into cookie
        if (dragger.resizeablePanel.id == this.FILTERS_RESIZABLE_PANEL_ID) {
            new JSCookie(this.FILTERS_RESIZABLE_PANEL_COOKIE_NAME, dragger.resizeablePanel.getWidth());
        }
        //if resizeablePanel is properties panel then put resizeablePanel.width into cookie
        if (dragger.resizeablePanel.id == this.PROPERTIES_RESIZABLE_PANEL_ID) {
            new JSCookie(this.PROPERTIES_RESIZABLE_PANEL_COOKIE_NAME, dragger.resizeablePanel.getWidth());
        }
        //if resizeablePanel is fields panel then put resizeablePanel.width into cookie
        if (dragger.resizeablePanel.id == this.FIELDS_RESIZABLE_PANEL_ID) {
            new JSCookie(this.FIELDS_RESIZABLE_PANEL_COOKIE_NAME, dragger.resizeablePanel.getWidth());
        }

        //could not size the panel? restore position of sizer and style of panel
        if (!sizeTracker.changed(dragger.resizeablePanel[dragData.sizeProperty])) {
			var actualSize = getActualDimension(dragger.resizeablePanel, dragData.dimension);
            if (dragger.alignment[dragData.axis] != dragData.myAlignments[0]) {
                //if sizer not naturally left/top aligned, remove left/top styling added by scriptaculous dragger
                dragger.element.style[dragData.myAlignments[0]] = "";
            }
            dragger.element.setStyle(dragger.alignment[dragData.axis] + ':' + dragger.parentOffset[dragData.axis]);
            dragger.resizeablePanel.setStyle(dragData.dimension + ':' + actualSize + 'px');
        	if (dragger.primaryPanel && (dragger.primaryPanel.style.zIndex == dragger.resizeablePanel.style.zIndex)) {
				dragger.primaryPanel.setStyle(dragData.sizeableAnchorage + ':' + (actualSize) + 'px');
			}
            return;
        }

        //size primary panel if any (and in same layer)
        if (dragger.primaryPanel && (dragger.primaryPanel.style.zIndex == dragger.resizeablePanel.style.zIndex)) {
			var primaryOffset = getDimensionInPx(dragger.primaryPanel, dragData.sizeableAnchorage);
            dragger.primaryPanel.setStyle(dragData.sizeableAnchorage + ':' + (primaryOffset + dragData.dragDelta) + 'px'); //resize main (middle) panel if any
        }

        //finally restore sizer`s alignment w/ respect to its parent
        dragger.element.setStyle(dragger.alignment[dragData.axis] + ':' + dragger.parentOffset[dragData.axis]);
    },

    isInBounds: function(dragger, dragData) {
        if (dragger.primaryPanel) {
            var primaryMinMeasurement = parseInt(dragger.primaryPanel.getStyle("min-" + dragData.dimension));
            var sizeableAnchorageMeasurement = parseInt(dragger.primaryPanel.getStyle(dragData.sizeableAnchorage));
            var parentMeasurement = parseInt(dragger.primaryPanel.parentNode.getStyle(dragData.dimension));

            return parentMeasurement - sizeableAnchorageMeasurement - dragData.dragDelta > primaryMinMeasurement;
        } else {
            return true;
        }
    },

    getSizeTracker: function() {
        lastSize = -1;

        return {
            checkpoint: function(size){
                lastSize = size;
            },
            changed: function(size){
                return size != lastSize;
            }
        }
    },

    ///////////////////////////////////////////////////////////////////////////////////
    // Make moveable
    ///////////////////////////////////////////////////////////////////////////////////


    createMover : function(movable){
        //movable is the element we will move
        //mover is the handle we drag to move it
        var mover = movable.down(this.MOVER_PATTERN); //get first descendant with class mover
        if (!mover || matchMeOrUp(movable,"." + layoutModule.HIDDEN_CLASS)) {return;}           
		

        var dragger = new Draggable(movable, {handle: mover});
    },

    ///////////////////////////////////////////////////////////////////////////////////
    // Minimizer / Maximizer
    ///////////////////////////////////////////////////////////////////////////////////

    maximize : function(element){
        var toMaximize = element.up('.column');
        var aligments = layoutModule.alignmentModule.alignments[0];
        var offsets = aligments.map(function(al) {
            return parseInt(toMaximize.getStyle(al));
        });
        var thisAlignment = aligments[offsets[0] === 0 ? 0 : 1]; //left at 0, right at 1
        var primaryPanel = toMaximize.siblings().find(function(s) {
            return s.match('.primary')
        });
        if (primaryPanel) {
            switch (toMaximize.id) {
                case layoutModule.FOLDERS_RESIZABLE_PANEL_ID:
                    var ppOffset = new JSCookie(layoutModule.FOLDERS_RESIZABLE_PANEL_COOKIE_NAME).value;
                    break;
                case layoutModule.FILTERS_RESIZABLE_PANEL_ID:
                    ppOffset = new JSCookie(layoutModule.FILTERS_RESIZABLE_PANEL_COOKIE_NAME).value;
                    break;
                case layoutModule.PROPERTIES_RESIZABLE_PANEL_ID:
                    ppOffset = new JSCookie(layoutModule.PROPERTIES_RESIZABLE_PANEL_COOKIE_NAME).value;
                    break;
                case layoutModule.FIELDS_RESIZABLE_PANEL_ID:
                    ppOffset = new JSCookie(layoutModule.FIELDS_RESIZABLE_PANEL_COOKIE_NAME).value;
                    break;
            }
            ppOffset += 'px';
        }

        if (ppOffset) {
            //This...
            new Effect.Morph(primaryPanel, {style: thisAlignment + ":" + ppOffset, duration: 0.6});
            //...runs parallel to these two...
            new Effect.Opacity(toMaximize, {to: 0, from: 1, duration: 0.3, queue: {position: 'front', scope: 'sidePanel'}, afterFinish: function() {
                toMaximize.removeClassName('minimized');
                switch (toMaximize.id) {
                    case layoutModule.FOLDERS_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.FOLDERS_MINIMIZED_PANEL_COOKIE_NAME, 'false');
                        break;
                    case layoutModule.FILTERS_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.FILTERS_MINIMIZED_PANEL_COOKIE_NAME, 'false');
                        break;
                    case layoutModule.PROPERTIES_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.PROPERTIES_MINIMIZED_PANEL_COOKIE_NAME, 'false');
                        break;
                    case layoutModule.FIELDS_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.FIELDS_MINIMIZED_PANEL_COOKIE_NAME, 'false');
                        break;
                }
            }});
            new Effect.Opacity(toMaximize, {to: 1, from: 0, duration: 0.3, queue: {position: 'end', scope: 'sidePanel'}});
        }
    },

    minimize : function(element){
        var primaryPanel, ppOffset;

        //MINIMIZE
        var toMinimize = element.up('.column');
        if ($(layoutModule.FOLDERS_RESIZABLE_PANEL_ID) && new JSCookie(layoutModule.FOLDERS_MINIMIZED_PANEL_COOKIE_NAME).value != 'true') {
            new JSCookie(layoutModule.FOLDERS_RESIZABLE_PANEL_COOKIE_NAME, $(layoutModule.FOLDERS_RESIZABLE_PANEL_ID).getWidth());
        }
        if ($(layoutModule.FILTERS_RESIZABLE_PANEL_ID) && new JSCookie(layoutModule.FILTERS_MINIMIZED_PANEL_COOKIE_NAME).value != 'true') {
            new JSCookie(layoutModule.FILTERS_RESIZABLE_PANEL_COOKIE_NAME, $(layoutModule.FILTERS_RESIZABLE_PANEL_ID).getWidth());
        }
        if ($(layoutModule.PROPERTIES_RESIZABLE_PANEL_ID) && new JSCookie(layoutModule.PROPERTIES_MINIMIZED_PANEL_COOKIE_NAME).value != 'true') {
            new JSCookie(layoutModule.PROPERTIES_RESIZABLE_PANEL_COOKIE_NAME, $(layoutModule.PROPERTIES_RESIZABLE_PANEL_ID).getWidth());
        }
        if ($(layoutModule.FIELDS_RESIZABLE_PANEL_ID) && new JSCookie(layoutModule.FIELDS_MINIMIZED_PANEL_COOKIE_NAME).value != 'true') {
            new JSCookie(layoutModule.FIELDS_RESIZABLE_PANEL_COOKIE_NAME, $(layoutModule.FIELDS_RESIZABLE_PANEL_ID).getWidth());
        }

        //figure out alignment (left or right)
        var aligments = layoutModule.alignmentModule.alignments[0];
        var offsets = aligments.map(function(al){
            return parseInt(toMinimize.getStyle(al));
        });
        var thisAlignment = aligments[offsets[0] === 0 ? 0 : 1]; //left at 0, right at 1

        primaryPanel = toMinimize.siblings().find(function(s) {return s.match('.primary')});

        if (primaryPanel) {
            ppOffset = primaryPanel.getStyle(thisAlignment);

            //This...
            new Effect.Morph(primaryPanel, {style: thisAlignment + ':0px', duration: 0.6});
            //...runs parallel to these two...
            new Effect.Opacity(toMinimize, {to: 0, from: 1, duration: 0.3, queue: {position: 'front', scope: 'sidePanel'}, afterFinish: function() {
                toMinimize.addClassName('minimized');
                switch (toMinimize.id) {
                    case layoutModule.FOLDERS_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.FOLDERS_MINIMIZED_PANEL_COOKIE_NAME, 'true');
                        break;
                    case layoutModule.FILTERS_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.FILTERS_MINIMIZED_PANEL_COOKIE_NAME, 'true');
                        break;
                    case layoutModule.PROPERTIES_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.PROPERTIES_MINIMIZED_PANEL_COOKIE_NAME, 'true');
                        break;
                    case layoutModule.FIELDS_RESIZABLE_PANEL_ID:
                        new JSCookie(layoutModule.FIELDS_MINIMIZED_PANEL_COOKIE_NAME, 'true');
                        break;
                }
            }});
            new Effect.Opacity(toMinimize, {to: 1, from: 0, duration: 0.3, queue: {position: 'end', scope: 'sidePanel'}});
        }
    },

    resizeOnClient: function(leftPanelID, mainPanelID, rightPanelID) {
        var leftPanelWidth = new JSCookie(leftPanelID + layoutModule.PANEL_WIDTH).value;
        var rightPanelWidth = new JSCookie(rightPanelID + layoutModule.PANEL_WIDTH).value;
        var leftPanelMinimized = new JSCookie(leftPanelID + layoutModule.MINIMIZED).value == 'true';
        var rightPanelMinimized = new JSCookie(rightPanelID + layoutModule.MINIMIZED).value == 'true';

        var style = '';
        if (leftPanelMinimized) {
            style += 'left: 0;';
        } else if (leftPanelWidth) {
            style += 'left: ' + leftPanelWidth + 'px;';
        }
        if (rightPanelMinimized) {
            style += 'right: 0;';
        } else if (rightPanelWidth) {
            style += 'right: ' + rightPanelWidth + 'px;';
        }
        $(mainPanelID).setStyle(style);

        if (leftPanelMinimized) {
            var leftPanel = $(leftPanelID);
            leftPanel.addClassName('minimized');
        }
        if (leftPanelWidth) {
            leftPanel = leftPanel ? leftPanel : $(leftPanelID);
            leftPanel.setStyle('width: ' + leftPanelWidth + 'px;');
        }

        if (rightPanelMinimized) {
            var rightPanel = $(rightPanelID);
            rightPanel.addClassName('minimized');
        }
        if (rightPanelWidth) {
            rightPanel = rightPanel ? rightPanel : $(rightPanelID);
            rightPanel.setStyle('width: ' + rightPanelWidth + 'px;');
        }
    },
	
	fixIE7Sizes: function() {
		$$(".control.tabSet.buttons.vertical").each(function(elem) {
			elem.immediateDescendants().each(function(child) {
				child.style.width = elem.clientWidth || elem.offsetWidth;
			});
		});
	}		
};



