/*******************************************************************************
 * 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.QueryBuilder");
dojo.require("org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryDialog");
dojo.require("org.eclipse.cosmos.provisional.dr.ps.components.widget.common");
dojo.require("dijit.Menu");
dojo.require("dijit.form.ComboBox");
dojo.require("dojox.grid.editors");
dojo.require("dojox.grid.Grid");
dojo.require("dijit.form.Textarea");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.form.Button");
dojo.require("dojox.grid._data.dijitEditors")
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dojo.date");
dojo.requireLocalization("nls.org.eclipse.cosmos.provisional.dr.ps.components", "widget");

function removeSelectedRows(inIndex) {
	_cosmos_prop_table.removeSelectedRows();
}

dojo.declare(
		// class
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryOverviewTree",

		// superclass
		[org.eclipse.cosmos.provisional.dr.ps.components.widget.Navigator],
		
		// member variables/functions
		{
			supportRel: true,
			postMixInProperties: function(){
				org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryOverviewTree.superclass.postMixInProperties.apply(this, arguments);
				this.nodeFactory = new org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderFactory({factory:this.contextMap.factory, mdrId: this.contextMap.mdrId, localId: this.contextMap.localId});
				this.supportRel = this.contextMap.supportRel;
				this.menuFactoryStore = new dojo.data.ItemFileReadStore({data:this.contextMap.menuRules});
			},
			deleteTreeNode:function(treeNode){
					org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryOverviewTree.superclass.deleteTreeNode.apply(this, arguments);
					//need to publish that the node was deleted
					for (i=0;i < this.publish.length;i++){
				 	    //lets clone the information we're going to send to another widget since we don't want the other
				 	    //widget modifying our content
						var cloneMap = new Object();
				 	    dojo.mixin(cloneMap,treeNode.item);
				 	    //let tag the data we're going to send so that the consumer of this data knows where the data came from
				 	    cloneMap.nodeClass = this.attachPoint + " nodedeleted" ;
						dojo.publish(this.publish[i], [{contextMap:cloneMap}]);
					}
					
			},
		    addToMessage: function(message){	   
				message.menuFactory = this.menuFactoryStore;
				message.nodeFactory = this.nodeFactory;

		    }
			
		}
		
	);	

dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.RemoveMenu",
			// superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryMenu,
			{
				widgetClass:'cosmos:RemoveMenu',
				createContextMenu:function(menu, store, className){
					menu.addChild(new dijit.MenuItem({onClick:function(){
						store.tree.deleteTreeNode(store.item);
					},
					label:this.label
					}));
				}
			}
		);



dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.AddRelationshipMenu",
			// superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryMenu,
			{
				widgetClass:'cosmos:AddRelMenu',
				builder:null,
				createContextMenu:function(menu, store, className){
			   		if (this.sourceObject.supportRel == false) return;
			   		var _self = this;
			   		menu.addChild(new dijit.MenuItem({onClick:function(){

			   			if (dijit.byId("newRelDialog") != null)
			   				dijit.byId("newRelDialog").destroy();
			   			this.builder = new org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelDialog({
			   				sourceId: store.item.title,
							nodeFactory:_self.nodeFactory,
							callback:function(nodes, parent){
			   				
								if (parent)
									return store.tree.addTreeNode(nodes, parent, true);
								else
									return store.tree.addTreeNode(nodes, store.item, true);
								
							},
						labelQuery:_self.labelDialogQuery, title:_self.title, labelTarget:_self.labelTarget, stateStore:store.tree.store});
			   			this.builder.show();
			   		},
			   		label:this.label
			   		}));
				}
			}
		);

dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.AddRelationshipSourceTargetMenu",
			// superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryMenu,
			{
				widgetClass:'cosmos:AddRelMenu',
				builder:null,
				createContextMenu:function(menu, store, className){
			   		if (this.sourceObject.supportRel == false) return;
			   		var _self = this;
			   		menu.addChild(new dijit.MenuItem({onClick:function(){

			   			if (dijit.byId("newRelSrcDialog") != null)
			   				dijit.byId("newRelSrcDialog").destroy();
			   			this.builder = new org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelSrcTrgtDialog({
			   				sourceId: store.item.title,
							nodeFactory:_self.nodeFactory,
							callback:function(nodes, parent){
								if (parent){
									return store.tree.addTreeNode(nodes, parent, false);
								}
								else{
									return store.tree.addTreeNode(nodes, store.item, false);
								}
								
							},
						labelQuery:_self.labelDialogQuery, title:_self.title, labelSource:_self.labelSource, labelTarget:_self.labelTarget, stateStore:store.tree.store});
			   			this.builder.show();
			   		},
			   		label:this.label
			   		}));
				}
			}
		);

dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.AddItemMenu",
			// superclass
			org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryMenu,
			{
				widgetClass:'cosmos:AddItemMenu',
				builder: null,
				createContextMenu:function(menu, store, className){
			   		var _self = this;
					menu.addChild(new dijit.MenuItem({onClick:function(){
			   			if (dijit.byId("newItemDialog") != null)
			   				dijit.byId("newItemDialog").destroy();
						this.builder = new org.eclipse.cosmos.provisional.dr.ps.components.widget.NewItemDialog({
								nodeFactory:_self.nodeFactory,
								callback:function(nodes, parent){
									if (parent)
										return store.tree.addTreeNode(nodes, parent, true);
									else
										return store.tree.addTreeNode(nodes, store.item, true);
								},
								labelQuery:_self.labelDialogQuery, title:_self.title});
						this.builder.show();
					},
					label:this.label
					}));
				}
			}
		); 



dojo.declare(
			"org.eclipse.cosmos.provisional.dr.ps.components.widget.NewItemDialog",
			[org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryDialog], 
			{
			 	rows:12,
			 	cols:80,
				templatePath:dojo.moduleUrl("org.eclipse.cosmos.provisional.dr.ps.components.widget", "html/NewItem.html"),
				widgetId: "newItemDialog",
				submitQuery: function(){
					if (!(document.getElementById(this.id+"_templateId"))) return;
					var templateId = document.getElementById(this.id+"_templateId").value;
				    var trimTemplateId =  templateId.replace(/^\s*/, "").replace(/\s*$/, "");
					if (trimTemplateId != ""){
				   		var _self = this;
				   		this.nodeFactory.createNode("itemTemplate", null,function(node, childrenNodes){
				   			node.object = templateId;
				   			node.elem = node.title;
				   			node.title = node.title + " - " + templateId;
							var store =  new org.eclipse.cosmos.provisional.dr.ps.components.data.LazyLoadStore({data:{ identifier: "object",  label: "title",  items:[node]}});
							if (childrenNodes){
								store.fetchItemByIdentity({identity:templateId, onItem: function(item){
									for (x = 0; x < childrenNodes.length; x++){
										store.newItem(childrenNodes[x], {parent:item,attribute:'children'});
									}
								}
								});
							}
							_self.callback({title:templateId,nodeClass:"item",object:templateId, store:store});
				   		},
				   		[[ "id", templateId],[ "suppressFromResult", false]]
				   		);
					}
					
					this.destroy();
				},
				onKeyEvt: function(/*Event*/ evt){
					// summary: keep keyboard focus in dialog; close dialog on escape key
					if(evt.keyCode == dojo.keys.ENTER){
						this.submitQuery();
						this.destroy();
					}
					else if(evt.keyCode == dojo.keys.ESCAPE){
							this.destroy(); 
						}
				},		
				postCreate: function(){
					//need to programmically create the combobox due to timing issues with the store
					//call superclass
					org.eclipse.cosmos.provisional.dr.ps.components.widget.NewItemDialog.superclass.postCreate.apply(this, arguments);
					dojo.connect(this.dialogBox, "_onKey", this, "onKeyEvt");			
				}
			
			
				
			}
		);

dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.query.QueryBuilderDialog",
			// superclass	
		   null,
			{
				labelDialogQuery:"",
				builder:null,
				_message: dojo.i18n.getLocalization("nls.org.eclipse.cosmos.provisional.dr.ps.components", "widget"),
				queryNodeClass:"queryCMDBf",
				callbackMethod:null,
				objectConnections: [],
				constructor: function(params){
			   		dojo.mixin(this,params);
		   		},
				bindInput: function(data, callbackMethod){
			   		this.callbackMethod = callbackMethod;
					if ((this.capability) && (!(this.capability.capabilityUnknown))){
						//check the data store for the mdrId
						if (data.mdrId)
							this.capability.mdrId=data.mdrId;
				   		this.builder = new org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderDialog({callback: callbackMethod, description:this.description, title:this.title, UIContext:this.UIContext, epr:this.queryEPR, dialogStore: this.capability});
						this.objectConnections.push(dojo.connect(this.builder,"addItem", this, "addItem"));
					}
					else{
						this.builder = new org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryDialog({callback: callbackMethod, labelQuery:this.labelDialogQuery, title:this.title, UIContext:this.UIContext, epr:this.queryEPR});			   	   
						this.objectConnections.push(dojo.connect(this.builder,"addItem", this, "addItem"));
					}
					this.builder.show();											
			   		
				},
				destroy:function(){
					this.inherited(arguments);
					   for (var z=0; z< this.objectConnections.length; z++){
						   dojo.disconnect(this.objectConnections[z]);
					   }			
					
				},
				addItem: function(item){
					item.nodeClass = this.queryNodeClass;
					this.callbackMethod(item);
					this.builder.destroy();
					this.builder = null;
				}
			}
		); 



dojo.declare(
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.IgnoreOnKeyDialog",
		[dijit.Dialog], 
		{
			_onKey: function(/*Event*/ evt){
			}		
		}
);

dojo.declare(
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderDialog",
		[org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryDialog], 
		{
			templatePath:dojo.moduleUrl("org.eclipse.cosmos.provisional.dr.ps.components.widget", "html/QueryBuilder.html"),
			widgetId: "queryBuilderDialog",
			description:"",
			namespace:"http://cmdbf.org/schema/1-0-0/datamodel",
			localname:"s",
			height: "100%",	
			minHeight: 770,
			isOpen:false,			
			create: function(params, srcNodeRef) {
				//for some reason I need to destroy widget explicitly
	   			if (dijit.byId(this.widgetId) != null)
	   				dijit.byId(this.widgetId).destroy();
	   			//change height based on view port and add 30 px padding
	   			var newHeight = (dijit.getViewport().h-30);
	   			if (newHeight > this.minHeight)
	   				newHeight = this.minHeight;
				params.height = newHeight+"px";

				org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderDialog.superclass.create.apply(this, arguments);
			},		
			buildQuery: function(pretty){
				var _self = this;
				var eol = "";
				var spaces = "";
				if (pretty){
					eol = "__EOL__";
					spaces = "__SPACES__";
				}
				
				var buffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+eol;
				buffer+="<"+_self.localname+":query xmlns:"+_self.localname+"=\""+_self.namespace+"\">"+eol;
				var processElement = function(childItem, childRequest){
					   // should only have 1 item
					   if (childItem.length > 0){
						   var childrenBuffer = "";
						   var printRecursive = function(parentObj, tab){
							   if ((parentObj.title=="any") || (parentObj.title == "expression")){
								   if (parentObj.title == "expression")
									   buffer += tab+"<"+_self.localname+":"+parentObj.title + ">";
								   // text area
								   if ((parentObj.factory) && (parentObj.factory[0])){
									   parentObj.factory[0].fetchItemByIdentity({identity:"textarea",
										   onItem: function(item){
										   if ((item) && (item.value)){
											   buffer += item.value[0];
										   }													  
									   }
									   });
								   }
								   if (parentObj.title == "expression")
									   buffer+="</"+_self.localname+":"+parentObj.title+">"+eol;												   
							   }
							   else if(parentObj.title=="instanceId"){
								   buffer += tab+"<"+_self.localname+":"+parentObj.title + ">"+eol;
								   var attributes = parentObj.factory[0].data;
								   for (var z=0; z< attributes.length; z++){
									   buffer += tab+"<"+_self.localname+":"+attributes[z][0] + ">";
									   buffer += attributes[z][1];
									   buffer += "</"+_self.localname+":"+attributes[z][0] + ">";
								   }								
								   buffer+=tab+"</"+_self.localname+":"+parentObj.title+">"+eol;
							   }
							   else{
								   //sometimes the parentObj elem contains the correct  element name
								   if (parentObj.elem){
									   buffer += tab+"<"+_self.localname+":"+parentObj.elem + " ";
								   }
								   else
									   buffer += tab+"<"+_self.localname+":"+parentObj.title + " ";
							   if ((parentObj.factory)  && (parentObj.factory[0])){
								   // simple grid widget that
									// contains attribute values
								   if (parentObj.factory[0].data){
									   var attributes = parentObj.factory[0].data;
									   for (var z=0; z< attributes.length; z++){
										   if ((parentObj.title == "sourceTemplate") || (parentObj.title == "targetTemplate")){
											   var attrValue = String(attributes[z][1]);
												if ((attributes[z][0]=="minimum") || (attributes[z][0]=="maximum")){
													if (attrValue.length > 0)
													   buffer += attributes[z][0] + "=\""+attributes[z][1]+"\" ";
												}
												else
													   buffer += attributes[z][0] + "=\""+attributes[z][1]+"\" ";
										   }
										   else  
											   buffer += attributes[z][0] + "=\""+attributes[z][1]+"\" ";
									   }								
								   }
								   // the property widget
								   else if ((parentObj.factory[0].propModel) && (parentObj.factory[0].propModel.data)){
									   var attributes = parentObj.factory[0].propModel.data;
									   for (var z=0; z< attributes.length; z++){
										   buffer += attributes[z][0] + "=\""+attributes[z][1]+"\" ";
									   }			
									   if ((parentObj.factory[0].opModel) && (parentObj.factory[0].opModel.data)){
										   attributes = parentObj.factory[0].opModel.data;
										   for (var z=0; z< attributes.length; z++){
											   if (attributes[z][0]=="="){
												   elemName= _self.localname+":"+"equal ";
											   }
											   else if (attributes[z][0]=="<"){
												   elemName= _self.localname+":"+"less ";
											   }
											   else if (attributes[z][0]=="<="){
												   elemName= _self.localname+":"+"lessOrEqual ";
											   }
											   else if (attributes[z][0]==">="){
												   elemName= _self.localname+":"+"greaterOrEqual ";
											   }
											   else if (attributes[z][0]==">"){
												   elemName= _self.localname+":"+"greater ";
											   }
											   else{
												   elemName= _self.localname+":"+attributes[z][0]+" ";
											   }
											   childrenBuffer += tab+"<"+elemName+" negate=\""+attributes[z][2]+"\" ";
											   if ((attributes[z][0]=="=") || (attributes[z][0]=="contains")||(attributes[z][0]=="like"))
												   childrenBuffer += "caseSensitive=\""+attributes[z][3]+"\" ";
											   childrenBuffer += ">";
											   childrenBuffer += attributes[z][1];
											   childrenBuffer += tab+"</"+elemName+">"+eol;
										   }	
									   }
								   }
							   }
							   buffer += ">"+eol;
							   buffer +=childrenBuffer;
							   if (parentObj.children){
								   var localChildren = parentObj.children;
								   for (var y=0; y < localChildren.length; y++){
									   try{
									   printRecursive(localChildren[y], tab+spaces);
									   }
									   catch(e){
										   console.debug(e);
									   }
								   }
							   }
							   if (parentObj.elem){
								   buffer+=tab+"</"+_self.localname+":"+parentObj.elem+">"+eol;
							   }
							   else
								   buffer+=tab+"</"+_self.localname+":"+parentObj.title+">"+eol;
						   }
					   };										   
						   var child = childItem[0];
						   printRecursive(child,spaces);
						   
						   
					   }
				   };
				
				this.overview.childWidget.store.fetch({
					   query: {nodeClass: "item"},
					   queryOptions:{deep:true},
					   onComplete:function(items, request){
						   for (var x=0 ; x < items.length; x++){
							   items[x].store[0].fetch({
								   query: {nodeClass:"itemTemplate"},
								   onComplete:processElement
							   });
						   }
					   }
				});
				this.overview.childWidget.store.fetch({
					   query: {nodeClass: "relationship"},
					   queryOptions:{deep:true},
					   onComplete:function(items, request){
						   for (var x=0 ; x < items.length; x++){
							   if (items.length > 0){
								   items[x].store[0].fetch({
									   query: {nodeClass:"relationshipTemplate"},
									   onComplete:processElement
								   });
							   }
						   }
					   }
				});
				buffer+="</"+_self.localname+":query>"
				if (pretty){
					buffer = buffer.replace(/&/g, "&amp;");					
					buffer = buffer.replace(/>/g, "&gt;");					
					buffer = buffer.replace(/</g, "&lt;");					
					buffer = buffer.replace(/"/g, "&quot;");
					buffer = buffer.replace(/__EOL__/g, "<br>");
					buffer = buffer.replace(/__SPACES__/g, "&nbsp;&nbsp;&nbsp;");
					
				}
				return buffer;
			},
			submitQuery: function(){
			   //submit query
				this.quit(); 
				this.item.query = this.buildQuery(false);
				this.item.epr = this.epr;
				this.item.title = this.nameNode.value;			
				this.addItem(this.item);				
			},
			addItem: function(item){
			},
			postCreate: function(){
				// call superclass								
				org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderDialog.superclass.postCreate.apply(this, arguments);
				// need to initalize widgets
				var _self = this;
				_self.overview = dijit.byId(_self.widgetId+"_over");
				_self.detail = dijit.byId(_self.widgetId+"_detail");
				_self.attribute = dijit.byId(_self.widgetId+"_attribute");
				_self.overview.initWidget({context:_self.UIContext},this.dialogStore);
				_self.detail.initWidget({context:_self.UIContext});
				_self.attribute.initWidget({context:_self.UIContext});
				_self.preview = dijit.byId(_self.widgetId+"_preview");
				_self.tooltip = dijit.byId(_self.widgetId+"_tooltip");
				dojo.connect(_self.preview , "_onDropDownClick", _self, "toggleTooltip")
			},
			toggleTooltip: function(/*Event*/ evt){
				if (this.isOpen)
					this.tooltip.onCancel();
				this.isOpen = !this.isOpen;
				if (this.isOpen){
					this.xmlPreview.innerHTML=this.buildQuery(true);
				}
			},			
			destroy: function(){
				this.overview.destroy();
				this.detail.destroy();
				this.attribute.destroy();
				if (dijit.byId(this.widgetId+"_sub")!=null)
	   				dijit.byId(this.widgetId+"_sub").destroy();
				if (dijit.byId(this.widgetId+"_cancel")!=null)
	   				dijit.byId(this.widgetId+"_cancel").destroy();
				if (dijit.byId(this.widgetId+"_preview")!=null)
	   				dijit.byId(this.widgetId+"_preview").destroy();
				if (dijit.byId(this.widgetId+"_tooltip")!=null)
	   				dijit.byId(this.widgetId+"_tooltip").destroy();
				org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderDialog.superclass.destroy.apply(this, arguments);
			}
			
		}
	);


dojo.declare(
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelDialog",
		[org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryDialog], 
		{
			templatePath:dojo.moduleUrl("org.eclipse.cosmos.provisional.dr.ps.components.widget", "html/NewRel.html"),
			widgetId: "newRelDialog",
			labelTarget:"",			
			combo:null,
			objectConnections :[],
			submitQuery: function(){

				var templateId = dojo.byId(this.id+"_templateId").value;
				var targetId = this.combo.getValue();
			    var trimTarget =  targetId.replace(/^\s*/, "").replace(/\s*$/, "");
			    var trimtemplateId =  templateId.replace(/^\s*/, "").replace(/\s*$/, "");
				if ((trimTarget != "") && (trimtemplateId != "")){
				
				var _self = this;
				this.stateStore.fetch({
					   query: {title: targetId},
					   queryOptions:{deep:true},
					   onComplete:function(items, request){
						   var addRelationship=function(itemstore, queryItem){
									   		_self.nodeFactory.createNode("relationshipTemplate", null,function(node, childrenNodes){
									   			node.object = templateId;
									   			node.elem = node.title;
									   			node.title = node.title + " - " + templateId;
												var store =  new org.eclipse.cosmos.provisional.dr.ps.components.data.LazyLoadStore({data:{ identifier: "object",  label: "title",  items:[node]}});
												store.fetchItemByIdentity({identity:templateId, onItem: function(item){
													// need to add specific
													// source and target nodes
										   			var factory = new dojox.grid.data.Table(null, [[ "ref", _self.sourceId],[ "minimum", ""],[ "maximum", ""]]);
										   			var d= new Date();
													var sourceTemplate = {title:'sourceTemplate',nodeLbl:'sourceTemplate',nodeClass:'sourceTemplate',object:'sourceTemplate'+d.getTime(), factory: factory};
													store.newItem(sourceTemplate, {parent:item,attribute:'children'});

										   			factory = new dojox.grid.data.Table(null, [[ "ref", targetId],[ "minimum", ""],[ "maximum", ""]]);
										   			d= new Date();
													var targetTemplate = {title:'targetTemplate',nodeLbl:'targetTemplate',nodeClass:'targetTemplate',object:'targetTemplate'+d.getTime(), factory: factory};
													store.newItem(targetTemplate, {parent:item,attribute:'children'});
													
										   			_self.callback({title:templateId,nodeClass:"clonerelationship",object:"clone"+templateId,store:store,children:[{title:targetId,nodeClass:"cloneitem",object:"clone"+targetId,store:itemstore}]});
										   			_self.callback({title:templateId,nodeClass:"relationship",object:templateId,store:store},queryItem);										   													   			
																										
												}});
												
									   		},
									   		[[ "id", templateId],[ "suppressFromResult", false]]
									   		);
						   }
						   
							   // this is a new item we need to add the new
								// item to the root node
								_self.stateStore.fetch({
									   query: {title: "query"},
									   onItem: function(item){
										    if (items.length == 0){
										   		_self.nodeFactory.createNode("itemTemplate", null,function(node, childrenNodes){
										   			node.object = targetId;
										   			node.elem = node.title;
										   			node.title = node.title + " - " + targetId;
													var store =  new org.eclipse.cosmos.provisional.dr.ps.components.data.LazyLoadStore({data:{ identifier: "object",  label: "title",  items:[node]}});
													if (childrenNodes){
														store.fetchItemByIdentity({identity:templateId, onItem: function(childitem){
															for (var x = 0; x < childrenNodes.length; x++){
																store.newItem(childrenNodes[x], {parent:childitem,attribute:'children'});
															}
														}
														});
													}						
													_self.callback({title:targetId,nodeClass:"item",object:targetId, store:store}, item);
													addRelationship(store, item);
													
										   		},
										   		[[ "id", targetId],[ "suppressFromResult", false]]
										   		);
											}
											   else{
												   addRelationship(items[0].store, item);
										   }
										   		
									   }
							});
					   }
					});			
				}
				
// this.callback({title:templateId,nodeClass:"relationship",object:templateId,store:store,children:[{title:targetId,nodeClass:"item",object:"clone"+targetId,store:itemstore}]});
				
			},
			onKeyEvt: function(/*Event*/ evt){
				// summary: keep keyboard focus in dialog; close dialog on escape key
				if(evt.keyCode == dojo.keys.ENTER){
					this.submitQuery();
					this.dialogBox.destroy();
					this.destroy();
				}
			},			
		postCreate: function(){
				// for some reason we need to check if the combo box was already
				// created.
	   			if (dijit.byId(this.widgetId+"_cmb") != null)
	   				dijit.byId(this.widgetId+"_cmb").destroy();
				// need to programmically create the combo box due to timing
				// during initialization
				this.combo = new dijit.form.ComboBox({
					name:this.widgetId+"_cmb2",
					autoComplete:true,
					store:this.stateStore,
					query:{nodeClass:'item'},
					searchAttr:"title"
				}, dojo.byId(this.widgetId+"_cmb"));
				// call superclass
				org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelDialog.superclass.postCreate.apply(this, arguments);
				this.objectConnections.push(dojo.connect(this.dialogBox, "_onKey", this, "onKeyEvt"));			
			},
			destroy:function(){
				this.combo.destroy();
				org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelDialog.superclass.destroy.apply(this, arguments);
				   for (var z=0; z< this.objectConnections.length; z++){
					   dojo.disconnect(this.objectConnections[z]);
				   }			
				
			}
		
		
			
		}
	);

dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.RemoveRelMenu",
			// superclass	
			org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryMenu,
			{
				createContextMenu:function(menu, store, className){
					menu.addChild(new dijit.MenuItem({onClick:function(){
						store.tree.deleteTreeNode(store.item);
						store.tree.store.fetchItemByIdentity({identity:"clone"+store.item.object, onItem: function(item){							
									store.tree.deleteTreeNode(item);
							   }
						});
						
					},
					label:this.label
					}));
				}
			}
		); 


dojo.declare(
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelSrcTrgtDialog",
		[org.eclipse.cosmos.provisional.dr.ps.components.widget.NewRelDialog], 
		{
			templatePath:dojo.moduleUrl("org.eclipse.cosmos.provisional.dr.ps.components.widget", "html/NewRelSrcTrgt.html"),
			widgetId: "newRelSrcTrgtDialog",
			labelTarget:"",			
			labelSource:"",			
			combo:null,
			comboSrc:null,
			submitQuery: function(){

				var templateId = dojo.byId(this.id+"_templateId").value;
				var targetId = this.combo.getValue();
				var sourceId = this.comboSrc.getValue();
			    var trimTarget =  targetId.replace(/^\s*/, "").replace(/\s*$/, "");
			    var trimtemplateId =  templateId.replace(/^\s*/, "").replace(/\s*$/, "");
			    var trimSource =  sourceId.replace(/^\s*/, "").replace(/\s*$/, "");
				if ((trimTarget != "") && (trimtemplateId != "") && (trimSource != "")){
				
				var _self = this;
				this.stateStore.fetch({
					   query: {title: targetId},
					   queryOptions:{deep:true},
					   onComplete:function(items, request){
						   var addRelationship=function(itemstore, srcStore){
									   		_self.nodeFactory.createNode("relationshipTemplate", null,function(node, childrenNodes){
									   			node.object = templateId;
									   			node.elem = node.title;
									   			node.title = node.title + " - " + templateId;
												var store =  new org.eclipse.cosmos.provisional.dr.ps.components.data.LazyLoadStore({data:{ identifier: "object",  label: "title",  items:[node]}});
												store.fetchItemByIdentity({identity:templateId, onItem: function(item){
													// need to add specific
													// source and target nodes
										   			var factory = new dojox.grid.data.Table(null, [[ "ref", sourceId],[ "minimum", ""],[ "maximum", ""]]);
										   			var d= new Date();
													var sourceTemplate = {title:'sourceTemplate',nodeLbl:'sourceTemplate',nodeClass:'sourceTemplate',object:'sourceTemplate'+d.getTime(), factory: factory};
													store.newItem(sourceTemplate, {parent:item,attribute:'children'});

										   			factory = new dojox.grid.data.Table(null, [[ "ref", targetId],[ "minimum", ""],[ "maximum", ""]]);
										   			d= new Date();
													var targetTemplate = {title:'targetTemplate',nodeLbl:'targetTemplate',nodeClass:'targetTemplate',object:'targetTemplate'+d.getTime(), factory: factory};
													store.newItem(targetTemplate, {parent:item,attribute:'children'});
													
										   			_self.callback({title:templateId,nodeClass:"clonerelationship",object:"clone"+templateId,store:store,children:[{title:targetId,nodeClass:"cloneitem",object:"clone"+targetId,store:itemstore}]}, srcStore);
										   			_self.callback({title:templateId,nodeClass:"relationship",object:templateId,store:store});										   													   			
												}});
												
									   		},
									   		[[ "id", templateId],[ "suppressFromResult", false]]
									   		);
						   };
						   var addSource = function(itemstore){
							   _self.stateStore.fetch({
								   query: {title: sourceId},
								   queryOptions:{deep:true},
								   onComplete:function(srcItems, request){
									   if (srcItems.length == 0){
										   // this is a new item we need to add the new
											// item to the root node
											_self.stateStore.fetch({
												   query: {title: "query"},
												   onItem: function(item){
												   		_self.nodeFactory.createNode("itemTemplate", null,function(node, childrenNodes){
												   			node.object = sourceId;
												   			node.elem = node.title;
												   			node.title = node.title + " - " + sourceId;
															var store =  new org.eclipse.cosmos.provisional.dr.ps.components.data.LazyLoadStore({data:{ identifier: "object",  label: "title",  items:[node]}});
															if (childrenNodes){
																store.fetchItemByIdentity({identity:templateId, onItem: function(childitem){
																	for (var x = 0; x < childrenNodes.length; x++){
																		store.newItem(childrenNodes[x], {parent:childitem,attribute:'children'});
																	}
																}
																});
															}						
															var srcItem = _self.callback({title:sourceId,nodeClass:"item",object:sourceId, store:store}, item);
															addRelationship(itemstore, srcItem);
															
												   		},
												   		[[ "id", sourceId],[ "suppressFromResult", false]]
												   		);
												   }
												});
									   }
									   else{
										   addRelationship(itemstore, items[0]);
									   }
									   
								   }
							   });								   						
						   };
						   
						   
						   if (items.length == 0){
							   // this is a new item we need to add the new
								// item to the root node
								_self.stateStore.fetch({
									   query: {title: "query"},
									   onItem: function(item){
									   		_self.nodeFactory.createNode("itemTemplate", null,function(node, childrenNodes){
									   			node.object = targetId;
									   			node.elem = node.title;
									   			node.title = node.title + " - " + targetId;
												var store =  new org.eclipse.cosmos.provisional.dr.ps.components.data.LazyLoadStore({data:{ identifier: "object",  label: "title",  items:[node]}});
												if (childrenNodes){
													store.fetchItemByIdentity({identity:templateId, onItem: function(childitem){
														for (var x = 0; x < childrenNodes.length; x++){
															store.newItem(childrenNodes[x], {parent:childitem,attribute:'children'});
														}
													}
													});
												}
												_self.callback({title:targetId,nodeClass:"item",object:targetId, store:store}, item);
												addSource(store);
												
									   		},
									   		[[ "id", targetId],[ "suppressFromResult", false]]
									   		);
									   }
									});
						   }
						   else{
							   addSource(items[0].store);
						   }
					   }
					});			
				}				
			},
			postCreate: function(){
				// for some reason we need to check if the combo box was already
				// created.
	   			if (dijit.byId(this.widgetId+"_Srccmb") != null)
	   				dijit.byId(this.widgetId+"_Srccmb").destroy();
				// need to programmically create the combo box due to timing
				// during initialization
				this.comboSrc = new dijit.form.ComboBox({
					name:this.widgetId+"_Srccmb2",
					autoComplete:true,
					store:this.stateStore,
					query:{nodeClass:'item'},
					searchAttr:"title"
				}, dojo.byId(this.widgetId+"_Srccmb"));
				// call superclass
				this.inherited(arguments);
			},
			destroy:function(){
				this.comboSrc.destroy();
				this.inherited(arguments);
			}
			
		}
	);

dojo.declare("org.eclipse.cosmos.provisional.dr.ps.components.widget.TextBox", dijit.form.TextBox,{
	inRowIndex:0,
	_onMouse : function(/*Event*/ event){
		this.inherited(arguments);
		if(!this.disabled){
			if (event.type == "mouseleave"){
				this.applyEdit(this.getValue(), this.inRowIndex);
			}
		}
	},
	applyEdit:function(value, inRowIndex){
	}	
})

dojo.declare("org.eclipse.cosmos.provisional.dr.ps.components.widget.ComboBox", dijit.form.ComboBox,{
	inRowIndex:0,
	onChange: function(value){
		this.applyEdit(value, this.inRowIndex);
		this.inherited(arguments);
		this.applyEdit("", 1);
		
	},
	applyEdit:function(value, inRowIndex){
	}	
})

dojo.declare("org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor", dojox.grid.editors.Dijit, {
	// summary:
	// grid cell editor that provides a standard select
	// options: text of each item
	// values: value for each item
	// returnIndex: editor returns only the index of the selected option and not
	// the value
	metaData:null,
	editors:[],
	//special select combo box
	localIdSelect: null,
	//special select combo box
	mdrIdSelect: null,
	localIdMDRList: null,
	constructor: function(inCell){
		this.options = this.options || this.cell.options;
		this.values = this.values || this.cell.values || this.options;
		this.metaData = this.options.metaData;
		this.editor = null;
		this.cell = inCell;
		
	},
	createEditor: function(inNode, inDatum, inRowIndex){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
			if (metaRow.type == "Boolean"){
				this.editors[metaRow.type] =  new dijit.form.CheckBox(this.getEditorProps(inDatum), inNode);
				this.editors[metaRow.type].checked = inDatum;
			}
			else if (metaRow.type == "Integer")
				this.editors[metaRow.type] =  new dijit.form.NumberSpinner(this.getEditorProps(inDatum), inNode);
			else if (metaRow.type == "Select"){
				var dataItems =  {identifier:"id",
						items: []
					};
				var selectOptions = metaRow.options;
				if (metaRow.localId){
					this.localIdMDRList = metaRow.localIdMDRList;
					selectOptions = this.localIdMDRList[this.mdrIdSelect.getValue()];
				}
				for (var i=0, o, v; (o=selectOptions[i])&&(v=selectOptions[i]); i++){
					var item= new Object();
					
					item.name = o;
					item.label=o;
					item.id= i;
					dataItems.items[i] = item;
				}
				var store = new dojo.data.ItemFileWriteStore({data: dataItems});
				var properties = this.getEditorProps(inDatum);
				properties.store = store;
				this.editors[metaRow.type] =  new org.eclipse.cosmos.provisional.dr.ps.components.widget.ComboBox(properties, inNode);
				this.editors[metaRow.type].inRowIndex = inRowIndex;
				dojo.connect(this.editors[metaRow.type], "applyEdit", this, "applyEdit");			
				if (metaRow.mdrId){
					this.mdrIdSelect = this.editors[metaRow.type];
				}
				else if (metaRow.localId){
					this.localIdSelect = this.editors[metaRow.type];
					dojo.connect(this.mdrIdSelect,"onChange",this, "linkSelects");
					
				}
			}
			else if (metaRow.type == "ReadOnly"){
				return;
			}
			else{
				this.editors[metaRow.type] = new org.eclipse.cosmos.provisional.dr.ps.components.widget.TextBox(this.getEditorProps(inDatum), inNode);
				this.editors[metaRow.type].inRowIndex = inRowIndex;
				dojo.connect(this.editors[metaRow.type], "applyEdit", this, "applyEdit");			
			}
			return this.editors[metaRow.type];
		}
		return org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.createEditor.apply(this, arguments);
	},	
	linkSelects: function(/*Object*/ value){
		
		var _self = this;
		localIdSelect.store.fetch({
			queryOptions:{deep:true},
		   onComplete:function(items, request){
				for (var i=0;i < items.length;i++){
					localIdSelect.store.deleteItem(items[i]);
					   
				}
				localIdSelect.store.save({onComplete: function(){
					var list = _self.localIdMDRList[value];
					for (var j=0;j < list.items.length;j++){
						var item= new Object();
						
						item.name = list.items[j];
						item.label=list.items[j];
						item.id= j;

						localIdSelect.store.newItem(item);								
					}
				}});
			}
		});
		
	},
	applyEdit:function(value, inRowIndex){
		var e = this.cell.grid.edit;
		e.applyCellEdit(value, this.cell, inRowIndex);
	},
	format: function(inDatum, inRowIndex){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
				if(metaRow.type=="ReadOnly"){
				this.inDatum = inDatum;
				return ""+inDatum;
			}
		}
		return org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.format.apply(this, arguments);
	},	
	sizeEditor: function(inNode, inDatum, inRowIndex){
		if(this.editor)
			this.inherited(arguments);
	},
	_finish: function(inRowIndex){
		if(this.editor){
			this.inherited(arguments);
		}
	},	
	formatNode: function(inNode, inDatum, inRowIndex){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
			if ((metaRow.type == "Seleect") || (metaRow.type == "ReadOnly")){
				if(dojo.isIE){
					// IE sux bad
					dojox.grid.whenIdle(this, "focus", inRowIndex, inNode);
				}else{
					this.focus(inRowIndex, inNode);
				}
			}
		}
		return org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.formatNode.apply(this, arguments);
	},	
	getSelectEditorProps: function(inDatum, options){
		var items=[];
		dojo.forEach(options, function(o){
			items.push({name: o, value: o});
		});
		var store = new dojo.data.ItemFileReadStore({data: {identifier:"name", items: items}});
		return dojo.mixin({}, {}, {
			value: inDatum,
			store: store
		});
	},
	
	attachEditor: function(inNode, inDatum, inRowIndex){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
			var rowEditor = this.editors[metaRow.type];
			if (rowEditor){
				if (this.editor)
					this.editor.destroy();
				this.editor = this.createEditor(inNode, inDatum, inRowIndex);
			}
			else{
				this.editor = this.createEditor(inNode, inDatum, inRowIndex);
			}
		}
	},
	getValue: function(inRowIndex){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
			if (metaRow.type == "Boolean"){
				return this.editor.checked;
			}
			else if (metaRow.type == "ReadOnly"){
				return this.inDatum;
			}
		}
			
		return org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.getValue.apply(this, arguments);
	},
	focus: function(inRowIndex, inNode){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
			if (metaRow.type == "Select"){
				dojox.grid.focusSelectNode(inNode || this.getNode(inRowIndex));
			}
		}
		else {
			org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.focus.apply(this, arguments);
		}
	},	
	setValue: function(inRowIndex, inValue){
		if ((this.metaData != null) && (this.metaData[inRowIndex])){
			var metaRow  = this.metaData[inRowIndex];
			if (metaRow.type == "Boolean"){
				this.editor.checked = inValue;
			}
			else
				org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.setValue.apply(this, arguments);
		}
		else
			org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor.superclass.setValue.apply(this, arguments);
	}

});


dojo.declare(
		// class
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.AttributeTable",

		// superclass
		[dojox.Grid],
		
		// member variables/functions
		{
			singleClickEdit: true,
			create: function(params, srcNodeRef) {
			
			if (params.contextMap){
					if (params.contextMap.factory){
			   			params.model = params.contextMap.factory[0];
			   			//should remove observers if the current widget was removed
			   			params.model.observers=[];
					}
					if (params.contextMap.metadata)
						params.metadata = params.contextMap.metadata;
				}

				params.structure[1].rows[0][1].editor = org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor;
				org.eclipse.cosmos.provisional.dr.ps.components.widget.AttributeTable.superclass.create.apply(this, arguments);
			},			
			doStartEdit: function(inCell, inRowIndex){
				if ((inCell.editor)&& (this.metadata)){
					// override metadata
					if ((this.metadata[0][inRowIndex]) && (inCell.editor.metaData)){
						inCell.editor.metaData[inRowIndex] = this.metadata[0][inRowIndex];
					}
				}
				return org.eclipse.cosmos.provisional.dr.ps.components.widget.AttributeTable.superclass.doStartEdit.apply(this, arguments);
			}
		}
		
	);	

dojo.declare(
		// class
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.AttributeTextArea",

		// superclass
		[dijit.form.Textarea],
		
		// member variables/functions
		{
			textAreaValue: null,
			create: function(params, srcNodeRef) {
				var _self = this;
				var _funcArgs = arguments;
				if ((params.contextMap) && (params.contextMap.factory)){
			   			params.model = params.contextMap.factory[0];
			   			params.model.fetchItemByIdentity({identity:"textarea", onItem: function(item){
							if (item){
								params.textAreaValue = item;
							}
							else
								params.textAreaValue = params.model.newItem({id:'textarea',value: ""});
							params.value = params.textAreaValue.value[0];
							org.eclipse.cosmos.provisional.dr.ps.components.widget.AttributeTable.superclass.create.apply(_self, _funcArgs);							
						}
						});
				}

			},
			onChange: function(newValue){					
		  	  this.inherited(arguments);
			  this.model.setValue(this.textAreaValue, "value", newValue);
			}
		}
		
		
	);	


dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryBuilderFactory",
			// superclass
			null,
			{
				constructor: function(params){
					dojo.mixin(this,params);
					this.store = new dojo.data.ItemFileReadStore({data:params.factory});
				},
				createNode:function(nodeClass, parentClass, callback, factoryOverride){
					if (dojo.isArray(nodeClass))
						nodeClass = nodeClass[0];
					var _self = this;
					this.store.fetch({
						query: {nodeClass:nodeClass},
						queryOptions:{deep:true},
					   onComplete:function(items, request){
							   if (items.length > 0){
								   var factory = null;
							   		if (items[0].factoryType){
							   			factoryClass = dojo.getObject(items[0].factoryType[0], true);
							   			if (!(factoryOverride)){
							   				factoryOverride = items[0].factory;
							   			}
							   			if (factoryOverride){
											var dataClone = dojo.clone(factoryOverride);
							   				factory = new factoryClass(null, dataClone);
							   			}
							   			else if (items[0].factoryType[0] == "dojo.data.ItemFileWriteStore")												   		 
							   				factory = new factoryClass({data:{ identifier: 'id', items: []}});
							   			else if (items[0].params){
											var dataClone = dojo.clone(items[0].params[0][0]);
							   				factory = new factoryClass(dataClone);
							   			}
							   			else
							   				factory = new factoryClass();
							   		}
							   		//check to see if the factory has a mdrId parameter
							   		if (items[0].pop == true){
							   			if ((this.mdrId) || (this.localId)){
											for ( var z = 0; z < factory.length; z++) {
												if (dojo.isArray(factory[z])){
													if (factory[z][0] == "mdrId") {
														factory[z][1] = this.mdrId;
													}
													else if  (factory[z][0] == "localId"){
														factory[z][1] = this.localId
													}
												}
											}
							   			}
									}
						   			var d= new Date();
						   			var node = null;
						   			// check if the item has meta data
									// informationc
						   			if (items[0].metadata)
						   				node = {title:items[0].nodeLbl,nodeClass:nodeClass,object:parentClass+d.getTime(), factory: factory, metadata:items[0].metadata};
						   			else
						   				node = {title:items[0].nodeLbl,nodeClass:nodeClass,object:parentClass+d.getTime(), factory: factory};						   			
						   			var childNodes = [];
						   			var complete = 0;
									if  (items[0].addChild){
										for (var z = 0 ; z < items[0].addChild.length; z++){
											var childClass = items[0].addChild[z]
											_self.store.fetch({
												query: {nodeClass:childClass},
												queryOptions:{deep:true},
  											    onComplete:function(childItems, request){
													d = new Date();
													if (childItems.length > 0){
														var childFactory = null;
												   		if (childItems[0].factoryType){
												   			factoryClass = dojo.getObject(childItems[0].factoryType[0], true);
												   			if (childItems[0].factory)
												   				childFactory = new factoryClass(null, childItems[0].factory);
												   			else if (childItems[0].factoryType[0] == "dojo.data.ItemFileWriteStore")												   		 
												   				childFactory = new factoryClass({data:{ identifier: 'id', items: []}});
												   		}
												   		if (childItems[0].pop[0] == true){
												   			if ((_self.mdrId) || (_self.localId)){
																for ( var zz = 0; zz < childFactory.data.length; zz++) {
																	if (dojo.isArray(childFactory.data[z])){
																		if (childFactory.data[zz][0] == "mdrId") {
																			childFactory.data[zz][1] = _self.mdrId;
																		}
																		else if  (childFactory.data[zz][0] == "localId"){
																			childFactory.data[zz][1] = _self.localId
																		}
																	}
																}
												   			}
														}
														childNodes[z] = {title:childItems[0].nodeLbl,nodeClass:childClass,object:childClass+d.getTime(), factory: childFactory};
													}
													else{
														childNodes[z] = {title:childItems[0].nodeLbl,nodeClass:childClass,object:childClass+d.getTime(), factory: null};
													}
													complete++;
													// done processing all
													// children
													if (complete == items[0].addChild.length){
														callback(node, childNodes);
													}
												}
											});
										}
									}else{																   			
										callback(node, childNodes);
									}
							   }
							   else
						   			callback(null, null);							   										   
						}
					});														
									
				}
			}
		);


dojo.declare(
		   "org.eclipse.cosmos.provisional.dr.ps.components.widget.PropValueDataStore",
			// superclass
			null,
			{
				constructor: function(params){
					dojo.mixin(this,params);
					this.opModel = new dojox.grid.data.Table(null, []);

					// default data
					this.propModel = new dojox.grid.data.Table(null, params.datao);
				}
			}
		);

dojo.declare(
		"org.eclipse.cosmos.provisional.dr.ps.components.widget.PropertyValueBuilder",
		[dijit._Widget, dijit._Templated, dijit._Container], 
		{
			_message: dojo.i18n.getLocalization("nls.org.eclipse.cosmos.provisional.dr.ps.components", "widget"),
			templatePath:dojo.moduleUrl("org.eclipse.cosmos.provisional.dr.ps.components.widget", "html/PropertyValueBuilder.html"),
			widgetsInTemplate: true,
			widgetId: "mygridwidget",
			model:null,
			propLayout:null,
			opLayout:null,
			create: function(params, srcNodeRef) {
				if ((params.contextMap) && (params.contextMap.factory)){
			   			params.model = params.contextMap.factory[0];
				}
				org.eclipse.cosmos.provisional.dr.ps.components.widget.PropertyValueBuilder.superclass.create.apply(this, arguments);
			},			
			addRow: function(){
				this.opGrid.addRow([ ">","",false,false ]);								
			},
			removeSelectedRows: function(){
				this.opGrid.removeSelectedRows();
			},
			postMixInProperties: function(){
				this.addLbl=this._message.ADDOP,
				this.removeLbl=this._message.REMOVEOP,		
				this.opLayout = [{
					type: 'dojox.GridRowView', width: '20px'
				},{
					defaultCell: { width: '100%', styles: 'text-align: center;'  },
					rows: [[
						{name: ' ', get:this.cellRenderer, width:"6%"},					        
						{ name: 'operator', width: '21%', editor: dojox.grid.editors.Select, options: this.model.opOptions[0]},
						{ name: 'value', width: '21%',  editor: dojox.grid.editors.Input},
						{ name: 'negate', width: '21%', editor: dojox.grid.editors.Bool },
						{ name: 'caseSensitive', width: '21%', editor: dojox.grid.editors.Bool }
					]]
				}];

				
					this.propLayout = [{
						type: 'dojox.GridRowView', width: '20px'
					},{
						defaultCell: {styles: ''  },
						rows: [[
							{ name: this._message.ATTRIBUTE, width: '50%'},
							{ name: this._message.VALUE, width: '50%',	editor: org.eclipse.cosmos.provisional.dr.ps.components.widget.MetaColumnEditor,options: {
								metaData:[
											{type:"Input"}, {type:"Input"} ]}}
						]]
					}];
			
				org.eclipse.cosmos.provisional.dr.ps.components.widget.PropertyValueBuilder.superclass.postMixInProperties.apply(this, arguments);
			},
			cellRenderer:function(inRowIndex){
				return "<span onclick='removeSelectedRows(" + inRowIndex + ")' class=\"propDeleteIcon\"></span>";
			},			
			postCreate: function(){
				// need to programmically create the combobox due to timing
				// issues with the store
				// call superclass
				org.eclipse.cosmos.provisional.dr.ps.components.widget.PropertyValueBuilder.superclass.postCreate.apply(this, arguments);
				this.opGrid = new dojox.Grid({
					name:this.widgetId+"_op",
					singleClickEdit: true,
					model:this.model.opModel,
					structure:this.opLayout
				}, this.opGridAttachPoint);
				this.propGrid = new org.eclipse.cosmos.provisional.dr.ps.components.widget.AttributeTable({
					name:this.widgetId+"_prop",
					singleClickEdit: true,
					model:this.model.propModel,
					metadata:this.model.metadata,
					structure:this.propLayout
				}, this.propGridAttachPoint);
				window["_cosmos_prop_table"] = this;
				
								
			},
			destroy: function(){
				if (this.opGrid)
					this.opGrid.destroy();
				if (this.propGrid)
					this.propGrid.destroy();
				if (dijit.byId(this.widgetId+"_add")!=null)
	   				dijit.byId(this.widgetId+"_add").destroy();
				if (dijit.byId(this.widgetId+"_remove")!=null)
	   				dijit.byId(this.widgetId+"_remove").destroy();
				this.inherited(arguments);
			}

			
		}
	);
