
registerType('Core.UI', (function () { function DragItem() {} var __super = setSupertypeFromDomain(DragItem, 'BasicObject', 'Core');


	Object.defineProperty(DragItem.prototype, "isInCopyMode", {
	synthesized: true, 
		set: function (v) {if (!Object.hasOwnProperty(this, "_isInCopyMode")) Object.defineProperty(this, "_isInCopyMode", { writable: true, configurable: true });
			this._isInCopyMode = true;
			this.cursorForDropEffect['move'] = v ? 'copy' : 'default';
		}, get:function () { return this._isInCopyMode; }});
	

	Object.defineProperty(DragItem.prototype, "cursor", {
	synthesized: true, 
		set: function (v) {if (!Object.hasOwnProperty(this, "_cursor")) Object.defineProperty(this, "_cursor", { writable: true, configurable: true });
			for (var key in this.cursorForDropEffect) {
				this.cursorForDropEffect[key] = v;
			}
		}, get:function () { return this._cursor; }});
	

	Object.defineProperty(DragItem.prototype, "updatesCursor", {
	synthesized: true, get:function () { return this._updatesCursor; }, set:function (v) {if (!Object.hasOwnProperty(this, "_updatesCursor")) Object.defineProperty(this, "_updatesCursor", { writable: true, configurable: true }); this._updatesCursor = v; }});
	


DragItem.prototype.updateCursorForDropEffect = function DragItem__updateCursorForDropEffect() {
		var effect = dropEffect;
		if (this.updatesCursor === false) return;
		document.body.style.cursor = this.cursorForDropEffect[effect];};
	
	
DragItem.prototype.restoreCursor = function DragItem__restoreCursor() {
		if (this.updatesCursor === false) return;
		document.body.style.cursor = 'default';};
	

// role BasicObject (Core) 

DragItem.prototype.initFromData = function DragItem_initFromData(data) {

			this.cursorForDropEffect = {
				'copy': 'copy',
				'none': 'no-drop',
				'move': 'default',
				'alias': 'alias'
			};
		
			this.sourceView = data.sourceView;
			this.dragContext = data.dragContext || this.sourceView.context;
			
			var sourceViewData = this.sourceView.encode();
			delete sourceViewData.bindings;
			delete sourceViewData.observations;
			delete sourceViewData.position;
			if (sourceViewData.frame)
			delete sourceViewData.frame.origin;
	
			this.sourceViewClone = (this.dragContext || this.context).decodeObjectTree(sourceViewData);
			this.sourceViewClone.style({
				marginTop: '0',
				pointerEvents: 'none'
			});
			
			if (!data.containerStyle) {
				data.containerStyle = {
					opacity: .6
				};
			}
			data.containerStyle.pointerEvents = 'none';
			data.containerStyle.zIndex = 10000;
			
			this.startPosition = data.position;

			this.dragView = createComponentFromDomain("View", "Core.UI", this.context, {
				style: data.containerStyle,
				size: this.sourceViewClone.size,
				hidden: true})
			;
			
			this.dragView.addSubview(this.sourceViewClone);
			document.body.appendChild(this.dragView.DOMNode);
			
			this.onBegin = data.onBegin;
			this.onFinish = data.onFinish;
			this.onCancel = data.onCancel;
			this.onWillCancel = data.onWillCancel;
			this.dataTransferData = data.dataTransferData || { };
			this.minimumMovement = data.minimumMovement;
			
			return this;
			};
		
		
DragItem.prototype.destroy = function DragItem_destroy() {
			this.sourceViewClone.removeFromSuperview();
			delete this.sourceViewClone;
			document.body.removeChild(this.dragView.DOMNode);
			this.dragView.destroy();
			delete this.dragView;
			this.resetClassVariables();
			this.clearWindowEvents();
			this.restoreCursor();};
		
	
	
	
	var eStartX, eStartY, viewStartX, viewStartY, isVisible,
		lastOverElement = null,
		dropHandler = null,
		dropEffect = null,
		event;
	
// role DragItem 

DragItem.prototype.dragWithEvent = function DragItem_dragWithEvent(e) {
		
			var isDragEvent = e.type === 'dragstart';

			if (isDragEvent && e.preventDefault)
				e.preventDefault();
			
			this.modifyDOM();
			
			if (this.startPosition) {
				this.dragView.position = this.startPosition;
			}
			else if (this.sourceView.superview) {
				this.dragView.position = {
					left: e.x - this.sourceView.getRelativeX(e.x),
					top: e.y - this.sourceView.getRelativeY(e.y)
				};
			}
			else {
				this.dragView.position = {
					left: e.x - this.sourceView.size.width/2,
					top: e.y - this.sourceView.size.height/2
				};
			}
	
			viewStartX = this.dragView.position.left;
			viewStartY = this.dragView.position.top;
			eStartX = e.x;
			eStartY = e.y;
			pseudoEvent = {
				x: e.x,
				y: e.y,
				dragItem: this,
				preventDefault: function () {},
			};
			minMovement = this.minimumMovement || 5;

			pseudoEvent.dataTransfer = {
					getData: function (key) {
						return this.dataTransferData[key];
					}.bind(this),
					setData: function (key, value) {
						this.dataTransferData[key] = value;
						return true;
					}.bind(this),
					files: []
				};
			
			Object.defineProperty(pseudoEvent.dataTransfer, 'types', {
				get: function () {
					return Object.keys(this.dataTransferData);
				}.bind(this)
			});
			
			window.onmousemove = function (e) {
			
				this.updatePseudoEvent(e);
	
				if (isVisible !== true) {
					if (Math.abs(eStartX-e.x) >= minMovement ||
						Math.abs(eStartY-e.y) >= minMovement) {
						this.dragView.hidden = false;
						pseudoEvent.x = eStartX; pseudoEvent.y = eStartY;
						if (this.onBegin) this.onBegin(pseudoEvent);
						isVisible = true;
					}
				}
				
				this.dragView.position.left = viewStartX + e.x-eStartX;
				this.dragView.position.top = viewStartY + e.y-eStartY;

				if (!isVisible) {
					
					return;
				}
				
				var overElement = document.elementFromPoint(e.x, e.y);
				if (overElement !== lastOverElement) {
	
					if (dropHandler !== null) {
						if (dropHandler.didLeaveWithEvent !== undefined)
							dropHandler.didLeaveWithEvent.call(dropHandler, pseudoEvent);
					}
					
					dropHandler = overElement !== null ? overElement._dropHandler || null : null;

					if (dropHandler !== null) {
						if (dropHandler.didEnterWithEvent !== undefined)
						dropHandler.didEnterWithEvent.call(dropHandler, pseudoEvent);
					}
	
					lastOverElement = overElement;
				}
				
				this.updateDropEffect();
				
			}.bind(this);
			
			window.onkeydown = function (e) {
				if (this.context.isCancelEvent(e)) {
					this.cancel(e);
					e.preventDefault();
					return;
				}
				this.updatePseudoEvent(e);
				this.updateDropEffect();
			}.bind(this);

			window.onkeyup = function (e) {
				this.updatePseudoEvent(e);
				this.updateDropEffect();
			}.bind(this);
			
			window.onmouseup = function (e) {
			
				this.restoreDOM();
				this.restoreCursor();

				if (isDragEvent) {
					e.stopPropagation();
					e.returnValue = false;
				}
				var result;
				
				if (!isVisible) {
					this.destroy();
					return;
				}
				
				if ((dropEffect === 'move' || dropEffect === 'alias' || dropEffect === 'copy') && dropHandler !== null) {
					try {
						result = dropHandler.didDropWithEvent.call(dropHandler, pseudoEvent, dropEffect);

						if (result === false) {
							this.didSucceed = false;
							this.cancelDragWithEvent(e);
							delete this.onFinish;
							return;
						}
						else if (this.onFinish) {
							this.didSucceed = true;
							this.onFinish(pseudoEvent);
							delete this.onFinish;
						}
						
						this.destroy();
					}
					catch (err) {
						setTimeout(function () {
							throw err;
						}, 100);
					}
				}

				if (dropEffect === 'none') {
					this.cancelDragWithEvent(e);
				}

				isVisible = false;
				
			}.bind(this);
			
			return pseudoEvent;
			};
		
		
DragItem.prototype.cancel = function DragItem_cancel(e) {
			this.restoreDOM();
			
			this.cancelDragWithEvent(e);};
		
		
DragItem.prototype.cancelDragWithEvent = function DragItem__cancelDragWithEvent(e) {

			this.restoreCursor();
		
			e.didCancel = true;
	
			if (dropHandler !== null) {
				if (dropHandler.didLeaveWithEvent !== undefined)
					dropHandler.didLeaveWithEvent(lastOverElement, e);
			}
	
			var duration = this.getAnimationDuration();
		
			this.dragView.style({
				webkitTransitionProperty: '-webkit-transform opacity',
				webkitTransitionDuration: (duration/1000)+'s',
				webkitTransitionTimingFunction: 'ease-out',
				webkitTransform: this.getInverseTransformation() + ' ' +this.dragView.DOMNode.style.webkitTransform
			});
			
			setTimeout(function () {
				if (this.onCancel) {
					if (this.onCancel(e) === false)
						return;
				}
				this.destroy();
			}.bind(this), duration + 80);
			
			this.clearWindowEvents();
			if (this.onFinish) this.onFinish(e);
		};
		
		
DragItem.prototype.setScaleAnimated = function DragItem_setScaleAnimated(scale, animated) {
			if (!animated) {
				this.sourceViewClone.style({
					webkitTransform: 'scale('+scale+')'
				});
				return;
			}
			
			setTimeout(function () {
				if (this._contentScale !== scale) return;
				if (this.sourceViewClone)
				this.sourceViewClone.style({
					webkitTransform: 'scale('+scale+')',
					webkitTransition: '-webkit-transform 0.4s ease-in-out'
				});
			}.bind(this), 100);
			this._contentScale = scale;};
		
		
		Object.defineProperty(DragItem.prototype, "contentScale", {
		synthesized: true, 
			set: function (v) {if (!Object.hasOwnProperty(this, "_contentScale")) Object.defineProperty(this, "_contentScale", { writable: true, configurable: true });
				this.setScaleAnimated(v, false);
			}, get:function () { return this._contentScale; }});
		
		
		Object.defineProperty(DragItem.prototype, "size", {
			get: function () { return this.sourceViewClone.size }});
		

		Object.defineProperty(DragItem.prototype, "position", {
			get: function () { return this.dragView.position }, 
			set: function (v) { this.dragView.position = v; }});
		
	
	
	
DragItem.prototype.updateDropEffect = function DragItem__updateDropEffect() {

		if (dropHandler !== null) {
			dropEffect =
				dropHandler.dropEffectForEvent.call(dropHandler, pseudoEvent);
		}
		else dropEffect = 'none';
		
		this.updateCursorForDropEffect();
	};
	
	
DragItem.prototype.updatePseudoEvent = function DragItem__updatePseudoEvent(e) {
		['x', 'y', 'altKey', 'shiftKey', 'metaKey'].every(function (key) {
			if (e[key] !== undefined)
				pseudoEvent[key] = e[key];				return true; }, this);
		};
	


DragItem.prototype.resetClassVariables = function DragItem__resetClassVariables() {
		isVisible = null;
		dropHandler = null;
		dropEffect = null;
		lastOverElement = null;};
	
	
DragItem.prototype.clearWindowEvents = function DragItem__clearWindowEvents() {
		window.onmousemove = null;
		window.onmouseup = null;
		window.onkeydown = null;
		window.onkeyup = null;};
	
	
DragItem.prototype.getInverseTransformation = function DragItem__getInverseTransformation() {
	
		var x = viewStartX-this.dragView.position.left,
			y = viewStartY-this.dragView.position.top;
	
		return 'translate('+x+'px, '+y+'px)';
	};
	
	
DragItem.prototype.getAnimationDuration = function DragItem__getAnimationDuration() {
	
		var distance = Math.max(
			Math.abs(viewStartX-this.dragView.position.left),
			Math.abs(viewStartY-this.dragView.position.top)
		);
		
		return (distance/120 + 19)*16;
	};
	

	
	
	
	var disablePointerEventsRecursive = function (childNodes, recursive) {
		if (!childNodes) return;
		for (var j = 0, cj = childNodes.length; j < cj; j++) {

			if (!childNodes[j].style) continue;
			
			
			if (childNodes[j]._dropHandler) continue; 
			
			childNodes[j]._pointerEvents = childNodes[j].style.pointerEvents;
			childNodes[j].style.pointerEvents = 'none';
			if (recursive) disablePointerEventsRecursive(childNodes[j].childNodes, true);
		}
	},
		enablePointerEventsRecursive = function (childNodes, recursive) {
		if (!childNodes) return;
		for (var j = 0, cj = childNodes.length; j < cj; j++) {
			if (childNodes[j]._pointerEvents === undefined) continue;
			childNodes[j].style.pointerEvents = childNodes[j]._pointerEvents;
			delete childNodes[j]._pointerEvents;
			if (recursive) enablePointerEventsRecursive(childNodes[j].childNodes, true);
		}
	};
	
DragItem.prototype.modifyDOM = function DragItem__modifyDOM() {

		var allNodes = document.getElementsByTagName('*');

		for (var i = 0, c = allNodes.length; i < c; i++) {
			if (allNodes[i]._dropHandler) {
				disablePointerEventsRecursive(allNodes[i].childNodes);
			}
		}
	};
	
	
DragItem.prototype.restoreDOM = function DragItem__restoreDOM() {

		var allNodes = document.getElementsByTagName('*');

		for (var i = 0, c = allNodes.length; i < c; i++) {
			if (allNodes[i]._dropHandler) {
				enablePointerEventsRecursive(allNodes[i].childNodes);
			}
		}
};
	

DragItem.prototype.expectedTypeForProperty = function DragItem_expectedTypeForProperty(key) {
	if (key === "isInCopyMode") return "";
	if (key === "cursor") return "";
	if (key === "updatesCursor") return "";
	if (key === "contentScale") return "";
	if (key === "size") return "";
	if (key === "position") return "";
	if (__super) return __super.prototype.expectedTypeForProperty(key);
};

return DragItem; }()));