	// Form Builder - FormAssembly.com
	// Copyright (c) 2009 Veer West LLC (veerwest.com)
	// All Rights Reserved - do not reuse without permission.
	
				
	// Tutorial namespace
	var Tutorial = function() {
		
		this.title 			= arguments[0]?arguments[0]:'',
		this.x 				= arguments[1]?arguments[1]:null,
		this.y 				= arguments[2]?arguments[2]:null,
		this.steps 			= arguments[3]?arguments[3]:[],
		this._current 		= 0;	
		this._domElement 	= null;
		this._pause			= false;
	}  

	Tutorial.Step = function() {
		
		this.text 	= arguments[0]?arguments[0]:'',
		this.tips 	= arguments[1]?arguments[1]:[],		
		this.next 	= arguments[2]?arguments[2]:6; // condition. If numeric assumed timeout. Else function that returns true/false. Evaluated every second.	
		this.action = arguments[3]?arguments[3]:null;
		
		var _self = this;
		this._delay = function() { 
			if(_self._timer) clearTimeout(_self._timer); 
			_self._timer = setTimeout(function(){ if(!_self._Tutorial._pause) { _self.moveNext() } }, 6000) 
		};
		this._waitFor 		= null;
		this._button   		= null;		
		this._moveWindow	= null;
		this._Tutorial 		= null;	
			
	}
	
	Tutorial.Step.Tip = function() {
		this.text 		= arguments[0]?arguments[0]:'';
		this.x 			= arguments[1]?arguments[1]:0;
	   	this.y 			= arguments[2]?arguments[2]:0;	  
	   	this.relativeTo = arguments[3]?arguments[3]:null;
	   	this.layout 	= arguments[4]?arguments[4]:null;
	   	this._domElement = null;
	}
	
	
	
	Tutorial.prototype.addStep = function() {
		var s = new Tutorial.Step(	arguments[0]?arguments[0]:null,
							  		arguments[1]?arguments[1]:null,
							  		arguments[2]?arguments[2]:null);
		s._Tutorial = this;						  		
		this.steps.push(s);
		return s;												 
	}
	
	Tutorial.Step.prototype.withTip = function() {
		var t = new Tutorial.Step.Tip(	 arguments[0]?arguments[0]:null,
									     arguments[1]?arguments[1]:null,
										 arguments[2]?arguments[2]:null,
										 arguments[3]?arguments[3]:null,
										 arguments[4]?arguments[4]:null);
		this.tips.push(t);
		return this;	
	}
	
	Tutorial.Step.prototype.withAction = function(f) {
		this.action = f;
		return this;	
	}
	
	Tutorial.Step.prototype.withButton = function() {
		this._button = arguments[0]?arguments[0]:'Ok';
		return this;	
	}
		
	Tutorial.Step.prototype.wait = function() {
		var _self = this;
		var delay = arguments[0]?arguments[0]*1000:6000;
		this._delay = function() { 
			if(_self._timer) clearTimeout(_self._timer); 
			_self._timer = setTimeout(function(){ if(!_self._Tutorial._pause) { _self.moveNext() } }, delay) 
		} ;
		return this;	
	}
	
	Tutorial.Step.prototype.waitFor = function(f) {
		var _self 		= this;
		this._userFunc	= f;
		this._userParam = arguments.length>1 ? arguments[1]: null;
		this._waitFor 	= function() { _self._userFunc(_self._userParam)?_self.moveNext():_self._delay() };		
		this._delay 	= function() {
			if(_self._timer) clearTimeout(_self._timer); 
			_self._timer = setTimeout(function(){ _self._waitFor() }, 1000) };
		return this;
	}
	
	
	Tutorial.Step.prototype.moveWindow = function(x,y) {
		this._moveWindow = {x:x,y:y};
		return this;
	}
	
	Tutorial.Step.prototype.skipIf = function(f) {
		var _self 		= this;
		this._skipFunc	= f;
		this._skipParam = arguments.length>1 ? arguments[1]: null;
		return this;
	}
	
	
	
	
	Tutorial.prototype.start = function() {
		
		if(!this._domElement) {
			this._domElement = this.createDomElement();
		}
		
		this._current = 0;
		if(this.steps[this._current]) {
			this.steps[this._current].show();
		} else {
			this.end();
		}
	}
	
	Tutorial.prototype.moveNext = function(delay) {	
		
		if(this.steps[this._current]) {
			this.steps[this._current].end();
		}
			
		this._pause = false;
		this._current++;
		if(this.steps[this._current]) {
			if(delay) {
				var _self = this;
				setTimeout(function(){ _self.steps[_self._current].show(); }, delay*1000);
			} else {
				this.steps[this._current].show();
			}
		} else {
			this.end();
		}
	}

	Tutorial.prototype.moveBack = function() {		
		
		if(this.steps[this._current]) {
			this.steps[this._current].end();
		}
		this._pause = true;
		if(this._current>0) {
			this._current--;
		}
		if(this.steps[this._current]) {
			this.steps[this._current].show();
		} 
	}	
	Tutorial.prototype.end = function() {
		if(this.steps[this._current]) {
			this.steps[this._current].end();
		}
		if(this._domElement){ 
			this._domElement.parentNode.removeChild(this._domElement);
			this._domElement = null;
		}
	}
	
	Tutorial.prototype.moveWindow = function(x,y, callback) {
		if(this._domElement) {
			if(this._moveInterval) {
				clearInterval(this._moveInterval);				
			}	
			var pos = Tutorial.aux.getScreenCoordinates(this._domElement);
			this._moveStep = 0;						
			var self = this;			
			this._moveInterval = setInterval(function() {
				var maxSteps = 15;
				
				self._domElement.style.opacity = (maxSteps-self._moveStep)/maxSteps;
				
				/*@cc_on
				// IE only			
				var perc = Math.round((maxSteps-self._moveStep)/maxSteps*100);
				document.getElementById('tutInner').style.MsFilter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity='+perc+')';
				document.getElementById('tutInner').style.filter = 'alpha(opacity=' + perc + ')';
				document.getElementById('tutBackground').style.MsFilter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity='+perc/10+')';
				document.getElementById('tutBackground').style.filter = 'alpha(opacity=' + perc/10 + ')';
				@*/
					
				/* scroll (disabled) */
				/* 
				var newx = self.windowMoveEaseInOut(pos.x,x,maxSteps,self._moveStep);
				var newy = self.windowMoveEaseInOut(pos.y,y,maxSteps,self._moveStep);
				self._domElement.style.left = newx+'px';  
				self._domElement.style.top  = newy+'px'; 				
				*/
				self._moveStep++;
				if (self._moveStep > maxSteps) {
					clearInterval(self._moveInterval);	
					self._moveStep = 0;
						
					self._domElement.style.left = x+'px';  
					self._domElement.style.top  = y+'px'; 		
					
					callback();
					
					self._moveInterval = setInterval(function() {
						
						self._domElement.style.opacity = (self._moveStep)/maxSteps;
						var perc = Math.round((self._moveStep)/maxSteps*100);
					
						/*@cc_on
						// IE only			
						var perc = Math.round((self._moveStep)/maxSteps*100);
						document.getElementById('tutInner').style.MsFilter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity='+perc+')';
						document.getElementById('tutInner').style.filter = 'alpha(opacity=' + perc + ')';
						document.getElementById('tutBackground').style.MsFilter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity='+perc/10+')';
						document.getElementById('tutBackground').style.filter = 'alpha(opacity=' + perc/10 + ')';
						@*/
						
						
						self._moveStep++;
						if (self._moveStep > maxSteps) {
							clearInterval(self._moveInterval);	
							
						}
					},20);
				}
			},20);
			
			
		}
	}
	
	Tutorial.prototype.windowMoveEaseInOut = function(minValue,maxValue,totalSteps,actualStep) { 
		var powr = 1.5;
	    var delta = maxValue - minValue; 
    	var step = minValue+(Math.pow(((1 / totalSteps) * actualStep), powr) * delta); 
    	return Math.ceil(step) 
    } 
	
	
	Tutorial.prototype.createDomElement = function() {
		
		var d = document.body.appendChild(document.createElement('div'));
		var b = d.appendChild(this.createBackgroundLayer());
		var i = d.appendChild(this.createInnerLayer());
		var t = i.appendChild(this.createTitleBar());
		var c = i.appendChild(this.createContentPanel());
		var n = i.appendChild(this.createNavBar());
			
		d.className = 'tutorialWindow';
		d.id = 'tutorialWindow'; 
		if (this.x) { d.style.left = this.x+'px';  }
		if (this.y) { d.style.top = this.y+'px'; }
		return d;
	}
	
	Tutorial.prototype.repaintWindow = function() {
		// resize background
		var bg = document.getElementById('tutBackground');
		var inner = document.getElementById('tutInner');
		bg.style.width  = inner.offsetWidth  + 'px';
		bg.style.height = inner.offsetHeight + 'px';
	}
	
	Tutorial.prototype.createBackgroundLayer = function() {
		var d = document.createElement('div');
		d.className = 'background';
		d.id = 'tutBackground';
		d.innerHTML = '&nbsp;';
		return d;
	}
	
	Tutorial.prototype.createInnerLayer = function() {
		var d = document.createElement('div');
		d.className = 'inner';
		d.id = 'tutInner';
		return d;
	}
	
	Tutorial.prototype.createTitleBar = function() {
		var d = document.createElement('div');
		d.className = 'title';
		d.innerHTML = this.title;
		var x = d.insertBefore(document.createElement('a'),d.firstChild);
		x.className = 'close';
		var _self = this;
		x.onclick = function() { _self.end(); };
		d.onmousedown = function(e) { 
			Tutorial.aux.mouseDownHandler(d,e?e:window.event, true); 
		};
		return d;
	}
	
	Tutorial.prototype.createNavBar = function() {
		var d = document.createElement('div');
		d.className = 'nav';
		
		var back = d.appendChild(document.createElement('a'));
		var next = d.appendChild(document.createElement('a'));
		back.innerHTML = '&lt;';
		back.className = 'back';
		next.innerHTML = '&gt;';
		next.className = 'next';
		
		var _self = this;
		back.onclick = function() { _self.moveBack(); };
		next.onclick = function() { _self.moveNext(); };
		return d;
	}
	
	Tutorial.prototype.createContentPanel = function() {
		var d = document.createElement('div');
		d.className = 'content';
		d.id = 'tutContent'; 
		return d;
	}

	Tutorial.Step.prototype.end = function() {
		if(this._timer) clearTimeout(this._timer); 
		
		for(var i=0;i<this.tips.length;i++) {
			this.tips[i].close();
		}
	}
	
	Tutorial.Step.prototype.moveNext = function(delay) {
		this._Tutorial.moveNext(delay);
		return this;
	}
		
	Tutorial.Step.prototype.show = function() {
		if(this._moveWindow) {
			var self = this;
			this._Tutorial.moveWindow(this._moveWindow.x, this._moveWindow.y, function() { self._show() } );
		}
		else {
			this._show();
		}
	}
	
	Tutorial.Step.prototype._show = function() {
		
		var d = document.getElementById('tutContent');
		d.innerHTML = this.text;
		
		if(this._skipFunc && this._skipFunc(this._skipParam)) {
			this.moveNext();
			return;
		}
		if(this.action) this.action();
		for(var i=0;i<this.tips.length;i++) {
			this.tips[i].show();
		}
		if(this._button) {
			d.appendChild(this.createButton());
		} else {
			if(this._waitFor) {
				d.appendChild(this.createWaitMessage('waiting for your action'));
			} else {
				d.appendChild(this.createWaitMessage('will move to next step in a few seconds'));
			}
			this._delay();
		}
		this._Tutorial.repaintWindow();		
		
	}
	
	Tutorial.Step.prototype.createWaitMessage = function(msg) {
		var d = document.createElement('div');
		var s = d.appendChild(document.createElement('span'));
		s.innerHTML = msg;
		d.className = 'action';
		return d;
	}
	
	Tutorial.Step.prototype.createButton = function() {
		var d = document.createElement('div');
		var b = document.createElement('input');
		b.type= 'button';
		/*@cc_on
		b = document.createElement('<input type="button">'); // IE
		@*/
		d.appendChild(b);
		b.value = this._button;
		d.className = 'action';
		var _self = this;
		b.onclick = function () { _self.moveNext(); };
		return d;
	}
	
	Tutorial.Step.Tip.prototype.show = function() {

		if(!this._domElement) {
			this._domElement = this.createDomElement();
		}
	}
	
	Tutorial.Step.Tip.prototype.close = function() {
		if(this._domElement){ 
			this._domElement.parentNode.removeChild(this._domElement);
			this._domElement = null;
		}
	}
	
	Tutorial.Step.Tip.prototype.createDomElement = function() {
		
		var d = document.body.appendChild(document.createElement('div'));
		d.style.position = "absolute";
		
		if(this.relativeTo) {
			var rel = Tutorial.aux.getScreenCoordinates(document.getElementById(this.relativeTo));
		} else {
			rel = {x:0,y:0};
		}
		
		if(this.y<0) {
			var y = -this.y + rel.y;			
			this.style.bottom = y+"px";
		} else {
			var y = this.y + rel.y;	  
			d.style.top = y+"px";
		}
		if(this.x<0) {
			var x = -this.x + rel.x;
			d.style.right = x +"px";
			d.className = 'rightTip';
		} else {
			var x = this.x + rel.x;
			d.style.left = x+"px";
			d.className = 'tip';
		}
		
		if(this.layout) {
			d.className += ' ' + this.layout;  			
		}
		
		var bg = d.appendChild(document.createElement('div'));
		bg.className = "background";
		var di = d.appendChild(document.createElement('div'));
		di.className = "inner";

		di.appendChild(document.createTextNode(this.text));
		bg.style.width  = di.offsetWidth  + 'px';
		bg.style.height = di.offsetHeight + 'px';
		d.style.width  = di.offsetWidth  + 'px';
		d.style.height = di.offsetWidth  + 'px';
		
		var _self = this;
		d.onclick = function(){_self.close()};
		return d;
	}
	
	
	
	
	Tutorial.aux = {};
	
	Tutorial.aux.getScreenCoordinates = function (element) {
		var curleft = curtop = 0;
		if (element.offsetParent) {
			curleft = element.offsetLeft
			curtop = element.offsetTop
			while (element = element.offsetParent) {
				curleft += element.offsetLeft
				curtop += element.offsetTop
			}
		}
		return {x:curleft,y:curtop};
	}
	
	Tutorial.aux.getMouseCoordinates = function (e) {
		var posx = 0;
		var posy = 0;
		if (!e) var e = window.event;
		if (e.pageX || e.pageY) 	{
			posx = e.pageX;
			posy = e.pageY;
		}
		else if (e.clientX || e.clientY) 	{
			posx = e.clientX + document.body.scrollLeft
				+ document.documentElement.scrollLeft;
			posy = e.clientY + document.body.scrollTop
				+ document.documentElement.scrollTop;
		}		
		return {x: posx, y: posy};
	}


	Tutorial.aux.mouseDownHandler = function (handle /*, e, showDrag*/) {
		Tutorial.aux._dragStarted      = true;
		Tutorial.aux._draggedElement   = handle.parentNode.parentNode;
		Tutorial.aux._draggedContainer = Tutorial.aux._draggedElement.parentNode;
		Tutorial.aux._showDrag		   = arguments[2]?arguments[2]:false;
		Tutorial.aux._eventCoord	   = arguments[1]?Tutorial.aux.getMouseCoordinates(arguments[1]):{};
		
		document.onkeypress = Tutorial.aux.resetDrag;	
		document.onmouseup  = Tutorial.aux.dropDrag;
		Tutorial.aux._draggedElement.style.MozUserSelect="none";
		Tutorial.aux._draggedContainer.style.MozUserSelect="none";
		setTimeout(Tutorial.aux.startDrag,300);		
		
		document.body.onselectstart = function(e) {
			Tutorial.aux.stopPropagation(e); 
			return Tutorial.aux.preventEvent(e); 
		};
		document.body.ondrag = function(e) { 
			Tutorial.aux.stopPropagation(e); 
			return Tutorial.aux.preventEvent(e); 
		};		
		
		return false;
	}	
	
	Tutorial.aux.startDrag = function(e) {
		if(Tutorial.aux._dragStarted) {		
			Tutorial.aux._draggedContainer.onmouseout = function(e){ 		
				if (!e) var e = window.event;
				var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
				p = Tutorial.aux._draggedContainer.parentNode;
				while(p && p!=reltg)
					 p = p.parentNode;
				if(p) 
					Tutorial.aux.resetDrag();	
			};	
			if(Tutorial.aux._showDrag) {
				
				// Tutorial.aux._draggedContainer.style.position = 'absolute';	
				// Tutorial.aux._draggedElement.style.margin = "0";				
				document.onmousemove = Tutorial.aux.drag;
			}
			Tutorial.aux._draggedContainer.style.cursor = "pointer";	
			Tutorial.aux._draggedElement.className += " isDragged";
		}				
	}
	
	Tutorial.aux.drag = function(e) {
		if(Tutorial.aux._draggedElement) {
			var mouse = Tutorial.aux.getMouseCoordinates(e);
			
			if(!Tutorial.aux._draggedElementOffset) {
				var coord = Tutorial.aux.getScreenCoordinates(Tutorial.aux._draggedElement);
				Tutorial.aux._draggedElementOffset = { 	x: mouse.x - coord.x,
												  		y: mouse.y - coord.y };
			}
			var x = mouse.x - Tutorial.aux._draggedElementOffset.x;
			var y = mouse.y - Tutorial.aux._draggedElementOffset.y;
			Tutorial.aux._draggedElement.style.left = x + "px";
			Tutorial.aux._draggedElement.style.top  = y + "px";
		}
	}
	
	Tutorial.aux.dropDrag = function() {
		if(Tutorial.aux._dragStarted && Tutorial.aux._draggedElement && Tutorial.aux._dragTarget) {		
			Tutorial.aux._dragTarget.parentNode.insertBefore(Tutorial.aux._draggedElement, Tutorial.aux._dragTarget);		
			updateListOfChoices();				
		}
		Tutorial.aux.resetDrag();
	}
	
	Tutorial.aux.resetDrag  = function() {
		Tutorial.aux._dragStarted = false;
		// document.on  = null;		
		document.onmouseup    = null;
		document.onkeypress   = null;		
		document.body.ondrag  = null;
		document.body.onselectstart = null;
		document.on = null;
		
		if(Tutorial.aux._draggedElement) {
			Tutorial.aux._draggedElement.style.MozUserSelect="text";
			Tutorial.aux._draggedContainer.style.MozUserSelect="text";
			Tutorial.aux._draggedElement.className = Tutorial.aux._draggedElement.className.replace(" isDragged","");
			Tutorial.aux._draggedContainer.style.cursor = "default";
			Tutorial.aux._draggedContainer.onmouseout = null;
			Tutorial.aux._draggedElement = null;
			Tutorial.aux._draggedContainer = null;
			Tutorial.aux._draggedElementOffset = null;
		}
		if(Tutorial.aux._dragTarget) {
			Tutorial.aux._dragTarget.className = Tutorial.aux._dragTarget.className.replace(" draggedOver","");	
			Tutorial.aux._dragTarget = null;		
			Tutorial.aux._previousDragTarget = null;
		}
	}
	
	
	
	/**
	 * Cancel the default execution of an event.
	 */ 
	Tutorial.aux.preventEvent = function(e) {
		if (!e) e = window.event;
		if (e.preventDefault) e.preventDefault();
		else e.returnValue = false;
		return false;
	}
	
	/**
	 *  Cancel the propagation of the event
	 */
	Tutorial.aux.stopPropagation = function(e) {
		if (!e) var e = window.event;
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}
	