text: define("dojox/gfx/Moveable", ["dojo/_base/lang","dojo/_base/declare","dojo/_base/array","dojo/_base/event","dojo/topic","dojo/touch",
  	"dojo/dom-class","dojo/_base/window","./Mover"],
    function(lang,declare,arr,event,topic,touch,domClass,win,Mover){
  
  	/*=====
  	var __MoveableCtorArgs = declare("dojox.gfx.__MoveableCtorArgs", null, {
  		// summary:
  		//		The arguments used for dojox/gfx/Moveable constructor.
  
  		// delay: Number
  		//		delay move by this number of pixels
  		delay:0,
  
  		// mover: Object
  		//		a constructor of custom Mover
  		mover:Mover
  	});
  	=====*/
  
  	return declare("dojox.gfx.Moveable", null, {
  		constructor: function(shape, params){
  			// summary:
  			//		an object, which makes a shape moveable
  			// shape: dojox/gfx.Shape
  			//		a shape object to be moved.
  			// params: __MoveableCtorArgs
  			//		an optional configuration object.
  
  			this.shape = shape;
  			this.delay = (params && params.delay > 0) ? params.delay : 0;
  			this.mover = (params && params.mover) ? params.mover : Mover;
  			this.events = [
  				this.shape.on(touch.press, lang.hitch(this, "onMouseDown"))
  				// cancel text selection and text dragging
  				//, dojo.connect(this.handle, "ondragstart",   dojo, "stopEvent")
  				//, dojo.connect(this.handle, "onselectstart", dojo, "stopEvent")
  			];
  		},
  
  		// methods
  		destroy: function(){
  			// summary:
  			//		stops watching for possible move, deletes all references, so the object can be garbage-collected
  			arr.forEach(this.events, function(handle){
  				handle.remove();
  			});
  			this.events = this.shape = null;
  		},
  
  		// mouse event processors
  		onMouseDown: function(e){
  			// summary:
  			//		event processor for onmousedown, creates a Mover for the shape
  			// e: Event
  			//		mouse event
  			if(this.delay){
  				this.events.push(
  					this.shape.on(touch.move, lang.hitch(this, "onMouseMove")),
  					this.shape.on(touch.release, lang.hitch(this, "onMouseUp")));
  				this._lastX = e.clientX;
  				this._lastY = e.clientY;
  			}else{
  				new this.mover(this.shape, e, this);
  			}
  			event.stop(e);
  		},
  		onMouseMove: function(e){
  			// summary:
  			//		event processor for onmousemove, used only for delayed drags
  			// e: Event
  			//		mouse event
  			var clientX = e.clientX,
  				clientY = e.clientY;
  
  			if(Math.abs(clientX - this._lastX) > this.delay || Math.abs(clientY - this._lastY) > this.delay){
  				this.onMouseUp(e);
  				new this.mover(this.shape, e, this);
  			}
  			event.stop(e);
  		},
  		onMouseUp: function(e){
  			// summary:
  			//		event processor for onmouseup, used only for delayed delayed drags
  			// e: Event
  			//		mouse event
  			this.events.pop().remove();
  		},
  
  		// local events
  		onMoveStart: function(/* dojox/gfx/Mover */ mover){
  			// summary:
  			//		called before every move operation
  			// mover:
  			//		A Mover instance that fired the event.
  			topic.publish("/gfx/move/start", mover);
  			domClass.add(win.body(), "dojoMove");
  		},
  		onMoveStop: function(/* dojox/gfx/Mover */ mover){
  			// summary:
  			//		called after every move operation
  			// mover:
  			//		A Mover instance that fired the event.
  			topic.publish("/gfx/move/stop", mover);
  			domClass.remove(win.body(), "dojoMove");
  		},
  		onFirstMove: function(/* dojox/gfx/Mover */ mover){
  			// summary:
  			//		called during the very first move notification,
  			//		can be used to initialize coordinates, can be overwritten.
  			// mover:
  			//		A Mover instance that fired the event.
  
  			// default implementation does nothing
  		},
  		onMove: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){
  			// summary:
  			//		called during every move notification,
  			//		should actually move the node, can be overwritten.
  			// mover:
  			//		A Mover instance that fired the event.
  			// shift:
  			//		An object as {dx,dy} that represents the shift.
  			this.onMoving(mover, shift);
  			this.shape.applyLeftTransform(shift);
  			this.onMoved(mover, shift);
  		},
  		onMoving: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){
  			// summary:
  			//		called before every incremental move,
  			//		can be overwritten.
  			// mover:
  			//		A Mover instance that fired the event.
  			// shift:
  			//		An object as {dx,dy} that represents the shift.
  
  			// default implementation does nothing
  		},
  		onMoved: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){
  			// summary:
  			//		called after every incremental move,
  			//		can be overwritten.
  			// mover:
  			//		A Mover instance that fired the event.
  			// shift:
  			//		An object as {dx,dy} that represents the shift.
  
  			// default implementation does nothing
  		}
  	});
  });
  