// The global array of objects that have been instanciated
if (!Bs_Objects) {var Bs_Objects = [];};


/**
* resize stuff, needs to be in the global scope :/
*/
var bs_rg_currentObj;
this.bs_rg_resize = function() {
	bs_rg_currentObj.resize();
}
this.bs_rg_resizeEnd = function() {
	bs_rg_currentObj.resizeEnd();
}



/**
* Resize Grip to resize a window/div/whatever.
* 
* dependencies: /core/lang/Bs_Misc.lib.js
* 
* @author     andrej arn <andrej-at-blueshoes-dot-org>
* @package    javascript_components
* @subpackage resizegrip
* @copyright  blueshoes.org
*/
function Bs_ResizeGrip(containerId) {

  // To support the old interface call with 2 arguments. (First argument used to be the object name). 
  var a = arguments;
  this._containerId = (a.length>1) ? a[1] :  a[0];  
	this._containerElm = document.getElementById(this._containerId);
	
	/**
  * Unique Object/Tag ID is initialized in the constuctor.
  * Bassed on this._id. Can be used in genarate JS-code as ID. Is set together 
  * from the  classname + this._id (see _constructor() code ).
  *
  * @access private
  * @var  string 
  */
  this._objectId;

	
	/**
	* max width of the window. not specified = no limit.
	* @access public
	* @var    int maxWidth
	*/
	this.maxWidth;
	
	this.minWidth = 50;
	
	/**
	* max height of the window. not specified = no limit.
	* @access public
	* @var    int maxWidth
	*/
	this.maxHeight;
	
	this.minHeight = 50;
	
	/**
	* the full path to the grip icon.
	* @access public
	* @var    string gripIcon
	*/
	this.gripIcon = '/_bsImages/windows/resizeWindow.gif';
	
	this._startX;
	this._startY;
	this._containerWidth;
	this._containerHeight;
	
	this.onBeforeResizeStart;
	this.onAfterResizeStart;
	this.onBeforeResize;
	this.onAfterResize;
	this.onBeforeResizeEnd;
	this.onAfterResizeEnd;
	
	/**
	* @access private
	*/
	this._drawStyle;
	
	/**
	* constructor.
	*/
	this.constructor = function() {
  	// Put this instance into the global object instance list
    this._id = Bs_Objects.length;
    Bs_Objects[this._id] = this; 
    this._objectId = "Bs_ResizeGrip_"+this._id;
	}
	
	
	/**
	* does the rendering job; adds the resize grip to the container.
	* @access public
	* @return void
	*/
	this.draw = function() {
		var drawStyle = 'inline';
		
		if ((this._containerElm.currentStyle.overflow == 'auto') || (this._containerElm.currentStyle.overflow == 'scroll')) {
			drawStyle    = 'float';
		}
		var margin = -1;
		
		var gripCode = '';
		gripCode += '<div style="position:absolute; width:20px; height:20px; bottom:0px; right:0px; margin:' + margin + 'px; cursor:se-resize;" onMouseDown="Bs_Objects['+this._id+'].resizeWindowStart(this);" ondragstart="return false;">';
		gripCode += '<img src="' + this.gripIcon + '">';
		gripCode += '</div>';
		if ((this._containerElm.currentStyle.position != 'absolute') && (this._containerElm.currentStyle.position != 'relative')) {
			this._containerElm.style.position = 'relative';
		}
		//alert(gripCode);

		if (drawStyle == 'inline') {
			try {
				this._containerElm.insertAdjacentHTML('beforeEnd', gripCode);
			} catch (e) {
				drawStyle = 'box';
			}
		}
		if (drawStyle == 'box') {
			//that element does not allow to insert beforeEnd. so we have to wrap it in a container.
			var codeBefore = '<div style="position:absolute; display:inline;">';
			var codeAfter = gripCode + '<br><div style="display:inline; height:20px;"></div></div>';
			this._containerElm.outerHTML = codeBefore + this._containerElm.outerHTML + codeAfter;
		} else if (drawStyle == 'float') {
			var margin = 4;
			var pos = getAbsolutePos(this._containerElm, true);
			var width  = 20;
			var height = 20;
			var left = (pos.x + this._containerElm.clientWidth)  -width; //offsetWidth
			var top  = (pos.y + this._containerElm.clientHeight) -height; //offsetHeight
			var zIndex = (this._containerElm.currentStyle.zIndex > 0) ? (this._containerElm.currentStyle.zIndex +1) : 1;
			var gripCode = '';
			gripCode += '<div id="' + this._objectId + '_float" style="position:absolute; z-index:' + zIndex + '; width:' + width + 'px; height:' + height + 'px; left:' + left + 'px; top:' + top + 'px; margin:' + margin + 'px; cursor:se-resize;" onMouseDown="Bs_Objects['+this._id+'].resizeWindowStart(this);" ondragstart="return false;">';
			gripCode += '<img src="' + this.gripIcon + '">';
			gripCode += '</div>';
			//alert(gripCode);
			this._containerElm.insertAdjacentHTML('afterEnd', gripCode);
		}
		
		this._drawStyle = drawStyle;
		
		//alert(document.body.innerHTML);
		//document.body.innerText = document.body.innerHTML;
	}
	
	/**
	* if the drawStyle is 'float' then we need to update the floating grip while resizing.
	* @access private
	* @return void
	*/
	this._updateFloatingGrip = function() {
		var pos = getAbsolutePos(this._containerElm, true);
		var width  = 20;
		var height = 20;
		var grip = document.getElementById(this._objectId + '_float');
		grip.style.left = (pos.x + this._containerElm.clientWidth)  -width;
		grip.style.top  = (pos.y + this._containerElm.clientHeight) -height;
	}
	
	/**
	* fires when resizing of the editor window/toolbar starts.
	* @access public (used internally, you don't need that.)
	* @param  element elm
	* @return void
	*/
	this.resizeWindowStart = function(elm) {
		if (!this._fireEvent(this.onBeforeResizeStart)) return;
		
		bs_rg_currentObj = this;
		
		this._startX = event.clientX;
		this._startY = event.clientY;
		this._containerWidth  = this._containerElm.offsetWidth;
		this._containerHeight = this._containerElm.offsetHeight;
		
    if (document.all) {
		  document.body.attachEvent('onmouseup',   bs_rg_resizeEnd);
		  document.body.attachEvent('onmousemove', bs_rg_resize);
		} else {
      document.addEventListener('mouseup', bs_rg_resizeEnd, false);
      document.addEventListener('mousemove', bs_rg_resize, false);
    }
		this._fireEvent(this.onAfterResizeStart);
	}
	
	/**
	* @access public (you don't need that)
	* @return void
	*/
	this.resize = function() {
		if (!this._fireEvent(this.onBeforeResize)) return;
		
		var diffWidth  = event.clientX - this._startX;
		var diffHeight = event.clientY - this._startY;
		var newWidth   = this._containerWidth  + diffWidth;
		var newHeight  = this._containerHeight + diffHeight;
		
		if ((typeof(this.minWidth)  != 'undefined') && (newWidth  < this.minWidth))  newWidth  = this.minWidth;
		if ((typeof(this.maxWidth)  != 'undefined') && (newWidth  > this.maxWidth))  newWidth  = this.maxWidth;
		if ((typeof(this.minHeight) != 'undefined') && (newHeight < this.minHeight)) newHeight = this.minHeight;
		if ((typeof(this.maxHeight) != 'undefined') && (newHeight > this.maxHeight)) newHeight = this.maxHeight;
		
		try {
		this._containerElm.style.width  = newWidth;
		this._containerElm.style.height = newHeight;
		this._containerElm.width        = newWidth;
		this._containerElm.height       = newHeight;
		if (this._drawStyle == 'float') this._updateFloatingGrip();
		} catch (e) {}
		
		this._fireEvent(this.onAfterResize);
	}
	
	/**
	* @access public (you don't need that)
	* @return void
	*/
	this.resizeEnd = function() {
		if (!this._fireEvent(this.onBeforeResizeEnd)) return;
		
		if (document.all) {
		  document.body.detachEvent('onmouseup',   bs_rg_resizeEnd);
		  document.body.detachEvent('onmousemove', bs_rg_resize);
		} else {
      document.removeEventListener('mouseup', bs_rg_resizeEnd, false);
      document.removeEventListener('mousemove', bs_rg_resize, false);
    }

		
		this._fireEvent(this.onAfterResizeEnd);
	}
	
	
	/**
	* fires the event specified.
	* @access private
	* @param  mixed ev (event, string of code or function)
	* @return bool (true to go on, false to stop)
	*/
	this._fireEvent = function(ev) {
		switch (typeof(ev)) {
			case 'function':
				var status = ev(this);
				if (status == false) return false;
				return true;
			case 'string':
				var status = eval(ev);
				if (status == false) return false;
				return true;
			default: //also case 'undefined':
				return true;
		}
	}
	
	
	this.constructor(); //call the constructor. needs to be at the end.
	
}



