/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
dojo.provide("org.eclipse.cosmos.provisional.dr.ps.components.widget.WidgetContainer");
dojo.require("org.eclipse.cosmos.provisional.dr.ps.components.utility.common");
dojo.require("dijit.layout.ContentPane");

 dojo.declare(
	'org.eclipse.cosmos.provisional.dr.ps.components.widget.WidgetContainer',
	[dijit.layout.ContentPane], 
	{
		// summary: This widget provides a container for widget constructed from the widget factory object
		// description: This widget is used to declare attach points within a page template.  The attachPoint variable
		//              defines the value used to lookup widgets from the widget factory object.  The associates widgets
		//              are created and appended to the dom node of the WidgetContainer
		//childWidget: dijit._Widget
		// The widget that is constructed and appended to the dom node of the WidgetContainer
		childWidget: null,
		//UIContext: org.eclipse.cosmos.provisional.dr.ps.components.utility.UIContext
		// The factory class used to create widgets
		UIContext:null,
		//attachPoint: String
		// The tag name that defines the attach point for this container
		attachPoint: "",
		//parseOnLoad: boolean
		// inherited from dijit.layout.ContentPane.  pase content and create the widgets, if any
		parseOnLoad:true,
		//initTopic: Handle
		// the handle to the "initializeWidget" topic
		initTopic: "",
		//initTopic: Handle
		// the handle to the "attachPoint" topic
		attachTopic: "",
		widgetMap: null,		
		widthOffset: 0,
		heightOffset: 0,
		newWidth: 0,
		newHeight: 0,
		heightInit: false,
		postCreate: function(){
			//summary: inherited method
			org.eclipse.cosmos.provisional.dr.ps.components.widget.WidgetContainer.superclass.postCreate.apply(this, arguments);
		  	this.initTopic = dojo.subscribe("initializeWidget", this, this.initWidget);				
			this.attachTopic = dojo.subscribe(this.attachPoint, this, this.updateContainer);
		},		
		resize: function(size){
			//summary: inherited method
			
			//for some reason the singleChild member variable does not get updated. Make sure we update the singleChild member variable 
			if (this._singleChild == null){
				this._checkIfSingleChild();
			}
			//call superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.WidgetContainer.superclass.resize.apply(this, arguments);
		},		
		setChildWidget: function(/*dijit._Widget*/widget){
			//summary: sets the child widget of this container
				this.childWidget = widget;		
		},
		updateContainer: function(message){
			//summary: updates the content of the widget container based on the message received
			//description: This function is connected to the "attachPoint" topic.  Any message that is sent to the "attachPoint" topic is received
			//             by this method.  The message contains a contextMap object.  The contextMap object properties will be mixed into the 
			//             widget that is created.  The contextMap also contains a nodeClass property that is used to lookup the widgets from
			//             that should be attached to this widget container
			//message: object
			// message that is received 
			this.destroyDescendants();
			//need to cleanup single child variable properly
			delete this._singleChild;
			this._singleChild = null;
			
			
			if (this.oldWidget != null){
				this.oldWidget.destroy();
				this.oldWidget = null;
			}
		
	    	if (typeof(message.contextMap) != 'undefined'){
				resourceClass = message.contextMap.nodeClass;	
			}
		
	    	if (typeof(resourceClass) != 'undefined'){
				try{
					var styleProp = [this.attachPoint+" "+resourceClass,this.attachPoint];
					var self = this;							
					var div = document.createElement("div");
					this.domNode.appendChild(div);
					if (!this.heightInit){
						var oldWidth = dojo.marginBox(this.domNode).w;
						var oldHeight = dojo.marginBox(this.domNode).h;
						this.newWidth = oldWidth;
						this.newHeight = oldHeight;
						if ((oldWidth > this.widthOffset) && (oldHeight > this.heightOffset)){
							this.newWidth = oldWidth-this.widthOffset;
							this.newHeight = oldHeight-this.heightOffset;
						}
						this.heightInit = true;
					}
					if (this.newHeight > 0)
						dojo.marginBox(this.domNode, {w: this.newWidth, h: this.newHeight});
					
					if ((styleProp)  && (typeof(styleProp) != 'undefined')){
						//check the dojo id
						if (styleProp.id){
							var oldWidget = dijit.byId(styleProp.id);
							if (oldWidget)
								oldWidget.destroy();
						}
						this.UIContext.context.createWidgetView(styleProp, this, function(widget){
							if (widget == null){
								self.destroyDescendants();
							}
							else{
								self.childWidget=widget;
							}
						}, div,message.contextMap);
							
					}
				}catch(e){
					console.debug(e);
					
					self.destroyDescendants();
					this.UIContext.log.logError(e);
				}
			}
	    },		
	    destroyDescendants: function(){
			//summary: destroys all the children elements attached to the dom node of the widget container.
			if ((this.domNode.childNodes) && (this.domNode.childNodes.length>0)) {
				var nodeLength = this.domNode.childNodes.length;
				for (var x =0; x<nodeLength; x++)				
					this.domNode.removeChild(this.domNode.childNodes[0]);
			}
			//call superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.WidgetContainer.superclass.destroyDescendants.apply(this, arguments);
		},			    
	    destroy: function(){
			//summary: destroys the widget including any handles th widget subscribes to 
			dojo.unsubscribe(this.attachTopic);
			dojo.unsubscribe(this.initTopic);
			//call superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.WidgetContainer.superclass.destroy.apply(this, arguments);
		},			    	
		initWidget: function(UIContext, contextMap){
			//summary: initializes the widget container.
			//description: This method will initialize the widget container by setting the factory object passed in.  The contextMap 
			//             object properties will be mixed into the widget that is created.  The contextMap also contains a nodeClass 
			//             property that is used to lookup the widgets from that should be attached to this widget container			
			if (!(contextMap)){
				contextMap = null;
			}
			if ((this.domNode.childNodes) && (this.domNode.childNodes.length>0)) {
				var nodeLength = this.domNode.childNodes.length;
				for (var x =0; x<nodeLength; x++)				
					this.domNode.removeChild(this.domNode.childNodes[0]);
			}
			if (this.oldWidget != null){
				this.oldWidget.destroy();
				this.oldWidget = null;
			}
			this.UIContext = UIContext;		
			if ((this.widgetMap) && (dojo.isObject(this.widgetMap))){
				if (this.widgetMap[this.attachPoint]){
					if (contextMap)
						dojo.mixin(contextMap, this.widgetMap[this.attachPoint])
					else
						contextMap = this.widgetMap[this.attachPoint];
				}
			}			
			if (this.attachPoint != null){
				try{
						var  div = document.createElement("div");
						var self = this;
						this.domNode.appendChild(div);

						this.UIContext.context.createWidgetView(this.attachPoint, this, function(widget){
								if (widget == null){
									self.destroyDescendants();
								}
								else{
									self.childWidget=widget;
								}
							}, div, contextMap);
					}catch(e){
						console.debug(e);
						self.destroyDescendants();
						this.UIContext.context.log.logInfo(e);
					}						
			}
	    }
	    
	}
);
