<?xml version="1.0" encoding="utf-8" ?> 
<application-components>
	
	<!--
			Reference: http://www.imnmotion.com/documents/html/technical/dhtml/mdiOverview.html
			The 'manager' component's mousemove code was adapted from the MDI CContainer class.
			The 'window' component's behavior and delegation to 'manager' was modeled after the MDI CWindow class.
			Much of the MDI coding guff was completely dropped

	-->
	<application-component id = "manager">
		<![CDATA[
			component_init:function(){
				// bug note: getContainerId is coming through as an object because the component is being tied directly to the engine object
				// but, the getContainer() correctly points to the engine HTML element
				//
				if(typeof this.getContainerId() != "object"){
					alert("Invalid container reference.  terminating object");
					this.destroy();
					return;
				}
				
				var _s = this.getStatus();
				this.setTopWindow(null);
				this.createHandler("mousemove",0,0,1);
				
				org.cote.js.dom.event.addEventListener(this.getContainer(),"mousemove",this._prehandle_mousemove);

				_s.mod_x = 0;
				_s.mod_y = 0;
				
				_s.animate_delay = 1;
				_s.animate_step = 10;
				_s.animate_count = 0;
				
			},
			_handle_mousemove:function(e){
						
				var evt=org.cote.js.dom.event._gevt(e);
				
				if(this.getTopWindow() && (this.getTopWindow().getStatus().is_moving || this.getTopWindow().getStatus().is_resizing)){
					
					var iX = evt.clientX;
					var iY = evt.clientY;
					var oObj = this.getContainer();
					
					var oWin = this.getTopWindow();
					var oCont= oWin.getContainer();
					var oFr = oWin.getPointers().active_frame;
					if(oWin.getStatus().is_resizing){
						var oTemp= (oWin.getIsBound() ? oObj : document.documentElement);
						var iNewW=iX - oFr.offsetLeft - oTemp.offsetLeft + document.documentElement.scrollLeft;
						var iNewH=iY - oFr.offsetTop - oTemp.offsetTop + document.documentElement.scrollTop;
						if(oWin.getStatus().is_bound){
							var iTop3 = oObj.offsetTop + oObj.offsetHeight +  this.getStatus().mod_y;
							var iLeft3 = oObj.offsetLeft + oObj.offsetWidth +  this.getStatus().mod_x;
							if(iY >= iTop3 || iX >= iLeft3) return;
						}
						if(iNewH > 50 && iNewW > 50){
							oFr.style.height = iNewH + "px";
							oFr.style.width = iNewW + "px";
						}
						
					}
					if(oWin.getStatus().is_moving){
						/*
							Unbound windows should be sized against their parent.
						*/
						var oTemp= (oWin.getIsBound() ? oObj : document.documentElement);

						/*
							Bound or unbound, windows should not be able to be moved into a position where the 
							user can't "grab" the title bar.  In this case, the window can't be moved beyond the point where
							the mouse pointer exits the frame.
						*/

						var iX2 = org.cote.js.dom.event.getAbsoluteLeft(oTemp) + oTemp.clientWidth;
						var iY2 = org.cote.js.dom.event.getAbsoluteTop(oTemp) + oTemp.clientHeight;

						iX=(iX < 0)?0:(iX > iX2)?iX2:iX;
						iY=(iY < 0)?0:(iY > iY2)?iY2:iY;
						var iNewX=iX - oWin.getStatus().track_x;
						var iNewY=iY - oWin.getStatus().track_y;
						
						if(!oWin.getIsBound()){
							iNewY=(iNewY<0)?0:iNewY;
							oFr.style.left = iNewX + "px";
							oFr.style.top = iNewY + "px";
						}
						else{
						
							var iLeft1=oFr.offsetLeft + oObj.offsetLeft;
							var iLeft2=oObj.offsetLeft;
							var iLeft3=iLeft1 + oFr.offsetWidth;
							var iLeft4=iLeft2 + oObj.offsetWidth;
							var iTop1=oFr.offsetTop + oObj.offsetTop;
							var iTop2=org.cote.js.dom.event.getAbsoluteTop(oObj);
							var iTop3=iTop1 + oFr.offsetHeight;
							var iTop4=iTop2 + oObj.offsetHeight;
							window.status=iTop4;		
							if((iLeft1>=iLeft2)&&(iLeft3<=iLeft4)){
								var iCheckFarLeft=oObj.offsetWidth - oFr.offsetWidth - this.getStatus().mod_x;
								if(iNewX<0){
									iNewX=0;
								}
								if(iNewX>iCheckFarLeft){
									iNewX=iCheckFarLeft;
								}
								oFr.style.left = iNewX + "px";
							}
							else{
								if(iLeft3>iLeft4){
									oFr.style.left = (iLeft4 - iLeft2 - oFr.offsetWidth) + "px";
								}
							}
							if((iTop1>=iTop2)&&(iTop3<=iTop4)){
								var iCheckFarTop=oObj.offsetHeight - oFr.offsetHeight - this.getStatus().mod_y;
								if(iNewY<0){
									iNewY = 0;
								}
								if(iNewY>iCheckFarTop){
									iNewY = iCheckFarTop;
								}
								oFr.style.top = iNewY + "px";
							}
							else{
								if(iTop3>iTop4){
									oFr.style.top=(iTop4 - iTop2 - oFr.offsetHeight) + "px";
								}
							}			
					 } // end if bound
					} // end if is moving
				} // end if valid window object

			},
			getTopWindow:function(){
				return this.getPointers().top_window;
			},
			setTopWindow:function(o){
			  this.getPointers().top_window = o;
			},
			setFocus:function(o){
				if(this.getTopWindow()){
					var y = this.getTopWindow()
					y.getContainer().style.zIndex = y.getStatus().lostFocusIndex;
					y._handle_lost_focus();
				}
				this.setTopWindow(o);
				if(o) o.getContainer().style.zIndex = o.getStatus().setFocusIndex;
			},
			
			animateMove : function(o,iCX,iCY,iDX,iDY){
				if(!org.cote.js.registry.ObjectRegistry.isRegistered(o)) return;
				
				var iDistX=iDX - iCX;
				var iDistY=iDY - iCY;
				var iDist=Math.sqrt(Math.pow(iDistX,2) + Math.pow(iDistY,2));
				var iSNum=iDist/this.getStatus().animate_step;
				var iMX=iDistX/iSNum;
				var iMY=iDistY/iSNum;
				o.getStatus().expected_x = iDX;
				o.getStatus().expected_y = iDY;

				this.getStatus().animate_count++;
				this.animateMotion(o.getObjectId(),iMX,iMY,iDX,iDY,iCX,iCY,iDist);
		},
		animateMotion : function(sId,iMX,iMY,iDX,iDY,iCX,iCY,iOrgDist){
			var o = org.cote.js.registry.ObjectRegistry.getObject(sId);
			if(!o || o.getReadyState() != 4 || typeof o.getContainer != "function" || o.getContainer() == null) return;
			
			var iPerc = parseInt((Math.sqrt(Math.pow(iDX - iCX,2) + Math.pow(iDY - iCY,2)) / iOrgDist) * 100);
			
			if(

				Math.floor(Math.abs(iMX)) < Math.floor(Math.abs(iDX - iCX))
				||
				Math.floor(Math.abs(iMY)) < Math.floor(Math.abs(iDY - iCY))
			){
				iCX+=iMX;
				iCY+=iMY;

				o.getContainer().style.top = iCY + "px";
				o.getContainer().style.left = iCX + "px";
				o.getStatus().animated = 1;
				
				var sAFP="org.cote.js.registry.ObjectRegistry.getObject('" + this.getObjectId() + "').animateMotion('" + sId + "'," + iMX + "," + iMY + "," + iDX + "," + iDY + "," + iCX + "," + iCY + "," + iOrgDist + ")";
				window.setTimeout(sAFP,this.getStatus().animate_delay);
			}
			else{
				this.getStatus().animate_count--;
				o.getContainer().style.top = iDY + "px";
				o.getContainer().style.left = iDX + "px";
				o.getStatus().animated = 0;
				if(typeof o._handle_animation_complete == "function") o._handle_animation_complete();
			}
		}
	
    
		]]>
	</application-component>
	<application-component id = "window">
		<![CDATA[
		component_init:function(){
			var oEngine = org.cote.js.engine.EngineService.getEngine(this.getReferenceId()), oManager, _p = this.getPointers(),_s = this.getStatus();
			if(oEngine == null || typeof oEngine != "object"){
					alert("Invalid engine reference");
					this.destroy();
					return;
			}
			
			oManager = oEngine.getObjectByName("manager");
			if(!oManager){
				alert("Could not find manager");
				this.destroy();
				return;
			}
			_p.manager = oManager.object;

			this.getContainer().className = "window_gizmo";
			_p.active_frame = document.createElement("div");
			_p.active_frame.className = "window_gizmo_frame";
			oEngine.engine_element.appendChild(_p.active_frame);
			
			_p.title_bar = document.createElement("div");
			_p.title_bar.onselectstart = function(){return false;};
			_p.title_bar.className = "window_title";
			_p.title_label = document.createElement("span");
			_p.title_bar.appendChild(_p.title_label);
			
			this.createHandler("title_mousedown",0,0,1);
			this.createHandler("frame_mouseup",0,0,1);
			this.createHandler("frame_mousemove",0,0,1);
			this.createHandler("minimize_click",0,0,1);
			this.createHandler("close_click",0,0,1);
			
			_p.active_frame.onmouseup = this._prehandle_frame_mouseup;
			_p.active_frame.onmousemove = _p.manager._prehandle_mousemove;
			 _p.title_bar.onmousedown = this._prehandle_title_mousedown;
			 

			 _p.close_button = document.createElement("div");
			 _p.close_button.setAttribute("is-button","1");
			 _p.close_button.appendChild(document.createTextNode(" "));
			 _p.close_button.className = "button_close";
			 _p.title_bar.appendChild(_p.close_button);
			 _p.close_button.onclick = this._prehandle_close_click;

			 _p.minimize_button = document.createElement("div");
			 _p.minimize_button.setAttribute("is-button","1");
			 _p.minimize_button.className = "button_minimize";
			 _p.title_bar.appendChild(_p.minimize_button);
			 _p.minimize_button.onclick = this._prehandle_minimize_click;
			
			_s.lostFocusIndex = 10;
			_s.setFocusIndex = 11;
			_s.resizeFocusIndex = 12;
			_s.moveFocusIndex = 12;
			_s.dialogFocusIndex = 15;
			_s.stackFocusIndex = 8;
			_s.is_moving = 0;
			_s.can_move = 1;
			_s.is_resizing = 0;
			_s.can_resize = 1;
			_s.can_restore = 1;
			_s.is_bound = 1;
			_s.can_minimize = 1;
			_s.is_minimized = 0;
			_s.mod_x = 0;
			_s.mod_y = 0;
			
			this.getContainer().appendChild(_p.title_bar);
			
		},

		component_post_init:function(){
			var _p = this.getPointers();
			
			var a = this.getContainer().getElementsByTagName("div");
			for(var i = 0; i < a.length; i++){
				if(a[i].getAttribute("is-body")){
					_p.body = a[i];
					break;
				}
			}
			if(!_p.body){
				alert("Invalid content structure.  Expecting to find <div is-body=\"1\" />");
				return;
			}
			
			_p.status_bar = document.createElement("div");
			_p.status_bar.onselectstart = function(){return false;};
			_p.status_bar.className = "window_status";
			_p.status_label = document.createElement("span");
			_p.status_bar.appendChild(_p.status_label);

			this.getContainer().appendChild(_p.status_bar);
			_p.body.className = "window_body";
			
			this.setTitle("[ title ]");
			this.setStatus("[ status ]");
			
			 _p.resize_button = document.createElement("div");
			 _p.resize_button.setAttribute("is-button","1");
			 _p.resize_button.appendChild(document.createTextNode(" "));
			 _p.resize_button.className = "button_resize";
			 _p.status_bar.appendChild(_p.resize_button);
			 this.createHandler("resize_mousedown",0,0,1);
			_p.resize_button.onmousedown = this._prehandle_resize_mousedown;
			
			_p.body.style.height = (this.getContainer().clientHeight - _p.status_bar.offsetHeight - _p.title_bar.offsetHeight) + "px";
		
		},
		minimize : function(){

			var _s = this.getStatus(), _p = this.getPointers();
			if(!_s.can_minimize || _s.is_minimized) return 0;
			if(_s.is_maximized) this.restore();

			_s.is_minimized = 1;
			_s.last_height = this.getContainer().clientHeight;
			_s.last_width = this.getContainer().clientWidth;
			_p.body.style.display = "none";
			_p.status_bar.style.display = "none";
			this.getContainer().style.height = _p.title_bar.offsetHeight + "px";
			_p.minimize_button.style.backgroundImage = "url(/projects/engine/demonstrations/demonstration_16/mill_norm_ico.gif)";
		},
		
		restore : function(){
			var _s = this.getStatus(), _p = this.getPointers();
			if((_s.is_minimized || _s.is_maximized) && _s.can_restore){
				_s.is_minimized = 0;
				_s.is_maximized = 0;
				this.getContainer().style.width = _s.last_width + "px";
				this.getContainer().style.height = _s.last_height + "px";
				_p.body.style.display = "block";
				_p.status_bar.style.display = "block";
				_p.minimize_button.style.backgroundImage = "url(/projects/engine/demonstrations/demonstration_16/mill_min_ico.gif)";
			}
		},
		_handle_close_click : function(e){
			var _p = this.getPointers();

			// Make sure to remove the active frame, since it was added outside the scope of this XHTML element.
			var oEngine = org.cote.js.engine.EngineService.getEngine(this.getReferenceId());
			oEngine.engine_element.removeChild(_p.active_frame);
			this.blur();
			this.destroy();

		},
		_handle_minimize_click : function(e){
			var _s = this.getStatus(), _p = this.getPointers();
			if(_s.is_minimized){
				this.restore();
			}
			else{
				this.minimize();
			}
		},
		setTitle : function(s){
			org.cote.js.xml.setInnerXHTML(this.getPointers().title_label,s);

		},
		setStatus : function(s){
			org.cote.js.xml.setInnerXHTML(this.getPointers().status_label,s);
		},
		clearContents : function(){
			var _p = this.getPointers();
			if(_p.child_engine) org.cote.js.engine.EngineService.clearEngine(_p.child_engine);
			org.cote.js.xml.removeChildren(_p.body);
		},
		getIsBound:function(){
			return this.getStatus().is_bound;
		},
		setIsBound:function(b){
			this.getStatus().is_bound = b;
		},
		moveTo:function(x, y, b){
		
			 if(typeof x == "number" || typeof x == "string") this.getContainer().style.left = x;
			 if(typeof y == "number" || typeof y == "string") this.getContainer().style.top = y;
		},
		_handle_frame_mouseup:function(e){
			var _p = this.getPointers();
			
			if((this.getStatus().can_resize && this.getStatus().is_resizing)|| (this.getStatus().can_move && this.getStatus().is_moving)){
				_p.active_frame.style.zIndex=this.getStatus().setFocusIndex;
				if(this.getStatus().is_resizing){
					this.getStatus().is_resizing = 0;
					this.resizeTo(_p.active_frame.clientWidth, _p.active_frame.clientHeight);
				}	
				if(this.getStatus().is_moving){
					this.moveTo(_p.active_frame.offsetLeft + "px",_p.active_frame.offsetTop + "px");
					this.getStatus().is_moving = 0;
				}
				org.cote.js.dom.event.disableMotionCapture(_p.active_frame);
				_p.active_frame.style.display = "none";
			}
	
		},
		_handle_resize_mousedown:function(e){
			var evt = org.cote.js.dom.event._gevt(e);
			
			var _s = this.getStatus(),_p = this.getPointers();
			var oS = org.cote.js.dom.event._gevt_src(e);
			if(!oS || oS.getAttribute("is-button") != "1") return;
			
			this.getFocus();
			
			_s.track_x = evt.clientX - this.getContainer().offsetLeft;
			_s.track_y = evt.clientY - this.getContainer().offsetTop;	
			_s.is_resizing = 1;
			
			this.translateDimensions(_p.active_frame,this.getContainer());

			_p.active_frame.style.zIndex = this.getStatus().moveFocusIndex;
			_p.active_frame.style.display = "block";	

			org.cote.js.dom.event.enableMotionCapture(_p.active_frame,_p.manager._prehandle_mousemove,this._prehandle_frame_mouseup);

		},
		_handle_title_mousedown:function(e){
			var evt = org.cote.js.dom.event._gevt(e);
			

			var _s = this.getStatus(),_p = this.getPointers();
			
			var oS = org.cote.js.dom.event._gevt_src(e);
			if(oS && oS.getAttribute("is-button") == "1") return;
			
			this.getFocus();
			
			_s.track_x = evt.clientX - this.getContainer().offsetLeft;
			_s.track_y = evt.clientY - this.getContainer().offsetTop;	
			_s.is_moving = 1;
			
			
		
			this.translateDimensions(_p.active_frame,this.getContainer());

			_p.active_frame.style.zIndex = this.getStatus().moveFocusIndex;
			_p.active_frame.style.display = "block";	

			org.cote.js.dom.event.enableMotionCapture(_p.active_frame,_p.manager._prehandle_mousemove,this._prehandle_frame_mouseup);

		},
		resizeTo:function(x, y){
			this.getContainer().style.width = x + "px";
			this.getContainer().style.height = y + "px";
			this.getPointers().body.style.height = (this.getContainer().clientHeight - this.getPointers().status_bar.offsetHeight - this.getPointers().title_bar.offsetHeight) + "px";
		},
		translateDimensions:function(x,y){
			x.style.left = y.offsetLeft + "px";
			x.style.top = y.offsetTop + "px";
			x.style.width = y.clientWidth + "px";
			x.style.height = y.clientHeight + "px";
			
		},
		getIsDialog:function(){
			return this.getStatus().is_dialog;
		},
		setIsDialog:function(i){
				this.getStatus().is_dialog = i;
		},
		component_destroy:function(){
			this.getPointers().manager = null;
		},
		getFocus:function(){
			// if(this.getPointers().manager.getTopWindow() && this.getPointers().manager.getTopWindow()  != this && !this.getPointers().manager.getTopWindow().getIsDialog()) this.getPointers().manager.getTopWindow()._handle_lost_focus();
			if(!this.getPointers().manager.getTopWindow() || !this.getPointers().manager.getTopWindow().getIsDialog()){
				this.getPointers().manager.setFocus(this);
			}
		},
		blur:function(){
			if(this.getPointers().manager.getTopWindow() == this) this.getPointers().manager.setFocus(null);
		},
		_handle_lost_focus:function(){
			//this.getContainer().style.zIndex = this.getStatus().lostFocusIndex;
		}
		
		]]>
	</application-component>

	<application-component id = "demoform">
		<![CDATA[
			component_init : function(){
				// make a note of the engine object, and set it an any parent application component object so that it can be cleaned up later on
				//
				var oEngine = org.cote.js.engine.EngineService.getEngine(this.getReferenceId());
				var id = oEngine.engine_element.getAttribute("comp-id"), o;
				o = org.cote.js.registry.ObjectRegistry.getObject(id);
				if(o){
					o.getPointers().child_engine = this.getReferenceId();
					this.getStatus().parent_comp_id = id;
					o.setStatus("");
					o.setTitle("Here's the demo");
				}
			},
			_handle_click : function(){

				var oForm = org.cote.js.xhtml.form.XHTMLFormComponent.getFormByName(this.getReferenceId());
				var oName = oForm.getElementByName("demo_name");
				var oEmail = oForm.getElementByName("demo_email");
				if(!org.cote.js.xhtml.form.XHTMLFormComponent.validate(oName)){
					org.cote.js.registry.ObjectRegistry.getObject(this.getStatus().parent_comp_id).setStatus(org.cote.js.xhtml.validator.XHTMLValidator.getValidationErrorText(oName.getElement()));
					return;
				}
				if(!org.cote.js.xhtml.form.XHTMLFormComponent.validate(oEmail)){
					org.cote.js.registry.ObjectRegistry.getObject(this.getStatus().parent_comp_id).setStatus(org.cote.js.xhtml.validator.XHTMLValidator.getValidationErrorText(oEmail.getElement()));
					return;
				}
				org.cote.js.registry.ObjectRegistry.getObject(this.getStatus().parent_comp_id).setStatus("Thanks!");
				

			//	alert('click '  + org.cote.js.xhtml.validator.XHTMLValidator.validate(oName));
				
				//alert(org.cote.js.xhtml.form.XHTMLFormComponent.validate(oName));
			}
		]]>
	</application-component>
</application-components>
