/**
 * @class Ext.layout.BorderLayout
 * @extends Ext.layout.ContainerLayout
 *

This is a multi-pane, application-oriented UI layout style that supports multiple
 * nested panels, automatic {@link Ext.layout.BorderLayout.Region#split split} bars between
 * {@link Ext.layout.BorderLayout.Region#BorderLayout.Region regions} and built-in
 * {@link Ext.layout.BorderLayout.Region#collapsible expanding and collapsing} of regions.


 *

This class is intended to be extended or created via the layout:'border'
 * {@link Ext.Container#layout} config, and should generally not need to be created directly
 * via the new keyword.


 *

BorderLayout does not have any direct config options (other than inherited ones).
 * All configuration options available for customizing the BorderLayout are at the
 * {@link Ext.layout.BorderLayout.Region} and {@link Ext.layout.BorderLayout.SplitRegion}
 * levels.


 *

Example usage:


 *

var myBorderPanel = new Ext.Panel({
    {@link Ext.Component#renderTo renderTo}: document.body,
    {@link Ext.BoxComponent#width width}: 700,
    {@link Ext.BoxComponent#height height}: 500,
    {@link Ext.Panel#title title}: 'Border Layout',
    {@link Ext.Container#layout layout}: 'border',
    {@link Ext.Container#items items}: [{
        {@link Ext.Panel#title title}: 'South Region is resizable',
        {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'south',     // position for region
        {@link Ext.BoxComponent#height height}: 100,
        {@link Ext.layout.BorderLayout.Region#split split}: true,         // enable resizing
        {@link Ext.SplitBar#minSize minSize}: 75,         // defaults to {@link Ext.layout.BorderLayout.Region#minHeight 50}
        {@link Ext.SplitBar#maxSize maxSize}: 150,
        {@link Ext.layout.BorderLayout.Region#margins margins}: '0 5 5 5'
    },{
        // xtype: 'panel' implied by default
        {@link Ext.Panel#title title}: 'West Region is collapsible',
        {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}:'west',
        {@link Ext.layout.BorderLayout.Region#margins margins}: '5 0 0 5',
        {@link Ext.BoxComponent#width width}: 200,
        {@link Ext.layout.BorderLayout.Region#collapsible collapsible}: true,   // make collapsible
        {@link Ext.layout.BorderLayout.Region#cmargins cmargins}: '5 5 0 5', // adjust top margin when collapsed
        {@link Ext.Component#id id}: 'west-region-container',
        {@link Ext.Container#layout layout}: 'fit',
        {@link Ext.Panel#unstyled unstyled}: true
    },{
        {@link Ext.Panel#title title}: 'Center Region',
        {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'center',     // center region is required, no width/height specified
        {@link Ext.Component#xtype xtype}: 'container',
        {@link Ext.Container#layout layout}: 'fit',
        {@link Ext.layout.BorderLayout.Region#margins margins}: '5 5 0 0'
    }]
});

 *

Notes:


 */

Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
   
// private
    monitorResize
:true,
   
// private
    rendered
: false,

   
// private
    onLayout
: function(ct, target){
       
var collapsed;
       
if(!this.rendered){
            target
.addClass('x-border-layout-ct');
           
var items = ct.items.items;
            collapsed
= [];
           
for(var i = 0, len = items.length; i < len; i++) {
               
var c = items[i];
               
var pos = c.region;
               
if(c.collapsed){
                    collapsed
.push(c);
               
}
                c
.collapsed = false;
               
if(!c.rendered){
                    c
.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
                    c
.render(target, i);
               
}
               
this[pos] = pos != 'center' && c.split ?
                   
new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
                   
new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
               
this[pos].render(target, c);
           
}
           
this.rendered = true;
       
}

       
var size = target.getViewSize();
       
if(size.width < 20 || size.height < 20){ // display none?
           
if(collapsed){
               
this.restoreCollapsed = collapsed;
           
}
           
return;
       
}else if(this.restoreCollapsed){
            collapsed
= this.restoreCollapsed;
           
delete this.restoreCollapsed;
       
}

       
var w = size.width, h = size.height;
       
var centerW = w, centerH = h, centerY = 0, centerX = 0;

       
var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
       
if(!c && Ext.layout.BorderLayout.WARN !== false){
           
throw 'No center region defined in BorderLayout ' + ct.id;
       
}

       
if(n && n.isVisible()){
           
var b = n.getSize();
           
var m = n.getMargins();
            b
.width = w - (m.left+m.right);
            b
.x = m.left;
            b
.y = m.top;
            centerY
= b.height + b.y + m.bottom;
            centerH
-= centerY;
            n
.applyLayout(b);
       
}
       
if(s && s.isVisible()){
           
var b = s.getSize();
           
var m = s.getMargins();
            b
.width = w - (m.left+m.right);
            b
.x = m.left;
           
var totalHeight = (b.height + m.top + m.bottom);
            b
.y = h - totalHeight + m.top;
            centerH
-= totalHeight;
            s
.applyLayout(b);
       
}
       
if(west && west.isVisible()){
           
var b = west.getSize();
           
var m = west.getMargins();
            b
.height = centerH - (m.top+m.bottom);
            b
.x = m.left;
            b
.y = centerY + m.top;
           
var totalWidth = (b.width + m.left + m.right);
            centerX
+= totalWidth;
            centerW
-= totalWidth;
            west
.applyLayout(b);
       
}
       
if(e && e.isVisible()){
           
var b = e.getSize();
           
var m = e.getMargins();
            b
.height = centerH - (m.top+m.bottom);
           
var totalWidth = (b.width + m.left + m.right);
            b
.x = w - totalWidth + m.left;
            b
.y = centerY + m.top;
            centerW
-= totalWidth;
            e
.applyLayout(b);
       
}
       
if(c){
           
var m = c.getMargins();
           
var centerBox = {
                x
: centerX + m.left,
                y
: centerY + m.top,
                width
: centerW - (m.left+m.right),
                height
: centerH - (m.top+m.bottom)
           
};
            c
.applyLayout(centerBox);
       
}
       
if(collapsed){
           
for(var i = 0, len = collapsed.length; i < len; i++){
                collapsed
[i].collapse(false);
           
}
       
}
       
if(Ext.isIE && Ext.isStrict){ // workaround IE strict repainting issue
            target
.repaint();
       
}
   
},

    destroy
: function() {
       
var r = ['north', 'south', 'east', 'west'];
       
for (var i = 0; i < r.length; i++) {
           
var region = this[r[i]];
           
if(region){
               
if(region.destroy){
                    region
.destroy();
               
}else if (region.split){
                    region
.split.destroy(true);
               
}
           
}
       
}
       
Ext.layout.BorderLayout.superclass.destroy.call(this);
   
}

   
/**
     * @property activeItem
     * @hide
     */

});

/**
 * @class Ext.layout.BorderLayout.Region
 *

This is a region of a {@link Ext.layout.BorderLayout BorderLayout} that acts as a subcontainer
 * within the layout.  Each region has its own {@link Ext.layout.ContainerLayout layout} that is
 * independent of other regions and the containing BorderLayout, and can be any of the
 * {@link Ext.layout.ContainerLayout valid Ext layout types}.


 *

Region size is managed automatically and cannot be changed by the user -- for
 * {@link #split resizable regions}, see {@link Ext.layout.BorderLayout.SplitRegion}.


 * @constructor
 * Create a new Region.
 * @param {Layout} layout The {@link Ext.layout.BorderLayout BorderLayout} instance that is managing this Region.
 * @param {Object} config The configuration options
 * @param {String} position The region position.  Valid values are:
north, south,
 *
east, west and center.  Every {@link Ext.layout.BorderLayout BorderLayout}
 *
must have a center region for the primary content -- all other regions are optional.
 */

Ext.layout.BorderLayout.Region = function(layout, config, pos){
   
Ext.apply(this, config);
   
this.layout = layout;
   
this.position = pos;
   
this.state = {};
   
if(typeof this.margins == 'string'){
       
this.margins = this.layout.parseMargins(this.margins);
   
}
   
this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
   
if(this.collapsible){
       
if(typeof this.cmargins == 'string'){
           
this.cmargins = this.layout.parseMargins(this.cmargins);
       
}
       
if(this.collapseMode == 'mini' && !this.cmargins){
           
this.cmargins = {left:0,top:0,right:0,bottom:0};
       
}else{
           
this.cmargins = Ext.applyIf(this.cmargins || {},
                pos
== 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
       
}
   
}
};

Ext.layout.BorderLayout.Region.prototype = {
   
/**
     * @cfg {Boolean} animFloat
     * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated
     * panel that will close again once the user mouses out of that panel (or clicks out if
     *
{@link #autoHide} = false).  Setting {@link #animFloat} = false will
     * prevent the open and close of these floated panels from being animated (defaults to
true).
     */

   
/**
     * @cfg {Boolean} autoHide
     * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated
     * panel.  If
autoHide = true, the panel will automatically hide after the user mouses
     * out of the panel.  If
autoHide = false, the panel will continue to display until the
     * user clicks outside of the panel (defaults to
true).
     */

   
/**
     * @cfg {String} collapseMode
     *
collapseMode supports two configuration values:


     *

Note: if a collapsible region does not have a title bar, then set collapseMode =
     * 'mini'
and {@link #split} = true in order for the region to be {@link #collapsible}
     * by the user as the expand/collapse tool button (that would go in the title bar) will not be rendered.


     *

See also {@link #cmargins}.


     */

   
/**
     * @cfg {Object} margins
     * An object containing margins to apply to the region when in the expanded state in the
     * format:

{
    top: (top margin),
    right: (right margin),
    bottom: (bottom margin),
    left: (left margin)
}

     *

May also be a string containing space-separated, numeric margin values. The order of the
     * sides associated with each value matches the way CSS processes margin values:


     *


     *

Defaults to:


     * {top:0, right:0, bottom:0, left:0}
     *

     */

   
/**
     * @cfg {Object} cmargins
     * An object containing margins to apply to the region when in the collapsed state in the
     * format:

{
    top: (top margin),
    right: (right margin),
    bottom: (bottom margin),
    left: (left margin)
}

     *

May also be a string containing space-separated, numeric margin values. The order of the
     * sides associated with each value matches the way CSS processes margin values.


     *


     */

   
/**
     * @cfg {Boolean} collapsible
     *

true to allow the user to collapse this region (defaults to false).  If
     *
true, an expand/collapse tool button will automatically be rendered into the title
     * bar of the region, otherwise the button will not be shown.


     *

Note: that a title bar is required to display the collapse/expand toggle button -- if
     * no
title is specified for the region's panel, the region will only be collapsible if
     *
{@link #collapseMode} = 'mini' and {@link #split} = true.
     */

    collapsible
: false,
   

/**
     * @cfg {Boolean} split
     *

true to create a {@link Ext.layout.BorderLayout.SplitRegion SplitRegion} and
     * display a 5px wide {@link Ext.SplitBar} between this region and its neighbor, allowing the user to
     * resize the regions dynamically.  Defaults to
false creating a
     * {@link Ext.layout.BorderLayout.Region Region}.



     *

Notes:

 
     */

    split
:false,
   
/**
     * @cfg {Boolean} floatable
     *
true to allow clicking a collapsed region's bar to display the region's panel floated
     * above the layout,
false to force the user to fully expand a collapsed region by
     * clicking the expand button to see it again (defaults to
true).
     */

    floatable
: true,
   
/**
     * @cfg {Number} minWidth
     *

The minimum allowable width in pixels for this region (defaults to 50).
     *
maxWidth may also be specified.



     *

Note: setting the {@link Ext.SplitBar#minSize minSize} /
     *
{@link Ext.SplitBar#maxSize maxSize} supersedes any specified
     *
minWidth / maxWidth.


     */

    minWidth
:50,
   
/**
     * @cfg {Number} minHeight
     * The minimum allowable height in pixels for this region (defaults to
50)
     *
maxHeight may also be specified.



     *

Note: setting the {@link Ext.SplitBar#minSize minSize} /
     *
{@link Ext.SplitBar#maxSize maxSize} supersedes any specified
     *
minHeight / maxHeight.


     */

    minHeight
:50,

   
// private
    defaultMargins
: {left:0,top:0,right:0,bottom:0},
   
// private
    defaultNSCMargins
: {left:5,top:5,right:5,bottom:5},
   
// private
    defaultEWCMargins
: {left:5,top:0,right:5,bottom:0},
    floatingZIndex
: 100,

   
/**
     * True if this region is collapsed. Read-only.
     * @type Boolean
     * @property
     */

    isCollapsed
: false,

   
/**
     * This region's panel.  Read-only.
     * @type Ext.Panel
     * @property panel
     */

   
/**
     * This region's layout.  Read-only.
     * @type Layout
     * @property layout
     */

   
/**
     * This region's layout position (north, south, east, west or center).  Read-only.
     * @type String
     * @property position
     */


   
// private
    render
: function(ct, p){
       
this.panel = p;
        p
.el.enableDisplayMode();
       
this.targetEl = ct;
       
this.el = p.el;

       
var gs = p.getState, ps = this.position;
        p
.getState = function(){
           
return Ext.apply(gs.call(p) || {}, this.state);
       
}.createDelegate(this);

       
if(ps != 'center'){
            p
.allowQueuedExpand = false;
            p
.on({
                beforecollapse
: this.beforeCollapse,
                collapse
: this.onCollapse,
                beforeexpand
: this.beforeExpand,
                expand
: this.onExpand,
                hide
: this.onHide,
                show
: this.onShow,
                scope
: this
           
});
           
if(this.collapsible || this.floatable){
                p
.collapseEl = 'el';
                p
.slideAnchor = this.getSlideAnchor();
           
}
           
if(p.tools && p.tools.toggle){
                p
.tools.toggle.addClass('x-tool-collapse-'+ps);
                p
.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
           
}
       
}
   
},

   
// private
    getCollapsedEl
: function(){
       
if(!this.collapsedEl){
           
if(!this.toolTemplate){
               
var tt = new Ext.Template(
                     
'
'
               
);
                tt
.disableFormats = true;
                tt
.compile();
               
Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
           
}
           
this.collapsedEl = this.targetEl.createChild({
                cls
: "x-layout-collapsed x-layout-collapsed-"+this.position,
                id
: this.panel.id + '-xcollapsed'
           
});
           
this.collapsedEl.enableDisplayMode('block');

           
if(this.collapseMode == 'mini'){
               
this.collapsedEl.addClass('x-layout-cmini-'+this.position);
               
this.miniCollapsedEl = this.collapsedEl.createChild({
                    cls
: "x-layout-mini x-layout-mini-"+this.position, html: " "
               
});
               
this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
               
this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
               
this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
           
}else {
               
if(this.collapsible !== false && !this.hideCollapseTool) {
                   
var t = this.toolTemplate.append(
                           
this.collapsedEl.dom,
                           
{id:'expand-'+this.position}, true);
                    t
.addClassOnOver('x-tool-expand-'+this.position+'-over');
                    t
.on('click', this.onExpandClick, this, {stopEvent:true});
               
}
               
if(this.floatable !== false || this.titleCollapse){
                   
this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
                   
this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
               
}
           
}
       
}
       
return this.collapsedEl;
   
},

   
// private
    onExpandClick
: function(e){
       
if(this.isSlid){
           
this.afterSlideIn();
           
this.panel.expand(false);
       
}else{
           
this.panel.expand();
       
}
   
},

   
// private
    onCollapseClick
: function(e){
       
this.panel.collapse();
   
},

   
// private
    beforeCollapse
: function(p, animate){
       
this.lastAnim = animate;
       
if(this.splitEl){
           
this.splitEl.hide();
       
}
       
this.getCollapsedEl().show();
       
this.panel.el.setStyle('z-index', 100);
       
this.isCollapsed = true;
       
this.layout.layout();
   
},

   
// private
    onCollapse
: function(animate){
       
this.panel.el.setStyle('z-index', 1);
       
if(this.lastAnim === false || this.panel.animCollapse === false){
           
this.getCollapsedEl().dom.style.visibility = 'visible';
       
}else{
           
this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
       
}
       
this.state.collapsed = true;
       
this.panel.saveState();
   
},

   
// private
    beforeExpand
: function(animate){
       
var c = this.getCollapsedEl();
       
this.el.show();
       
if(this.position == 'east' || this.position == 'west'){
           
this.panel.setSize(undefined, c.getHeight());
       
}else{
           
this.panel.setSize(c.getWidth(), undefined);
       
}
        c
.hide();
        c
.dom.style.visibility = 'hidden';
       
this.panel.el.setStyle('z-index', this.floatingZIndex);
   
},

   
// private
    onExpand
: function(){
       
this.isCollapsed = false;
       
if(this.splitEl){
           
this.splitEl.show();
       
}
       
this.layout.layout();
       
this.panel.el.setStyle('z-index', 1);
       
this.state.collapsed = false;
       
this.panel.saveState();
   
},

   
// private
    collapseClick
: function(e){
       
if(this.isSlid){
           e
.stopPropagation();
           
this.slideIn();
       
}else{
           e
.stopPropagation();
           
this.slideOut();
       
}
   
},

   
// private
    onHide
: function(){
       
if(this.isCollapsed){
           
this.getCollapsedEl().hide();
       
}else if(this.splitEl){
           
this.splitEl.hide();
       
}
   
},

   
// private
    onShow
: function(){
       
if(this.isCollapsed){
           
this.getCollapsedEl().show();
       
}else if(this.splitEl){
           
this.splitEl.show();
       
}
   
},

   
/**
     * True if this region is currently visible, else false.
     * @return {Boolean}
     */

    isVisible
: function(){
       
return !this.panel.hidden;
   
},

   
/**
     * Returns the current margins for this region.  If the region is collapsed, the
     * {@link #cmargins} (collapsed margins) value will be returned, otherwise the
     * {@link #margins} value will be returned.
     * @return {Object} An object containing the element's margins:
{left: (left
     * margin), top: (top margin), right: (right margin), bottom: (bottom margin)}

     */

    getMargins
: function(){
       
return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
   
},

   
/**
     * Returns the current size of this region.  If the region is collapsed, the size of the
     * collapsedEl will be returned, otherwise the size of the region's panel will be returned.
     * @return {Object} An object containing the element's size:
{width: (element width),
     * height: (element height)}

     */

    getSize
: function(){
       
return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
   
},

   
/**
     * Sets the specified panel as the container element for this region.
     * @param {Ext.Panel} panel The new panel
     */

    setPanel
: function(panel){
       
this.panel = panel;
   
},

   
/**
     * Returns the minimum allowable width for this region.
     * @return {Number} The minimum width
     */

    getMinWidth
: function(){
       
return this.minWidth;
   
},

   
/**
     * Returns the minimum allowable height for this region.
     * @return {Number} The minimum height
     */

    getMinHeight
: function(){
       
return this.minHeight;
   
},

   
// private
    applyLayoutCollapsed
: function(box){
       
var ce = this.getCollapsedEl();
        ce
.setLeftTop(box.x, box.y);
        ce
.setSize(box.width, box.height);
   
},

   
// private
    applyLayout
: function(box){
       
if(this.isCollapsed){
           
this.applyLayoutCollapsed(box);
       
}else{
           
this.panel.setPosition(box.x, box.y);
           
this.panel.setSize(box.width, box.height);
       
}
   
},

   
// private
    beforeSlide
: function(){
       
this.panel.beforeEffect();
   
},

   
// private
    afterSlide
: function(){
       
this.panel.afterEffect();
   
},

   
// private
    initAutoHide
: function(){
       
if(this.autoHide !== false){
           
if(!this.autoHideHd){
               
var st = new Ext.util.DelayedTask(this.slideIn, this);
               
this.autoHideHd = {
                   
"mouseout": function(e){
                       
if(!e.within(this.el, true)){
                            st
.delay(500);
                       
}
                   
},
                   
"mouseover" : function(e){
                        st
.cancel();
                   
},
                    scope
: this
               
};
           
}
           
this.el.on(this.autoHideHd);
       
}
   
},

   
// private
    clearAutoHide
: function(){
       
if(this.autoHide !== false){
           
this.el.un("mouseout", this.autoHideHd.mouseout);
           
this.el.un("mouseover", this.autoHideHd.mouseover);
       
}
   
},

   
// private
    clearMonitor
: function(){
       
Ext.getDoc().un("click", this.slideInIf, this);
   
},

   
/**
     * If this Region is {@link #floatable}, this method slides this Region into full visibility
over the top
     * of the center Region
where it floats until either {@link #slideIn} is called, or other regions of the layout
     * are clicked, or the mouse exits the Region.
     */

    slideOut
: function(){
       
if(this.isSlid || this.el.hasActiveFx()){
           
return;
       
}
       
this.isSlid = true;
       
var ts = this.panel.tools;
       
if(ts && ts.toggle){
            ts
.toggle.hide();
       
}
       
this.el.show();
       
if(this.position == 'east' || this.position == 'west'){
           
this.panel.setSize(undefined, this.collapsedEl.getHeight());
       
}else{
           
this.panel.setSize(this.collapsedEl.getWidth(), undefined);
       
}
       
this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
       
this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
       
this.el.setStyle("z-index", this.floatingZIndex+2);
       
this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
       
if(this.animFloat !== false){
           
this.beforeSlide();
           
this.el.slideIn(this.getSlideAnchor(), {
                callback
: function(){
                   
this.afterSlide();
                   
this.initAutoHide();
                   
Ext.getDoc().on("click", this.slideInIf, this);
               
},
                scope
: this,
                block
: true
           
});
       
}else{
           
this.initAutoHide();
             
Ext.getDoc().on("click", this.slideInIf, this);
       
}
   
},

   
// private
    afterSlideIn
: function(){
       
this.clearAutoHide();
       
this.isSlid = false;
       
this.clearMonitor();
       
this.el.setStyle("z-index", "");
       
this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
       
this.el.dom.style.left = this.restoreLT[0];
       
this.el.dom.style.top = this.restoreLT[1];

       
var ts = this.panel.tools;
       
if(ts && ts.toggle){
            ts
.toggle.show();
       
}
   
},

   
/**
     * If this Region is {@link #floatable}, and this Region has been slid into floating visibility, then this method slides
     * this region back into its collapsed state.
     */

    slideIn
: function(cb){
       
if(!this.isSlid || this.el.hasActiveFx()){
           
Ext.callback(cb);
           
return;
       
}
       
this.isSlid = false;
       
if(this.animFloat !== false){
           
this.beforeSlide();
           
this.el.slideOut(this.getSlideAnchor(), {
                callback
: function(){
                   
this.el.hide();
                   
this.afterSlide();
                   
this.afterSlideIn();
                   
Ext.callback(cb);
               
},
                scope
: this,
                block
: true
           
});
       
}else{
           
this.el.hide();
           
this.afterSlideIn();
       
}
   
},

   
// private
    slideInIf
: function(e){
       
if(!e.within(this.el)){
           
this.slideIn();
       
}
   
},

   
// private
    anchors
: {
       
"west" : "left",
       
"east" : "right",
       
"north" : "top",
       
"south" : "bottom"
   
},

   
// private
    sanchors
: {
       
"west" : "l",
       
"east" : "r",
       
"north" : "t",
       
"south" : "b"
   
},

   
// private
    canchors
: {
       
"west" : "tl-tr",
       
"east" : "tr-tl",
       
"north" : "tl-bl",
       
"south" : "bl-tl"
   
},

   
// private
    getAnchor
: function(){
       
return this.anchors[this.position];
   
},

   
// private
    getCollapseAnchor
: function(){
       
return this.canchors[this.position];
   
},

   
// private
    getSlideAnchor
: function(){
       
return this.sanchors[this.position];
   
},

   
// private
    getAlignAdj
: function(){
       
var cm = this.cmargins;
       
switch(this.position){
           
case "west":
               
return [0, 0];
           
break;
           
case "east":
               
return [0, 0];
           
break;
           
case "north":
               
return [0, 0];
           
break;
           
case "south":
               
return [0, 0];
           
break;
       
}
   
},

   
// private
    getExpandAdj
: function(){
       
var c = this.collapsedEl, cm = this.cmargins;
       
switch(this.position){
           
case "west":
               
return [-(cm.right+c.getWidth()+cm.left), 0];
           
break;
           
case "east":
               
return [cm.right+c.getWidth()+cm.left, 0];
           
break;
           
case "north":
               
return [0, -(cm.top+cm.bottom+c.getHeight())];
           
break;
           
case "south":
               
return [0, cm.top+cm.bottom+c.getHeight()];
           
break;
       
}
   
}
};

/**
 * @class Ext.layout.BorderLayout.SplitRegion
 * @extends Ext.layout.BorderLayout.Region
 *

This is a specialized type of {@link Ext.layout.BorderLayout.Region BorderLayout region} that
 * has a built-in {@link Ext.SplitBar} for user resizing of regions.  The movement of the split bar
 * is configurable to move either {@link #tickSize smooth or incrementally}.


 * @constructor
 * Create a new SplitRegion.
 * @param {Layout} layout The {@link Ext.layout.BorderLayout BorderLayout} instance that is managing this Region.
 * @param {Object} config The configuration options
 * @param {String} position The region position.  Valid values are: north, south, east, west and center.  Every
 * BorderLayout must have a center region for the primary content -- all other regions are optional.
 */

Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
   
Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
   
// prevent switch
   
this.applyLayout = this.applyFns[pos];
};

Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
   
/**
     * @cfg {Number} tickSize
     * The increment, in pixels by which to move this Region's {@link Ext.SplitBar SplitBar}.
     * By default, the {@link Ext.SplitBar SplitBar} moves smoothly.
     */

   
/**
     * @cfg {String} splitTip
     * The tooltip to display when the user hovers over a
     * {@link Ext.layout.BorderLayout.Region#collapsible non-collapsible} region's split bar
     * (defaults to
"Drag to resize.").  Only applies if
     *
{@link #useSplitTips} = true.
     */

    splitTip
: "Drag to resize.",
   
/**
     * @cfg {String} collapsibleSplitTip
     * The tooltip to display when the user hovers over a
     * {@link Ext.layout.BorderLayout.Region#collapsible collapsible} region's split bar
     * (defaults to "Drag to resize. Double click to hide."). Only applies if
     *
{@link #useSplitTips} = true.
     */

    collapsibleSplitTip
: "Drag to resize. Double click to hide.",
   
/**
     * @cfg {Boolean} useSplitTips
     *
true to display a tooltip when the user hovers over a region's split bar
     * (defaults to
false).  The tooltip text will be the value of either
     *
{@link #splitTip} or {@link #collapsibleSplitTip} as appropriate.
     */

    useSplitTips
: false,

   
// private
    splitSettings
: {
        north
: {
            orientation
: Ext.SplitBar.VERTICAL,
            placement
: Ext.SplitBar.TOP,
            maxFn
: 'getVMaxSize',
            minProp
: 'minHeight',
            maxProp
: 'maxHeight'
       
},
        south
: {
            orientation
: Ext.SplitBar.VERTICAL,
            placement
: Ext.SplitBar.BOTTOM,
            maxFn
: 'getVMaxSize',
            minProp
: 'minHeight',
            maxProp
: 'maxHeight'
       
},
        east
: {
            orientation
: Ext.SplitBar.HORIZONTAL,
            placement
: Ext.SplitBar.RIGHT,
            maxFn
: 'getHMaxSize',
            minProp
: 'minWidth',
            maxProp
: 'maxWidth'
       
},
        west
: {
            orientation
: Ext.SplitBar.HORIZONTAL,
            placement
: Ext.SplitBar.LEFT,
            maxFn
: 'getHMaxSize',
            minProp
: 'minWidth',
            maxProp
: 'maxWidth'
       
}
   
},

   
// private
    applyFns
: {
        west
: function(box){
           
if(this.isCollapsed){
               
return this.applyLayoutCollapsed(box);
           
}
           
var sd = this.splitEl.dom, s = sd.style;
           
this.panel.setPosition(box.x, box.y);
           
var sw = sd.offsetWidth;
            s
.left = (box.x+box.width-sw)+'px';
            s
.top = (box.y)+'px';
            s
.height = Math.max(0, box.height)+'px';
           
this.panel.setSize(box.width-sw, box.height);
       
},
        east
: function(box){
           
if(this.isCollapsed){
               
return this.applyLayoutCollapsed(box);
           
}
           
var sd = this.splitEl.dom, s = sd.style;
           
var sw = sd.offsetWidth;
           
this.panel.setPosition(box.x+sw, box.y);
            s
.left = (box.x)+'px';
            s
.top = (box.y)+'px';
            s
.height = Math.max(0, box.height)+'px';
           
this.panel.setSize(box.width-sw, box.height);
       
},
        north
: function(box){
           
if(this.isCollapsed){
               
return this.applyLayoutCollapsed(box);
           
}
           
var sd = this.splitEl.dom, s = sd.style;
           
var sh = sd.offsetHeight;
           
this.panel.setPosition(box.x, box.y);
            s
.left = (box.x)+'px';
            s
.top = (box.y+box.height-sh)+'px';
            s
.width = Math.max(0, box.width)+'px';
           
this.panel.setSize(box.width, box.height-sh);
       
},
        south
: function(box){
           
if(this.isCollapsed){
               
return this.applyLayoutCollapsed(box);
           
}
           
var sd = this.splitEl.dom, s = sd.style;
           
var sh = sd.offsetHeight;
           
this.panel.setPosition(box.x, box.y+sh);
            s
.left = (box.x)+'px';
            s
.top = (box.y)+'px';
            s
.width = Math.max(0, box.width)+'px';
           
this.panel.setSize(box.width, box.height-sh);
       
}
   
},

   
// private
    render
: function(ct, p){
       
Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);

       
var ps = this.position;

       
this.splitEl = ct.createChild({
            cls
: "x-layout-split x-layout-split-"+ps, html: " ",
            id
: this.panel.id + '-xsplit'
       
});

       
if(this.collapseMode == 'mini'){
           
this.miniSplitEl = this.splitEl.createChild({
                cls
: "x-layout-mini x-layout-mini-"+ps, html: " "
           
});
           
this.miniSplitEl.addClassOnOver('x-layout-mini-over');
           
this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
       
}

       
var s = this.splitSettings[ps];

       
this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
       
this.split.tickSize = this.tickSize;
       
this.split.placement = s.placement;
       
this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
       
this.split.minSize = this.minSize || this[s.minProp];
       
this.split.on("beforeapply", this.onSplitMove, this);
       
this.split.useShim = this.useShim === true;
       
this.maxSize = this.maxSize || this[s.maxProp];

       
if(p.hidden){
           
this.splitEl.hide();
       
}

       
if(this.useSplitTips){
           
this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
       
}
       
if(this.collapsible){
           
this.splitEl.on("dblclick", this.onCollapseClick,  this);
       
}
   
},

   
//docs inherit from superclass
    getSize
: function(){
       
if(this.isCollapsed){
           
return this.collapsedEl.getSize();
       
}
       
var s = this.panel.getSize();
       
if(this.position == 'north' || this.position == 'south'){
            s
.height += this.splitEl.dom.offsetHeight;
       
}else{
            s
.width += this.splitEl.dom.offsetWidth;
       
}
       
return s;
   
},

   
// private
    getHMaxSize
: function(){
         
var cmax = this.maxSize || 10000;
         
var center = this.layout.center;
         
return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
   
},

   
// private
    getVMaxSize
: function(){
       
var cmax = this.maxSize || 10000;
       
var center = this.layout.center;
       
return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
   
},

   
// private
    onSplitMove
: function(split, newSize){
       
var s = this.panel.getSize();
       
this.lastSplitSize = newSize;
       
if(this.position == 'north' || this.position == 'south'){
           
this.panel.setSize(s.width, newSize);
           
this.state.height = newSize;
       
}else{
           
this.panel.setSize(newSize, s.height);
           
this.state.width = newSize;
       
}
       
this.layout.layout();
       
this.panel.saveState();
       
return false;
   
},

   
/**
     * Returns a reference to the split bar in use by this region.
     * @return {Ext.SplitBar} The split bar
     */

    getSplitBar
: function(){
       
return this.split;
   
},

   
// inherit docs
    destroy
: function() {
       
Ext.destroy(
           
this.miniSplitEl,
           
this.split,
           
this.splitEl
       
);
   
}
});

Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;