text: define("dojox/layout/GridContainer", [
  	"dojo/_base/kernel",
  	"dojo/_base/declare", // declare
  	"dojo/_base/array",
  	"dojo/_base/connect",
  	"dojo/_base/sniff",
  	"dojo/dom-class",
  	"dojo/dom-style",
  	"dojo/dom-geometry",
  	"dojo/dom-construct",
  	"dojo/_base/lang",
  	"dojo/_base/window",
  	"dojo/ready",	// dojo.ready
  	"dojox/layout/GridContainerLite"
  ],function(dojo, declare, array, connect, has, domClass, domStyle, geom, domConstruct, lang, win, ready, GridContainerLite){
  	return declare(
  		"dojox.layout.GridContainer",
  		GridContainerLite,
  	{
  		// summary:
  		//		A grid containing any kind of objects and acting like web portals.
  		//
  		// description:
  		//		This component inherits of all features of gridContainerLite plus :
  		//
  		//		- Resize colums
  		//		- Add / remove columns
  		//		- Fix columns at left or at right.
  		// example:
  		// 	|	<div dojoType="dojox.layout.GridContainer" nbZones="3" isAutoOrganized="true">
  		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
  		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div>
  		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div>
  		// 	|	</div>
  		//
  		// example:
  		// 	|	dojo.ready(function(){
  		// 	|		var cpane1 = new dijit.layout.ContentPane({ title:"cpane1", content: "Content Pane 1 : Drag Me !" }),
  		// 	|			cpane2 = new dijit.layout.ContentPane({ title:"cpane2", content: "Content Pane 2 : Drag Me !" }),
  		// 	|			cpane3 = new dijit.layout.ContentPane({ title:"cpane3", content: "Content Pane 3 : Drag Me !" });
  		// 	|
  		// 	|		var widget = new dojox.layout.GridContainer({
  		// 	|			nbZones: 3,
  		// 	|			isAutoOrganized: true
  		// 	|		}, dojo.byId("idNode"));
  		// 	|		widget.addChild(cpane1, 0, 0);
  		// 	|		widget.addChild(cpane2, 1, 0);
  		// 	|		widget.addChild(cpane3, 2, 1);
  		// 	|		widget.startup();
  		// 	|	});
  
  		// hasResizableColumns: Boolean
  		//		Allow or not resizing of columns by a grip handle.
  		hasResizableColumns: true,
  
  		// liveResizeColumns: Boolean
  		//		Specifies whether columns resize as you drag (true) or only upon mouseup (false)
  		liveResizeColumns : false,
  
  		// minColWidth: Integer
  		//		Minimum column width in percentage.
  		minColWidth: 20,
  
  		// minChildWidth: Integer
  		//		Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property)
  		minChildWidth: 150,
  
  		// mode: String
  		//		Location to add/remove columns, must be set to 'left' or 'right' (default).
  		mode: "right",
  
  		// isRightFixed: Boolean
  		//		Define if the last right column is fixed.
  		//		Used when you add or remove columns by calling setColumns method.
  		isRightFixed: false,
  
  		// isLeftFixed: Boolean
  		//		Define if the last left column is fixed.
  		//		Used when you add or remove columns by calling setColumns method.
  		isLeftFixed: false,
  
  		startup: function(){
  			// summary:
  			//		Call the startup of GridContainerLite and place grips
  			//		if user has chosen the hasResizableColumns attribute to true.
  
  			//console.log("dojox.layout.GridContainer ::: startup");
  			this.inherited(arguments);
  			if(this.hasResizableColumns){
  				for(var i = 0; i < this._grid.length - 1; i++){
  					this._createGrip(i);
  				}
  				// If widget has a container parent, grips will be placed
  				// by method onShow.
  				if(!this.getParent()){
  					// Fix IE7 :
  					//		The CSS property height:100% for the grip
  					//		doesn't work anytime. It's necessary to wait
  					//		the end of loading before to place grips.
  					ready(lang.hitch(this, "_placeGrips"));
  				}
  			}
  		},
  
  		resizeChildAfterDrop : function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){
  			// summary:
  			//		Call when a child is dropped.
  			// description:
  			//		Allow to resize and put grips
  			// node:
  			//		domNode of dropped widget.
  			// targetArea:
  			//		AreaManager Object containing information of targetArea
  			// indexChild:
  			//		Index where the dropped widget has been placed
  
  			if(this.inherited(arguments)){
  				this._placeGrips();
  			}
  		},
  
  		onShow: function(){
  			// summary:
  			//		Place grips in the right place when the GridContainer becomes visible.
  
  			//console.log("dojox.layout.GridContainer ::: onShow");
  			this.inherited(arguments);
  			this._placeGrips();
  		},
  
  		resize: function(){
  			// summary:
  			//		Resize the GridContainer widget and columns.
  			//		Replace grips if it's necessary.
  			// tags:
  			//		callback
  
  			//console.log("dojox.layout.GridContainer ::: resize");
  			this.inherited(arguments);
  			// Fix IE6 :
  			//		IE6 calls method resize itself.
  			//		If the GridContainer is not visible at this time,
  			//		the method _placeGrips can return a negative value with
  			//		contentBox method. (see method _placeGrip() with Fix Ie6 for the height)
  			if(this._isShown() && this.hasResizableColumns){
  				this._placeGrips();
  			}
  		},
  
  		_createGrip: function(/*Integer*/ index){
  			// summary:
  			//		Create a grip for a specific zone.
  			// index:
  			//		index where the grip has to be created.
  			// tags:
  			//		protected
  
  			//console.log("dojox.layout.GridContainer ::: _createGrip");
  			var dropZone = this._grid[index],
  				grip = domConstruct.create("div", { 'class': "gridContainerGrip" }, this.domNode);
  			dropZone.grip = grip;
  			dropZone.gripHandler = [
  				this.connect(grip, "onmouseover", function(e){
  					var gridContainerGripShow = false;
  					for(var i = 0; i < this._grid.length - 1; i++){
  						if(domClass.contains(this._grid[i].grip, "gridContainerGripShow")){
  							gridContainerGripShow = true;
  							break;
  						}
  					}
  					if(!gridContainerGripShow){
  						domClass.replace(e.target, "gridContainerGripShow", "gridContainerGrip");
  					}
  				})[0],
  				this.connect(grip, "onmouseout", function(e){
  					if(!this._isResized){
  						domClass.replace(e.target, "gridContainerGrip", "gridContainerGripShow");
  					}
  				})[0],
  				this.connect(grip, "onmousedown", "_resizeColumnOn")[0],
  				this.connect(grip, "ondblclick", "_onGripDbClick")[0]
  			];
  		},
  
  		_placeGrips: function(){
  			// summary:
  			//		Define the position of a grip and place it on page.
  			// tags:
  			//		protected
  
  			//console.log("dojox.layout.GridContainer ::: _placeGrips");
  			var gripWidth, height, left = 0, grip;
  			//var scroll = this.domNode.style.overflowY;
  
  			array.forEach(this._grid, function(dropZone){
  				if(dropZone.grip){
  					grip = dropZone.grip;
  					if(!gripWidth){
  						gripWidth = grip.offsetWidth / 2;
  					}
  
  					left += geom.getMarginBox(dropZone.node).w;
  
  					domStyle.set(grip, "left", (left - gripWidth) + "px");
  					//if(dojo.isIE == 6){ do it fot all navigators
  					if(!height){
  						height = geom.getContentBox(this.gridNode).h;
  					}
  					if(height > 0){
  						domStyle.set(grip, "height", height + "px");
  					}
  					//}
  				}
  			}, this);
  		},
  
  		_onGripDbClick: function(){
  			// summary:
  			//		Called when a double click is catch. Resize all columns with the same width.
  			//		The method resize of children have to be called.
  			// tags:
  			//		callback protected
  
  			//console.log("dojox.layout.GridContainer ::: _onGripDbClick");
  			this._updateColumnsWidth(this._dragManager);
  			this.resize();
  		},
  
  		_resizeColumnOn: function(/*Event*/e){
  			// summary:
  			//		Connect events to listen the resize action.
  			//		Change the type of width columns (% to px).
  			//		Calculate the minwidth according to the children.
  			// tags:
  			//		callback
  
  			//console.log("dojox.layout.GridContainer ::: _resizeColumnOn", e);
  			this._activeGrip = e.target;
  			this._initX = e.pageX;
  			e.preventDefault();
  
  			win.body().style.cursor = "ew-resize";
  
  			this._isResized = true;
  
  			var tabSize = [];
  			var grid;
  			var i;
  
  			for(i = 0; i < this._grid.length; i++){
  				tabSize[i] = geom.getContentBox(this._grid[i].node).w;
  			}
  
  			this._oldTabSize = tabSize;
  
  			for(i = 0; i < this._grid.length; i++){
  				grid = this._grid[i];
  				if(this._activeGrip == grid.grip){
  					this._currentColumn = grid.node;
  					this._currentColumnWidth = tabSize[i];
  					this._nextColumn = this._grid[i + 1].node;
  					this._nextColumnWidth = tabSize[i + 1];
  				}
  				grid.node.style.width = tabSize[i] + "px";
  			}
  
  			// calculate the minWidh of all children for current and next column
  			var calculateChildMinWidth = function(childNodes, minChild){
  				var width = 0;
  				var childMinWidth = 0;
  
  				array.forEach(childNodes, function(child){
  					if(child.nodeType == 1){
  						var objectStyle = domStyle.getComputedStyle(child);
  						var minWidth = (has("ie")) ? minChild : parseInt(objectStyle.minWidth);
  
  						childMinWidth = minWidth +
  									parseInt(objectStyle.marginLeft) +
  									parseInt(objectStyle.marginRight);
  
  						if(width < childMinWidth){
  							width = childMinWidth;
  						}
  					}
  				});
  				return width;
  			};
  			var currentColumnMinWidth = calculateChildMinWidth(this._currentColumn.childNodes, this.minChildWidth);
  
  			var nextColumnMinWidth = calculateChildMinWidth(this._nextColumn.childNodes, this.minChildWidth);
  
  			var minPix = Math.round((geom.getMarginBox(this.gridContainerTable).w * this.minColWidth) / 100);
  
  			this._currentMinCol = currentColumnMinWidth;
  			this._nextMinCol = nextColumnMinWidth;
  
  			if(minPix > this._currentMinCol){
  				this._currentMinCol = minPix;
  			}
  			if(minPix > this._nextMinCol){
  				this._nextMinCol = minPix;
  			}
  			this._connectResizeColumnMove = connect.connect(win.doc, "onmousemove", this, "_resizeColumnMove");
  			this._connectOnGripMouseUp = connect.connect(win.doc, "onmouseup", this, "_onGripMouseUp");
  		},
  
  		_onGripMouseUp: function(){
  			// summary:
  			//		Call on the onMouseUp only if the reiszeColumnMove was not called.
  			// tags:
  			//		callback
  
  			//console.log(dojox.layout.GridContainer ::: _onGripMouseUp");
  			win.body().style.cursor = "default";
  
  			connect.disconnect(this._connectResizeColumnMove);
  			connect.disconnect(this._connectOnGripMouseUp);
  
  			this._connectOnGripMouseUp = this._connectResizeColumnMove = null;
  
  			if(this._activeGrip){
  				domClass.replace(this._activeGrip, "gridContainerGrip", "gridContainerGripShow");
  			}
  
  			this._isResized = false;
  		},
  
  		_resizeColumnMove: function(/*Event*/e){
  			// summary:
  			//		Change columns size.
  			// tags:
  			//		callback
  
  			//console.log("dojox.layout.GridContainer ::: _resizeColumnMove");
  			e.preventDefault();
  			if(!this._connectResizeColumnOff){
  				connect.disconnect(this._connectOnGripMouseUp);
  				this._connectOnGripMouseUp = null;
  				this._connectResizeColumnOff = connect.connect(win.doc, "onmouseup", this, "_resizeColumnOff");
  			}
  
  			var d = e.pageX - this._initX;
  			if(d == 0){ return; }
  
  			if(!(this._currentColumnWidth + d < this._currentMinCol ||
  					this._nextColumnWidth - d < this._nextMinCol)){
  
  				this._currentColumnWidth += d;
  				this._nextColumnWidth -= d;
  				this._initX = e.pageX;
  				this._activeGrip.style.left = parseInt(this._activeGrip.style.left) + d + "px";
  
  				if(this.liveResizeColumns){
  					this._currentColumn.style["width"] = this._currentColumnWidth + "px";
  					this._nextColumn.style["width"] = this._nextColumnWidth + "px";
  					this.resize();
  				}
  			}
  		},
  
  		_resizeColumnOff: function(/*Event*/e){
  			// summary:
  			//		Disconnect resize events.
  			//		Change the type of width columns (px to %).
  			// tags:
  			//		callback
  
  			//console.log("dojox.layout.GridContainer ::: _resizeColumnOff");
  			win.body().style.cursor = "default";
  
  			connect.disconnect(this._connectResizeColumnMove);
  			connect.disconnect(this._connectResizeColumnOff);
  
  			this._connectResizeColumnOff = this._connectResizeColumnMove = null;
  
  			if(!this.liveResizeColumns){
  				this._currentColumn.style["width"] = this._currentColumnWidth + "px";
  				this._nextColumn.style["width"] = this._nextColumnWidth + "px";
  				//this.resize();
  			}
  
  			var tabSize = [],
  				testSize = [],
  				tabWidth = this.gridContainerTable.clientWidth,
  				node,
  				update = false,
  				i;
  
  			for(i = 0; i < this._grid.length; i++){
  				node = this._grid[i].node;
  				if(has("ie")){
  					tabSize[i] = geom.getMarginBox(node).w;
  					testSize[i] = geom.getContentBox(node).w;
  				}
  				else{
  					tabSize[i] = geom.getContentBox(node).w;
  					testSize = tabSize;
  				}
  			}
  
  			for(i = 0; i < testSize.length; i++){
  				if(testSize[i] != this._oldTabSize[i]){
  					update = true;
  					break;
  				}
  			}
  
  			if(update){
  				var mul = has("ie") ? 100 : 10000;
  				for(i = 0; i < this._grid.length; i++){
  					this._grid[i].node.style.width = Math.round((100 * mul * tabSize[i]) / tabWidth) / mul + "%";
  				}
  				this.resize();
  			}
  
  			if(this._activeGrip){
  				domClass.replace(this._activeGrip, "gridContainerGrip", "gridContainerGripShow");
  			}
  
  			this._isResized = false;
  		},
  
  		setColumns: function(/*Integer*/nbColumns){
  			// summary:
  			//		Set the number of columns.
  			// nbColumns:
  			//		Number of columns
  
  			//console.log("dojox.layout.GridContainer ::: setColumns");
  			var z, j;
  			if(nbColumns > 0){
  				var length = this._grid.length,
  					delta = length - nbColumns;
  				if(delta > 0){
  					var count = [], zone, start, end, nbChildren;
  					// Check if right or left columns are fixed
  					// Columns are not taken in account and can't be deleted
  					if(this.mode == "right"){
  						end = (this.isLeftFixed && length > 0) ? 1 : 0;
  						start = (this.isRightFixed) ? length - 2 : length - 1
  						for(z = start; z >= end; z--){
  							nbChildren = 0;
  							zone = this._grid[z].node;
  							for(j = 0; j < zone.childNodes.length; j++){
  								if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){
  									nbChildren++;
  									break;
  								}
  							}
  							if(nbChildren == 0){ count[count.length] = z; }
  							if(count.length >= delta){
  								this._deleteColumn(count);
  								break;
  							}
  						}
  						if(count.length < delta){
  							connect.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
  						}
  					}
  					else{ // mode = "left"
  						start = (this.isLeftFixed && length > 0) ? 1 : 0;
  						end = (this.isRightFixed) ? length - 1 : length;
  						for(z = start; z < end; z++){
  							nbChildren = 0;
  							zone = this._grid[z].node;
  							for(j = 0; j < zone.childNodes.length; j++){
  								if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){
  									nbChildren++;
  									break;
  								}
  							}
  							if(nbChildren == 0){ count[count.length] = z; }
  							if(count.length >= delta){
  								this._deleteColumn(count);
  								break;
  							}
  						}
  						if(count.length < delta){
  							//Not enough empty columns
  							connect.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
  						}
  					}
  				}
  				else{
  					if(delta < 0){ this._addColumn(Math.abs(delta)); }
  				}
  				if(this.hasResizableColumns){ this._placeGrips(); }
  			}
  		},
  
  		_addColumn: function(/*Integer*/nbColumns){
  			// summary:
  			//		Add some columns.
  			// nbColumns:
  			//		Number of column to added
  			// tags:
  			//		private
  
  			//console.log("dojox.layout.GridContainer ::: _addColumn");
  			var grid = this._grid,
  				dropZone,
  				node,
  				index,
  				length,
  				isRightMode = (this.mode == "right"),
  				accept = this.acceptTypes.join(","),
  				m = this._dragManager;
  
  			//Add a grip to the last column
  			if(this.hasResizableColumns && ((!this.isRightFixed && isRightMode)
  				|| (this.isLeftFixed && !isRightMode && this.nbZones == 1) )){
  				this._createGrip(grid.length - 1);
  			}
  
  			for(var i = 0; i < nbColumns; i++){
  				// Fix CODEX defect #53025 :
  				//		Apply acceptType attribute on each new column.
  				node = domConstruct.create("td", {
  					'class': "gridContainerZone dojoxDndArea" ,
  					'accept': accept,
  					'id': this.id + "_dz" + this.nbZones
  				});
  
  				length = grid.length;
  
  				if(isRightMode){
  					if(this.isRightFixed){
  						index = length - 1;
  						grid.splice(index, 0, {
  							'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
  						});
  					}
  					else{
  						index = length;
  						grid.push({ 'node': this.gridNode.appendChild(node) });
  					}
  				}
  				else{
  					if(this.isLeftFixed){
  						index = (length == 1) ? 0 : 1;
  						this._grid.splice(1, 0, {
  							'node': this._grid[index].node.parentNode.appendChild(node, this._grid[index].node)
  						});
  						index = 1;
  					}
  					else{
  						index = length - this.nbZones;
  						this._grid.splice(index, 0, {
  							'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
  						});
  					}
  				}
  				if(this.hasResizableColumns){
  					//Add a grip to resize columns
  					if((!isRightMode && this.nbZones != 1) ||
  							(!isRightMode && this.nbZones == 1 && !this.isLeftFixed) ||
  								(isRightMode && i < nbColumns-1) ||
  									(isRightMode && i == nbColumns-1 && this.isRightFixed)){
  						this._createGrip(index);
  					}
  				}
  				// register tnbZoneshe new area into the areaManager
  				m.registerByNode(grid[index].node);
  				this.nbZones++;
  			}
  			this._updateColumnsWidth(m);
  		},
  
  		_deleteColumn: function(/*Array*/indices){
  			// summary:
  			//		Remove some columns with indices passed as an array.
  			// indices:
  			//		Column index array
  			// tags:
  			//		private
  
  			//console.log("dojox.layout.GridContainer ::: _deleteColumn");
  			var child, grid, index,
  				nbDelZones = 0,
  				length = indices.length,
  				m = this._dragManager;
  			for(var i = 0; i < length; i++){
  				index = (this.mode == "right") ? indices[i] : indices[i] - nbDelZones;
  				grid = this._grid[index];
  
  				if(this.hasResizableColumns && grid.grip){
  					array.forEach(grid.gripHandler, function(handler){
  						connect.disconnect(handler);
  					});
  					domConstruct.destroy(this.domNode.removeChild(grid.grip));
  					grid.grip = null;
  				}
  
  				m.unregister(grid.node);
  				domConstruct.destroy(this.gridNode.removeChild(grid.node));
  				this._grid.splice(index, 1);
  				this.nbZones--;
  				nbDelZones++;
  			}
  
  			// last grip
  			var lastGrid = this._grid[this.nbZones-1];
  			if(lastGrid.grip){
  				array.forEach(lastGrid.gripHandler, connect.disconnect);
  				domConstruct.destroy(this.domNode.removeChild(lastGrid.grip));
  				lastGrid.grip = null;
  			}
  
  			this._updateColumnsWidth(m);
  		},
  
  		_updateColumnsWidth: function(/*Object*/ manager){
  			// summary:
  			//		Update the columns width.
  			// manager:
  			//		dojox.mdnd.AreaManager singleton
  			// tags:
  			//		private
  
  			//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
  			this.inherited(arguments);
  			if(manager === null){
  				manager = this._dragManager;
  			}
  			manager._dropMode.updateAreas(manager._areaList);
  		},
  
  		destroy: function(){
  			connect.unsubscribe(this._dropHandler);
  			this.inherited(arguments);
  		}
  	});
  });
  