/*!
 * Ext JS Library 3.1.0
 * Copyright(c) 2006-2009 Ext JS, LLC
 * licensing@extjs.com
 * http://www.extjs.com/license
 */
Ext.ux.Portal = Ext.extend(Ext.Panel, {
	// layout: 'column',
	cls: 'x-portal',
	// defaultType: 'portalcolumn',
	// defaultType: 'portlet',
	
	initComponent: function(){
		Ext.ux.Portal.superclass.initComponent.call(this);
		this.addEvents({
			validatedrop: true,
			beforedragover: true,
			dragover: true,
			beforedrop: true,
			drop: true
		});
	},
	
	initEvents: function(){
		Ext.ux.Portal.superclass.initEvents.call(this);
		this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);
	},
	
	beforeDestroy: function(){
		if (this.dd) {
			this.dd.unreg();
		}
		Ext.ux.Portal.superclass.beforeDestroy.call(this);
	}
});

Ext.reg('portal', Ext.ux.Portal);


Ext.ux.Portal.DropZone = function(portal, cfg){
	this.portal = portal;
	Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom, cfg);
};

Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, {

	createEvent: function(dd, e, data, pos){
		return {
			portal: this.portal,
			panel: data.panel,
			position: pos,
			data: data,
			source: dd,
			rawEvent: e,
			status: this.dropAllowed
		};
	},
	
	notifyOver: function(dd, e, data){
		var xy = e.getXY(), portal = this.portal, px = dd.proxy;
		
		// handle case scroll where scrollbars appear during drag
		var cw = portal.body.dom.clientWidth;
		if (!this.lastCW) {
			this.lastCW = cw;
		}
		else if (this.lastCW != cw) {
			this.lastCW = cw;
			portal.doLayout();
		}
		
		// find insert position
		var p, match = false, pos = 0, items = portal.items.items, overSelf = false, lastX = 0, lastY, lastItem = false;
		
		for (var len = items.length; pos < len; pos++) {
			p = items[pos];
			var w = p.el.getWidth();
			var h = p.el.getHeight();
			var x = p.el.getX();
			var y = p.el.getY();
			var xEnd = x + w;
			var yEnd = y + h;
			
			if (h === 0) {
				// presun za puvodni pozici
				overSelf = true;
			}
			
			else if (yEnd > xy[1]) {
				// jsem uvnitr prvku
				if (x < xy[0] && xEnd > xy[0]) {
					// pohyb na dalsi prvek 
					if (this.lastPos < pos || (this.lastPos == pos && !overSelf)) {
						pos++;
					}
					match = true;
					break;
				}
				// jsem pred prvkem ale jiz za predchozim
				else if (lastX <= xy[0] && x >= xy[0]) {
					match = true;
					break;
				}
				else if (y > lastY) {
					match = true;
					break;
				}
				lastX = xEnd;
				lastY = y;
			}
		}
		
		if (pos < len) {
			p = items[pos];
		} else {
			p = items[len - 1];
			lastItem = true;
		}
		pos = (match ? pos : items.length) + (overSelf ? -1 : 0);
		
		var overEvent = this.createEvent(dd, e, data, pos);
		
		if (portal.fireEvent('validatedrop', overEvent) !== false &&
		portal.fireEvent('beforedragover', overEvent) !== false) {
		
			px.moveProxy(p.el.dom.parentNode, !lastItem ? p.el.dom : null);
			
			this.lastPos = overSelf || match ? pos : false;
			
			portal.fireEvent('dragover', overEvent);
			
			return overEvent.status;
		}
		else {
			return overEvent.status;
		}
		
	},
	
	notifyOut: function(){
	},
	
	notifyDrop: function(dd, e, data){
		var pos = this.lastPos, portal = this.portal;
		
		var dropEvent = this.createEvent(dd, e, data, pos !== false ? pos : items.getCount());
		
		if (this.portal.fireEvent('validatedrop', dropEvent) !== false &&
		this.portal.fireEvent('beforedrop', dropEvent) !== false) {
		
			dd.proxy.getProxy().remove();
			dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom);
			
			if (pos !== false) {
				portal.insert(pos, dd.panel);
			}
			else {
				portal.add(dd.panel);
			}
			
			portal.doLayout();
			portal.fireEvent('drop', dropEvent);
		}
		delete this.lastPos;
	}
});

