﻿// JScript File

function _QuanticksDragGroup(factory, element) {
	this.factory = factory
	this.element = element
	this._handle = null
	this._thresholdDistance = 0
	this._transforms = new Array()
	// TODO: refactor into a helper object, move into events.js
	this._listeners = new Array()
	this._listeners['draginit'] = new Array()
	this._listeners['dragstart'] = new Array()
	this._listeners['dragmove'] = new Array()
	this._listeners['dragend'] = new Array()
	this._listeners['click'] = new Array()
}

_QuanticksDragGroup.prototype = {
	setHandle : function(handle) {
		var events = Quanticks.events()

		handle.QuanticksDragGroup = this
		events.register(handle, 'mousedown', this._dragInit)
		handle.onmousedown = function() { return false }

		if (this.element != handle)
			events.unregister(this.element, 'mousedown', this._dragInit)
	},

	register : function(type, func) {
		this._listeners[type].push(func)
	},

	addTransform : function(transformFunc) {
		this._transforms.push(transformFunc)
	},

	verticalOnly : function() {
		this.addTransform(this.factory.constraints().vertical())
	},

	horizontalOnly : function() {
		this.addTransform(this.factory.constraints().horizontal())
	},

	setThreshold : function(thresholdDistance) {
		this._thresholdDistance = thresholdDistance
	},

	transparentDrag : function(opacity) {
		var opacity = typeof(opacity) != "undefined" ? opacity : 0.25;
		var originalOpacity = Quanticks.css().readStyle(this.element, "opacity")

		this.register('dragstart', function(dragEvent) {
			var element = dragEvent.group.element
			element.style.opacity = opacity
			element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')'
		})
		this.register('dragend', function(dragEvent) {
			var element = dragEvent.group.element
			element.style.opacity = originalOpacity
			element.style.filter = 'alpha(opacity=100)'
		})
	},

	onTopWhileDragging : function(zIndex) {

		var zIndex = (typeof(zIndex) != "undefined") ? zIndex : 100000;
		
		var originalZIndex = Quanticks.css().readStyle(this.element, "z-index")

		this.register('dragstart', function(dragEvent) {
			dragEvent.group.element.style.zIndex = zIndex
		})
//		this.register('dragend', function(dragEvent) {
//			dragEvent.group.element.style.zIndex = originalZIndex
//		})

	},

	_dragInit : function(event) {
	    event = Quanticks.events().fix(event)
		var srcClass = event.srcElement.className
	    if (srcClass == "jack") return;
	    if (srcClass == "bind") return;
	    var rightclick = false;
	    var group = document.QuanticksDragGroup = this.QuanticksDragGroup;

	    if (event.which) rightclick = (event.which == 3);
	    else if (event.button) rightclick = (event.button == 2);   	    
	    if (rightclick)
	    {
            if (group.element.className!='toolboxitem' && group.element.className!='workflow' ){
                showcontextmenu(GetOffsetLeft(event.clientX)-8,GetOffsetTop(event.clientY)-8,"Delete",DeleteSelectedActivity);
                event.cancelBubble = true;	
            }
	    }
	    else
	    {
            
        if (group.element.className!='toolboxitem'){
          Quanticks._activityFactory._Select(group.element)
        }

		    var dragEvent = group.factory._createEvent('draginit', event, group)        
		    group._isThresholdExceeded = false
		    group._initialMouseOffset = dragEvent.mouseOffset
		    group._grabOffset = dragEvent.mouseOffset.minus(dragEvent.topLeftOffset)
		    Quanticks.events().register(document, 'mousemove', group._drag)
		    document.onmousemove = function() { return false }
		    Quanticks.events().register(document, 'mouseup', group._dragEnd)

		    group._notifyListeners(dragEvent)
		}
	},

	_drag : function(event) {
		event = Quanticks.events().fix(event)
		var coordinates = Quanticks.coordinates()
		var group = this.QuanticksDragGroup
		if (!group) return
		var dragEvent = group.factory._createEvent('dragmove', event, group)

		var newTopLeftOffset = dragEvent.mouseOffset.minus(group._grabOffset)

		// TODO: replace with DragThreshold object
		if (!group._isThresholdExceeded) {
			var distance = 
					dragEvent.mouseOffset.distance(group._initialMouseOffset)
			if (distance < group._thresholdDistance) return
			group._isThresholdExceeded = true
			group._notifyListeners(
					group.factory._createEvent('dragstart', event, group))
		}

		for (i in group._transforms) {
			var transform = group._transforms[i]
			newTopLeftOffset = transform(newTopLeftOffset, dragEvent)
		}

		var dragDelta = newTopLeftOffset.minus(dragEvent.topLeftOffset)
		var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta)
		
		newTopLeftPosition.reposition(group.element)
		dragEvent.transformedMouseOffset = newTopLeftOffset.plus(group._grabOffset)

		group._notifyListeners(dragEvent)

		var errorDelta = newTopLeftOffset.minus(coordinates.topLeftOffset(group.element))
		if (errorDelta.x != 0 || errorDelta.y != 0) {
			coordinates.topLeftPosition(group.element).plus(errorDelta).reposition(group.element)
		}
	},

	_dragEnd : function(event) {
		event = Quanticks.events().fix(event)
		var group = this.QuanticksDragGroup
		if (group)
		{
		    var dragEvent = group.factory._createEvent('dragend', event, group)

		    group._notifyListeners(dragEvent)
		    this.QuanticksDragGroup = null
		    Quanticks.events().unregister(document, 'mousemove', group._drag)
		    document.onmousemove = null
		    Quanticks.events().unregister(document, 'mouseup', group._dragEnd)
		}
	},

	_notifyListeners : function(dragEvent) {
		var listeners = this._listeners[dragEvent.type]
		for (i in listeners) {
			listeners[i](dragEvent)
		}
	}
}

