/*
 * Ext.nd - Ext for Notes / Domino Alpha 2
 * Copyright(c) 2006, Ext.nd Team.
 * 
 * http://www.extjs.com/license
 */



Ext.namespace("Ext.nd", "Ext.nd.grid", "Ext.nd.data", "Ext.nd.domino");

Ext.nd.extndUrl = "/extnd.nsf/";  

Ext.nd.getBlankImageUrl = function() {
   return this.extndUrl + "extnd/resources/images/s.gif";
};

Ext.nd.init = function(config) {
   Ext.apply(this,config);
   Ext.BLANK_IMAGE_URL = this.getBlankImageUrl();  
};



Ext.nd.Document = function(config) {
   var sForm = 'Ext.nd.Document.json';
   
   
   Ext.apply(this,config);

   var sHREF, locNSF, urlStart;
   sHREF = location.href;
   locNSF = sHREF.toLowerCase().indexOf('.nsf/');
   urlStart = sHREF.substring(0,locNSF+5);
   this.url = urlStart + '($Ext.nd.SwitchForm)/' + this.unid + '?OpenDocument&form=' + sForm;
         
   var cb = {
      success: this.assignValue.createDelegate(this),
      failure: this.processException,
      scope: this
   };    

   Ext.lib.Ajax.request('POST', this.url, cb);
   
};

Ext.nd.Document.prototype = {
  onComplete: function() {},
  
  assignValue: function(req) {
   var sTmp, oTmp;
    sTmp = req.responseText;
    oTmp = eval('(' + sTmp + ')');
  
    
    Ext.apply(this,oTmp);
  
    
    this.onComplete();
  },
  
  processException: function(req) {
   Ext.MessageBox.alert("Error","There was an error in the instantiation of the Document class");
  }  
};


Ext.nd.grid.DominoGridView = function(config){
	Ext.nd.grid.DominoGridView.superclass.constructor.call(this);
	this.el = null;
	
	Ext.apply(this, config);	
};

Ext.extend(Ext.nd.grid.DominoGridView, Ext.grid.GridView, {

	emptyText : "No Documents Found",
	
	handleHeaderClick : function(g, index) {
		if(this.headersDisabled){
			return;
		}
		var dm = g.dataSource, cm = g.colModel;
		if(!cm.isSortable(index)){
			return;
		}
		g.stopEditing();
		
		dm.sort(index); 
		
	}
});



Ext.nd.DominoPagingToolbar = function(el, ds, config){
    Ext.nd.DominoPagingToolbar.superclass.constructor.call(this, el, ds, config);
    this.previousCursor = 1;
    this.previousStart = [];
};

Ext.extend(Ext.nd.DominoPagingToolbar, Ext.PagingToolbar, {
 	
	onClick : function(which){
		var ds = this.ds;
		var d = this.getPageData();
		var start;
		this.which = which;
			
		switch(which){
			case 'first':
				ds.load({params: Ext.apply(ds.lastOptions.params, {start: 1,count: this.pageSize})});
				this.activePagePrev = d.activePage;
				break;
			case 'prev':
				
				if (this.previousStart[d.activePage - 1]) {
					start = this.previousStart[d.activePage - 1];
				} else {
					start = Math.max(1,this.cursor-this.pageSize);
				}
				ds.load({params: Ext.apply(ds.lastOptions.params, {start: start,count: this.pageSize})});
				this.activePagePrev = d.activePage;
				break;
			case 'next':
				if (ds.data.length > 0) {
					start = parseInt(ds.data.last().node.attributes.getNamedItem('position').value,10);
				} else {
					start = 1;
				}
				ds.load({params: Ext.apply(ds.lastOptions.params, {start: start,count: this.pageSize})});
      			this.activePagePrev = d.activePage;
				break;
			case 'last':
				var total = ds.getTotalCount();
				var extra = total % this.pageSize;
				var lastStart = extra ? (total - extra) : total-this.pageSize
				ds.load({params: Ext.apply(ds.lastOptions.params, {start: lastStart, count: this.pageSize})});
				this.activePagePrev = d.activePage;
				break;
			case 'refresh':
				ds.load({params: Ext.apply(ds.lastOptions.params, {start: this.cursor, count: this.pageSize})});
				break;
		}
	},

  
	onLoad : function(ds, r, o){
		this.cursor = o.params ? (o.params.start ? o.params.start : 1) : 1;
		var d = this.getPageData(), ap = d.activePage, ps = d.pages;
		
		
		
		
		if (!o.params.start) {
			d.activePage = 1;
			ap = 1;
		}
		
		
		if (d.activePage == 1 || d.activePage > this.activePagePrev) {
			if (ds.data.length > 0) {
				this.previousStart[d.activePage] = parseInt(ds.data.first().node.attributes.getNamedItem('position').value,10);
				this.previousStart[d.activePage + 1] = parseInt(ds.data.last().node.attributes.getNamedItem('position').value,10);
			}
		} else {
			
		}	
		this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
		this.field.dom.value = ap;
		this.first.setDisabled(ap == 1);
		this.prev.setDisabled(ap == 1);
		this.next.setDisabled(ap == ps);
		this.last.setDisabled(ap == ps);
		this.loading.enable();
	},

  
	getPageData : function(){
		var total = this.ds.getTotalCount();
		var activePage;
		if (this.which == 'next') {
			activePage = this.activePagePrev ? this.activePagePrev + 1 : 1;
		} else if (this.which == 'prev') {
			activePage = this.activePagePrev ? this.activePagePrev - 1 : 1;
		} else if (this.cursor == 1) {
			activePage = 1;
		} else {
			activePage = Math.ceil((this.cursor+this.pageSize)/this.pageSize)
		}

		
		this.which = "";

		return {
			total : total,
			activePage : activePage,
			pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
		};
	}
	
});

Ext.nd.DominoUI = function(config) {

   
   this.uiView = {viewName: '', viewUrl: ''};
   this.uiOutline = {outlineName: '', outlineUrl: ''};

   this.west = {
      titlebar : true,
      split : true,
      collapsible : true, 
      initialSize : 200, 
      minSize : 100, 
      maxSize : 400,
      autoScroll : true
   };
   this.center = {
      titlebar : false,
      tabPosition : 'top',
      closeOnTab : true,
      initialSize : 400,
      autoScroll : true
   };
   this.south = {
      titlebar : false, 
      split : false,
      minSize : 16,
      maxSize : 16,
      collapsible : false,
      animate : false
   };

   
   this.includeWest = true;
   this.includeCenter = true;
   this.includeSouth = true;
   
   
   Ext.apply(this,config);

   
   this.init();
   
}; 

Ext.nd.DominoUI.prototype = {
  init: function() {
    
    
    this.createDominoUI();
    
    
    if (this.uiView.viewName != '' || this.uiView.viewUrl != '') {
      this.uiView = new Ext.nd.UIView(Ext.apply({
        container : this.viewPanel,
        layout : this.layout,
        statusPanel : this.statusPanel
      }, this.uiView));
 
      
      this.viewTitle = (this.viewTitle) ? this.viewTitle : (this.uiView.viewName) ? this.uiView.viewName : this.uiView.viewUrl;
      this.viewPanel.setTitle(this.viewTitle);
    }
    
    
    if (this.uiOutline.outlineName != '' || this.uiOutline.outlineUrl != '') {
      this.uiOutline = new Ext.nd.UIOutline(Ext.apply({
        layout : this.layout,
        container : this.outlinePanel, 
        viewPanel : this.viewPanel,
        uiView : this.uiView
      },this.uiOutline));
    }
  },
  
  
  createDominoUI: function() {
    this.layout = new Ext.BorderLayout(document.body, {
        hideOnLayout: true,
        west: this.west,
        center: this.center,
        south: this.south
     });
  
     this.layout.beginUpdate();
  
     
     this.statusPanel = this.layout.add('south', new Ext.ContentPanel('extnd-status', {
        autoCreate : true
     }));
  
     
     this.outlinePanel = this.layout.add('west', new Ext.ContentPanel('extnd-outline', {
        autoCreate : true,
        title : document.title,
        fitToFrame : true
     }));
     
     
     this.viewPanel = this.layout.add('center', new Ext.ContentPanel('extnd-view', {
        autoCreate : true,
        title : 'View',
        closable : false,
        fitToFrame : true
     }));
     
     
     this.layout.endUpdate();
  },

  showError: function() {
    alert("An error has occured");
  }
};


Ext.nd.data.DominoViewStore = function(config){
	Ext.nd.data.DominoViewStore.superclass.constructor.call(this, config);
};

Ext.extend(Ext.nd.data.DominoViewStore, Ext.data.Store, {
  
	load : function(options){
		options = options || {};
		if(this.fireEvent("beforeload", this, options) !== false){
			this.storeOptions(options);
			var p = Ext.apply(options.params || {}, this.baseParams);
			if(this.sortInfo && this.remoteSort){
				var pn = this.paramNames;
				
				
				
				
				
				
				
				var sortColumn = this.sortInfo.mapping; 
				
				
				var colConfig = this.reader.meta.columnConfig[sortColumn];
				if (colConfig.resortviewunid != "") {
					return; 
				}
				
				
				var sortDir = this.sortInfo.direction;
				
				
				if (sortDir == "ASC") {
					if (p.resortascending) {
						if (p.resortascending != sortColumn) { 
							p.resortascending = sortColumn;
							if (p.start ) {
								delete p.start;
								delete p.startkey
							}
							if (p.resortdescending) { 
								delete p.resortdescending;
							}
						} else {
							if (p.start) {
								delete p.startkey; 
							}
						}
					
					} else {
						p["resortascending"] = sortColumn;
						delete p.start;
						delete p.startkey;
						delete p.resortdescending;
					}

				
				} else {
					if (p.resortdescending) {
						if (p.resortdescending != sortColumn) { 
							p.resortdescending = sortColumn;
							if (p.start) {
								delete p.start;
								delete p.startkey;
							}
							if (p.resortascending) {
								delete p.resortdescending;
							}
						} else {
							if (p.start) {
								delete p.startkey; 
							}
						}
					
					} else {
						p["resortdescending"] = sortColumn;
						delete p.start;
						delete p.startkey;
						delete p.resortascending;
					}
				}
			}

			
			p = Ext.apply(p, {random : new Date().getTime()});
			this.proxy.load(p, this.reader, this.loadRecords, this, options);
		}
	},
  
    	
	sort : function(fieldName, dir){
		var f = this.fields.get(fieldName);
		if(!dir){
			if(this.sortInfo && this.sortInfo.field == f.name){
				dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
			}else{
				dir = f.sortDir;
			}
		}
		this.sortToggle[f.name] = dir;
		
		this.sortInfo = {field: f.name, direction: dir, mapping: f.mapping};
		if(!this.remoteSort){
			this.applySort();
			this.fireEvent("datachanged", this);
		}else{
			this.load(this.lastOptions);
		}
	}
	
});

Ext.nd.data.DominoViewXmlReader = function(meta, recordType){
   Ext.nd.data.DominoViewXmlReader.superclass.constructor.call(this, meta, recordType);
};

Ext.extend(Ext.nd.data.DominoViewXmlReader, Ext.data.XmlReader, {
       
   readRecords : function(doc){
  
      this.xmlData = doc;
      var root = doc.documentElement || doc;
      var q = Ext.DomQuery;
      var recordType = this.recordType, fields = recordType.prototype.fields;
      var sid = this.meta.id;
      var totalRecords = 0;
      if(this.meta.totalRecords){
         totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
      }
      var records = [];
      var ns = q.select(this.meta.record, root);
      for(var i = 0, len = ns.length; i < len; i++) {
         var n = ns[i];
         var values = {};
         var id = sid ? q.selectValue(sid, n) : undefined;
         for(var j = 0, jlen = fields.length; j < jlen; j++){
            var f = fields.items[j];
            
            
            var v = this.getViewColumnValue(n, f.mapping, f.defaultValue);
            v = f.convert(v);
            values[f.name] = v;
         }
         var record = new recordType(values, id);
         record.node = n;
         records[records.length] = record;
      }
      
      return {
         records : records,
         totalRecords : totalRecords || records.length
      };
   },

   beforeload : function() {
      alert('this is a test');
   },
            
   
   getViewColumnValue : function(node, colNbr, defaultValue){
      var q = Ext.DomQuery;
      var type;
      var data;
      
      var oValue = {type:'text',data:[]};
      var entryDataNodes = q.select('entrydata',node);
      for (var i = 0; i<entryDataNodes.length; i++) {
         
         var cn = q.selectNumber('@columnnumber',entryDataNodes[i]);
         
         if(cn == colNbr) {

            
            type = 'text';
            data = q.select(type,entryDataNodes[i]);
                        
            if (data.length == 0) {
               type = 'datetime';
               data = q.select(type,entryDataNodes[i]);
            }
            
            if (data.length == 0) {
               type = 'number';
               data = q.select(type,entryDataNodes[i]);
            }
                        
            
            oValue = this.getValue(entryDataNodes[i], type);

         } 
      } 

      return oValue;
      
   }, 

   getValue : function(entryDataNode, type) {
      var q = Ext.DomQuery;
      var oValue = {type:type, data:[]};
      var data = q.select(type,entryDataNode);               
      
      if(data && data[0] && data[0].firstChild) {
         for (var i=0; i<data.length; i++) {
            oValue.data[i] = data[i].firstChild.nodeValue;
         }
      }
      
      return oValue;
      
   }, 
   
   expand : function(url, params, callback, insertIndex){
      Ext.MessageBox.alert('Coming Soon','expand')
   },

   collapse : function(url, params, callback, insertIndex){
      Ext.MessageBox.alert('Coming Soon','collapse')
   }
   
});

Ext.nd.Formula = function(sFormula, config) {
	var sForm = 'Ext.nd.FormulaEval';
	
	
	this.ExecuteInDocumentContext = false;
	if (sFormula) {
		this.text = sFormula;
	} else {
		this.text = null;
	}

	
	Ext.apply(this,config);
	
	var sHREF = location.href;
	var locNSF = sHREF.toLowerCase().indexOf('.nsf/');
	var urlStart = sHREF.substring(0,locNSF+5);
	
	if (this.unid == 'undefined') {
		
		var arTmp = sHREF.substring(locNSF+5,sHREF.length).split('/');
		var arDoc = arTmp[1].split('?');
		this.unid = arDoc[0];
	}	
	
	if (this.ExecuteInDocumentContext) {		
		this.url = urlStart + '($Ext.nd.SwitchForm)/' + this.unid + '?SaveDocument&form=' + sForm;
	} else {
		this.url = urlStart + sForm + '?CreateDocument';
	}
	
	
	this.value = new Array();
};

Ext.nd.Formula.prototype = {

  eval: function() {
    var body = 'formula='+encodeURIComponent(this.text);
  
    var cb = {
      success: this.assignValue.createDelegate(this),
      failure: this.processException,
      scope: this
    };    
  
    Ext.lib.Ajax.request('POST', this.url, cb);
      
    if (this.target != null) {
      var el = Ext.get(target);
      var mgr = el.getUpdateManager();
      mgr.update(this.url, body, this.assignValue.createDelegate(this));
    } else {
      Ext.lib.Ajax.request('POST', this.url, cb);
    }
  },
  
  onComplete: function() {},
  
  
  assignValue: function(req) {
    var response = req.responseText;
    
    
    var iBodyStartTagBegin = response.indexOf("<body");
    var sBody = response.substring(iBodyStartTagBegin);
    
    var iBodyStartTagEnd = sBody.indexOf(">");
    var iBodyEndTag = sBody.indexOf("</body>");
    
    var result = sBody.substring(iBodyStartTagEnd+1, iBodyEndTag);
  
    
    this.value = result.split('~~');
    
    
    this.onComplete();
  }
};


Ext.nd.UIOutline = function(config) {

   var sess = Ext.nd.Session; 
   var db = sess.CurrentDatabase;

   
   this.dbPath = db.WebFilePath;
   this.outlineName = '';
   this.useOutlineIcons = false;

   
   Ext.apply(this,config);
   
   
   this.outlineUrl = (this.outlineUrl) ? this.outlineUrl : this.dbPath + this.outlineName;

   
   this.init();
};

Ext.nd.UIOutline.prototype = {
  init: function() {
    var cb = {
      success : this.init2.createDelegate(this), 
      failure : this.init2.createDelegate(this),
      scope: this
    };    
    Ext.lib.Ajax.request('POST', this.outlineUrl + '?ReadEntries', cb);
  },
  
  
  init2: function(o) {
    var response = o.responseXML;
    var arEntries = response.getElementsByTagName('outlineentry');
  
    
    var dh = Ext.DomHelper;
    var container = (this.container.getEl) ? this.container.getEl() : this.container;
    
    var Tree = Ext.tree;
    var tree = new Tree.TreePanel(container, {
        animate : true, 
        enableDD : true,
        ddGroup: 'TreeDD',
        containerScroll : true,
        dropConfig : {appendOnly : true},
        rootVisible : false
    });
     
     
     
            
     
     
    var root = new Tree.TreeNode({
        text : 'domino-folders', 
        draggable : false, 
        id : 'domino-folders'
    });
    tree.setRootNode(root);
    var curNode = null;
    var arNodes = [];
    for (var i=0; i<arEntries.length; i++) {
      var entry = arEntries.item(i);
      var extndType = entry.attributes.getNamedItem('type').value;
      var extndTitle = entry.attributes.getNamedItem('title').value;
      var tmpextndHref = entry.attributes.getNamedItem('url');
      var extndHref = (tmpextndHref) ? tmpextndHref.value : "";
      
      
      
      
      
      var expandable = entry.attributes.getNamedItem('expandable');
      var isExpandable = (expandable) ? true : false;
         
      var tmpextndIcon = entry.attributes.getNamedItem('icon');
      var extndIcon = (tmpextndIcon) ? tmpextndIcon.value : "";
      var curPosition = entry.attributes.getNamedItem('position').value;
      
      var cls;          
      switch (extndType) {
         
         case "0" :
            cls = (isExpandable) ? "folder" : "file";
            break;
         
         case "2" :
            cls = "file";
            break;
         
         case "20" :
            cls = "folder";
            break;
         default :
            cls = "file";
      };
            
      var curNode = new Tree.TreeNode({
        text : extndTitle, 
        cls : cls, 
        allowDrag : true, 
        allowDrop : (extndType == "20" || extndType == "0") ? true : false,
        isTarget : true,
        leaf : false,
        extndHref : extndHref,
        extndType : extndType,
        extndExpandable: isExpandable,
        extndPosition : curPosition,
        icon : (this.useOutlineIcons) ? extndIcon : null
      });
         
      curNode.on('click', this.openEntry.createDelegate(this), this, true);   
      
      
      arNodes[curPosition] = curNode;
      
      if (curPosition.indexOf('.') > 0) {
        var parentPosition = curPosition.substring(0,curPosition.lastIndexOf('.'));
        arNodes[parentPosition].appendChild(curNode);   
      } else {
        root.appendChild(curNode);
      }
    }

   
   tree.on('beforenodedrop', this.addToFolder);

   
   tree.render();
   tree.expandAll();
          
   
   //root.expand(); 
  },
  
  
  addToFolder: function(e) {
    console.log('nodedragover - start');
    console.log('addToFolder - start');
  
    var type = e.target.attributes.extndType;
    console.log('type='+type);
  
    if (type == "20" || type == "0") {
      console.log('expanding');
      e.target.expand();
    } else {
      console.log('no, this is not a folder you can drop docs onto');
    }
     
    var unid, sFormula;
    sFormula = '@username';
    var selections = e.data.selections;
    if (selections) {
      console.log('we have some docs selected!');
      for (var i=0; i<selections.length; i++) {
        var oUNID = selections[i].node.attributes.getNamedItem('unid')
        var unid = (oUNID) ? oUNID.value : null;
        if (unid != null) {
          console.log('unid='+unid);
          var formula = new Ext.nd.Formula(sFormula,{
            "ExecuteInDocumentContext": true,
            "unid" : unid
          });
          
          console.log('evaling formula');
          formula.eval();      
        }
      }
    }
  
    console.log('addToFolder - end');
    console.log('nodedragover - end');
  },
  
  
  openEntry: function(node, e) {
    var attributes, extndType, extndHref, extndPosition, entryId, title;
    attributes = node.attributes;
    extndHref = attributes.extndHref;
    extndType = attributes.extndType;
    extndPosition = attributes.extndPosition;
    entryId = "id-" + extndPosition;
    title = node.text;
   
    if (extndType == "2" || extndType == "20") {
      
      if (this.uiView.grid) {
        this.viewPanel.setContent("");
        try {
          this.uiView.grid.destroy();
        } catch(e) {}
      }
      var viewUrl = (extndHref.indexOf('?') > 0) ? extndHref.split('?')[0] : extndHref.split('!')[0];       
      
      
      this.uiView = new Ext.nd.UIView({
        layout : this.layout,
        viewUrl : viewUrl,
        viewParams : "",
        container : this.viewPanel,
        statusPanel : this.statusPanel
      });
         
      this.viewPanel.setTitle(title);
      this.layout.showPanel(this.viewPanel);
    } else if (extndHref != "") {
      var entry = this.layout.getRegion('center').getPanel(entryId);
      if(!entry){ 
        var iframe = Ext.DomHelper.append(document.body, {
          tag: 'iframe', 
          frameBorder: 0, 
          src: extndHref,
          id : entryId
        });
        var panel = new Ext.ContentPanel(iframe, {
          title: Ext.util.Format.ellipsis(title,16),
          fitToFrame:true, 
          closable:true
        });
        this.layout.add('center', panel);
      } else { 
        this.layout.showPanel(entry);
      }
    }
  }
};


Ext.data.Node.prototype.hasChildNodes = function() {
   
   var attr = this.attributes;
   if (attr.extndType == "20" || ((attr.extndType == "0" || attr.extndType == "2") && (this.attributes.extndExpandable))) {
      return true;
   } else { 
      return false;
   }
};


Ext.nd.UIView = function(config) {

   var sess = Ext.nd.Session; 
   var db = sess.CurrentDatabase;
   
   
   this.dbPath = db.WebFilePath;
   this.count = 40,
   this.singleSelect = false,
   this.viewName = '';
   this.baseParams = {};
   this.loadMask = true
   
   this.showActionbar = true;
   this.toolbar = false;
   
   
   this.showSingleCategory = null;
   this.emptyText = 'Select a category...';
   this.showCategoryComboBox = true;
   this.categoryComboBoxCount = -1;
   
   
   this.showSearch = false;
   this.searchCount = 20;
   this.isSearching = false;
   this.searchInPagingToolbar = true;
   
   
   Ext.apply(this,config);
   
   
   if (this.showSingleCategory) {
      this.baseParams.RestrictToCategory = this.showSingleCategory;
   }
   
   
   this.viewUrl = (this.viewUrl) ? this.viewUrl : this.dbPath + this.viewName;
   
   
   if (this.viewName == '') {
      var vni = this.viewUrl.lastIndexOf('/')+1;
      this.dbPath = this.viewUrl.substring(0,vni);
      this.viewName = this.viewUrl.substring(vni);
   }
   
   
   this.init();
};

Ext.nd.UIView.prototype = {

  init: function() {
  
    
    if (this.showActionbar || this.toolbar) {
      if (!this.toolbar) {
         var tb = Ext.DomHelper.append(document.body,{tag: 'div'});
         this.toolbar = new Ext.nd.Actionbar({
            container:tb, 
            noteType:'view', 
            noteName:this.viewName,
            useDxl: true
         });
         
         this.toolbar.addSeparator();

         if (this.showSingleCategory && this.showCategoryComboBox) {
            var store = new Ext.data.Store({
               proxy: new Ext.data.HttpProxy({
                  method:'GET', 
                  url: this.viewUrl + '?ReadViewEntries&CollapseView&count=' + this.categoryComboBoxCount + '&randomizer='+new Date().getTime()
               }),
               reader: new Ext.data.XmlReader({
                     record: 'viewentry',
                     totalRecords: '@toplevelentries',
                     id: '@position'
                  },[{name:'text'}]
               )
            });
            store.load();         
            
            var combo = new Ext.form.ComboBox({
                store: store,
                displayField:'text',
                typeAhead: true,
                mode: 'local',
                triggerAction: 'all',
                emptyText: this.emptyText,
                value: this.showSingleCategory,
                selectOnFocus:true,
                grow: true,
                resizable: true
            });
            this.toolbar.addField(combo);
            this.toolbar.addSeparator();
            combo.on('select',this.handleCategoryChange.createDelegate(this));
         }
        if (this.showSearch) {
          this.searchField = new Ext.form.TextField({
            blankText: "Search view...",
            name: "extnd-vw-search",
            width: 100
          });
          this.toolbar.addField(this.searchField);
          this.toolbar.addButton({text: "Search", scope: this, handler: this.handleViewSearch});
		  this.toolbar.addSeparator();
        }
      }
    } 
      
      this.getViewDesign();
  },
  
  
  handleViewSearch: function() {
    var qry = this.searchField.getValue();
	var ds = this.grid.dataSource;
    
    delete ds.lastOptions.params.start;
	
	var searchURL = this.viewUrl.slice(0, this.viewUrl.lastIndexOf("/")) + "/(SearchViewEntries)?OpenAgent&vw="+ this.viewName + "&q=" + qry; 
    
    ds = new Ext.nd.data.DominoViewStore({
        proxy: new Ext.data.HttpProxy({
            url: searchURL,
            method: "GET"
        }),
        baseParams: this.baseParams,
        reader: viewEntryReader,
		remoteSort:  true
    });
	ds.load();
	this.grid.render()
	//TODO: refresh the grid or set the new datastore
    
  },
  
  handleCategoryChange: function(combo, record, index) {
    var category = record.data.text;
    this.grid.dataSource.baseParams.RestrictToCategory = category;
    this.grid.dataSource.load({params:{start:1}});
    
  },
  
  getViewDesign: function() {
    
    var cb = {
      success : this.getViewDesignCB, 
      failure : this.getViewDesignFailure,
      scope: this
    };    
    Ext.lib.Ajax.request('GET', this.viewUrl + '?ReadDesign', cb); 
  },
  
  
  getViewDesignFailure: function(res) {
    
  },

  getViewDesignCB: function(o) {
    var q = Ext.DomQuery;
    var arColumns = q.select('column',o.responseXML);
  
    var arColumnConfig = [];
    var arRecordConfig = [];
  
    for (var i=0; i<arColumns.length; i++) {
        
        if (i==0 && this.showSingleCategory) {
           continue;
        }
        
        
        var col = arColumns[i];
        var columnnumber = q.selectNumber('@columnnumber',col);
        
        
        columnnumber = (this.showSingleCategory) ? columnnumber - 1 : columnnumber;
        
        
        var tmpName = q.selectValue('@name',col,'');
        var name = (tmpName == undefined) ? 'columnnumber_' + columnnumber : tmpName;
        
        var tmpTitle = q.selectValue('@title',col,"&nbsp;");
        var title = (tmpTitle == undefined) ? "&nbsp;" : tmpTitle;
        var width = q.selectNumber('@width',col) * 1.41; 
        
        
        var response = q.selectValue('@response',col,false);
        var responseValue = (response) ? true : false;
  
        
        var twistie = q.selectValue('@twistie',col,false);
        var twistieValue = (twistie) ? true : false;
  
        
        var listseparatorValue = q.selectValue('@listseparator',col,'none');
        
        
        var resize = q.selectValue('@resize',col,false);
        var resizeValue = (resize) ? true : false;
        
        
        var sortcategorize = q.selectValue('@sortcategorize',col,false)
        var sortcategorizeValue = (sortcategorize) ? true : false;
        
        
        var resortascending = q.selectValue('@resortascending',col,false);
        var resortascendingValue = (resortascending) ? true : false;
              
        
        var resortdescending = q.selectValue('@resortdescending',col,false);
        var resortdescendingValue = (resortdescending) ? true : false;
              
        
        var resorttoview = q.selectValue('@resorttoview',col,false);
        var resorttoviewValue = (resorttoview) ? true : false;
        var resortviewunidValue = (resorttoview) ? q.selectValue('@resortviewunid',col,"") : "";
           
        var isSortable = (resortascendingValue || resortdescendingValue || resorttoviewValue) ? true : false;
  
        
        var icon = q.selectValue('@icon',col,false);
        var iconValue = (icon) ? true : false;
  
        
        var align = q.selectValue('@align',col,false);
        var alignValue = (align) ? ((align == "2") ? 'center' : 'right') : 'left';

        
        var headerAlign = q.selectValue('@headeralign',col,false);
        var headerAlignValue = (headerAlign) ? ((headerAlign == "2") ? 'center' : 'right') : 'left';

        
        var tmpDateTimeFormat   = q.select('datetimeformat',col)[0];
        var datetimeformat = {};
        datetimeformat.show  = q.selectValue('@show',tmpDateTimeFormat);
        datetimeformat.date  = q.selectValue('@date',tmpDateTimeFormat);
        datetimeformat.time  = q.selectValue('@time',tmpDateTimeFormat);
        datetimeformat.zone  = q.selectValue('@zone',tmpDateTimeFormat);
     
        var columnConfig = {
           header: title,
           align: alignValue,
           dataIndex: name,
           width: width,
           renderer: this.dominoRenderer.createDelegate(this), 
           sortable: isSortable, 
           resortascending: resortascendingValue,
           resortdescending: resortdescendingValue,
           resortviewunid: resortviewunidValue,
           sortcategorize: sortcategorizeValue,
           resize: resizeValue,
           listseparator: listseparatorValue,
           response: responseValue,
           twistie: twistieValue,
           icon: iconValue,
           datetimeformat: datetimeformat
        };
  
        var recordConfig = {
           name: name, 
           mapping: columnnumber
        };          
  
        arColumnConfig.push(columnConfig);
        arRecordConfig.push(recordConfig);
        
    } 
  
    
    this.dominoView = {
        meta : {
           root : 'viewentries',
           record : 'viewentry',
           totalRecords : '@toplevelentries',
           id : '@position',
           columnConfig : arColumnConfig
        },
        recordConfig : arRecordConfig
    };
  
    
    this.createGrid();
  },

  createGrid: function() {
    var sViewParams = (this.viewParams == undefined) ? "" : this.viewParams;
   
    
    this.cm = new Ext.grid.DefaultColumnModel(this.dominoView.meta.columnConfig);
      
    
    var viewEntry = Ext.data.Record.create(this.dominoView.recordConfig);

    
    viewEntryReader = new Ext.nd.data.DominoViewXmlReader(this.dominoView.meta, viewEntry);

    
    var ds = new Ext.nd.data.DominoViewStore({
        proxy: new Ext.data.HttpProxy({
            url: this.viewUrl + '?ReadViewEntries',
            method: "GET"
        }),
        baseParams: this.baseParams,
        reader: viewEntryReader,
        remoteSort: true
    });

    
    if (this.grid) {
      try {
         this.grid.destroy();
      } catch (e) {}
    }

    
    var dh = Ext.DomHelper;
    this.grid = new Ext.nd.grid.DominoGrid(dh.append(document.body,{tag: 'div'}), {
      ds: ds,
      cm: this.cm,
      selModel: new Ext.grid.RowSelectionModel({singleSelect : this.singleSelect}),
      enableDragDrop: true,
      ddGroup: 'TreeDD',
      enableColLock: false    
    });

    
    
    var container = (this.container.getEl) ? this.container.getEl() : this.container;
    var layout = Ext.BorderLayout.create({
      center: {
         panels: [new Ext.GridPanel(this.grid, {toolbar: this.toolbar, fitToFrame : true})] 
      }
    }, container);
   



    
    
    this.grid.addListener('rowdblclick',this.gridHandleRowDblClick, this, true);

    
    this.grid.addListener('keydown',this.gridHandleKeyDown, this, true);

    
    this.grid.addListener('rowcontextmenu',this.gridHandleRowContextMenu, this, true);
   
    
    this.grid.addListener('headerclick',this.gridHandleHeaderClick, this, true);
      
    
    
         
    
    this.grid.render();  

    
    var gridFoot = this.grid.getView().getFooterPanel(true);

    
    var paging = new Ext.nd.DominoPagingToolbar(gridFoot, ds, {pageSize: this.count});
   
     
   
    
    ds.load({params:{count : this.count}});
    
    
   
    
       
       
  },


  dominoRenderer: function(value, cell, row, rowIndex, colIndex,dataStore) {
   var args = arguments;
   var colConfig = this.cm.config[colIndex];

   
   var viewentry = row.node;
   var dsItem = dataStore.data.items[rowIndex + 1]
   var nextViewentry = (dsItem) ? dsItem.data.node : null;

   
   var hasChildren = viewentry.attributes.getNamedItem('children');

   
   var isResponse = viewentry.attributes.getNamedItem('response');

   
   var viewentryPosition = viewentry.attributes.getNamedItem('position').value;
   var viewentryLevel = viewentryPosition.split('.').length;

   
   var sCollapseImage = '<img src="/icons/collapse.gif" style="vertical-align:bottom; padding-right:4px;"/>';
   var sExpandImage = '<img src="/icons/expand.gif" style="vertical-align:bottom; padding-right:4px;"/>';
   var indentPadding = (20 * viewentryLevel) + "px";
   var indentPaddingNoIcon = (20 + (20 * viewentryLevel)) + "px"; 

   
   if (hasChildren && colConfig.sortcategorize) {
      cell.css = " xnd-view-expand xnd-view-category";   
      cell.attr = "style='position: absolute;'";
      if (nextViewentry) {
         var nextViewentryPosition = nextViewentry.attributes.getNamedItem('position').value;
         var nextViewentryLevel = nextViewentryPosition.split('.').length;
         if (nextViewentryLevel > viewentryLevel) {
            value = sCollapseImage + this.getValue(value, colConfig);
         } else {
            value = sExpandImage + this.getValue(value, colConfig);
         }        
      } else { 
         value = sExpandImage + this.getValue(value, colConfig);
      }
   } 
   
   else if (hasChildren && !isResponse && colConfig.response) {
      cell.css = "xnd-view-expand xnd-view-category"; 
      cell.attr = "style='position: absolute;'";
      if (nextViewentry) {
         var nextViewentryPosition = nextViewentry.attributes.getNamedItem('position').value;
         var nextViewentryLevel = nextViewentryPosition.split('.').length;
         if (nextViewentryLevel > viewentryLevel) {
            value = sCollapseImage + this.getValue(value, colConfig);
         } else {
            value = sExpandImage + this.getValue(value, colConfig);
         }        
      } else { 
         value = sExpandImage + this.getValue(value, colConfig);
      }
   }  
   
   else if (hasChildren && isResponse && colConfig.response) { 
      cell.css = "xnd-view-expand xnd-view-response"; 
      cell.attr = "style='position: absolute; padding-left:" + indentPadding + ";'"; 
      if (nextViewentry) {
         var nextViewentryPosition = nextViewentry.attributes.getNamedItem('position').value;
         var nextViewentryLevel = nextViewentryPosition.split('.').length;
         if (nextViewentryLevel > viewentryLevel) {
            value = sCollapseImage + this.getValue(value, colConfig);
         } else {
            value = sExpandImage + this.getValue(value, colConfig);
         }        
      } else { 
         value = sExpandImage + this.getValue(value, colConfig);
      }
   }  
   
   else if (!hasChildren && isResponse && colConfig.response) { 
      cell.css = "xnd-view-response";  
      cell.attr = "style='position: absolute; padding-left:" + indentPaddingNoIcon + ";'"; 
      value = this.getValue(value, colConfig);
   }  
   
   else {
      value = this.getValue(value, colConfig);
   }
  
   return value;
  
  },

  
  getValue: function(value, colConfig) {
  
   var dataType, newValue, tmpDate, tmpDateFmt, separator;
   
   switch (colConfig.listseparator) {
      
      case "none" :
         separator = '';
         break;
         
      case "space" :
         separator = ' ';
         break;
         
      case "comma" :
         separator = ',';
         break;
         
      case "newline" :
         separator = '<br/>';
         break;
         
      case "semicolon" :
         separator = ';';
         break;
         
      default : 
         separator = '';
     
   }
   
   newValue = '';
   for (var i=0, len=value.data.length; i<len; i++) {
      var sep = (i+1 < len) ? separator : '';
      dataType = value.type; 
      var tmpValue = value.data[i];
      
      
      if (colConfig.icon) {
         if (isNaN(parseInt(tmpValue,10)) || tmpValue == 0) {
            return "";
         } else {
            
            newValue = (tmpValue < 10) ? "00" + tmpValue : (tmpValue < 100) ? "0" + tmpValue : (tmpValue > 186) ? "186" : tmpValue;
            return '<img src="/icons/vwicn' + newValue + '.gif"/>';
         }
      } else {
   
         switch (dataType) {

            
            case 'datetime':
               var dtf = colConfig.datetimeformat;
               if (tmpValue.indexOf('T') > 0) {
                  tmpDate = tmpValue.split(',')[0].replace('T','.');
                  tmpDateFmt = "Ymd.His";
               } else {
                  tmpDate = tmpValue;
                  tmpDateFmt = "Ymd";
               }
               var d = new Date(Date.parseDate(tmpDate,tmpDateFmt));
               switch (dtf.show) {
                  case 'date':
                     tmpValue = d ? d.dateFormat("m/d/Y") : '';
                     break;
                  case 'datetime':
                     tmpValue = d ? d.dateFormat("m/d/Y h:i:s A") : '';
                     break;
                  }
               break;
   
            
            case 'text':
               tmpValue = tmpValue;
               break;
   
            
            case 'number':
               tmpValue = tmpValue;
               break;

            
            default:
               tmpValue = tmpValue;
         } 
         
         newValue = newValue + tmpValue + sep;
         
      } 
  
   } 
   
      return newValue;
  },
  
  preprocessDominoData: function(value) {
   return value;
   
   var dataType = value.substring(0,1);
   var newvalue = value.substring(1);
   
   switch (dataType) {
      case 'd':
         var d = new Date(Date.parseDate(newvalue.split(',')[0].replace('T','.'),"Ymd.His"));
         newvalue = d ? d.dateFormat("m/d/Y h:i:s A") : '';
         break;
      case 't':
         newvalue = newvalue;
         break;
      case 'n':
         newvalue = newvalue;
         break;
      default:
         newvalue = newvalue;
   }
   return newvalue;
  },
  
  gridHandleKeyDown: function(e) {
   var node, row, rowIndex, unid, target;
   var keyCode = e.browserEvent.keyCode;
   var charCode = e.charCode;
   
   target = e.getTarget();
   row = this.grid.selModel.getSelected();
   rowIndex = this.grid.dataSource.indexOf(row);

   
   if (e.altKey) { 
      return;
   }

   
   if (e.ctrlKey && keyCode == 69) {
      if(row){
         this.openDocument(this.grid, rowIndex, e, true);
      }
      return;
   }
   
   
   if (e.ctrlKey) { 
      return;
   }
   
   
   if (e.shiftKey && keyCode == 16) {
      return;
   }
   
   switch (keyCode) {   
      case e.RETURN :
         if(row){
            this.openDocument(this.grid, rowIndex, e);
         }
         break;
      case e.DELETE :
         if(row){
            this.deleteDocument(this.grid, row, e);
         }
         break;
         
      case e.BACKSPACE :
      case e.DOWN :
      case e.ESC :
      case e.F5 :
      case e.HOME :
      case e.LEFT :
      case e.PAGEDOWN :
      case e.PAGEUP :
      case e.RIGHT :
      case e.UP :
      case e.TAB :
   
         break;
      
      case e.SPACE :
         Ext.MessageBox.alert("Coming Soon","In a future release, the space bar will toggle the selection of the document.");
         break;
      default :
         if (row) { 
            Ext.MessageBox.prompt( 'Search Text', 'Starts with...', this.quickSearch, this)
            

         }
   } 
  },

  quickSearch: function(btn, text) {
   var ds = this.grid.dataSource;
   if (btn == 'ok') {
      
      delete ds.lastOptions.params.start;
      
      ds.load({params: Ext.apply(ds.lastOptions.params, {startkey : text})}); 
   }
  },
  
  quickSearch_EXPERIMENT: function() {
   this.showQuickSearchDialog.hide();
   var vsi = Ext.get('extnd-view-search-input').dom;
   var s = vsi.value;
   vsi.value = ""; 
   Ext.MessageBox.alert('Coming Soon','this is where we would make an XHR call to view?readviewentries&startkey=' + s)
  },
  
  gridHandleHeaderClick: function(grid, colIndex, e) {
   var colConfig = this.cm.config[colIndex];
   if (colConfig.resortviewunid != "") {
      
      e.stopPropagation();
      e.stopEvent(); 
      
      
      if (this.grid) {
         try {
            this.grid.destroy();
         } catch(e) {}
      }
      
      this.grid = new Ext.nd.UIView({
         layout : this.layout,
         viewUrl : colConfig.resortviewunid,
         viewParams : "",
         container : this.container,
         statusPanel : this.statusPanel
      });
   } 
  },

  gridHandleCellClick: function(grid, rowIndex, colIndex, e) {
   var node, unid;
   
  },
  
  gridHandleRowContextMenu: function(grid, rowIndex, e) {
   e.stopEvent();
   
   var menu = new Ext.menu.Menu({
      id : 'xnd-context-menu'
   });
   menu.add({text : 'Document Properties', handler : this.gridContextMenuShowDocumentPropertiesDialog, scope: this});
   menu.addSeparator();
   menu.add({editMode : false, text : 'Open', handler : this.gridContextMenuOpenDocument, scope: this});
   menu.add({editMode : true, text : 'Edit', handler : this.gridContextMenuOpenDocument, scope: this});
   menu.addSeparator();
   menu.add({text : 'Search This View', handler : this.gridContextMenuSearchView, scope: this});
   
   
   
   menu.grid = grid;
   menu.rowIndex = rowIndex;
   var coords = e.getXY();
   menu.showAt([coords[0], coords[1]]);
  },

  gridContextMenuSearchView: function() {
   Ext.MessageBox.alert('Search View', 'In a future release, you will be able to search a view.');
   return;
  },

  gridContextMenuShowDocumentPropertiesDialog: function() {
   Ext.MessageBox.alert('Document Properties', 'In a future release, you will see a document properties box.');
   return;
    if(!this.dialog){ 
   this.dialog = new Ext.LayoutDialog("hello-dlg", { 
      modal:true,
      width:600,
      height:400,
      shadow:true,
      minWidth:300,
      minHeight:300,
      west: {
         split:true,
         initialSize: 150,
         minSize: 100,
         maxSize: 250,
         titlebar: true,
         collapsible: true,
         animate: true
          },
          center: {
         autoScroll:true,
         tabPosition: 'top',
         closeOnTab: true,
         alwaysShowTabs: true
          }
   });
   dialog.addKeyListener(27, dialog.hide, dialog);
   dialog.addButton('Submit', dialog.hide, dialog);
   dialog.addButton('Close', dialog.hide, dialog);

   var layout = dialog.getLayout();
   layout.beginUpdate();
   layout.add('west', new Ext.ContentPanel('west', {title: 'West'}));
   layout.add('center', new Ext.ContentPanel('center', {title: 'The First Tab'}));
   
   layout.add('center', new Ext.ContentPanel(Ext.id(), {
            autoCreate:true, title: 'Another Tab', background:true}));
   layout.add('center', new Ext.ContentPanel(Ext.id(), {
            autoCreate:true, title: 'Third Tab', closable:true, background:true}));
   layout.endUpdate();
    }
    dialog.show(showBtn.dom);
  },
  
  gridDeleteDocumentSuccess: function(o) {
   
   var row = o.argument;
   var ds = this.grid.dataSource;
   var sm = this.grid.selModel;
   var rowIndex = ds.indexOf(row);
   if (rowIndex == ds.data.length) {
      sm.selectRow(rowIndex);
   } else {
      sm.selectRow(rowIndex+1);
   }
   ds.remove(row);
  },
  
  removeRow: function(row) {
   ds.remove(row);
  },
  
  gridDeleteDocumentFailure: function(o) {
   Ext.MessageBox.alert('Delete Error','The document could not be deleted.  Please check your access.')
  },
  
  gridHandleRowsDeleted: function(row) {
   
  },

  gridHandleBeforeLoad: function(dm) {
   
  },
  
  loadView: function(view, dm) {
   if (this.statusPanel) {
      this.viewTitle = (typeof this.viewTitle == 'undefined') ? "" : this.viewTitle;
      this.statusPanel.setContent('Loading view ' + this.viewTitle + '...');
      this.statusPanel.getEl().removeClass('done');
   }
   ds.loadPage(1);
  },
  
  showError: function() {
   Ext.MessageBox.alert('Error','An error occurred.');
  },

  gridContextMenuOpenDocument: function(action, e) {
   var grid = action.parentMenu.grid;
   var rowIndex = action.parentMenu.rowIndex;
   var bEditMode = action.editMode;
   this.openDocument(grid, rowIndex, e, bEditMode);   
  },
  
  openDocument: function(grid, rowIndex, e, bEditMode) {
   var mode = (bEditMode) ? '?EditDocument' : '?OpenDocument';
   var title = "Opening...";
   var ds = grid.dataSource;
   var row = grid.selModel.getSelected();
   var node = row.node;
   var unid = node.attributes.getNamedItem('unid');
   
   if (!unid) { 
      return;
   } else {
      unid = unid.value;
   }
   var viewUrl = this.getViewUrl(grid);   
   var link = viewUrl + '/' + unid + mode     

   if (!this.layout) {
      window.open(link)
      return;
   }

      
   var entry = this.layout.getRegion('center').getPanel(unid);
            
   if(!entry){ 
      var iframe = Ext.DomHelper.append(document.body, {
         tag: 'iframe', 
         frameBorder: 0, 
         src: link,
         id : unid
      });
      var panel = new Ext.ContentPanel(iframe, {
         title: Ext.util.Format.ellipsis(title,16), 
         fitToFrame:true, 
         closable:true
      });
      this.layout.add('center', panel);

      
      var readyState;
      var id = setInterval( function() {
         try {
            var oContentDocument;
            if (document.getElementById(unid).contentDocument) {
               oContentDocument = document.getElementById(unid).contentDocument;
            } else {
               oContentDocument = document.frames[unid].document;
            }
            readyState = oContentDocument.readyState;
            if (readyState == 'complete') {
               title = oContentDocument.title;
               if (title != "") {
                  panel.setTitle(Ext.util.Format.ellipsis(title,16));
               } else {
                  panel.setTitle("Untitled");
               }
               clearInterval(id);
            }
         } catch (e) {clearInterval(id); }
      }, 50);
   } else { 
      this.layout.showPanel(entry);
   }
  },
  
  
  
  gridHandleRowDblClick: function(grid, rowIndex, e, bEditMode) {
    this.openDocument(grid, rowIndex, e, bEditMode);
  },
  
  deleteDocument: function(grid, rowIndex, e) {
   var ds = grid.dataSource;
   var row = grid.selModel.getSelected();
   var node = row.node;
   var unid = node.attributes.getNamedItem('unid');
   
   if (!unid) { 
      return;
   } else {
      unid = unid.value;
   }
   
   var viewUrl = this.getViewUrl(grid);   
   var deleteDocUrl = viewUrl + '/' + unid + '?DeleteDocument'
   var docExists = this.layout.getRegion('center').getPanel(unid);
   
   if (docExists) {
      Ext.MessageBox.alert("Delete Error","You have this document open in another tab.  Please close the document first before deleting.");
   } else {
      var cb = {
         success : this.gridDeleteDocumentSuccess, 
         failure : this.gridDeleteDocumentFailure, 
         argument: rowIndex,
         scope: this
      };    
   
      Ext.lib.Ajax.request('POST', deleteDocUrl, cb);

   }
  },
  
  getViewUrl: function(grid) {
   var viewUrlTmp = grid.dataSource.proxy.conn.url;
   var iLocReadViewEntries = viewUrlTmp.toLowerCase().indexOf('readviewentries') - 1; 
   var viewUrl = viewUrlTmp.substring(0,iLocReadViewEntries)
   return viewUrl;
  }
};

Ext.nd.UIWorkspace = function(config) {
  Ext.apply(this,config);
};

Ext.nd.UIWorkspace.prototype = {

  
  PickList : function(config) {
    var dialog, cb;
    var sess = Ext.nd.Session; 
    var db = sess.CurrentDatabase;

    
    this.server = "";
    this.dbPath = db.WebFilePath;
    this.viewName = "";
    this.width = 500;
    this.height = 400;
    this.shadow = true;
    this.minWidth = 500;
    this.minHeight = 400;
    this.type = "custom";
    this.select = "single";

    this.title = "PickList";
    this.prompt = "Please make your selection(s) and click <OK>.";
    this.column = 0;

    
    this.showSingleCategory = null;
    this.emptyText = 'Select a category...';
    this.showCategoryComboBox = false;
    this.categoryComboBoxCount = -1;
   
    
    Ext.apply(this,config);

    
    this.viewUrl = (this.viewUrl) ? this.viewUrl : this.dbPath + this.viewName;

    
    if (this.callback) {
       cb = this.callback;
       this.callback = false;
    }

    
    var pl = Ext.get('xnd-picklist');
    if (pl) {
       pl.remove(); 
    }
    if (this.uiView) {
       if (this.uiView.grid) {
          this.uiView.grid.destroy(); 
       }
    }

    
    if(!dialog){ 
      dialog = new Ext.LayoutDialog('xnd-picklist', { 
        autoCreate: true,
        modal:true,
        width:this.width,
        height:this.height,
        shadow:this.shadow,
        minWidth:this.minWidth,
        minHeight:this.minHeight,
        title:this.title,
        north : {
          titlebar : true
        },
        center : {
          autoScroll:true
        }
      });
      dialog.addKeyListener(27, handleOK, this);
      dialog.addButton('OK', handleOK, this);
      dialog.addButton('Cancel', handleCancel, this);

      
      var layout = dialog.getLayout();
      layout.beginUpdate();

      
      var promptPanel = layout.add('north', new Ext.ContentPanel('xnd-picklist-prompt', {autoCreate : true, title : this.prompt}));

      
      var viewPanel = layout.add('center', new Ext.ContentPanel('xnd-picklist-view', {
        autoCreate : true,
        title : this.title,
        closable : false,
        fitToFrame : true
      }));

      
      this.uiView = new Ext.nd.UIView({
        container : viewPanel,
        viewUrl : this.viewUrl,
        gridHandleRowDblClick : handleOK.createDelegate(this),
        showSingleCategory : this.showSingleCategory,
        emptyText : this.emptyText,
        showCategoryComboBox : this.showCategoryComboBox,
        categoryComboBoxCount : this.categoryComboBoxCount
      });

      
      layout.endUpdate();

    } 
      
    
    dialog.show();

    function handleOK() {
      var arSelections = this.uiView.grid.getSelections();
      var arReturn = new Array();
      dialog.hide();

      for (var i=0; i<arSelections.length; i++) {
        var map = arSelections[i].fields.keys[this.column];
        var data = arSelections[i].data[map].data;
        for (var d=0; d<data.length; d++) {
          arReturn.push(data[d]);
        }
      }

      
      if (cb) {
        cb(arReturn);
      } else {
        return arReturn; 
      }
    }

    function handleCancel() {
      dialog.hide();
      if (cb) {
        cb(null);
      } else {
        return null;
      }
    }

  },


  Prompt : function() {
    var cb;
    this.type = "ok";
   
    if (arguments.length > 0) {
      if (typeof arguments[0] == "object") {
        
        Ext.apply(this,arguments[0]);
      } else if (arguments.length >= 3) {
        this.type = arguments[0];
        this.title = arguments[1];
        this.prompt = arguments[2];   
      }
    }
   
    
    if (this.callback) {
      cb = this.callback;
      this.callback = false;
    }

    
    this.type = this.type.toLowerCase();
   
    switch (this.type) {
      case "ok" :
        Ext.MessageBox.alert(this.title, this.prompt, cb);
        break;
         
      default :
         Ext.MessageBox.alert("type '" + this.type + "', not yet supported");
    } 

  
  }
}; 


Ext.nd.UIWorkspace.PickListStrings = Ext.nd.UIWorkspace.PickList

Ext.nd.grid.DominoGrid = function(container, config){
	Ext.nd.grid.DominoGrid.superclass.constructor.call(this, container, config);
};

Ext.extend(Ext.nd.grid.DominoGrid, Ext.grid.Grid, {
  isDomino: true,
  
    
	getView : function(){
		if(!this.view){
			this.view = new Ext.nd.grid.DominoGridView();
		}
			return this.view;
		}
});


Ext.nd.Actionbar = function(config){
  var sess = Ext.nd.Session; 
  var db = sess.CurrentDatabase;
   
  
  this.dbPath = db.WebFilePath;
  this.noteType = '';
  this.noteName = '';
  this.useDxl = false;
  
  Ext.apply(this, config);
  Ext.nd.Actionbar.superclass.constructor.call(this, config.container);
   
  
  this.noteUrl = (this.noteUrl) ? this.noteUrl : this.dbPath + this.noteName;
  
  
  if (this.noteName == '') {
    var vni = this.noteUrl.lastIndexOf('/')+1;
    this.dbPath = this.noteUrl.substring(0,vni);
    this.noteName = this.noteUrl.substring(vni);
  }

  
  
  
  
  
  
  if(this.useDxl) {
    //this.add({text:'&nbsp;', id:'xnd-tb-tmp'});
  }
  
  
  this.createToolbar();

};

Ext.extend(Ext.nd.Actionbar, Ext.Toolbar, {
 
  createToolbar: function() {
    if (!this.useDxl) {
      this.createToolbarFromDocument();
      return;
    }
    var cb = {
      success : this.createToolbarFromDxl, 
      failure : this.createToolbarFailure,
      scope: this
    };    
    Ext.lib.Ajax.request('GET', this.dbPath + '($Ext.nd.NotesDxlExporter)?OpenAgent&type=' + this.noteType + '&name=' + this.noteName, cb); 
  },

  
  createToolbarFailure: function(res) {
    
  },
  
  createToolbarFromDocument: function(o) {
    var actionbar, arActions;
    var q = Ext.DomQuery;
    actionbar = this.getDominoActionbar();

    
    if (!actionbar) {
      this.add({text:'&nbsp;'}); 
      return; 
    }
    
    arActions = q.select('a',actionbar);
    var hasActionbar = (arActions.length > 0) ? true : false;
    
    var arJSONActions = [];
    var curLevelTitle = '';
    var isFirst = false;
    
    for (var i=0; i<arActions.length; i++) {
      var action = arActions[i];
      var title = action.lastChild.nodeValue;
      var slashLoc = (title) ? title.indexOf('\\') : -1;
      var imageRef = q.selectValue('img/@src',action, null);
      var cls = (title == null) ? 'x-btn-icon' : (imageRef) ? 'x-btn-text-icon' : null;
      
      if (slashLoc > 0) { 
        isSubAction = true;
        var arLevels = title.split('\\');
        var iLevels = arLevels.length;
        var tmpCurLevelTitle = title.substring(0,slashLoc);
        title = title.substring(slashLoc+1);
            
        if (tmpCurLevelTitle != curLevelTitle) {
          curLevelTitle = tmpCurLevelTitle
          isFirst = true;
        } else {
          isFirst = false;
        }
      } else {
        isSubAction = false;
        curLevelTitle = '';
      }

      
      var sHref, sOnclick, oOnclick, arOnclick;
      
      sHref = action.getAttribute('href',2); 
      
      if (sHref != '') {
        sOnclick = "location.href = '" + sHref + "';";
      } else {
        
        
        
        
        oOnclick = action.attributes['onclick'];
        if (oOnclick) {
          sOnclick = oOnclick.nodeValue;
        } else {
          sOnclick = ''
        }
          
        arOnclick = sOnclick.split('\r');
        arOnclick.splice(arOnclick.length-1,1); 
        sOnclick = arOnclick.join('\r');
      }
      
      
      var handler = function(bleh) { eval(bleh);}.createCallback(sOnclick);
        
      
      if (isSubAction) {
        
        if (isFirst) {
          if (i>0) {
            
            arJSONActions.push('-');
          }
          
          
          arJSONActions.push({
            text: curLevelTitle,
            menu: {
              items: [{
                text: title,
                cls: cls,
                icon: imageRef,
                handler: handler
              }]
            }
          }); 
              
        
        } else {
          
          arJSONActions[arJSONActions.length-1].menu.items.push({
            text: title,
            cls: cls,
            icon: imageRef,
            handler: handler
          });            
        }
      
      } else {
        if (i>0) {
          
          arJSONActions.push('-');
        }
        
        
        arJSONActions.push({            
          text: title,
          cls: cls,
          icon: imageRef,
          handler: handler
        });
      } 
    } 
    
    for (var i=0; i<arJSONActions.length; i++) {
      this.add(arJSONActions[i]);
    } 

    
    if (hasActionbar) {
      var tmp;
      tmp = actionbar.parentNode.removeChild(actionbar);
      tmp = null;                 
      var hr = q.selectNode('hr');
      tmp = hr.parentNode.removeChild(hr);
      tmp = null;
    }
  },
  
  getDominoActionbar: function() {
    
    var frm = document.forms[0]; 
    var isFirstTable = false;
    var q = Ext.DomQuery;
    
    var cn = frm.childNodes;
    var actionbar;
    var bTest1 = false; 
    var bTest2 = false; 
    var bTest3 = false; 
    var bTest4 = false; 
    
    for (var i=0; i<cn.length; i++) {
      var c = cn[i];
      if (c.nodeType == 1) {
        if (!bTest1) {
          if (c.tagName == 'TABLE') {
            actionbar = c;
            var arRows = q.select('tr',actionbar);
            if (arRows.length != 1) {
              break;
            } else {
              bTest1 = true;
              bTest2 = true;
              continue;
            }
          } else if (c.tagName == 'INPUT' && q.selectValue('@type',c,'') == 'hidden') {
            continue; 
          } else {
            break; 
          }
        } else { 
          if (c.tagName == 'HR'){
            bTest3 = true;
          }
          break; 
        } 
      } 
      if (bTest1 && bTest2 && bTest3) {
        
        break;
      }
    }
    
    if (bTest1 && bTest2 && bTest3) {
      
      var arTDs = q.select('td',actionbar);
      var arActions = q.select('a',actionbar);
      if (arTDs.length == arActions.length) {
        bTest4 = true;
        return actionbar;
      } else {
        return false;
      }
    } else {
      return false;
    }
    
  },
  
  createToolbarFromDxl: function(o) {
    var actionbar, arActions;
    var q = Ext.DomQuery;
    response = o.responseXML;
    arActions = q.select('action',response);
   
    var arJSONActions = [];
    var curLevelTitle = '';
    var isFirst = false;
    
    for (var i=0; i<arActions.length; i++) {
      var show = true;
      var action = arActions[i];

      var title = q.selectValue('@title',action,null);
      var hidewhen = q.selectValue('@hide',action,null);
      var showinbar = q.selectValue('@showinbar',action,null);
      var iconOnly = q.select('@onlyiconinbar',action);
      var icon = q.selectNumber('@icon',action,null);
      var imageRef = q.selectValue('imageref/@name',action,null);
      var syscmd = q.selectValue('@systemcommand',action,null);
      
      
      if (hidewhen) {
        var arHide = hidewhen.split(' ');
        for (var h=0; h<arHide.length; h++) {
          if (arHide[h] == 'web') {
            show = false;
          }
        }
      } 
      
      
      if (showinbar == 'false') {
        show = false;
      }
      
      if (icon) {
        if (icon < 10) {
          imageRef = "00"+icon;
        } else if (icon < 100) {
          imageRef = "0"+icon;
        } else {
          imageRef = ""+icon;
        }
        imageRef = "/icons/actn"+imageRef+".gif";
      }
       
      
      if (show && syscmd == null) {  
               
        var slashLoc = title.indexOf('\\');
        
        if (slashLoc > 0) { 
          isSubAction = true;
          var arLevels = title.split('\\');
          var iLevels = arLevels.length;
            
          var tmpCurLevelTitle = title.substring(0,slashLoc);
          title = title.substring(slashLoc+1);
            
          if (tmpCurLevelTitle != curLevelTitle) {
            curLevelTitle = tmpCurLevelTitle
            isFirst = true;
          } else {
            isFirst = false;
          }
        } else {
          isSubAction = false;
          curLevelTitle = '';
        }
         
        var tmpOnclick = Ext.DomQuery.selectValue('javascript',action,Ext.emptyFn);
        var handler = function(bleh) { eval(bleh);}.createCallback(tmpOnclick);
         
        if (isSubAction) {
          if (isFirst) {
            if (i>0) {
              
              arJSONActions.push('-');
            }
            
            arJSONActions.push({
              text: curLevelTitle,
              menu: {
                items: [{
                text: title,
                cls: (icon || imageRef) ? 'x-btn-text-icon' : null,
                icon: imageRef,
                handler: handler
              }]}
            }); 
          
          } else {
            
            arJSONActions[arJSONActions.length-1].menu.items.push({
              text: title,
              cls: (icon || imageRef) ? 'x-btn-text-icon' : null,
              icon: imageRef,
              handler: handler
            });            
          }
          
        } else {
          if (i>0) {
            
            arJSONActions.push('-');
          }
          
          arJSONActions.push({            
            text: title,
            cls: (icon || imageRef) ? 'x-btn-text-icon' : null,
            icon: imageRef,
            handler: handler
          }); 
        } 
      } 
    } 
    
    for (var i=0; i<arJSONActions.length; i++) {
      this.add(arJSONActions[i]);
    }
 }
});

Ext.nd.Form = function(config) {
   
  var sess = Ext.nd.Session; 
  var db = sess.CurrentDatabase;
  var uidoc = Ext.nd.UIDocument;
   
  
  this.dbPath = db.WebFilePath;
  this.showActionbar = true;
  this.toolbar = false; 
  this.toolbarContainer; 
  this.headerContainer; 
  this.bConvertFields = true;
  this.form = uidoc.form;
  this.formName = uidoc.formName;

  
  Ext.apply(this,config);
         
  
  this.formUrl = (this.formUrl) ? this.formUrl : this.dbPath + this.formName;
     
};

Ext.nd.Form.prototype = {

  render: function() {
    document.body.style.visibility = "hidden";
    var msg = Ext.MessageBox.wait("Loading document...");
    this.buildLayout();
    this.convertFields();
    msg.hide();
    document.body.style.visibility = "";
  },
 
  buildLayout: function() {

    var dh = Ext.DomHelper;
   
    
    var ui = dh.append(document.body,{tag:'div'});

    
    Ext.get(ui).dom.appendChild(this.form);
   
    
    if (this.showActionbar || this.toolbar) {
      if (!this.toolbar) {
        if (!this.toolbarContainer) {
          this.toolbarContainer = dh.append(ui,{tag: 'div'});
        }
        this.toolbar = new Ext.nd.Actionbar({
          container: this.toolbarContainer, 
          noteType: 'form', 
          noteName: this.formName
        });
      }
    } 

    
    
    if (!this.headerContainer) {
      this.headerContainer = this.toolbarContainer;
    }

    
    this.layout = new Ext.BorderLayout(document.body, {
      north : {titlebar: false},
      center: { }
    });
   
    this.layout.beginUpdate();
    this.layout.add('north', new Ext.ContentPanel(this.headerContainer));
    this.layout.add('center', new Ext.ContentPanel(ui, {fitToFrame : true, autoScroll : true}));
    this.layout.endUpdate();
    
  },
  
  convertFields: function() {

    var dh = Ext.DomHelper;
  
    
    var el, arClasses, cls;
    var q = Ext.DomQuery;
   
    if (this.bConvertFields) {
      
      var xndElements = this.form.elements;
      var converted;
      
      for (var i=0; i<xndElements.length; i++) {
        converted = false;
        el = xndElements[i];
        arClasses = el.className.split(' ');

        
        for (var c=0; c < arClasses.length; c++) {
          cls = arClasses[c];
   
          switch (cls) {
            case 'xnd-combobox' :
              var cb = new Ext.form.ComboBox({
                typeAhead : true,
                triggerAction : 'all',
                transform : el,
                forceSelection : true,
                resizable: true
              });
              var attr = el.attributes;
              if (attr) {
                var onChange = attr['onchange'];
                if (onChange) {
                  var sOnChange = onChange.nodeValue;
                  cb.on('select',function() { 
                    eval(sOnChange);
                  });
                }
              }
              converted = true;
              break;

            case 'xnd-date' :
              var dt = new Ext.form.DateField({
                selectOnFocus : true
              });      
              dt.applyTo(el);
              converted = true;
              break;
               
            default :
              break;               
          } 

        } 

        
        if (!converted) {
          switch(el.tagName) {
            case 'SELECT' :
              var cb = new Ext.form.ComboBox({
                typeAhead : true,
                triggerAction : 'all',
                transform : el,
                forceSelection : true,
                resizable: true
              });
              var attr = el.attributes;
              if (attr) {
                var onChange = attr['onchange'];
                if (onChange) {
                  var sOnChange = onChange.nodeValue;
                  cb.on('select',function() { 
                    eval(sOnChange);
                  });
                }
              }
              break;

            case 'TEXTAREA' :
              var ta = new Ext.form.TextArea({
                resizable: true
              });
              ta.applyTo(el);
              break;


            case 'INPUT' :
              var type = el.getAttribute('type');
              switch(type) {
                case 'hidden' :
                  break;
                case 'checkbox' :
                  
                  
                  break;
                default :
                  var f = new Ext.form.Field();
                  f.applyTo(el);
                  break;
              
              } 
              
            default :                  
              var f = new Ext.form.Field();
              f.applyTo(el);
              break;
              
          } 
          
        } 
   
         
      } 
      
    } 

  } 


};


